index.vue 61 KB

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