index.vue 61 KB

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