index.vue 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937
  1. <template>
  2. <div :class="`${prefixCls}__wrapper`">
  3. <RenderLjDetail v-bind="currentMould" :data="props.data" />
  4. <SettingWidget v-if="currentMould" v-bind="currentMould" ref="DetailSettingRef" @confirm="toSetDetailBase" />
  5. <!-- v-if="toolButton.length && toolButton.indexOf('print') > -1" -->
  6. <PrintEditor ref="printEditorRef" @closed="toClosedPrintEditor" />
  7. <PrintTemplateSelector
  8. ref="printTemplateRef"
  9. @newtemplate="toEditPrintTemplate"
  10. @edittemplate="toEditPrintTemplate"
  11. @preview="toPreviewPrintTemplate"
  12. @confirm="toPrintPrintTemplate"
  13. @closed="toGetPrinterState"
  14. />
  15. </div>
  16. </template>
  17. <script setup lang="tsx" name="LjDetail">
  18. import { ref, reactive, onMounted, useSlots, nextTick, provide, watch, computed, toRefs, inject } from "vue";
  19. import { Tools, ArrowUpBold, Printer, Setting } from "@element-plus/icons-vue";
  20. import { DetailProp, detailModelItemProp } from "./interface";
  21. import { useDesign } from "@/hooks/useDesign";
  22. import { useI18n } from "vue-i18n";
  23. import Affix from "./components/Affix.vue";
  24. import SettingWidget from "./components/Setting.vue";
  25. import { useLayoutLocalStore } from "@/stores/modules/layoutLocal";
  26. import { getDifference, setDifference, handleProp, streamlineFunc, streamlineAttrFunc, convertStrToObj } from "@/utils";
  27. import { cloneDeep, pick, get, omit, defaultsDeep } from "lodash-es";
  28. import LjHeader from "@/components/LjHeader/index.vue";
  29. import BaseMsgForm from "@/components/BaseMsgForm/index.vue";
  30. import LjFoldLayout from "@/components/LjFoldLayout/index.vue";
  31. import BaseForm from "./components/BaseForm.vue";
  32. import ButtonGroup from "./components/ButtonGroup.vue";
  33. import DropdownList from "./components/DropdownList.vue";
  34. import { ColumnProps, dwnameSaveLayoutAttr } from "@/components/LjVxeTable/interface";
  35. import { useLayoutStore } from "@/stores/modules/layout";
  36. import { useRoute } from "vue-router";
  37. import { useAuthButtons } from "@/hooks/useAuthButtons";
  38. import { ElNotification } from "element-plus";
  39. import { ElMessage } from "element-plus";
  40. import { useTable } from "@/hooks/useTable";
  41. import { useDwLayout } from "@/hooks/useDwLayout";
  42. import {
  43. TABLE_LAYOUT_ATTR,
  44. TABLE_LAYOUT_ATTR_DEFINE,
  45. DETAIL_BASICINFO_FORM_DEFINE,
  46. DETAIL_LAYOUT_ATTR,
  47. DETAIL_LAYOUT_DEFINE,
  48. PRINT_KEY_ATTR,
  49. TABLE_TYPE_FILTER,
  50. ALLOW_EDIT_STATE
  51. } from "@/config/index";
  52. import { useGlobalStore } from "@/stores/modules/global";
  53. // import BaseCardTimeline from "./components/BaseCardTimeline.vue";
  54. import { isFunction, isNumber, isArray } from "@/utils/is";
  55. import { usePrint } from "@/hooks/usePrint";
  56. import variables from "@/styles/js.module.scss";
  57. import PrintEditor from "@/components/PrintEditor/index.vue";
  58. import PrintTemplateSelector from "@/components/Selector/PrintTemplate/index.vue";
  59. const { t } = useI18n();
  60. /** 默认使用通用接口,并只读第一条数据作为主表数据 */
  61. const props = withDefaults(defineProps<DetailProp>(), {
  62. columns: () => [],
  63. data: () => [],
  64. rightFixedAction: () => [],
  65. rightFixedActionPower: () => [],
  66. requestAuto: true,
  67. pagination: true,
  68. initParam: {},
  69. layoutAttr: () => TABLE_LAYOUT_ATTR,
  70. layoutAttrDefine: () => TABLE_LAYOUT_ATTR_DEFINE,
  71. searchCol: () => ({ xs: 2, sm: 4, md: 5, lg: 6, xl: 6 }),
  72. basicGroupCol: () => ({ xs: 3, sm: 3, md: 6, lg: 6, xl: 6 }),
  73. autoLoadLayout: false,
  74. ifFoldLayout: true,
  75. ifLayoutEditable: true,
  76. ifBasicEditable: true,
  77. detailLayoutAttr: () => [
  78. "scrollspy",
  79. "sticky",
  80. "id",
  81. "props",
  82. "isHidden",
  83. "descColumn",
  84. "size",
  85. "direction",
  86. "border",
  87. "direction",
  88. "foldleft",
  89. "foldright",
  90. "mxprops",
  91. "originLeft",
  92. "originTop"
  93. ],
  94. editable: false
  95. });
  96. const slots: any = useSlots();
  97. const { prefixCls } = useDesign("detail-layout");
  98. const LjDetailRef = ref();
  99. const LjDetailBaseFormRef = ref();
  100. const LjDetailAffixRef = ref();
  101. const LjFoldLayoutRef = ref();
  102. const headerAffixTop = ref(0);
  103. const headerAffixHeight = ref(0);
  104. const _variables: any = variables;
  105. const layoutLocalStore = useLayoutLocalStore();
  106. // 布局暂存数据
  107. const layoutStore = useLayoutStore();
  108. /**
  109. * @description 过滤主表基础信息配置项
  110. */
  111. let infoColumns = ref<ColumnProps[]>([]);
  112. let infoParam = ref<any>({});
  113. /**
  114. * @description 查询后的主表结果
  115. */
  116. const mainData_api = ref();
  117. /**
  118. * @description 查询后的详情结果
  119. */
  120. const detailData_api = ref();
  121. /**
  122. * @description 主表数据,影子,只读
  123. */
  124. // const _mainData = computed(() => tableData.value[0] ?? props.data[0] ?? infoParam.value);
  125. // const _mainData = computed(() => {
  126. // // console.log("_mainData tableData.value[0] :>> ", tableData.value, tableData.value[0]);
  127. // // console.log("_mainData props.data.value[0] :>> ", props.data, props.data[0]);
  128. // // console.log("_mainData infoParam.value[0] :>> ", infoParam.value);
  129. // // console.log(
  130. // // "tableData.value[0] ?? props.data[0] ?? infoParam.value :>> ",
  131. // // tableData.value[0] ?? (props.data.length && props.data[0]) ?? infoParam.value,
  132. // // tableData.value[0] ?? { ...infoParam.value, ...props.data[0] }
  133. // // );
  134. // return tableData.value[0] ?? { ...infoParam.value, ...props.data[0] };
  135. // });
  136. const _mainData = ref<any>({});
  137. /**
  138. * @description 详情数据,影子,只读
  139. */
  140. const _detailData = computed(() => detailData_api.value);
  141. const tabsActive = ref();
  142. /**
  143. * @description 当前页面参数
  144. */
  145. const currentMould = ref<any>();
  146. const isScrollspy = computed(() => {
  147. console.log("isScrollspy currentMould.value :>> ", currentMould.value);
  148. console.log("DETAIL_LAYOUT_DEFINE :>> ", DETAIL_LAYOUT_DEFINE);
  149. return currentMould.value?.header?.tabsProp?.scrollspy ?? DETAIL_LAYOUT_DEFINE.tabsProp.scrollspy;
  150. });
  151. /**
  152. * @description 树形化:接收 columns 并设置为响应式
  153. */
  154. const globalStore = useGlobalStore();
  155. const route = useRoute();
  156. const orderStatus = ref<"edit" | "new" | string>("");
  157. provide("orderStatus", orderStatus);
  158. /**
  159. * @description 基础信息模块,是否可编辑
  160. */
  161. const editable = computed(() => {
  162. return ALLOW_EDIT_STATE.includes(orderStatus.value);
  163. });
  164. provide("editable", editable);
  165. // 页面按钮权限(按钮权限既可以使用 hooks,也可以直接使用 v-auth 指令,指令适合直接绑定在按钮上,hooks 适合根据按钮权限显示不同的内容)
  166. const { CheckPower, funcFilterPower, funcRightActionPower } = useAuthButtons(t);
  167. const layoutHeader = computed(() => {
  168. console.log("layoutHeader currentMould.value :>> ", currentMould.value);
  169. return currentMould.value.header;
  170. });
  171. const currentLayout = inject("currentLayout", ref<any>(null));
  172. console.log("Ljdetail currentLayout :>> ", currentLayout);
  173. /**
  174. * @description fold布局过滤保留字段
  175. * @enum string width hidden lastWidth
  176. */
  177. const FoldLayoutFilterAttr = ["width", "hidden", "lastWidth"];
  178. const emit = defineEmits(["update:orderStatus", "toPinDetail", "afterMounted"]);
  179. const basicinfoFormDefaultComputed = Object.assign(DETAIL_BASICINFO_FORM_DEFINE, props.basicDefault);
  180. // 表格参数:init
  181. let tableOptions = reactive<dwnameSaveLayoutAttr>({});
  182. console.log("onload!!!tableOptions :>> ", tableOptions);
  183. const loadLayoutCallBack = (data: any) => {
  184. console.log("loadLayoutCallBack data :>> ", data);
  185. if (data?.hasOwnProperty("tableprop") && data.tableprop) {
  186. tableOptions = data.tableprop;
  187. console.log("loadLayoutCallBack bfff tableOptions :>> ", tableOptions);
  188. // read
  189. let _loadBase = cloneDeep(tableOptions.basicinfo ?? {});
  190. let _oriBase = cloneDeep(basicinfoFormDefaultComputed);
  191. if (!_oriBase?.basicGroup) _oriBase.basicGroup = [];
  192. if (!_loadBase?.basicGroup) _loadBase.basicGroup = [];
  193. console.log("_oriBase :>> ", _oriBase);
  194. console.log("_loadBase :>> ", _loadBase);
  195. // 补充默认分组中,差异的部分
  196. _loadBase.basicGroup.forEach((item: any) => {
  197. let idx = _oriBase.basicGroup.findIndex((i: any) => i.label === item.label);
  198. if (idx == -1) {
  199. _oriBase.basicGroup.push({ label: item.label });
  200. }
  201. });
  202. console.log("aff _oriBase :>> ", _oriBase);
  203. tableOptions.basicinfo = setDifference(_oriBase, tableOptions.basicinfo, "label");
  204. console.log("loadLayoutCallBack tableOptions :>> ", tableOptions);
  205. }
  206. };
  207. // 通用查询接口返回的布局数据,保存
  208. const loadDwLayout = (data: any) => {
  209. console.log("layout data:>> ", data);
  210. // 表格结构: {tableprop: string, columns: string}
  211. // typeof layout.itemvalue == "string" && (layout.itemvalue = JSON.parse(layout.itemvalue.replace(/'/g, '"')));
  212. // 兼容部分结构直接记录行数据
  213. if (data.hasOwnProperty("columns") && data.columns) {
  214. dwLayout.value = data.columns;
  215. } else {
  216. dwLayout.value = data;
  217. }
  218. console.log("loadDwLayout bff data :>> ", props.dwname, data);
  219. loadLayoutCallBack(data);
  220. console.log("loadDwLayout affffffff data :>> ", props.dwname, data);
  221. props.dwname && layoutStore.setDwLayout(props.dwname, data, t, false);
  222. console.log("onMounted dwLayout.value :>> ", dwLayout.value);
  223. loadDwLayoutFunc(dwLayout.value);
  224. // tableColumns.value = cloneDeep(props.columns);
  225. console.log("数行化BF,还原个性设置 tableColumns.value :>> ", tableColumns.value);
  226. // 扁平化,并读取个性设置
  227. flatColumns.value = flatColumnsFunc(cloneDeep(props.columns), dwFieldMap);
  228. console.log("读取个性设置 flatColumns.value loadDwLayout:>> ", flatColumns.value);
  229. initLayoutColumns();
  230. };
  231. // 表格操作 Hooks
  232. const {
  233. tableData,
  234. pageable,
  235. searchParam,
  236. totalParam,
  237. searchInitParam,
  238. tableLoading,
  239. getTableList
  240. // search,
  241. // reset,
  242. // handleSizeChange,
  243. // handleCurrentChange,
  244. // handlePageChange
  245. } = useTable(
  246. props.requestApi,
  247. props.initParam,
  248. props.pagination,
  249. props.dataCallback,
  250. props.requestError,
  251. props.dwname,
  252. undefined,
  253. !props.autoLoadLayout,
  254. loadDwLayout
  255. );
  256. const flatColumnsCallBack = (col: any) => {
  257. col.field == "status" && console.log(" flatColumnsCallBack col :>> ", col);
  258. // 设置 enumMap
  259. setEnumMap(col);
  260. // // 设置 表格基础信息-format枚举
  261. // setBaseEnumMap(col);
  262. return col;
  263. };
  264. // 主表布局读取与存储
  265. const {
  266. tableColumns,
  267. dwLayout,
  268. dwFieldMap,
  269. flatColumns,
  270. loadLayoutFunc,
  271. loadDwLayoutFunc,
  272. flatColumnsFunc,
  273. getDefineAttr,
  274. loadRenderAttr,
  275. columnStreamlineFunc,
  276. getOriColumns
  277. } = useDwLayout(
  278. "detail",
  279. t,
  280. cloneDeep(props.columns),
  281. props.layoutAttr,
  282. props.layoutAttrDefine,
  283. props.autoLoadLayout,
  284. props.dwname,
  285. loadLayoutCallBack,
  286. flatColumnsCallBack
  287. );
  288. /**
  289. * @description 当前已选列表
  290. */
  291. const selectRecords = ref<any>();
  292. /**
  293. * @description 打印前检测状态
  294. */
  295. const funcBeforePrintCheck = () => {
  296. let _status = true;
  297. selectRecords.value = [];
  298. console.log("funcBeforePrintCheck _mainData.value :>> ", _mainData.value);
  299. if (_mainData.value && _mainData.value.length) {
  300. selectRecords.value = [_mainData.value[0]];
  301. }
  302. console.log("funcBeforePrintCheck selectRecords.value :>> ", selectRecords.value);
  303. props.beforePrintCallback && (_status = props.beforePrintCallback(selectRecords.value));
  304. console.log("beforePrintCallback _status :>> ", _status);
  305. return _status;
  306. };
  307. const getSelectRecords = () => {
  308. return selectRecords.value;
  309. };
  310. const {
  311. printEditorRef,
  312. printTemplateRef,
  313. printerListTpDropdownRef,
  314. activePrint,
  315. hiprinterStateList,
  316. hiprinterStateMx,
  317. printerTpList,
  318. toGetPrinterState,
  319. openPrint,
  320. openPrintPriveiew,
  321. toPreviewPrintTemplate,
  322. toPrintPrintTemplate,
  323. toEditPrintTemplate,
  324. checkPrintTemplateList
  325. } = usePrint(t, props.dwname, getSelectRecords, funcBeforePrintCheck, props.printDataCallback);
  326. /**
  327. * 关闭后,是否刷新打印模板列表页
  328. * @param saved 是否有保存过
  329. */
  330. const toClosedPrintEditor = (saved: boolean) => {
  331. saved && printTemplateRef.value?.getData();
  332. };
  333. const handleCheckPrintTemplateList = () => {
  334. console.log("handleCheckPrintTemplateList 1:>> ");
  335. checkPrintTemplateList("", () => {
  336. console.log("handleCheckPrintTemplateList 2:>> printerListTpDropdownRef.value", printerListTpDropdownRef.value);
  337. printerListTpDropdownRef.value && printerListTpDropdownRef.value.handleOpen();
  338. });
  339. };
  340. /**
  341. * @description 获取主表数据
  342. * @return void
  343. * */
  344. // const getMainData = async () => {
  345. // if (!props.mainApi?.requestApi) return;
  346. // try {
  347. // // 先把初始化参数和分页参数放到总参数里面
  348. // // Object.assign(state.totalParam, props.initParam, {});
  349. // // console.log("state.totalParam :>> ", state.totalParam);
  350. // // state.tableLoading = true;
  351. // console.log("props.initParam :>> ", props.mainApi?.initParam);
  352. // let data = await props.mainApi?.requestApi({ ...props.mainApi?.initParam });
  353. // props.mainApi?.dataCallback && (data = props.mainApi?.dataCallback(data));
  354. // // state.tableData = isPageable ? data.list : data;
  355. // // state.tableLoading = false;
  356. // console.log("getMainData data :>> ", data);
  357. // mainData_api.value = data;
  358. // // state.tableData = data[reqProp];
  359. // } catch (error) {
  360. // props.mainApi?.requestError && props.mainApi?.requestError(error);
  361. // // state.tableLoading = false;
  362. // }
  363. // };
  364. // // 监听主表 initParam 改化,重新获取表格数据
  365. // watch(() => props.mainApi?.initParam, getMainData, { deep: true });
  366. /**
  367. * @description 获取详情数据
  368. * @return void
  369. * */
  370. // const getDetailData = async () => {
  371. // nextTick(() => {
  372. // console.log("getDetailData LjDetailAffixRef.value :>> ", LjDetailAffixRef.value);
  373. // LjDetailAffixRef.value && LjDetailAffixRef.value.update();
  374. // });
  375. // if (!props.detailApi?.requestApi) return;
  376. // try {
  377. // // 先把初始化参数和分页参数放到总参数里面
  378. // // Object.assign(state.totalParam, props.initParam, {});
  379. // // console.log("state.totalParam :>> ", state.totalParam);
  380. // // state.tableLoading = true;
  381. // console.log("props.initParam :>> ", props.detailApi?.initParam);
  382. // let data = await props.detailApi?.requestApi({ ...props.detailApi?.initParam });
  383. // props.detailApi?.dataCallback && (data = props.detailApi?.dataCallback(data));
  384. // // state.tableData = isPageable ? data.list : data;
  385. // // state.tableLoading = false;
  386. // console.log("getDetailData data :>> ", data);
  387. // detailData_api.value = data;
  388. // // state.tableData = data[reqProp];
  389. // } catch (error) {
  390. // props.detailApi?.requestError && props.detailApi?.requestError(error);
  391. // // state.tableLoading = false;
  392. // }
  393. // };
  394. // // 监听详情 initParam 改化,重新获取表格数据
  395. // watch(() => props.detailApi?.initParam, getDetailData, { deep: true });
  396. /**
  397. * @description 打开设置界面
  398. */
  399. const DetailSettingRef = ref();
  400. const handleShowDetailSetting = () => {
  401. DetailSettingRef.value.show();
  402. };
  403. const orderBtnGroup = ref([]);
  404. const orderOtherFunc = ref([]);
  405. // 读取个性布局,用Map()储存
  406. // const dwFieldMap = new Map<string, any>();
  407. // const loadDwLayoutFunc = (loadLayout: any) => {
  408. // console.log("loadLayout.value :>> ", loadLayout);
  409. // if (JSON.stringify(loadLayout) == "{}") return false;
  410. // // // 个性布局加顺序号
  411. // // for (const i in loadLayout) {
  412. // // loadLayout[i].colorder = Number(i);
  413. // // }
  414. // // 个性布局构建键值Map()
  415. // dwFieldMap.clear();
  416. // for (const item of loadLayout) {
  417. // dwFieldMap.set(item.field, item);
  418. // }
  419. // console.log("dwFieldMap :>> ", dwFieldMap);
  420. // };
  421. // // // 扁平化 初始化 columns
  422. // const flatColumnsFunc = (columns: ColumnProps[], flatArr: ColumnProps[] = []) => {
  423. // columns.forEach(async (col: any) => {
  424. // if (col._children?.length) flatArr.push(...flatColumnsFunc(col._children));
  425. // flatArr.push(col);
  426. // // 给每一项 column 添加默认属性
  427. // // col.visible = col?.visible == false ? false : props.layoutAttrDefine.visible; // true
  428. // // col.width = col.width ?? props.layoutAttrDefine.width; // 200
  429. // // col.align = col.align ?? props.layoutAttrDefine.align; // "center"
  430. // // col.sortable = col.sortable ?? props.layoutAttrDefine.sortable; // false
  431. // // col.order = col.order ?? props.layoutAttrDefine.order; // ""
  432. // // col.fixed = col.fixed ?? props.layoutAttrDefine.fixed; // ""
  433. // // col.isFilterEnum = col.isFilterEnum ?? true;
  434. // // 读取个性设置属性
  435. // if (dwFieldMap.size) {
  436. // let userStyle = dwFieldMap.get(col.field);
  437. // if (userStyle) {
  438. // for (let prop of props.layoutAttr) {
  439. // if (userStyle.hasOwnProperty(prop) && prop != "title") {
  440. // col[prop] = userStyle[prop];
  441. // }
  442. // }
  443. // col.colorder = userStyle.colorder;
  444. // if (userStyle.search && col.search) {
  445. // col.search.order = userStyle.search.order ?? undefined;
  446. // col.search.span = userStyle.search.span ?? undefined;
  447. // col.search.labelPosition = userStyle.search.labelPosition ?? undefined;
  448. // col.search.labelWidth = userStyle.search.labelWidth ?? undefined;
  449. // }
  450. // }
  451. // }
  452. // // 搜索栏,读取个性设置属性
  453. // if (col.basicinfo) {
  454. // col.basicinfo.labelPosition = col.basicinfo.labelPosition ?? props.basicinfoLayoutAttrDefine.labelPosition; // "top"
  455. // col.basicinfo.labelWidth = col.basicinfo.labelWidth ?? props.basicinfoLayoutAttrDefine.labelWidth; // 120
  456. // col.basicinfo.span = col.basicinfo.span ?? props.basicinfoLayoutAttrDefine.span; // 1
  457. // }
  458. // // 设置 enumMap
  459. // setEnumMap(col);
  460. // });
  461. // // 读取个性设置后,排序,
  462. // if (dwFieldMap.size) {
  463. // flatArr.sort((a, b) => {
  464. // return a.colorder! - b.colorder!;
  465. // });
  466. // }
  467. // return flatArr.filter(item => !item._children?.length);
  468. // };
  469. // 定义 enumMap 存储 enum 值(避免异步请求无法格式化单元格内容 || 无法填充搜索下拉选择)
  470. const enumMap = ref(new Map<string, { [key: string]: any }[]>());
  471. /**
  472. * @description 当编辑状态不是从route中获取时,需要手动更新
  473. */
  474. watch(
  475. () => props.enum,
  476. (val: any) => {
  477. val &&
  478. val.forEach((val: any, key: any) => {
  479. enumMap.value.set(key, val);
  480. });
  481. },
  482. { immediate: true, deep: true }
  483. );
  484. // if (props.enum) {
  485. // props.enum.forEach((val: any, key: any) => {
  486. // enumMap.value.set(key, val);
  487. // });
  488. // }
  489. provide("mainEnumMap", enumMap);
  490. const setEnumMap = async (col: ColumnProps) => {
  491. if (!col.enum) return;
  492. console.log("deftail setEnumMap col :>> ", col);
  493. // 如果当前 enum 为后台数据需要请求数据,则调用该请求接口,并存储到 enumMap
  494. if (typeof col.enum !== "function") {
  495. let _enum = col.enum!;
  496. if (col.enumFilter) {
  497. _enum = col.enumFilter(totalParam.value, _enum, orderStatus.value);
  498. }
  499. return enumMap.value.set(col.field!, _enum);
  500. }
  501. const data = await col.enum();
  502. enumMap.value.set(col.field!, data);
  503. };
  504. /**
  505. * @description 当前布局
  506. */
  507. const dwnameLayout = computed(() => {
  508. return props.dwname + "__layout-detail";
  509. });
  510. // /**
  511. // * @description 当前基础信息的布展示列field集合
  512. // */
  513. // const showFields = ref<string[]>([]);
  514. const initLayoutColumns = () => {
  515. console.log("initLayoutColumns enumMap :>> ", enumMap);
  516. // 数行化,还原个性设置
  517. tableColumns.value = loadRenderAttr(flatColumns.value);
  518. // tableRef.value?.reloadColumn(tableColumns.value);
  519. console.log("数行化,还原个性设置 tableColumns.value :>> ", tableColumns.value);
  520. console.log("数行化,还原个性设置 flatColumns.value :>> ", flatColumns.value);
  521. // /**过滤主表基础信息配置项 */
  522. // let _showColumns = [];
  523. // switch (orderStatus.value) {
  524. // case "new":
  525. // _showColumns = tableColumns.value.filter((item: any) => {
  526. // if (item.basicinfo?.el || item.basicinfo?.render) {
  527. // return item.basicinfo?.editable ? item.basicinfo?.editable.includes("new") : true;
  528. // } else {
  529. // return false;
  530. // }
  531. // });
  532. // break;
  533. // case "edit":
  534. // _showColumns = tableColumns.value.filter((item: any) => {
  535. // if (item.basicinfo?.el || item.basicinfo?.render) {
  536. // return item.basicinfo?.editable ? item.basicinfo?.editable.includes("edit") : true;
  537. // } else {
  538. // return false;
  539. // }
  540. // });
  541. // break;
  542. // default:
  543. // _showColumns = tableColumns.value.filter(
  544. // (item: any) => !TABLE_TYPE_FILTER.includes(item.type!) && item.field !== "operation" && item.visible !== false
  545. // );
  546. // break;
  547. // }
  548. // // showFields.value = _showColumns.map((item: any) => item.field);
  549. // console.log("detail init infoColumns.value :>> ", _showColumns);
  550. // console.log("detail init tableColumns.value :>> ", tableColumns.value);
  551. // // if (props.mainDwname) {
  552. // // let basicLayout = [];
  553. // // console.log("basemsg indexawait layoutStore.getDwLayout(props.dwname) :>> ", await layoutStore.getDwLayout(props.mainDwname));
  554. // // let layout = await layoutStore.getDwLayout(props.mainDwname);
  555. // // console.log("layout :>> ", layout);
  556. // // if (layout?.hasOwnProperty("itemvalue") && layout.itemvalue) {
  557. // // typeof layout.itemvalue == "string" && (layout.itemvalue = JSON.parse(layout.itemvalue.replace(/'/g, '"')));
  558. // // // 兼容部分结构直接记录行数据
  559. // // if (layout.itemvalue.hasOwnProperty("columns") && layout.itemvalue.columns) {
  560. // // basicLayout = layout.itemvalue.columns;
  561. // // } else {
  562. // // basicLayout = layout.itemvalue;
  563. // // }
  564. // // }
  565. // // loadDwLayoutFunc(basicLayout);
  566. // // }
  567. // // // 扁平化,并读取个性设置
  568. // // infoColumns.value = flatColumnsFunc(_showColumns, dwFieldMap);
  569. // 过滤需要搜索的配置项
  570. infoColumns.value = flatColumns.value.filter((item: any) => item.field && item.field != "pid");
  571. console.log("detail init bf end infoColumns.value :>> ", infoColumns.value, infoParam.value);
  572. // console.log("detail init 1end infoColumns.value :>> ", infoColumns.value);
  573. // 设置搜索表单排序默认值 && 设置搜索表单项的默认值
  574. infoColumns.value.forEach((column, index) => {
  575. !Object.keys(column).includes("basicinfo") && (column.basicinfo = {});
  576. column.basicinfo!.order = column.basicinfo!.order ?? index + 2;
  577. if (column.basicinfo?.defaultValue !== undefined && column.basicinfo?.defaultValue !== null) {
  578. // searchInitParam.value[column.basicinfo.key ?? handleProp(column.field!)] = column.basicinfo?.defaultValue;
  579. infoParam.value[column.basicinfo.key ?? handleProp(column.field!)] = column.basicinfo?.defaultValue;
  580. } else {
  581. // 为新增单据的时候赋值
  582. let defVal: string | number = "";
  583. column?.basicinfo?.el == "input-number" && (defVal = 0);
  584. infoParam.value[column?.basicinfo?.key ?? handleProp(column.field!)] = column.basicinfo?.defaultValue ?? defVal;
  585. }
  586. column.rules = column.basicinfo?.rules ?? undefined;
  587. });
  588. console.log("props.defaultColumnsValue :>> ", props.defaultColumnsValue);
  589. infoParam.value = defaultsDeep(cloneDeep(props.defaultColumnsValue), infoParam.value);
  590. // // 表格搜索栏,设置缓存搜索信息
  591. // Object.assign(searchParam.value, queryHabit);
  592. // 第一次搜索带入参数
  593. // totalParam.value = searchParam.value;
  594. /** 赋值初始化搜索表单 */
  595. if (props.initParam) {
  596. for (const key in props.initParam) {
  597. !Object.keys(searchParam.value).includes(key) && (searchParam.value[key] = props.initParam[key]);
  598. }
  599. }
  600. // 第一次搜索带入参数
  601. totalParam.value = searchParam.value;
  602. console.log("detail infoParam.value :>> ", infoParam.value);
  603. // 排序搜索表单项
  604. infoColumns.value.sort((a, b) => a.basicinfo!.order! - b.basicinfo!.order!);
  605. console.log("detail init end infoColumns.value :>> ", infoColumns.value);
  606. // console.log("searchParam.value :>> ", searchParam.value);
  607. };
  608. const init = async () => {
  609. // 初始化布局
  610. await loadLayoutFunc();
  611. initLayoutColumns();
  612. props.action && (orderBtnGroup.value = funcFilterPower(props.action));
  613. props.rightAction && (orderOtherFunc.value = funcRightActionPower(props.rightAction));
  614. };
  615. /**
  616. * @description 读取布局
  617. */
  618. const getLayout = async () => {
  619. let res: any = await layoutLocalStore.getLayoutAttr(dwnameLayout.value);
  620. console.log("LJgetLayout getLayout res :>> ", res);
  621. console.log("LJgetLayout props :>> ", props);
  622. let _props = omit(props, ["mainData"]);
  623. console.log("LJgetLayout _props :>> ", _props);
  624. let _define = defaultsDeep(_props, { header: DETAIL_LAYOUT_DEFINE });
  625. console.log("LJgetLayout _define :>> ", _define);
  626. currentMould.value = setDifference(_define, res);
  627. console.log("LJgetLayout currentMould.value :>> ", currentMould.value);
  628. // 加载主表-基础信息布局
  629. await init();
  630. };
  631. /**
  632. * @description 页面刷新
  633. */
  634. const layoutRefresh = inject("layoutRefresh", () => {});
  635. /**
  636. * @description 悬浮按钮位置变化时,保存悬浮按钮位置
  637. */
  638. const toSetFloatBtnChange = (id: string, left: number, top: number) => {
  639. console.log("detail funcFloatBtnChange field, left ,top :>> ", id, left, top);
  640. let _layout = cloneDeep(currentMould.value);
  641. let _idx = _layout.header.floatbtn.findIndex((item: any) => item.id == id);
  642. if (_idx > -1) {
  643. _layout.header.floatbtn[_idx].originLeft = left;
  644. _layout.header.floatbtn[_idx].originTop = top;
  645. } else {
  646. _layout.header.floatbtn.push({
  647. id,
  648. originLeft: left,
  649. originTop: top
  650. });
  651. }
  652. let _props = pick(props, DETAIL_LAYOUT_ATTR);
  653. funcSaveDwLayout(_props, _layout, false, false);
  654. };
  655. /**
  656. * @description 保存当前布局
  657. */
  658. const toSetDetailBase = (layout: any, callback?: any, toast: boolean = true) => {
  659. console.log("LJgetLayout props :>> ", props);
  660. console.log("toSetDetailBase layout :>> ", JSON.stringify(layout));
  661. let _props = pick(props, DETAIL_LAYOUT_ATTR);
  662. /** 原布局清空部分属性,为保留该属性下全部属性值;这些属性,需要在传输进来前处理(精简化处理,过滤默认值)*/
  663. _props.header.foldright = {};
  664. _props.header.foldleft = {};
  665. _props.header.mxprops = {};
  666. // let _layout = pick(layout, DETAIL_LAYOUT_ATTR);
  667. // console.log("_layout :>> ", _layout);
  668. // let diff = getDifference(_props, _layout, props.detailLayoutAttr);
  669. // console.log("toSetDetailBase diff :>> ", diff);
  670. // let _toast = toast ? t : undefined;
  671. // // 保存布局
  672. // layoutLocalStore.setDwLayout(dwnameLayout.value, diff, _toast).then(() => {
  673. // if (callback) {
  674. // callback();
  675. // layoutRefresh();
  676. // }
  677. // // callback && callback();
  678. // currentMould.value = layout;
  679. // });
  680. funcSaveDwLayout(_props, layout, callback, toast);
  681. };
  682. const funcSaveDwLayout = (arg_prop: any, layout: any, callback?: any, toast: boolean = true) => {
  683. let _layout = pick(layout, DETAIL_LAYOUT_ATTR);
  684. console.log("_layout :>> ", _layout);
  685. console.log("arg_prop :>> ", arg_prop);
  686. let diff = getDifference(arg_prop, _layout, props.detailLayoutAttr);
  687. console.log("toSetDetailBase diff :>> ", diff);
  688. let _toast = toast ? t : undefined;
  689. // 保存布局
  690. layoutLocalStore.setDwLayout(dwnameLayout.value, diff, _toast).then(() => {
  691. if (callback) {
  692. callback();
  693. layoutRefresh();
  694. }
  695. // callback && callback();
  696. currentMould.value = layout;
  697. });
  698. };
  699. const beforeToSetting = () => {
  700. if (props.ifFoldLayout && LjFoldLayoutRef.value) {
  701. console.log("LjFoldLayoutRef.value.currentLayout :>> ", LjFoldLayoutRef.value.currentLayout);
  702. let _layout = LjFoldLayoutRef.value.currentLayout;
  703. if (_layout.right.width > 0 && _layout.right.lastWidth == 0) {
  704. let curWidth = _layout.right.width;
  705. _layout.right.lastWidth = curWidth;
  706. _layout.right.width = 0;
  707. toSaveFoldLayout(_layout, "foldright", "right");
  708. }
  709. }
  710. };
  711. const beforeCloseSetting = () => {
  712. if (props.ifFoldLayout && LjFoldLayoutRef.value) {
  713. console.log("LjFoldLayoutRef.value.currentLayout :>> ", LjFoldLayoutRef.value.currentLayout);
  714. let _layout = LjFoldLayoutRef.value.currentLayout;
  715. if (_layout.right.width == 0 && _layout.right.lastWidth > 0) {
  716. let curWidth = _layout.right.lastWidth;
  717. _layout.right.width = curWidth;
  718. _layout.right.lastWidth = 0;
  719. toSaveFoldLayout(_layout, "foldright", "right");
  720. }
  721. }
  722. };
  723. /**
  724. * @description 监听框架属性变化
  725. */
  726. const toSaveFoldLayout = (layout: any, saveAttr: string, readAttr: string) => {
  727. console.log("toSaveFoldLayout layout :>> ", layout);
  728. let _layout = cloneDeep(currentMould.value);
  729. let _define = cloneDeep(_layout.header[saveAttr]);
  730. _layout.header[saveAttr] = pick({ ..._define, ...layout[readAttr] }, FoldLayoutFilterAttr);
  731. toSetDetailBase(_layout, false, false);
  732. };
  733. // const columnStreamlineFunc = (column: any, searchColumns: any) => {
  734. // let saveCol = streamlineFunc(column, props.layoutAttr, props.layoutAttrDefine);
  735. // console.log("columnStreamlineFunc settingConfirm bf saveCol :>> ", saveCol);
  736. // // 简化搜索储存字段,以props.basicinfoLayoutAttr为标准
  737. // let searchMap = streamlineAttrFunc(searchColumns, props.basicinfoLayoutAttr, props.basicinfoLayoutAttrDefine, "basicinfo");
  738. // // let searchMap = new Map();
  739. // // for (let item of searchColumns) {
  740. // // let saveProp = cloneDeep(props.basicinfoLayoutAttr);
  741. // // if (item.basicinfo) {
  742. // // for (let key in props.basicinfoLayoutAttrDefine) {
  743. // // if (item.basicinfo.hasOwnProperty(key) && props.basicinfoLayoutAttrDefine[key] === item.basicinfo[key]) {
  744. // // saveProp.splice(saveProp.indexOf(key), 1);
  745. // // }
  746. // // }
  747. // // searchMap.set(item.field, pick(item.basicinfo, saveProp));
  748. // // }
  749. // // }
  750. // // 合并
  751. // if (searchMap.size) {
  752. // for (let item of saveCol) {
  753. // let _map = searchMap.get(item.field);
  754. // if (_map) {
  755. // item.basicinfo = _map;
  756. // }
  757. // }
  758. // }
  759. // console.log("columnStreamlineFunc settingConfirm aaaf saveCol :>> ", saveCol);
  760. // return saveCol;
  761. // };
  762. /**
  763. * @description 基础设置: 保存基础信息布局方法
  764. * @param columns 处理后的基础信息布局,[group,....]
  765. * @param formParams basicinfo参数
  766. * @param {boolean} online 是否获取线上版本
  767. * @param {number} empid 员工id
  768. */
  769. const saveColumnsFunc = async (argColumns: any, formParams: any, online: boolean = false, empid?: number) => {
  770. let _data = cloneDeep(argColumns);
  771. let scol: any = [];
  772. /**还原:一维数组 */
  773. _data.map((item: any) => {
  774. let _list = item.list.map((itm: any) => {
  775. // itm.basicinfo.group = item.label;
  776. if (item.label) {
  777. itm.basicinfo.group = item.label;
  778. } else {
  779. itm.basicinfo.group = itm.basicinfo.group || itm.basicinfo.group === "" ? "" : undefined;
  780. }
  781. itm.basicinfo.visible = itm.basicinfo.visible !== false;
  782. return itm;
  783. });
  784. scol = scol.concat(_list);
  785. });
  786. /**记录顺序 */
  787. scol.forEach((item: any, index: number) => (item.basicinfo.order = index + 1));
  788. console.log("sort scol dwFieldMap:>> ", scol, JSON.stringify(dwFieldMap.get("typeid")));
  789. // 获取原始数据列
  790. let oriColumns = await getOriColumns(false, online, empid);
  791. // let oriColumns = cloneDeep(flatColumns.value);
  792. console.log("saveColumnsFunc oriColumns dwFieldMap:>> ", oriColumns, dwFieldMap);
  793. // loadDwLayoutFunc(oriColumns, true);
  794. // 仅仅读取详情页的basicinfo部分,其他读取原有
  795. let loadMaps = new Map();
  796. for (const sitm of scol) {
  797. let oriMap = dwFieldMap.get(sitm.field);
  798. console.log("sitm :>> ", oriMap, sitm);
  799. if (oriMap) {
  800. oriMap.basicinfo = sitm.basicinfo ?? oriMap.basicinfo;
  801. } else {
  802. oriMap = sitm;
  803. }
  804. loadMaps.set(sitm.field, oriMap);
  805. }
  806. console.log("after!!! dwFieldMap :>> ", dwFieldMap);
  807. console.log("after!!! loadMaps :>> ", JSON.stringify(loadMaps));
  808. console.log("after!!! oriColumns :>> ", JSON.stringify(oriColumns));
  809. // 扁平化,并读取个性设置
  810. let _saveCol = flatColumnsFunc(oriColumns.columns, loadMaps);
  811. console.log("saveBasicSettingFunc _saveCol :>> ", _saveCol);
  812. // let _save = cloneDeep(tableOptions);
  813. // _save.basicinfo = formParams;
  814. let oriOtherParams = omit(oriColumns, ["columns"])?.tableprop ?? tableOptions;
  815. oriOtherParams.basicinfo = formParams;
  816. console.log("_save :>> ", oriOtherParams);
  817. console.log("(props.columns) :>> ", JSON.stringify(props.columns));
  818. return columnStreamlineFunc(_saveCol, oriOtherParams, props.columns);
  819. };
  820. /**
  821. * @description 搜索栏,布局保存
  822. * @param columns 数据列
  823. * @param formParams basicinfo参数
  824. * @param callback 完成保存后返回
  825. */
  826. const saveBasicSettingFunc = async (columns: any, formParams: any, callback: any) => {
  827. if (!props.dwname) {
  828. ElMessage.error("LjDetail未设置储存的模版名称,无法保存");
  829. return false;
  830. }
  831. console.log("saveBasicSettingFunc columns :>> ", columns);
  832. console.log("saveBasicSettingFunc formParams :>> ", JSON.stringify(formParams));
  833. console.log("saveBasicSettingFunc formParams :>> ", formParams);
  834. let layout = await saveColumnsFunc(columns, formParams);
  835. console.log("saveBasicSettingFunc await layout :>> ", layout);
  836. // 保存布局-主表
  837. await layoutStore.setDwLayout(props.dwname, layout, t);
  838. // 复原各属性enum
  839. layout.columns.forEach((item: any) => {
  840. if (enumMap.value.has(item.field)) {
  841. item.enum = enumMap.value.get(item.field);
  842. }
  843. });
  844. loadDwLayoutFunc(layout.columns);
  845. tableColumns.value = cloneDeep(props.columns);
  846. console.log("after loadDwLayoutFunc dwFieldMap.value :>> ", tableColumns.value, dwFieldMap);
  847. // 扁平化,并读取个性设置
  848. flatColumns.value = flatColumnsFunc(tableColumns.value, dwFieldMap);
  849. initLayoutColumns();
  850. loadLayoutCallBack(layout);
  851. callback && callback();
  852. };
  853. /**
  854. * @description 基础设置: 保存系统默认模版
  855. */
  856. const saveDefaultLayout = async (columns: any, formParams: any, callback?: any) => {
  857. if (!props.dwname) {
  858. ElMessage.error("LjVextable组件未设置储存的模版名称,无法保存");
  859. return false;
  860. }
  861. let layout = await saveColumnsFunc(columns, formParams, true, -1);
  862. console.log("saveDefaultLayout layout :>> ", layout);
  863. await layoutStore.saveDwLayout_online(-1, props.dwname, layout);
  864. callback && callback();
  865. };
  866. const initLayoutColFunc = (data: any) => {
  867. console.log("initLayoutColFunc enumMap :>> ", enumMap);
  868. let result = cloneDeep(data);
  869. loadRenderAttr(result.columns);
  870. console.log("result.columns :>> ", JSON.stringify(result.columns));
  871. // 过滤需要搜索的配置项
  872. result.columns = result.columns.filter((item: any) => item.field && item.field != "pid");
  873. console.log("detail init bf end infoColumns.value :>> ", result.columns);
  874. // console.log("detail init 1end infoColumns.value :>> ", infoColumns.value);
  875. // 设置搜索表单排序默认值 && 设置搜索表单项的默认值
  876. result.columns.forEach((column: any, index: number) => {
  877. !Object.keys(column).includes("basicinfo") && (column.basicinfo = {});
  878. column.basicinfo!.order = column.basicinfo!.order ?? index + 2;
  879. if (column.basicinfo?.defaultValue !== undefined && column.basicinfo?.defaultValue !== null) {
  880. // searchInitParam.value[column.basicinfo.key ?? handleProp(column.field!)] = column.basicinfo?.defaultValue;
  881. infoParam.value[column.basicinfo.key ?? handleProp(column.field!)] = column.basicinfo?.defaultValue;
  882. } else {
  883. // 为新增单据的时候赋值
  884. let defVal: string | number = "";
  885. column?.basicinfo?.el == "input-number" && (defVal = 0);
  886. infoParam.value[column?.basicinfo?.key ?? handleProp(column.field!)] = column.basicinfo?.defaultValue ?? defVal;
  887. }
  888. column.rules = column.basicinfo?.rules ?? undefined;
  889. });
  890. // // 表格搜索栏,设置缓存搜索信息
  891. // Object.assign(searchParam.value, queryHabit);
  892. // 第一次搜索带入参数
  893. // totalParam.value = searchParam.value;
  894. console.log("detail infoParam.value :>> ", infoParam.value);
  895. // 排序搜索表单项
  896. result.columns.sort((a: any, b: any) => a.basicinfo!.order! - b.basicinfo!.order!);
  897. console.log("initLayoutColFunc detail init end infoColumns.value :>> ", result);
  898. // console.log("searchParam.value :>> ", searchParam.value);
  899. return result;
  900. };
  901. /**
  902. * @description 基础设置: 重置
  903. */
  904. const resetBasicSettingFunc = async (callback: any) => {
  905. // 获取原始数据列
  906. let oriColumns = await getOriColumns(true, true, -1, enumMap.value, props.columns);
  907. console.log("resetBasicSettingFunc enumMap :>> ", enumMap.value);
  908. console.log("resetBasicSettingFunc oriColumns -1:>> ", oriColumns);
  909. oriColumns = initLayoutColFunc(oriColumns);
  910. callback && callback(oriColumns);
  911. // if (oriColumns.columns.length) {
  912. // callback && callback(oriColumns);
  913. // } else {
  914. // ElMessage.warning(t("sys.layout.empty") + props.dwname);
  915. // // 获取原始数据列
  916. // oriColumns = await getOriColumns(true);
  917. // console.log("resetBasicSettingFunc oriColumns :>> ", oriColumns);
  918. // if (oriColumns.columns.length) {
  919. // oriColumns = initLayoutColFunc(oriColumns);
  920. // callback && callback(oriColumns);
  921. // } else {
  922. // ElMessage.warning(t("sys.layout.singleEmpty"));
  923. // callback && callback({ columns: props.columns, tableprop: { basicinfo: tableOptions.basicinfo } });
  924. // }
  925. // }
  926. // layoutStore.getDwLayout_online(-1, props.dwname!, 0).then((layout: any) => {
  927. // console.log("resetBasicSettingFunc layout :>> ", layout);
  928. // if (layout?.hasOwnProperty("itemvalue") && layout.itemvalue) {
  929. // let dwLayout: ColumnProps[] = [];
  930. // console.log("resetSetting loadLayoutFunc layout :>> ", layout);
  931. // if (layout?.hasOwnProperty("itemvalue") && layout.itemvalue) {
  932. // // 表格结构: {tableprop: string, columns: string}
  933. // typeof layout.itemvalue == "string" && (layout.itemvalue = JSON.parse(layout.itemvalue.replace(/'/g, '"')));
  934. // // 兼容部分结构直接记录行数据
  935. // if (layout.itemvalue.hasOwnProperty("columns") && layout.itemvalue.columns) {
  936. // dwLayout = layout.itemvalue.columns;
  937. // } else {
  938. // dwLayout = layout.itemvalue;
  939. // }
  940. // }
  941. // // 读取默认属性
  942. // loadDwLayoutFunc(props.columns, false);
  943. // let prototype = flatColumnsFunc(dwLayout, dwFieldMap);
  944. // /**备用(重置):原始数据列 */
  945. // let _oriCol = prototype.filter((item: any) => !TABLE_TYPE_FILTER.includes(item.type!) && item.field !== "operation");
  946. // /**只重置basicinfo的属性 */
  947. // let _columns = flatColumns.value.map((item: any) => {
  948. // let oriItem = _oriCol.find((oriItem: any) => oriItem.field == item.field);
  949. // return {
  950. // ...item,
  951. // basicinfo: oriItem?.basicinfo ?? {}
  952. // };
  953. // });
  954. // _columns = _columns.filter((item: any) => item.field && item.field != "pid");
  955. // console.log("resetBasicSettingFunc _columns :>> ", _columns);
  956. // callback && callback(_columns);
  957. // } else {
  958. // ElMessage.warning(t("sys.layout.empty") + props.dwname);
  959. // callback && callback([]);
  960. // }
  961. // });
  962. };
  963. /**
  964. * 检查功能权限
  965. * @param action detail/edit/add 赋值动作
  966. * @param power 权限值
  967. * @param powerFunc 状态判断函数
  968. * @param errorback 错误返回
  969. */
  970. const checkPowerFunc = (action: string, power: number | any, errorback: any) => {
  971. if (power) {
  972. if (isNumber(power)) {
  973. if (CheckPower(power)) {
  974. orderStatus.value = action;
  975. } else {
  976. orderStatus.value = "";
  977. errorback && errorback();
  978. }
  979. } else if (isFunction(power)) {
  980. if (power(_mainData.value)) {
  981. orderStatus.value = action;
  982. } else {
  983. orderStatus.value = "";
  984. errorback && errorback();
  985. }
  986. }
  987. } else {
  988. orderStatus.value = action;
  989. }
  990. };
  991. // const headerStatusList = ref<ColumnProps[]>([]);x
  992. // const getHeaderStatus = () => {
  993. // if (!props.headerstatus?.length) return;
  994. // headerStatusList.value = infoColumns.value.filter((item: any) => props.headerstatus!.includes(item.field));
  995. // };
  996. /**
  997. * @description 点击tabs标题
  998. */
  999. const handleClickTabs = (data: any) => {
  1000. // 启用foldLayout布局时,点击tabs标题时,若是折叠了,自动恢复
  1001. if (LjFoldLayoutRef.value) {
  1002. let _layout = LjFoldLayoutRef.value.currentLayout;
  1003. if (_layout.right.lastWidth > 0) {
  1004. LjFoldLayoutRef.value.foldRight();
  1005. }
  1006. }
  1007. // 记录当前tabs状态
  1008. if (props.dwname) {
  1009. let _detailtabs = globalStore.detailtabs ?? {};
  1010. _detailtabs[props.dwname] = data.name;
  1011. globalStore.setGlobalState("detailtabs", _detailtabs);
  1012. }
  1013. };
  1014. /**
  1015. * @description 表单校验
  1016. * @param formEl
  1017. */
  1018. const toValidateForm = async () => {
  1019. const { element } = LjDetailBaseFormRef.value;
  1020. if (!element) return;
  1021. return await element.validate();
  1022. };
  1023. /**
  1024. * @description 当编辑状态不是从route中获取时,需要手动更新
  1025. */
  1026. watch(
  1027. () => props.orderStatus,
  1028. (val: any) => {
  1029. val && (orderStatus.value = val);
  1030. },
  1031. { immediate: true }
  1032. );
  1033. onMounted(async () => {
  1034. if (route.path.indexOf("new") > -1) {
  1035. checkPowerFunc("new", props.addPower, () => {
  1036. ElNotification({
  1037. title: t("sys.api.operationFailed"),
  1038. message: t("sys.errorLog.notPower") + ":" + props.addPower,
  1039. type: "warning"
  1040. });
  1041. });
  1042. console.log("反向更新订单状态 orderStatus.value :>> ", orderStatus.value);
  1043. // 反向更新订单状态
  1044. emit("update:orderStatus", orderStatus.value);
  1045. } else if (route.path.indexOf("edit") > -1) {
  1046. checkPowerFunc("edit", props.editPower, () => {
  1047. ElNotification({
  1048. title: t("sys.api.operationFailed"),
  1049. message: t("sys.errorLog.notPower") + ":" + props.editPower,
  1050. type: "warning"
  1051. });
  1052. });
  1053. // 反向更新订单状态
  1054. emit("update:orderStatus", orderStatus.value);
  1055. } else if (route.path.indexOf("copy") > -1) {
  1056. checkPowerFunc("copy", props.editPower, () => {
  1057. ElNotification({
  1058. title: t("sys.api.operationFailed"),
  1059. message: t("sys.errorLog.notPower") + ":" + props.editPower,
  1060. type: "warning"
  1061. });
  1062. });
  1063. // 反向更新订单状态
  1064. emit("update:orderStatus", orderStatus.value);
  1065. }
  1066. console.log("反向更新订单状态 orderStatus.value :>> ", orderStatus.value, props.orderStatus);
  1067. // 读取布局记录
  1068. await getLayout().then(() => {
  1069. nextTick(() => {
  1070. let element = document.getElementById(prefixCls);
  1071. headerAffixTop.value = element?.getBoundingClientRect().top ?? 0;
  1072. headerAffixHeight.value = document.querySelector("." + prefixCls + "__header")?.clientHeight ?? 0;
  1073. console.log("onMounted LjDetailAffixRef.value :>> ", LjDetailAffixRef.value);
  1074. });
  1075. // if (orderStatus.value != "new") {
  1076. // props.mainApi?.requestAuto && getMainData();
  1077. // props.detailApi?.requestAuto && getDetailData();
  1078. // }
  1079. });
  1080. if (props.requestAuto) {
  1081. getTableList().then(() => {
  1082. console.log("getTableList orderStatus.value :>> ", orderStatus.value, tableData.value);
  1083. if (props.requestApi && !tableData.value.length && orderStatus.value != "new") {
  1084. ElNotification({
  1085. title: t("sys.api.selectFailed"),
  1086. message: t("sys.api.selectFailedMessage"),
  1087. type: "warning"
  1088. });
  1089. } else {
  1090. emit("afterMounted", _mainData.value);
  1091. }
  1092. });
  1093. } else {
  1094. console.log("onMounted detail end!!!! :>> ");
  1095. emit("afterMounted", _mainData.value);
  1096. }
  1097. });
  1098. const toPinDetailClick = () => {
  1099. emit("toPinDetail");
  1100. };
  1101. /**
  1102. * @description render 右侧固定菜单(print printMx),下拉Item
  1103. */
  1104. const RenderPrinterTpItem = (item: any) => {
  1105. return (
  1106. <el-dropdown-item class="flx-justify-between" onClick={() => openPrintPriveiew("", item, Boolean(item.printer))}>
  1107. {item.aliase || item.printid}
  1108. {item.printer && (
  1109. <el-tooltip
  1110. effect="dark"
  1111. content={t("sys.print.directPrint")}
  1112. placement="top"
  1113. show-after={200}
  1114. enterable={false}
  1115. hide-after={0}
  1116. >
  1117. <i class="iconfont iconflash ml-8" style={{ color: _variables.colorPolarGreen4 }}></i>
  1118. </el-tooltip>
  1119. )}
  1120. </el-dropdown-item>
  1121. );
  1122. };
  1123. /**
  1124. * @description 过滤表格按钮权限
  1125. * @param type 按钮类型
  1126. */
  1127. const getRightActionPower = (type: string) => {
  1128. let _idx = props.rightFixedAction.indexOf(type);
  1129. if (_idx > -1) {
  1130. if (
  1131. props.rightFixedActionPower.length &&
  1132. _idx < props.rightFixedActionPower.length &&
  1133. props.rightFixedActionPower[_idx] != 0
  1134. ) {
  1135. return CheckPower(props.rightFixedActionPower[_idx]);
  1136. } else {
  1137. return true;
  1138. }
  1139. }
  1140. return false;
  1141. };
  1142. /**
  1143. * @description 打印模板下拉列表
  1144. */
  1145. const getRenderRightFixedAction = () => {
  1146. let _render: any = [];
  1147. console.log("getRenderRightFixedAction :>> ", props.rightFixedAction);
  1148. if (!props.rightFixedAction.length) return _render;
  1149. props.rightFixedAction.map((itemAction: any) => {
  1150. console.log("itemAction :>> ", itemAction, getRightActionPower(itemAction));
  1151. switch (itemAction) {
  1152. case "print":
  1153. if (printerTpList.value.length) {
  1154. console.log("printerTpList.value :>> ", printerTpList.value);
  1155. printerTpList.value.map((item: any) => {
  1156. _render.push(RenderPrinterTpItem(item));
  1157. });
  1158. }
  1159. console.log("_render_dd_item :>> ", _render);
  1160. break;
  1161. case "printMx":
  1162. // 明细打印
  1163. break;
  1164. default:
  1165. break;
  1166. }
  1167. });
  1168. console.log("_render.length, _render :>> ", _render.length, _render);
  1169. return _render;
  1170. };
  1171. /**
  1172. * @deascription 渲染:默认头部render
  1173. * @param rProp prop
  1174. */
  1175. const RenderHeaderDefault = (rProp: any) => {
  1176. console.log("RenderHeaderDefault rProp :>> ", rProp);
  1177. console.log("RenderHeaderDefault _mainData.value :>> ", _mainData.value);
  1178. let nameValue = convertStrToObj(_mainData.value, props.header.fieldNames?.name);
  1179. let _params =
  1180. orderStatus.value == "new" ? infoParam.value : orderStatus.value == "edit" ? reactive(_mainData.value) : _mainData.value;
  1181. let _assemblySize = globalStore.assemblySize == "small" ? "default" : "large";
  1182. let _height = globalStore.assemblySize == "small" ? "32px" : "40px";
  1183. let pinBtnSlot = {
  1184. icon: () => {
  1185. return (
  1186. <i
  1187. class={{
  1188. iconfont: true,
  1189. "iconpin-02": currentLayout.value?.right.hidden,
  1190. "iconpin-01": !currentLayout.value?.right.hidden
  1191. }}
  1192. ></i>
  1193. );
  1194. }
  1195. };
  1196. let allowPowerAction = orderBtnGroup.value;
  1197. /**
  1198. * @description 折叠的单据功能菜单
  1199. */
  1200. let _render_right_action: any = [];
  1201. let hasRightAction = rProp?.rightAction && rProp.rightAction.length;
  1202. if (hasRightAction) {
  1203. orderOtherFunc.value.map((item: any) => {
  1204. _render_right_action.push(
  1205. <DropdownList
  1206. update={nameValue}
  1207. target="detail-button-group"
  1208. buttons={item}
  1209. data={_params}
  1210. assemblySize={_assemblySize}
  1211. />
  1212. );
  1213. });
  1214. }
  1215. /**
  1216. * @description 右侧固定下拉菜单
  1217. */
  1218. let _render_right_fixed_action: any = [];
  1219. let hasRightFixedAction = rProp?.rightFixedAction && rProp.rightFixedAction.length;
  1220. if (hasRightFixedAction) {
  1221. rProp.rightFixedAction.map((itemAction: any) => {
  1222. if (!getRightActionPower(itemAction)) return;
  1223. switch (itemAction) {
  1224. case "print":
  1225. // 订单打印
  1226. let _render_dd_item = getRenderRightFixedAction();
  1227. let hasPrinterList = Boolean(printerTpList.value.length);
  1228. let _slotsRightFixedAction = {
  1229. dropdown: () => {
  1230. return (
  1231. <>
  1232. <el-dropdown-menu>
  1233. <>
  1234. {hasPrinterList && _render_dd_item}
  1235. <el-dropdown-item divided={hasPrinterList} onClick={() => openPrint("")}>
  1236. <div class="flx-center">
  1237. <el-icon>
  1238. <Setting />
  1239. </el-icon>
  1240. {t("common.setText")}
  1241. </div>
  1242. </el-dropdown-item>
  1243. </>
  1244. </el-dropdown-menu>
  1245. </>
  1246. );
  1247. }
  1248. };
  1249. _render_right_fixed_action.push(
  1250. <el-dropdown
  1251. trigger="contextmenu"
  1252. placement="bottom-end"
  1253. ref={printerListTpDropdownRef}
  1254. v-slots={_slotsRightFixedAction}
  1255. >
  1256. <el-button icon={Printer} circle onClick={handleCheckPrintTemplateList}></el-button>
  1257. </el-dropdown>
  1258. );
  1259. break;
  1260. case "printMx":
  1261. // 明细打印
  1262. break;
  1263. default:
  1264. break;
  1265. }
  1266. });
  1267. }
  1268. return (
  1269. <>
  1270. {allowPowerAction.length > 0 && (
  1271. <div class={["flx w-full flx-justify-between", `${prefixCls}__header-inner`]} style={{ height: _height }}>
  1272. <div class="flx-start flx-1" id="detail-button-group">
  1273. <ButtonGroup
  1274. update={nameValue}
  1275. target="detail-button-group"
  1276. buttons={allowPowerAction}
  1277. data={_params}
  1278. assemblySize={_assemblySize}
  1279. ></ButtonGroup>
  1280. </div>
  1281. <div class="flx-end flx-shrink mr-12">
  1282. {nameValue && (
  1283. <>
  1284. <span class={["text-h4-r", "text-disable", hasRightAction ? "mr-8" : ""]}>{nameValue}</span>
  1285. </>
  1286. )}
  1287. {_render_right_action}
  1288. {_render_right_fixed_action}
  1289. {(nameValue || hasRightAction) && <el-divider direction="vertical" />}
  1290. <div class="setting-part">
  1291. {rProp.ifLayoutEditable && <el-button circle icon={Tools} onClick={handleShowDetailSetting}></el-button>}
  1292. {currentLayout.value && (
  1293. <el-button class="tag-item" circle onClick={toPinDetailClick} v-slots={pinBtnSlot}></el-button>
  1294. )}
  1295. {slots.rightBtn && slots.rightBtn?.({ data: _mainData.value })}
  1296. </div>
  1297. </div>
  1298. </div>
  1299. )}
  1300. </>
  1301. );
  1302. };
  1303. const RenderDetailHeader = (rProp: any) => {
  1304. console.log("route.meta.icon :>> ", route.meta.icon);
  1305. let iconRender = [];
  1306. // if (rProp.header?.icon) {
  1307. // switch (typeof rProp?.header.icon) {
  1308. // case "object":
  1309. // iconRender.push(<el-icon>{rProp.header.icon.render()}</el-icon>);
  1310. // break;
  1311. // case "function":
  1312. // iconRender.push(rProp.header.icon());
  1313. // break;
  1314. // case "string":
  1315. // iconRender.push(<i class={["iconfont", rProp.header.icon]} />);
  1316. // break;
  1317. // default:
  1318. iconRender.push(<i class={["iconfont", route.meta.icon]} />);
  1319. // break;
  1320. // }
  1321. // }
  1322. console.log("iconRender :>> ", iconRender);
  1323. let codeValue = convertStrToObj(_mainData.value, props.header.fieldNames?.code);
  1324. // console.log("rProp.headerstatus :>> ", props.headerstatus);
  1325. // let statusRender: any = [];
  1326. // if (props.headerstatus?.length) {
  1327. // let headerStatusList = infoColumns.value.filter((item: any) => props.headerstatus!.includes(item.field));
  1328. // headerStatusList.map((item: any) => {
  1329. // console.log("headerStatusList item :>> ", item);
  1330. // if (!item.render) {
  1331. // /** 复选框 */
  1332. // if (item?.datatype == "checkbox") {
  1333. // // item.render = (scope: any) => {
  1334. // // let _keys = Object.keys(scope);
  1335. // // let _data = _keys.includes("row") ? scope.row : _keys.includes("searchParam") ? scope.searchParam : scope;
  1336. // // let _field = scope?.column.field ?? "";
  1337. // switch (Number(_mainData.value[item.field])) {
  1338. // case 1:
  1339. // statusRender.push(<el-checkbox class={"el-checkbox__disabled-checked"} checked={true} disabled={true} />);
  1340. // default: // 0
  1341. // let bool = false;
  1342. // statusRender.push(<el-checkbox v-model={bool} disabled={true} />);
  1343. // }
  1344. // }
  1345. // // }
  1346. // // /**普通:enum,数值转文本 */
  1347. // // if (item.enum && item.enum.length) {
  1348. // // item.render = (scope: any) => {
  1349. // // let _keys = Object.keys(scope);
  1350. // // let _data: any = _keys.includes("row") ? scope.row : _keys.includes("searchParam") ? scope.searchParam : scope;
  1351. // // let _field = scope?.column.field ?? "";
  1352. // // let _item: any = {};
  1353. // // scope.enum && (_item = scope.enum.find((item: any) => item.value == Number(_data[_field])));
  1354. // // return _item?.label ?? "";
  1355. // // };
  1356. // // }
  1357. // } else {
  1358. // statusRender.push(item.render({ scope: _mainData.value[0], column: item, enum: item.enum }));
  1359. // }
  1360. // });
  1361. // }
  1362. // console.log("statusRender :>> ", statusRender);
  1363. const childrenSlot = {
  1364. template: () => {
  1365. return (
  1366. <>
  1367. <el-skeleton-item variant="caption" />
  1368. <el-skeleton-item variant="text" style="width: 50%;" />
  1369. </>
  1370. );
  1371. }
  1372. };
  1373. return (
  1374. <>
  1375. {/* <div class={["flx w-full flx-start", `${prefixCls}__header-inner`]}> */}
  1376. <div class={`flx-start ${prefixCls}__detail-header`}>
  1377. <div class={`${prefixCls}__header-icon flx-center mr-8`}>{iconRender}</div>
  1378. <div class="text-h4-m flx-col">
  1379. <el-skeleton style="width: 220px;height:50px" animated loading={!codeValue} v-slots={childrenSlot}>
  1380. {convertStrToObj(_mainData.value, props.header.fieldNames?.name)}
  1381. {codeValue && (
  1382. <span class="text-body-m text-secondary-text">
  1383. {(props.header.fieldNames?.codeLabel ? props.header.fieldNames.codeLabel : "") + codeValue}
  1384. </span>
  1385. )}
  1386. </el-skeleton>
  1387. </div>
  1388. {/* {codeValue && (
  1389. <span class="text-h4-r text-secondary-text">
  1390. {(props.header.fieldNames?.codeLabel ? props.header.fieldNames.codeLabel : "") + codeValue}
  1391. </span>
  1392. )} */}
  1393. {/* <div class="setting-part">{statusRender}</div> */}
  1394. </div>
  1395. {/* </div> */}
  1396. </>
  1397. );
  1398. };
  1399. const tasItemRender = (data: detailModelItemProp, renderFnc: any, header = true, disabled = false) => {
  1400. let val = _detailData.value && _detailData.value[data.id];
  1401. // console.log(" _detailData.value :>> ", _detailData.value, data.id);
  1402. let vanSlot: any = {};
  1403. if (slots[data.id + "__tabtitle"]) {
  1404. vanSlot.title = () => {
  1405. return <>{slots[data.id + "__tabtitle"]?.({ data: val, props: data })}</>;
  1406. };
  1407. }
  1408. if (isScrollspy.value && slots[data.id + "_header"]) {
  1409. vanSlot[data.id + "_header"] = () => {
  1410. if (slots[data.id + "_header"]) {
  1411. return slots[data.id + "_header"]?.({ data: val, props: data });
  1412. } else if (header) {
  1413. return <LjHeader title={data.label}></LjHeader>;
  1414. }
  1415. };
  1416. }
  1417. vanSlot.default = () => renderFnc();
  1418. return <van-tab name={data.id} title={data.label} disabled={disabled} v-slots={vanSlot}></van-tab>;
  1419. // return (
  1420. // <van-tab name={data.id} title={data.label} v-slots={vanSlot}>
  1421. // <>
  1422. // {isScrollspy.value &&
  1423. // (slots[data.id + "_header"]
  1424. // ? slots[data.id + "_header"]?.({ data: val, props: data })
  1425. // : header && <LjHeader title={data.label}></LjHeader>)}
  1426. // </>
  1427. // {renderFnc()}
  1428. // </van-tab>
  1429. // );
  1430. };
  1431. /**
  1432. * @deascription 渲染:van-tabs主体
  1433. * @param rProp prop
  1434. */
  1435. const RenderTabs = (rProps: DetailProp) => {
  1436. console.log("RenderTabs. :>> ", rProps, _mainData.value);
  1437. let tabRender: any = [];
  1438. let _sticky = rProps.header?.tabsProp?.sticky ?? DETAIL_LAYOUT_DEFINE.tabsProp.sticky;
  1439. // console.log("rProps.mould :>> ", rProps.mould);
  1440. // console.log("RenderTabs infoColumns.value :>> ", infoColumns.value);
  1441. // console.log('["new", "edit"].includes(orderStatus.value) :>> ', ["new", "edit"].includes(orderStatus.value));
  1442. // console.log("orderStatus.value :>> ", orderStatus.value);
  1443. // let _params =
  1444. // orderStatus.value == "new" ? infoParam.value : orderStatus.value == "edit" ? reactive(_mainData.value) : _mainData.value;
  1445. if (rProps?.mould && rProps.mould.length > 0) {
  1446. let _dftabs = undefined;
  1447. if (globalStore?.detailtabs && Object.keys(globalStore?.detailtabs).includes(rProps.dwname)) {
  1448. _dftabs = globalStore.detailtabs[rProps.dwname];
  1449. rProps.mould
  1450. .map(item => {
  1451. let _limited = isFunction(item?.limited) ? item.limited(detailParams) : item?.limited ?? false;
  1452. if (_limited || !item.isHidden) return false;
  1453. return item;
  1454. })
  1455. .filter(o => o)
  1456. .find((o: any) => o?.id == _dftabs);
  1457. }
  1458. _dftabs = _dftabs ?? rProps.mould[0].id;
  1459. tabsActive.value = _dftabs;
  1460. // let bacsCardRender: any = [];
  1461. // if (rProps.header?.baseCard) {
  1462. // switch (rProps.header?.baseCard.type) {
  1463. // case "timeline":
  1464. // bacsCardRender.push(<BaseCardTimeline data={_mainData.value} />);
  1465. // break;
  1466. // default:
  1467. // break;
  1468. // }
  1469. // }
  1470. console.log("RenderTabs rProps.mould :>> ", rProps.mould);
  1471. tabRender = rProps.mould
  1472. .map((item: detailModelItemProp) => {
  1473. // console.log("tasItemRender item :>> ", item);
  1474. // let _limited = isFunction(item?.limited) ? item.limited(_mainData.value) : item?.limited ?? false;
  1475. let _limited = isFunction(item?.limited) ? item.limited(detailParams) : item?.limited ?? false;
  1476. // if (_limited) return false;
  1477. let _disabled = _limited;
  1478. if (!item.isHidden) {
  1479. if (slots[item.id]) {
  1480. return tasItemRender(
  1481. item,
  1482. () => {
  1483. let val = _detailData.value && _detailData.value[item.id];
  1484. return slots[item.id]?.({
  1485. data: _mainData.value,
  1486. props: item,
  1487. orderStatus: orderStatus.value,
  1488. isScrollspy: isScrollspy.value,
  1489. layout: currentMould.value.header
  1490. });
  1491. },
  1492. true,
  1493. _disabled
  1494. );
  1495. } else if (item.render) {
  1496. return tasItemRender(
  1497. item,
  1498. () => {
  1499. let val = _detailData.value && _detailData.value[item.id];
  1500. return item.render && item.render(val);
  1501. },
  1502. true,
  1503. _disabled
  1504. );
  1505. } else {
  1506. return tasItemRender(
  1507. item,
  1508. () => {
  1509. // if (item.type == "base") {c
  1510. // console.log("item.id!!! :>> ", item);
  1511. // return (
  1512. // <>
  1513. // <div class="flx">
  1514. // <div class="flx-1">
  1515. // {slots[item.id] ? (
  1516. // slots[item.id]?.({ data: _mainData.value, props: infoColumns.value, orderStatus: orderStatus.value })
  1517. // ) : (
  1518. // <BaseForm
  1519. // columns={infoColumns.value}
  1520. // searchParam={_params}
  1521. // searchCol={{ xs: 2, sm: 4, md: 5, lg: 6, xl: 6 }}
  1522. // {...item.props}
  1523. // formProps={tableOptions.basicinfo ?? {}}
  1524. // layoutAttrDefine={basicinfoFormDefaultComputed}
  1525. // onConfirm={saveBasicSettingFunc}
  1526. // onReset={resetBasicSettingFunc}
  1527. // onSaveDefault={saveDefaultLayout}
  1528. // />
  1529. // )}
  1530. // </div>
  1531. // {slots.headerAside ? (
  1532. // <div class="flx-shrink ml-12 enter-x">
  1533. // {slots.headerAside({ data: _mainData.value, props: infoColumns.value })}
  1534. // </div>
  1535. // ) : (
  1536. // ""
  1537. // )}
  1538. // </div>
  1539. // </>
  1540. // );
  1541. // } else {
  1542. return item.label;
  1543. // }
  1544. },
  1545. false,
  1546. _disabled
  1547. );
  1548. }
  1549. }
  1550. })
  1551. .filter(Boolean);
  1552. // if (!tabRender.length) return;
  1553. // } else {
  1554. // return;
  1555. }
  1556. let tabsSlot: any = {};
  1557. if (slots.tabNavRight) {
  1558. tabsSlot["nav-right"] = () => {
  1559. return slots.tabNavRight?.({ active: tabsActive.value });
  1560. };
  1561. }
  1562. console.log("RenderTabs tabRender :>> ", tabsActive.value, tabRender);
  1563. return (
  1564. <>
  1565. {tabRender.length > 0 && (
  1566. <van-tabs
  1567. class={`${prefixCls}__tabs ${isScrollspy.value ? "scrollspy" : ""}`}
  1568. v-model:active={tabsActive.value}
  1569. scrollspy={isScrollspy.value}
  1570. sticky={isScrollspy.value ? _sticky : false}
  1571. shrink={true}
  1572. offsetTop={headerAffixTop.value + headerAffixHeight.value}
  1573. lazy-render={false}
  1574. onClickTab={handleClickTabs}
  1575. v-slots={tabsSlot}
  1576. >
  1577. {tabRender}
  1578. </van-tabs>
  1579. )}
  1580. </>
  1581. );
  1582. };
  1583. let detailParams = reactive<any>({});
  1584. // watch(
  1585. // () => _mainData.value,
  1586. // val => {
  1587. // // detailParams = editable.value ? reactive(val) : val;
  1588. // for (const key in val) {
  1589. // detailParams[key] = val[key];
  1590. // }
  1591. // detailParams.bednetname = "32123123";
  1592. // console.log("detailParams _mainData val :>> ", val, detailParams);
  1593. // },
  1594. // {
  1595. // immediate: true,
  1596. // deep: true
  1597. // }
  1598. // );
  1599. /**
  1600. * @description 模块:基础信息
  1601. */
  1602. const basicinfoRender = (rProps: any) => {
  1603. let soltinfo = "basicinfo";
  1604. // let _params =
  1605. // orderStatus.value == "new" ? infoParam.value : orderStatus.value == "edit" ? reactive(_mainData.value) : _mainData.value;
  1606. let _params = editable.value ? reactive(_mainData.value) : _mainData.value;
  1607. detailParams = editable.value ? reactive(_mainData.value) : _mainData.value;
  1608. console.log("basicinfoRender rProps :>> ", rProps);
  1609. console.log("basicinfoRender _params :>> ", editable.value, _params);
  1610. console.log("basicinfoRender _mainData.value :>> ", _mainData.value);
  1611. console.log("basicinfoRender infoColumns.value :>> ", infoParam.value);
  1612. console.log("basicinfoRender searchParam.value :>> ", searchParam.value);
  1613. // let codeValue = orderStatus.value == "new" ? true : convertStrToObj(_mainData.value, props.header.fieldNames?.code);
  1614. return (
  1615. <>
  1616. <div class="flx basicinfo-container">
  1617. <div class="flx-1">
  1618. {slots[soltinfo] ? (
  1619. slots[soltinfo]?.({ data: _mainData.value, props: infoColumns.value, orderStatus: orderStatus.value })
  1620. ) : (
  1621. <BaseForm
  1622. loading={orderStatus.value != "new" && tableLoading.value}
  1623. ref={LjDetailBaseFormRef}
  1624. columns={infoColumns.value}
  1625. searchParam={detailParams}
  1626. searchCol={rProps.searchCol}
  1627. basicGroupCol={rProps.basicGroupCol}
  1628. formProps={tableOptions.basicinfo ?? {}}
  1629. layoutAttrDefine={basicinfoFormDefaultComputed}
  1630. ifLayoutEditable={rProps.ifBasicEditable}
  1631. onConfirm={saveBasicSettingFunc}
  1632. onReset={resetBasicSettingFunc}
  1633. onSaveDefault={saveDefaultLayout}
  1634. onToSetting={beforeToSetting}
  1635. onBeforeClose={beforeCloseSetting}
  1636. />
  1637. )}
  1638. </div>
  1639. {slots.headerSuffix ? (
  1640. <div class="flx-shrink ml-12">{slots.headerSuffix({ data: _mainData.value, props: infoColumns.value })}</div>
  1641. ) : (
  1642. <></>
  1643. )}
  1644. </div>
  1645. </>
  1646. );
  1647. };
  1648. /**
  1649. * @description 渲染:主体
  1650. * @param rProps prop
  1651. */
  1652. const RenderLjDetail = (rProps: DetailProp) => {
  1653. // console.log("RenderLjDetail rProps :>> ", JSON.stringify(rProps));
  1654. // console.log("isScrollspy.value :>> ", isScrollspy.value);
  1655. if (isScrollspy.value) {
  1656. // 滚动模式
  1657. return (
  1658. <>
  1659. <div ref="LjDetailRef" class={`${prefixCls} ${globalStore.assemblySize}`} id={prefixCls}>
  1660. {slots.header ? (
  1661. slots.header?.()
  1662. ) : (
  1663. <Affix class={`${prefixCls}__header`} ref="LjDetailAffixRef" offset={headerAffixTop.value}>
  1664. <RenderHeaderDefault {...rProps} />
  1665. </Affix>
  1666. )}
  1667. {/* {orderStatus.value != "new" && RenderDetailHeader(rProps)} */}
  1668. {basicinfoRender(rProps)}
  1669. {RenderTabs(rProps)}
  1670. {slots.default?.()}
  1671. <el-backtop target={`.lj-main-body`} right={20} bottom={80}>
  1672. <el-icon>
  1673. <ArrowUpBold />
  1674. </el-icon>
  1675. </el-backtop>
  1676. </div>
  1677. </>
  1678. );
  1679. } else {
  1680. let _foldLayout: any = {
  1681. direction: rProps?.header?.direction ?? DETAIL_LAYOUT_DEFINE.direction,
  1682. right: {
  1683. width: rProps?.header?.foldright?.width ?? DETAIL_LAYOUT_DEFINE.foldright.width,
  1684. minWidth: rProps?.header?.foldright?.minWidth ?? DETAIL_LAYOUT_DEFINE.foldright.minWidth,
  1685. lastWidth: rProps?.header?.foldright?.lastWidth ?? DETAIL_LAYOUT_DEFINE.foldright.lastWidth,
  1686. hidden: rProps?.header?.foldright?.hidden ?? DETAIL_LAYOUT_DEFINE.foldright.hidden
  1687. }
  1688. };
  1689. console.log("_foldLayout :>> ", _foldLayout);
  1690. let foldSlot = {
  1691. right: () => {
  1692. return RenderTabs(rProps);
  1693. }
  1694. };
  1695. return (
  1696. <>
  1697. <div ref="LjDetailRef" class={`${prefixCls} ${globalStore.assemblySize} fold-vertical`} id={prefixCls}>
  1698. {rProps.ifFoldLayout ? (
  1699. <LjFoldLayout
  1700. ref={LjFoldLayoutRef}
  1701. v-slots={foldSlot}
  1702. {..._foldLayout}
  1703. onFoldRight={layout => toSaveFoldLayout(layout, "foldright", "right")}
  1704. >
  1705. {slots.header ? (
  1706. slots.header?.()
  1707. ) : (
  1708. <Affix class={`${prefixCls}__header`} ref="LjDetailAffixRef" offset={headerAffixTop.value}>
  1709. <RenderHeaderDefault {...rProps} />
  1710. </Affix>
  1711. )}
  1712. {basicinfoRender(rProps)}
  1713. </LjFoldLayout>
  1714. ) : (
  1715. <>
  1716. {slots.header ? (
  1717. slots.header?.()
  1718. ) : (
  1719. <Affix class={`${prefixCls}__header`} ref="LjDetailAffixRef" offset={headerAffixTop.value}>
  1720. <RenderHeaderDefault {...rProps} />
  1721. </Affix>
  1722. )}
  1723. {basicinfoRender(rProps)}
  1724. {RenderTabs(rProps)}
  1725. </>
  1726. )}
  1727. {slots.default?.()}
  1728. <el-backtop target={`.lj-main-body`} right={20} bottom={80}>
  1729. <el-icon>
  1730. <ArrowUpBold />
  1731. </el-icon>
  1732. </el-backtop>
  1733. </div>
  1734. </>
  1735. );
  1736. }
  1737. };
  1738. watch(
  1739. () => props.data,
  1740. val => {
  1741. if (val.length > 0) {
  1742. _mainData.value = { ...infoParam.value, ...val[0] };
  1743. } else {
  1744. _mainData.value = { ...infoParam.value };
  1745. }
  1746. }
  1747. );
  1748. watch(
  1749. () => tableData.value,
  1750. val => {
  1751. _mainData.value = val[0] ?? { ...infoParam.value, ...props.data[0] };
  1752. }
  1753. );
  1754. defineExpose({
  1755. element: LjDetailRef,
  1756. baseformRef: LjDetailBaseFormRef,
  1757. infoParam,
  1758. totalParam,
  1759. mainData_api,
  1760. detailData_api,
  1761. _mainData,
  1762. layoutHeader,
  1763. enumMap,
  1764. currentMould,
  1765. tabsActive,
  1766. toSaveFoldLayout,
  1767. toSetFloatBtnChange,
  1768. refresh: layoutRefresh,
  1769. toValidateForm
  1770. });
  1771. </script>
  1772. <style lang="scss">
  1773. @import "./index.scss";
  1774. </style>