index.vue.vm 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454
  1. ##通用参数
  2. #parse("PublicMacro/ConstantMarco.vm")
  3. #ConstantParams()
  4. <script lang="ts" setup>
  5. import { getList, del, exportData, batchDelete } from './helper/api';
  6. import { getConfigData,getViewList } from '#/api/onlineDev/visualDev';
  7. #if(${context.isFlow})
  8. // 工作流
  9. import FlowParser from '#/views/workFlow/components/FlowParser.vue';
  10. import { useFlowState } from '#/hooks/flow/useFlowStatus';
  11. import { getFlowStartFormId } from '#/api/workFlow/template';
  12. import { useTabs } from '@vben/hooks';
  13. // 工作流
  14. #end
  15. import { getDictionaryDataSelector } from '#/api/systemData/dictionary';
  16. import { getDataInterfaceRes } from '#/api/systemData/dataInterface';
  17. import { getOrgByOrganizeCondition,getOrganizeSelector } from '#/api/permission/organize';
  18. import { ref, reactive, onMounted, toRefs, computed, unref, nextTick, toRaw, provide } from 'vue';
  19. import { useMessage, usePermission } from '@jnpf/hooks';
  20. import { $t } from '#/locales';
  21. import { useOrganizeStore } from '#/store';
  22. import { useAccessStore,useUserStore } from '@vben/stores';
  23. import { BasicModal, useModal } from '@jnpf/ui/modal';
  24. import { usePopup } from '@jnpf/ui/popup';
  25. import { ScrollContainer,BasicLeftTree,type TreeActionType } from '@jnpf/ui';
  26. import { BasicForm, useForm } from '@jnpf/ui/form';
  27. import { BasicVxeTable, useVxeTable, TableAction, type ActionItem, type TableActionType, type SorterResult } from '@jnpf/ui/vxeTable';
  28. #if(${context.childTableStyle}==2)
  29. import { Grid as VxeGrid } from 'vxe-table';
  30. #end
  31. #if(${context.superQuery})
  32. import { SuperQueryModal } from '#/components/CommonModal';
  33. #end
  34. #if(!$context.isFlow && ${context.webType} !=4)
  35. import Form from './Form.vue';
  36. #end
  37. #foreach($itemBtn in ${context.columnBtnPcList})
  38. #if(!${context.isFlow} &&${itemBtn.value}=="detail")
  39. import Detail from './Detail.vue';
  40. #end
  41. #if(${itemBtn.value}=="edit")
  42. #end
  43. #if(${itemBtn.value}=="remove")
  44. #end
  45. #end
  46. #if(${context.webType} !=4)
  47. // 有关联表单详情:开始
  48. import RelationDetail from '#/views/common/dynamicModel/list/detail/index.vue';
  49. // 有关联表单详情:结束
  50. #end
  51. #if(${context.childTableStyle}==1)
  52. import ChildTableColumn from '#/views/common/dynamicModel/list/ChildTableColumn.vue';
  53. #end
  54. #foreach($itemBtn in ${context.btnPcList})
  55. #if(${itemBtn.value}=="add")
  56. #end
  57. #if(${itemBtn.value}=="upload")
  58. import { ImportModal} from '#/components/CommonModal';
  59. #end
  60. #if(${itemBtn.value}=="download")
  61. import { ExportModal } from '#/components/CommonModal';
  62. import { downloadByUrl } from '@jnpf/utils';
  63. #end
  64. #if(${itemBtn.value}=="batchRemove")
  65. #end
  66. #if(${itemBtn.value}=="batchPrint")
  67. // 打印模板多条生成PrintSelect
  68. import PrintSelect from '#/components/PrintDesign/printSelect/index.vue';
  69. import PrintBrowse from '#/components/PrintDesign/printBrowse/index.vue';
  70. #end
  71. #end
  72. #if(${context.tabConfig.createTab})
  73. import { useBaseStore } from '#/store';
  74. #end
  75. import { useRoute,useRouter } from 'vue-router';
  76. import { FilterOutlined } from '@ant-design/icons-vue';
  77. import { getSearchFormSchemas } from '#/components/FormGenerator/src/helper/transform';
  78. import { cloneDeep,omit } from 'lodash-es';
  79. import columnList from './helper/columnList';
  80. import searchList from './helper/searchList';
  81. #if(${context.webType} !=4)
  82. import superQueryJson from './helper/superQueryJson';
  83. #end
  84. import { dyOptionsList, systemComponentsList ,slotsList} from '#/components/FormGenerator/src/helper/config';
  85. import { thousandsFormat} from '@jnpf/utils';
  86. import { getParamList} from '#/utils/jnpf';
  87. import ViewSetting from '#/views/common/dynamicModel/list/components/ViewSetting.vue';
  88. import ViewList from '#/views/common/dynamicModel/list/components/ViewList.vue';
  89. interface State {
  90. config: any;
  91. #if($!{context.isFlow})
  92. flowId: string;
  93. #end
  94. columnList: any[];
  95. printListOptions: any[];
  96. columnBtnsList: any[];
  97. customBtnsList: any[];
  98. treeFieldNames: any;
  99. leftTreeData: any[];
  100. leftTreeLoading: boolean;
  101. treeActiveId: string;
  102. treeActiveNodePath: any;
  103. columns: any[];
  104. allColumns: any[];
  105. complexColumns: any[];
  106. childColumnList: any[];
  107. mergeList: any[];
  108. exportList: any[];
  109. cacheList: any[];
  110. currFlow: any;
  111. isCustomCopy: boolean;
  112. candidateType: number;
  113. currRow: any;
  114. workFlowFormData: any;
  115. expandObj: any;
  116. columnSettingList: any[];
  117. searchSchemas: any[];
  118. treeRelationObj: any;
  119. treeQueryJson: any;
  120. leftTreeActiveInfo: any;
  121. keyword: string;
  122. #if(${context.tabConfig.createTab})
  123. tabActiveKey: any;
  124. tabList: any[];
  125. tabQueryJson: any;
  126. #end
  127. viewList: any[];
  128. currentView: any;
  129. }
  130. const route = useRoute();
  131. const { hasBtnP } = usePermission();
  132. const { createMessage, createConfirm } = useMessage();
  133. const organizeStore = useOrganizeStore();
  134. const userStore = useUserStore();
  135. const accessStore = useAccessStore();
  136. const { permissionList } = accessStore;
  137. const userInfo = userStore.getUserInfo;
  138. #if(${context.tabConfig.createTab})
  139. const baseStore = useBaseStore();
  140. #end
  141. const [registerExportModal, { openModal: openExportModal, closeModal: closeExportModal, setModalProps: setExportModalProps }] = useModal();
  142. const [registerImportModal, { openModal: openImportModal }] = useModal();
  143. const [registerSuperQueryModal, { openModal: openSuperQuery }] = useModal();
  144. #if(${context.hasPrintBtn})
  145. const [registerPrintSelect, { openModal: openPrintSelect }] = useModal();
  146. const [registerPrintBrowse, { openModal: openPrintBrowse }] = useModal();
  147. #end
  148. #if(${context.isFlow})
  149. // 工作流
  150. const { closeCurrentTab } = useTabs();
  151. const router = useRouter();
  152. const [registerFlowParser, { openPopup: openFlowParser }] = usePopup();
  153. const { getFlowStatusContent, getFlowStatusColor } = useFlowState();
  154. #end
  155. #if(${context.leftTreeTable})
  156. const leftTreeRef = ref<Nullable<TreeActionType>>(null);
  157. #end
  158. const formRef = ref<any>(null);
  159. const tableRef = ref<Nullable<TableActionType>>(null);
  160. const detailRef = ref<any>(null);
  161. const relationDetailRef = ref<any>(null);
  162. const state = reactive<State>({
  163. config: {},
  164. #if($!{context.isFlow})
  165. flowId:'',//请在这里填写流程模板id
  166. #end
  167. columnList: [],
  168. printListOptions: [],
  169. columnBtnsList: [],
  170. customBtnsList: [],
  171. treeFieldNames: {
  172. children: #if(${context.columnData.treePropsChildren}) '${context.columnData.treePropsChildren}' #else 'children' #end,
  173. title: #if(${context.columnData.treePropsLabel}) '${context.columnData.treePropsLabel}' #else 'fullName' #end,
  174. key: #if(${context.columnData.treePropsValue}) '${context.columnData.treePropsValue}' #else 'id' #end,
  175. isLeaf: 'isLeaf',
  176. },
  177. leftTreeData: [],
  178. leftTreeLoading: false,
  179. treeActiveId: '',
  180. treeActiveNodePath: [],
  181. columns: [],
  182. allColumns: [],
  183. complexColumns: [], // 复杂表头
  184. childColumnList: [],
  185. mergeList: [],
  186. exportList: [],
  187. cacheList: [],
  188. currFlow: {},
  189. isCustomCopy: false,
  190. candidateType: 1,
  191. currRow: {},
  192. workFlowFormData: {},
  193. expandObj: {},
  194. columnSettingList: [],
  195. searchSchemas: [],
  196. treeRelationObj: null,
  197. treeQueryJson: {},
  198. leftTreeActiveInfo: {},
  199. keyword: '',
  200. #if(${context.tabConfig.createTab})
  201. tabActiveKey: '',
  202. tabList: [],
  203. tabQueryJson: {},
  204. #end
  205. viewList: [],
  206. currentView: {},
  207. });
  208. const defaultSearchInfo = {
  209. menuId: route.meta.modelId as string,
  210. moduleId:'${context.moduleId}',
  211. superQueryJson: '',
  212. #if($!{context.isFlow})
  213. flowId: state.flowId,
  214. #end
  215. #if(${context.hasPage} && !${context.groupTable} && !${context.treeTable})
  216. dataType:0,
  217. #end
  218. #if(!${context.hasPage} || ${context.groupTable} || ${context.treeTable})
  219. pageSize:1000000, //没有分页,树形,分组
  220. #end
  221. };
  222. const searchInfo = reactive({
  223. ...cloneDeep(defaultSearchInfo),
  224. });
  225. const { childColumnList, searchSchemas, viewList, currentView#if($!{context.isFlow}), flowId #end,allColumns} = toRefs(state);
  226. const [registerSearchForm, { updateSchema, resetFields, submit: searchFormSubmit, setFieldsValue}] = useForm({
  227. baseColProps: { span: 6 },
  228. showActionButtonGroup: true,
  229. showAdvancedButton: true,
  230. compact: true,
  231. });
  232. const [registerTable, { reload, setLoading, getFetchParams, getSelectRows, getSelectRowKeys, redoHeight,clearSelectedRowKeys }] = useVxeTable({
  233. api: getList,
  234. immediate: false,
  235. tableSetting: { setting: false },
  236. afterFetch: (data) => {
  237. const list = data.map((o) => ({...o,...state.expandObj}));
  238. state.cacheList = cloneDeep(list);
  239. #if(${context.groupTable})
  240. list.map(o => {
  241. if (o.children && o.children.length) {
  242. o.children = o.children.map(e => ({
  243. ...e,
  244. ...state.expandObj,
  245. }));
  246. }
  247. });
  248. #end
  249. return list;
  250. },
  251. });
  252. provide('getLeftTreeActiveInfo', () => state.leftTreeActiveInfo);
  253. ##按钮权限,控制方法(用于生成复选框)
  254. const getHasBatchBtn = computed(() => {
  255. let btnsList: any[] =[]
  256. #if(${context.hasRemoveBtn})
  257. btnsList.push('batchRemove')
  258. #end
  259. #if(${context.hasPrintBtn})
  260. btnsList.push('batchPrint')
  261. #end
  262. #if(${context.hasDownloadBtn})
  263. btnsList.push('download')
  264. #end
  265. ### 有权限判断的时候生成这句代码
  266. #if(${context.columnData.useBtnPermission})
  267. btnsList=btnsList.filter(o => hasBtnP('btn_' + o))
  268. #end
  269. return !!btnsList.length
  270. });
  271. ##左侧树
  272. #if(${context.leftTreeTable})
  273. const getLeftTreeBindValue = computed(() => {
  274. const key = +new Date();
  275. const data: any = {
  276. title: #if(${context.columnData.treeTitleI18nCode}) $t('${context.columnData.treeTitleI18nCode}','${context.columnData.treeTitle}')#else'${context.columnData.treeTitle}'#end,
  277. showSearch: #if((${context.columnData.treeDataSource} == 'api' && ${context.columnData.treeSyncType} == 1)
  278. ||(${context.columnData.treeDataSource} == 'formField' && ${context.columnData.treeRelationFieldSelectType} == 'all' )
  279. ||${context.columnData.treeDataSource} == 'organize'|| !${context.columnData.hasTreeQuery}) false, #else true, //异步的时候为false #end
  280. fieldNames: state.treeFieldNames,
  281. defaultExpandAll: #if((${context.columnData.treeDataSource} == 'api' && ${context.columnData.treeSyncType} == 1)
  282. ||(${context.columnData.treeDataSource} == 'formField' && ${context.columnData.treeRelationFieldSelectType} == 'all' )
  283. ||${context.columnData.treeDataSource} == 'organize') false, #else true, //异步的时候为false #end
  284. treeData: state.leftTreeData,
  285. loading: state.leftTreeLoading,
  286. key,
  287. #if((${context.columnData.treeDataSource} == 'api' && ${context.columnData.treeSyncType} == 1)
  288. ||(${context.columnData.treeDataSource} == 'formField' && ${context.columnData.treeRelationFieldSelectType} == 'all' )
  289. ||${context.columnData.treeDataSource} == 'organize')
  290. //异步
  291. loadData: onLoadData,
  292. //异步
  293. #end
  294. };
  295. return data;
  296. });
  297. #end
  298. const getColumns = computed(() => {
  299. const columns = #if(${context.childTableStyle}==1) state.complexColumns; #else state.columns;#end
  300. return setListValue(state.currentView?.columnList, columns, 'prop');
  301. });
  302. const getSearchList = computed(() => {
  303. const searchSchemas = cloneDeep(state.searchSchemas).map(o => ({ ...o, show: true }));
  304. const schemas = setListValue(state.currentView?.searchList, searchSchemas, 'field');
  305. buildSearchOptions(schemas);
  306. return schemas;
  307. });
  308. const getTableBindValue = computed(() => {
  309. let columns = unref(getColumns).map((o) => ({ ...omit(o, ['type', 'format']) }));
  310. #if(${context.isFlow})
  311. const boo=columns.some(o=>o.dataIndex==='flowState')
  312. if(!boo) columns.push({ title: $t('component.table.status'), dataIndex: 'flowState', width: 100, align: 'center', fixed: columns.some(o => o.fixed == 'right') ? 'right' : false, slots: { default: 'flowState' }, });
  313. #end
  314. const defaultSortConfig:any[]=#if(${context.columnData.defaultSortConfig})${context.columnData.defaultSortConfig}#else []#end;
  315. const sortField = defaultSortConfig.map(o => (o.sort === 'desc' ? '-' : '') + o.field);
  316. const data: any = {
  317. #if(!${context.hasPage} || ${context.groupTable} || ${context.treeTable})
  318. pagination: false, //没有分页,树形,分组
  319. #else
  320. pagination: { pageSize: ${context.columnData.pageSize} }, //有分页
  321. #end
  322. searchInfo: unref(searchInfo),
  323. defSort: { sidx: sortField.join(',') },
  324. sortConfig: { multiple: true },
  325. sortFn: (sortInfo: SorterResult | SorterResult[]) => {
  326. if (Array.isArray(sortInfo)) {
  327. const sortList = sortInfo.map((o) => (o.order === 'desc' ? '-' : '') + o.field);
  328. return { sidx: sortList.join(',') };
  329. } else {
  330. const { field, order } = sortInfo;
  331. return field && order ? { sidx: (order === 'desc' ? '-' : '') + field } : {};
  332. }
  333. },
  334. showOverflow: false,
  335. columns,
  336. #if(${context.groupTable} || ${context.treeTable})
  337. isTreeTable: true,
  338. #else
  339. #if(${context.childTableStyle}==2)
  340. // 有子表且子表折叠展示
  341. showExpandColumn:!!state.childColumnList.length,
  342. #end
  343. #end
  344. #if(${context.childTableStyle}==1 || $!{context.complexHeaderList.size()}>0)
  345. border: true,
  346. #end
  347. #if(${context.webType} !=4)
  348. actionColumn: {
  349. width: 150,
  350. title: $t('component.table.action'),
  351. dataIndex: 'action',
  352. },
  353. #end
  354. showFooter:${context.configurationTotal},
  355. columnConfig: {
  356. resizable: ${context.columnData.resizable},
  357. },
  358. ##视图有设置主键
  359. #if(${context.webType}==4 && ${context.columnData.viewKey})
  360. rowKey: '${context.columnData.viewKey}',
  361. #end
  362. };
  363. ##树形表格代码没有多选框
  364. #if(!${context.treeTable} || (${context.webType}==4 && ${context.columnData.viewKey}))
  365. if (unref(getHasBatchBtn)) {
  366. const rowSelection: any = { type: 'checkbox' };
  367. #if(${context.groupTable}) rowSelection.getCheckboxProps = record => ({ disabled: !!record.top }); #end
  368. data.rowSelection = rowSelection;
  369. }
  370. #end
  371. #if(${context.childTableStyle}==1)
  372. // 有子表且子表分组展示
  373. if(state.childColumnList.length)data.spanMethod = spanMethod;
  374. #end
  375. #if(${context.configurationTotal})
  376. // 列表合计
  377. data.footerMethod = footerMethod;
  378. #end
  379. return data;
  380. });
  381. ##合计变量
  382. #if(${context.configurationTotal})
  383. const getSummaryColumn = computed(() => {
  384. let defaultColumns = unref(getColumns);
  385. // 处理列固定
  386. if (state.columnSettingList?.length) {
  387. for (let i = 0; i < defaultColumns.length; i++) {
  388. inner: for (let j = 0; j < state.columnSettingList.length; j++) {
  389. if (defaultColumns[i].dataIndex === state.columnSettingList[j].dataIndex) {
  390. defaultColumns[i].fixed = state.columnSettingList[j].fixed;
  391. defaultColumns[i].visible = state.columnSettingList[j].visible;
  392. break inner;
  393. }
  394. }
  395. }
  396. defaultColumns = defaultColumns.filter((o) => o.visible);
  397. }
  398. let columns: any[] = [];
  399. for (let i = 0; i < defaultColumns.length; i++) {
  400. const e = defaultColumns[i];
  401. if (e.jnpfKey === 'table' || e.jnpfKey === 'complexHeader') {
  402. if (e.children?.length) columns.push(...e.children);
  403. } else {
  404. columns.push(e);
  405. }
  406. if (e.fixed && e.children?.length) {
  407. for (let j = 0; j < e.children.length; j++) {
  408. e.children[j].fixed = e.fixed;
  409. }
  410. }
  411. }
  412. const leftFixedList = columns.filter((o) => o.fixed === 'left');
  413. const rightFixedList = columns.filter((o) => o.fixed === 'right');
  414. const noFixedList = columns.filter((o) => o.fixed !== 'left' && o.fixed !== 'right');
  415. return [...leftFixedList, ...noFixedList, ...rightFixedList];
  416. });
  417. #end
  418. async function init() {
  419. state.config = {};
  420. searchInfo.menuId = route.meta.modelId as string;
  421. state.columnList = columnList;
  422. #if(${context.groupTable})
  423. // 分组
  424. state.columnList = state.columnList.filter((o) => o.prop != '${context.groupField}');
  425. #end
  426. setLoading(true);
  427. getSearchSchemas();
  428. getColumnList();
  429. await initViewList();
  430. ## 列表标签面板初始化
  431. #if(${context.tabConfig.createTab})
  432. getTabList();
  433. #elseif(${context.leftTreeTable})
  434. // 有左侧树
  435. getTreeView(true);
  436. #else
  437. nextTick(() => {
  438. unref(getSearchList)?.length ? searchFormSubmit() : handleSearchSubmit({});
  439. });
  440. #end
  441. }
  442. #if(${context.leftTreeTable})
  443. // 有左侧树
  444. async function getTreeView(isInit = false) {
  445. state.leftTreeLoading = true;
  446. state.leftTreeData = [];
  447. #if(${context.columnData.treeDataSource}=='dictionary')
  448. // 左侧数据字典
  449. getDictionaryDataSelector('${context.columnData.treeDictionary}').then(res => {
  450. state.leftTreeData = res.data.list;
  451. state.leftTreeLoading = false;
  452. nextTick(() => {
  453. if(isInit){
  454. unref(getSearchList)?.length? searchFormSubmit() : reload({ page: 1 });
  455. }
  456. });
  457. });
  458. #elseif(${context.columnData.treeDataSource}=='api')
  459. // 数据接口
  460. let treeTemplateJson: any[] = #if($!{context.columnData.treeTemplateJson}) ${context.columnData.treeTemplateJson} #else [] #end
  461. const query = { paramList: getParamList(treeTemplateJson) };
  462. getDataInterfaceRes('${context.columnData.treePropsUrl}',query).then((res) => {
  463. state.leftTreeData = Array.isArray(res.data) ? res.data : [];
  464. state.leftTreeLoading = false;
  465. nextTick(() => {
  466. if (isInit){
  467. unref(getSearchList)?.length? searchFormSubmit() : reload({ page: 1 });
  468. }
  469. });
  470. });
  471. #elseif(${context.columnData.treeDataSource}=='organize')
  472. //组织或者部门
  473. const res = await getOrganizeSelector();
  474. state.leftTreeData = res.data.list;
  475. state.leftTreeLoading = false;
  476. nextTick(() => {
  477. if (state.leftTreeData.length) leftTreeRef.value?.setExpandedKeys([state.leftTreeData[0].id]);
  478. if (isInit){
  479. unref(getSearchList)?.length? searchFormSubmit() : reload({ page: 1 });
  480. }
  481. });
  482. #elseif(${context.columnData.treeDataSource}=='formField')
  483. //表单字段
  484. let leftTreeData: any[] =[]
  485. const treeRelationObj: any = state.treeRelationObj;
  486. const jnpfKey = treeRelationObj?.__config__?.jnpfKey || '';
  487. if ('${context.columnData.treeRelation}' && ['organizeSelect', 'depSelect'].includes(jnpfKey)) {
  488. if (treeRelationObj.selectType === 'all') {
  489. const res = await getOrganizeSelector();
  490. leftTreeData = res.data.list;
  491. }
  492. if (treeRelationObj.selectType === 'custom' && treeRelationObj.ableIds?.length) {
  493. const res = await getOrgByOrganizeCondition(treeRelationObj.ableIds);
  494. leftTreeData = res.data.list;
  495. }
  496. }
  497. state.leftTreeData = leftTreeData;
  498. state.leftTreeLoading = false;
  499. nextTick(() => {
  500. if (treeRelationObj.selectType === 'all') {
  501. if (state.leftTreeData.length) leftTreeRef.value?.setExpandedKeys([state.leftTreeData[0].id]);
  502. }
  503. if (isInit){
  504. unref(getSearchList)?.length? searchFormSubmit() : reload({ page: 1 });
  505. }
  506. });
  507. #end
  508. }
  509. #end
  510. function getSearchSchemas() {
  511. #if(${context.leftTreeTable})
  512. // 有左侧树,有关联字段
  513. if (!state.treeRelationObj) {
  514. for (let i = 0; i < superQueryJson.length; i++) {
  515. const e = superQueryJson[i];
  516. if (e.id === '${context.columnData.treeRelation}') {
  517. state.treeRelationObj = { ...e, searchMultiple: false, jnpfKey: e.__config__.jnpfKey };
  518. break;
  519. }
  520. }
  521. }
  522. #end
  523. const schemas = getSearchFormSchemas(searchList #if(${context.isFlow}),true#end);
  524. state.searchSchemas = schemas;
  525. }
  526. function buildSearchOptions(schemas){
  527. schemas.forEach((cur) => {
  528. const config = cur.__config__;
  529. if (dyOptionsList.includes(config.jnpfKey)) {
  530. if (config.dataType === 'dictionary') {
  531. if (!config.dictionaryType) return;
  532. getDictionaryDataSelector(config.dictionaryType).then((res) => {
  533. updateSchema([{ field: cur.field, componentProps: { options: res.data.list } }]);
  534. });
  535. }
  536. if (config.dataType === 'dynamic') {
  537. if (!config.propsUrl) return;
  538. const query = { paramList: getParamList(config.templateJson) };
  539. getDataInterfaceRes(config.propsUrl, query).then((res) => {
  540. const data = Array.isArray(res.data) ? res.data : [];
  541. updateSchema([{ field: cur.field, componentProps: { options: data } }]);
  542. });
  543. }
  544. }
  545. cur.defaultValue = cur.value;
  546. });
  547. }
  548. function getColumnList() {
  549. #if(${context.columnData.useColumnPermission})
  550. // 开启列表过滤权限
  551. let columnList: any[] = [];
  552. const list = permissionList.filter(o => o.modelId === searchInfo.menuId);
  553. const perColumnList = list[0] && list[0].column ? list[0].column : [];
  554. for (let i = 0; i < state.columnList.length; i++) {
  555. inner: for (let j = 0; j < perColumnList.length; j++) {
  556. if (state.columnList[i].prop === perColumnList[j].enCode) {
  557. columnList.push(state.columnList[i]);
  558. break inner;
  559. }
  560. }
  561. }
  562. #else
  563. // 没有开启列表权限
  564. let columnList = state.columnList;
  565. #end
  566. state.exportList = columnList;
  567. let columns = columnList.map((o) => {
  568. const item: any = {
  569. ...o,
  570. title: o.labelI18nCode ? $t(o.labelI18nCode, o.label) : o.label,
  571. dataIndex: o.prop,
  572. align: o.align,
  573. fixed: o.fixed == 'none' ? false : o.fixed,
  574. width: o.width || '',
  575. minWidth: o.width || 100,
  576. }
  577. // 行内编辑和部分控件加插槽
  578. if ((slotsList.includes(item.jnpfKey)) && !item.dataIndex.includes('-')) {
  579. item.slots = { default: item.prop };
  580. }
  581. item.showOverflow = !!(#if(${context.columnData.showOverflow})${context.columnData.showOverflow} #else false #end&& item.jnpfKey !== 'rate' );
  582. return item;
  583. });
  584. state.allColumns = columns;
  585. //添加复杂表头
  586. columns = getComplexColumns(columns);
  587. state.columns = columns.filter((o) => !o.prop.includes('-'));
  588. //子表表头
  589. getChildComplexColumns(columns);
  590. }
  591. #if(${context.tabConfig.createTab})
  592. //标签初始化
  593. async function getTabList() {
  594. #if(${context.tabConfig.fieldsModel})
  595. #set($fm =${context.tabConfig.fieldsModel})
  596. #set($config =$fm.config)
  597. #if(${config.dataType} == 'dictionary')
  598. // 字典
  599. const data = (await baseStore.getDicDataSelector('${config.dictionaryType}'))
  600. const options = #if($fm.props.value == 'enCode') data.map(o => ({ ...o, id: o.enCode }))#else data #end;
  601. state.tabList = [...state.tabList,...options]
  602. #end
  603. #if(${config.dataType} == 'static')
  604. //静态
  605. state.tabList = #if(${fm.options}) ${fm.options} #else[] #end
  606. #end
  607. #end
  608. #if(${context.tabConfig.hasAllTab})
  609. state.tabList.unshift({ fullName: '全部', id: '' });
  610. #end
  611. state.tabActiveKey = state.tabList[0].id || '';
  612. state.tabQueryJson = { ${context.tabConfig.relationField} : state.tabList[0].id };
  613. nextTick(() => {
  614. unref(getSearchList)?.length? searchFormSubmit() : reload({ page: 1 });
  615. });
  616. }
  617. #end
  618. //复杂表头
  619. function getComplexColumns(columns) {
  620. //这里生成复杂表头的配置
  621. let complexHeaderList: any[] = #if(${context.complexHeaderList}) ${context.complexHeaderList}; #else []; #end
  622. if (!complexHeaderList.length) return columns;
  623. let childColumns: any[] = [];
  624. let firstChildColumns: string[] = [];
  625. for (let i = 0; i < complexHeaderList.length; i++) {
  626. const e = complexHeaderList[i];
  627. e.label = e.fullName;
  628. e.labelI18nCode = e.fullNameI18nCode;
  629. e.title = e.fullNameI18nCode ? $t(e.fullNameI18nCode, e.fullName) : e.fullName;
  630. e.dataIndex = e.id;
  631. e.prop = e.id;
  632. e.children = [];
  633. e.jnpfKey = 'complexHeader';
  634. if (e.childColumns?.length) {
  635. childColumns.push(...e.childColumns);
  636. for (let k = 0; k < e.childColumns.length; k++) {
  637. const item = e.childColumns[k];
  638. for (let j = 0; j < columns.length; j++) {
  639. const o = columns[j];
  640. if (o.prop == item && o.fixed !== 'left' && o.fixed !== 'right') e.children.push({...omit(o, ['fixed']) });
  641. }
  642. }
  643. }
  644. if (e.children.length) firstChildColumns.push(e.children[0].prop);
  645. }
  646. complexHeaderList = complexHeaderList.filter(o => o.children.length);
  647. let list: any[] = [];
  648. for (let i = 0; i < columns.length; i++) {
  649. const e = columns[i];
  650. if (!childColumns.includes(e.prop) || e.fixed === 'left' || e.fixed === 'right') {
  651. list.push(e);
  652. } else {
  653. if (firstChildColumns.includes(e.prop)) {
  654. const item = complexHeaderList.find(o => o.childColumns.includes(e.prop));
  655. list.push(item);
  656. }
  657. }
  658. }
  659. return list;
  660. }
  661. //子表表头
  662. function getChildComplexColumns(columnList) {
  663. let list: any[] = [];
  664. for (let i = 0; i < columnList.length; i++) {
  665. const e = columnList[i];
  666. if (!e.prop.includes('-')) {
  667. list.push(e);
  668. } else {
  669. let prop = e.prop.split('-')[0];
  670. let label = e.label.split('-')[0];
  671. let childLabel = e.label.replace(label + '-', '');
  672. if (e.fullNameI18nCode && Array.isArray(e.fullNameI18nCode) && e.fullNameI18nCode[0]) label = $t(e.fullNameI18nCode[0], label);
  673. let newItem = {
  674. align: 'center',
  675. jnpfKey: 'table',
  676. prop,
  677. label,
  678. title: label,
  679. dataIndex: prop,
  680. children: [],
  681. };
  682. e.dataIndex = e.prop;
  683. e.title = e.labelI18nCode ? $t(e.labelI18nCode, childLabel) : childLabel;
  684. if (!Object.prototype.hasOwnProperty.call(state.expandObj, `${prop}Expand`)) state.expandObj[prop+`Expand`] = false;
  685. if (!list.some((o) => o.prop === prop)) list.push(newItem);
  686. for (let i = 0; i < list.length; i++) {
  687. if (list[i].prop === prop) {
  688. #if(${context.childTableStyle}==1)
  689. const childItem = !list[i].children.length?{ ...e, slots: { default: list[i].dataIndex }, showOverflow: false, className: 'child-table-box' }:e
  690. list[i].children.push({ ...omit(childItem, ['fixed']) });
  691. #else
  692. list[i].children.push({ ...omit(e, ['fixed']) });
  693. #end
  694. break;
  695. }
  696. }
  697. }
  698. }
  699. #if(${context.childTableStyle}==1)
  700. // 行内分组展示
  701. getMergeList(list);
  702. #end
  703. state.complexColumns = list;
  704. state.childColumnList = list.filter((o) => o.jnpfKey === 'table');
  705. // 子表分组展示宽度取100
  706. for (let i = 0; i < state.childColumnList.length; i++) {
  707. const e = state.childColumnList[i];
  708. if (e.children?.length) e.children = e.children.map(o => {
  709. const item = { ...o };
  710. #if(${context.childTableStyle}==1)
  711. item.width = o.width || '';
  712. item.minWidth = o.width || 100;
  713. #else
  714. item.field = o.__vModel__;
  715. item.dataIndex = o.__vModel__;
  716. if ( slotsList.includes(item.jnpfKey)) item.slots = { default: item.dataIndex };
  717. item.width = o.width || '';
  718. item.minWidth = o.width || 100;
  719. #end
  720. return item;
  721. });
  722. }
  723. }
  724. function getMergeList(list) {
  725. list.forEach((item) => {
  726. if (item.jnpfKey === 'table' && item.children?.length) {
  727. item.children.forEach((child, index) => {
  728. state.mergeList.push({
  729. prop: child.prop,
  730. rowspan: index == 0 ? 1 : 0,
  731. colspan: index == 0 ? item.children.length : 0,
  732. });
  733. });
  734. }
  735. });
  736. }
  737. function toggleExpand(row, field) {
  738. row[field] = !row[field];
  739. }
  740. // 关联表单查看详情
  741. function toDetail(modelId, id, propsValue) {
  742. if (!id) return;
  743. getConfigData(modelId).then((res) => {
  744. if (!res.data || !res.data.formData) return;
  745. const formConf = JSON.parse(res.data.formData);
  746. formConf.popupType = 'general';
  747. formConf.hasPrintBtn = false;
  748. formConf.customBtns = [];
  749. const data = { id, formConf, modelId, propsValue};
  750. relationDetailRef.value?.init(data);
  751. });
  752. }
  753. function handleColumnChange(data) {
  754. state.columnSettingList = data;
  755. }
  756. ##行内按键
  757. function getTableActions(record): ActionItem[] {
  758. return [
  759. #foreach($itemBtn in ${context.columnBtnPcList})
  760. #if(${itemBtn.value}=="edit" && ${itemBtn.show})
  761. {
  762. label: #if(${itemBtn.labelI18nCode}) $t('${itemBtn.labelI18nCode}','${itemBtn.label}') #else '${itemBtn.label}' #end,
  763. #if(${context.isFlow})
  764. disabled: ![0,8,9].includes(record.flowState), //有流程加上
  765. #end
  766. onClick: updateHandle.bind(null, record),
  767. #if(${context.columnData.useBtnPermission})
  768. auth: 'btn_edit', //有按钮权限
  769. #end
  770. },
  771. #end
  772. #if(${itemBtn.value}=="detail" && ${itemBtn.show})
  773. {
  774. label: #if(${itemBtn.labelI18nCode}) $t('${itemBtn.labelI18nCode}','${itemBtn.label}') #else '${itemBtn.label}' #end,
  775. #if(${context.isFlow})
  776. disabled: !record.flowState, //有流程加上
  777. #end
  778. onClick: goDetail.bind(null, record),
  779. #if(${context.columnData.useBtnPermission})
  780. auth: 'btn_detail', //有按钮权限
  781. #end
  782. },
  783. #end
  784. #if(${itemBtn.value}=="remove" && ${itemBtn.show})
  785. {
  786. label: #if(${itemBtn.labelI18nCode}) $t('${itemBtn.labelI18nCode}','${itemBtn.label}') #else '${itemBtn.label}' #end,
  787. color: 'error',
  788. #if(${context.isFlow})
  789. disabled: ![0,9].includes(record.flowState), //有流程加上
  790. #end
  791. modelConfirm: {
  792. onOk: handleDelete.bind(null, record.id),
  793. },
  794. #if(${context.columnData.useBtnPermission})
  795. auth: 'btn_remove', //有按钮权限
  796. #end
  797. },
  798. #end
  799. #end
  800. ];
  801. }
  802. ##行内按键方法
  803. #foreach($itemBtn in ${context.columnBtnPcList})
  804. #if(${itemBtn.value}=="edit" && ${itemBtn.show})
  805. // 编辑
  806. function updateHandle(record) {
  807. #if(${context.isFlow})
  808. // 带工作流
  809. let data = {
  810. id: record.flowTaskId || record.id,
  811. flowId: state.flowId,
  812. opType: '-1',
  813. };
  814. openFlowParser(true, data);
  815. #else
  816. // 不带工作流
  817. const data = {
  818. id: record.id,
  819. menuId: searchInfo.menuId,
  820. allList: state.cacheList,
  821. };
  822. formRef.value?.init(data);
  823. #end
  824. }
  825. #end
  826. #if(${itemBtn.value}=="detail" && ${itemBtn.show})
  827. // 查看详情
  828. function goDetail(record) {
  829. #if(${context.isFlow})
  830. // 带流程
  831. const data = {
  832. id: record.flowTaskId,
  833. flowId: state.flowId,
  834. opType: 0,
  835. status: record.flowState,
  836. };
  837. openFlowParser(true, data);
  838. #else
  839. // 不带流程
  840. const data = {
  841. id: record.id,
  842. };
  843. detailRef.value?.init(data);
  844. #end
  845. }
  846. #end
  847. #if(${itemBtn.value}=="remove" && ${itemBtn.show})
  848. // 删除
  849. function handleDelete(id) {
  850. const query={ids:[id] #if(${context.isFlow}) ,flowId:state.flowId #end}
  851. batchDelete(query).then((res) => {
  852. createMessage.success(res.msg);
  853. clearSelectedRowKeys();
  854. reload();
  855. });
  856. }
  857. #end
  858. #end
  859. ##表头按键方法
  860. #foreach($itemBtn in ${context.btnPcList})
  861. #if(${itemBtn.value}=="add" && ${itemBtn.show})
  862. // 新增
  863. function addHandle() {
  864. #if(${context.isFlow})
  865. // 带流程新增
  866. const data = {
  867. id: '',
  868. flowId: state.flowId,
  869. opType: '-1',
  870. };
  871. openFlowParser(true, data);
  872. #else
  873. // 不带流程新增
  874. const data = {
  875. id: '',
  876. menuId: searchInfo.menuId,
  877. allList: state.cacheList,
  878. };
  879. formRef.value?.init(data);
  880. #end
  881. }
  882. #end
  883. #if(${itemBtn.value}=="upload" && ${itemBtn.show})
  884. #end
  885. #if(${itemBtn.value}=="download" && ${itemBtn.show})
  886. // 导出
  887. function handleDownload(data) {
  888. let query = { ...getFetchParams(), ...data };
  889. exportData(query)
  890. .then((res) => {
  891. setExportModalProps({ confirmLoading: false });
  892. if (!res.data.url) return;
  893. downloadByUrl({ url: res.data.url });
  894. closeExportModal();
  895. })
  896. .catch(() => {
  897. setExportModalProps({ confirmLoading: false });
  898. });
  899. }
  900. #end
  901. #if(${itemBtn.value}=="batchRemove" && ${itemBtn.show})
  902. // 批量删除
  903. function handelBatchRemove() {
  904. const ids = getSelectRowKeys();
  905. if (!ids.length) return createMessage.error('请选择一条数据');
  906. createConfirm({
  907. iconType: 'warning',
  908. title: $t('common.tipTitle'),
  909. content: '您确定要删除这些数据吗, 是否继续?',
  910. onOk: () => {
  911. const query={ids:ids #if(${context.isFlow}) ,flowId:state.flowId #end}
  912. batchDelete(query).then((res) => {
  913. createMessage.success(res.msg);
  914. clearSelectedRowKeys();
  915. reload();
  916. });
  917. },
  918. });
  919. }
  920. #end
  921. #if(${itemBtn.value}=="batchPrint" && ${itemBtn.show})
  922. //打印方法
  923. function handelBatchPrint() {
  924. let printIds=#if(${context.columnData.printIds}) ${context.columnData.printIds} #else [] #end
  925. if (!printIds?.length) return createMessage.error('未配置打印模板');
  926. const ids = getSelectRowKeys();
  927. if (!ids.length) return createMessage.error('请选择一条数据');
  928. if (printIds?.length === 1) return handleShowBrowse(printIds[0]);
  929. openPrintSelect(true, printIds);
  930. }
  931. function handleShowBrowse(id) {
  932. const formInfo: any[] = (getSelectRows() || []).map(o => {
  933. const item: any = { formId: o.id };
  934. #if(${context.isFlow})
  935. item.flowTaskId = o.flowTaskId || o.id;
  936. #end
  937. return item;
  938. });
  939. openPrintBrowse(true, { id, formInfo });
  940. }
  941. #end
  942. #end
  943. ##合计方法
  944. #if(${context.configurationTotal})
  945. //合计方法
  946. function getCmpValOfRow(row, key) {
  947. const summaryField: any = #if(${context.fieldsTotal})${context.fieldsTotal}#else [] #end; //取summaryField
  948. const isSummary = (key) => summaryField.includes(key);
  949. if (!summaryField.length || !isSummary(key)) return 0;
  950. const target = row[key];
  951. if (!target) return 0;
  952. const data = Number.isNaN(target) ? 0 : Number(target);
  953. return data;
  954. }
  955. #end
  956. ##左侧树
  957. #if(${context.leftTreeTable})
  958. function handleLeftTreeSelect(id, _node, nodePath) {
  959. if (state.treeActiveId == id) return;
  960. state.treeActiveId = id;
  961. state.treeActiveNodePath = nodePath;
  962. #if(${context.columnData.hasTreeQuery})
  963. // 有搜索
  964. resetFields();
  965. #end
  966. updateSearchFormValue();
  967. }
  968. #if(${context.columnData.treeDataSource} == 'api' && ${context.columnData.treeSyncType} == 1)
  969. // 左侧树异步加载
  970. function onLoadData(node) {
  971. return new Promise((resolve: (value?: unknown) => void) => {
  972. let treeSyncTemplateJson: any[] = #if($!{context.columnData.treeSyncTemplateJson}) ${context.columnData.treeSyncTemplateJson} #else [] #end; // 获取treeTemplateJson字段
  973. const query = { paramList: getParamList(treeSyncTemplateJson,node) };
  974. getDataInterfaceRes('${context.columnData.treeSyncInterfaceId}', query).then((res) => {
  975. const data = Array.isArray(res.data) ? res.data : [];
  976. leftTreeRef.value?.updateNodeByKey(node.eventKey, { children: data, isLeaf: !data.length });
  977. resolve();
  978. });
  979. });
  980. }
  981. #end
  982. #if((${context.columnData.treeDataSource} == 'formField' && ${context.columnData.treeRelationFieldSelectType} == 'all' )
  983. ||${context.columnData.treeDataSource} == 'organize')
  984. // 左侧树异步加载
  985. function onLoadData(node) {
  986. return new Promise((resolve: (value?: unknown) => void) => {
  987. getOrganizeSelector({parentId:node.id}).then(res => {
  988. const list = res.data.list;
  989. leftTreeRef.value?.updateNodeByKey(node.eventKey, { children: list, isLeaf: !list.length });
  990. resolve();
  991. });
  992. });
  993. }
  994. #end
  995. #end
  996. ##高级查询
  997. #if(${context.superQuery})
  998. // 高级查询
  999. function handleSuperQuery(superQueryJson) {
  1000. searchInfo.superQueryJson = superQueryJson;
  1001. reload({ page: 1 });
  1002. }
  1003. #end
  1004. function handleSearchReset() {
  1005. searchFormSubmit();
  1006. }
  1007. function handleSearchSubmit(data) {
  1008. clearSelectedRowKeys();
  1009. let obj = {
  1010. ...defaultSearchInfo,
  1011. superQueryJson: searchInfo.superQueryJson,
  1012. ...data,
  1013. #if(${context.tabConfig.createTab})
  1014. ...state.tabQueryJson,
  1015. #end
  1016. };
  1017. Object.keys(searchInfo).map(key => {
  1018. delete searchInfo[key];
  1019. return key;
  1020. });
  1021. for (let [key, value] of Object.entries(obj)) {
  1022. searchInfo[key.replaceAll('-', '_')] = value;
  1023. }
  1024. console.log(searchInfo);
  1025. reload({ page: 1 });
  1026. }
  1027. ##列表标签切换方法
  1028. #if(${context.tabConfig.createTab})
  1029. function onTabChange(val) {
  1030. state.tabQueryJson = { ${context.tabConfig.relationField} : val }; //这个key是取json中的tabConfig.relationFiled
  1031. unref(getSearchList).length?searchFormSubmit():resetFields()
  1032. }
  1033. #end
  1034. function updateSearchFormValue() {
  1035. if (!state.treeActiveId) return searchFormSubmit();
  1036. let queryJson: any = {};
  1037. let leftTreeActiveInfo: any = {};
  1038. const isMultiple = !state.treeRelationObj ? false : state.treeRelationObj.searchMultiple;
  1039. //多级左侧树,需要拼父级->转为查询参数
  1040. if (state.treeRelationObj && state.treeRelationObj.jnpfKey && ${multipleTwoUnitStr}.includes(state.treeRelationObj.jnpfKey)) {
  1041. let currValue = [];
  1042. #if(${context.columnData.treeDataSource} == 'formField')
  1043. if (state.treeRelationObj.jnpfKey === 'organizeSelect') {
  1044. currValue = state.treeActiveNodePath[state.treeActiveNodePath.length - 1].organizeIds;
  1045. }else{
  1046. currValue = state.treeActiveNodePath.map(o => o[state.treeFieldNames.key]);
  1047. }
  1048. #else
  1049. currValue = state.treeActiveNodePath.map(o => o[state.treeFieldNames.key]);
  1050. #end
  1051. queryJson = { '${context.columnData.treeRelation}': isMultiple ? [currValue] : currValue };
  1052. leftTreeActiveInfo = { '${context.columnData.treeRelation}': state.treeRelationObj.multiple ? [currValue] : currValue };
  1053. } else {
  1054. queryJson = { '${context.columnData.treeRelation}': isMultiple ? [state.treeActiveId] : state.treeActiveId };
  1055. leftTreeActiveInfo = { '${context.columnData.treeRelation}': state.treeRelationObj.multiple ? [state.treeActiveId] : state.treeActiveId };
  1056. }
  1057. state.leftTreeActiveInfo = leftTreeActiveInfo;
  1058. if(unref(getSearchList)?.length){
  1059. // 有搜索列表
  1060. setFieldsValue(queryJson);
  1061. searchFormSubmit();
  1062. }else{
  1063. // 无搜索列表
  1064. handleSearchSubmit(queryJson);
  1065. }
  1066. }
  1067. #if(${context.isFlow})
  1068. function getFlowId(){
  1069. if(!state.flowId){
  1070. createMessage.error('流程模板的flowId未填写')
  1071. closeCurrentTab();
  1072. router.replace('/404');
  1073. return
  1074. }
  1075. getFlowStartFormId(state.flowId).then(res => {
  1076. init()
  1077. }).catch(() => {
  1078. closeCurrentTab();
  1079. router.replace('/404');
  1080. });
  1081. }
  1082. #end
  1083. async function initViewList(currentId = '') {
  1084. const query = {
  1085. menuId: route.meta.modelId,
  1086. };
  1087. await getViewList(query).then(res => {
  1088. const columns : any[]= #if(${context.childTableStyle}==1) state.complexColumns; #else state.columns;#end
  1089. const searchList: any[] = state.searchSchemas.map(o => ({ label: o.label, id: o.field, show: o.show, labelI18nCode: o.labelI18nCode }));
  1090. const columnList: any[] = columns.map(o => ({ label: o.label, id: o.prop, show: true, fixed: o.fixed || 'none', labelI18nCode: o.labelI18nCode }));
  1091. state.viewList = (res.data || []).map(o => {
  1092. if (o.type == 0) return { ...o, searchList, columnList };
  1093. return { ...o, searchList: o.searchList ? JSON.parse(o.searchList) : [], columnList: o.columnList ? JSON.parse(o.columnList) : [] };
  1094. });
  1095. if (currentId) {
  1096. state.currentView = state.viewList.filter(o => o.id === currentId)[0] || state.viewList[0];
  1097. } else {
  1098. state.currentView = state.viewList.filter(o => o.status === 1)[0] || state.viewList[0];
  1099. }
  1100. });
  1101. }
  1102. function handleViewClick(item) {
  1103. state.currentView = item;
  1104. }
  1105. function setListValue(data: any[] = [], defaultData: any[] = [], key) {
  1106. let list: any[] = [];
  1107. for (let i = 0; i < data.length; i++) {
  1108. for (let j = 0; j < defaultData.length; j++) {
  1109. if (data[i].show && data[i].id == defaultData[j][key]) list.push(defaultData[j]);
  1110. }
  1111. }
  1112. return list;
  1113. }
  1114. function spanMethod({ column }) {
  1115. for (let i = 0; i < state.mergeList.length; i++) {
  1116. if (column.property == state.mergeList[i].prop) {
  1117. return { rowspan: state.mergeList[i].rowspan, colspan: state.mergeList[i].colspan };
  1118. }
  1119. }
  1120. }
  1121. #if(${context.configurationTotal})
  1122. // 列表合计
  1123. function footerMethod({ columns, data }) {
  1124. const summaryField: any =#if(${context.fieldsTotal})${context.fieldsTotal}#else [] #end; //取summaryField
  1125. const isSummary = (key) => summaryField.includes(key);
  1126. const useThousands = (key) => unref(getSummaryColumn).some((o) => o.__vModel__ === key && o.thousands);
  1127. return [
  1128. columns.map((column, columnIndex) => {
  1129. if (columnIndex === 0) return '合计';
  1130. if (!data.length) return '';
  1131. let sumVal = data.reduce((sum, d) => sum + getCmpValOfRow(d, column.property), 0);
  1132. if (!isSummary(column.property)) sumVal = '';
  1133. sumVal = Number.isNaN(sumVal) ? '' : sumVal;
  1134. const realVal = sumVal && !Number.isInteger(sumVal) ? Number(sumVal).toFixed(2) : sumVal;
  1135. sumVal = useThousands(column.property) ? thousandsFormat(realVal) : realVal;
  1136. return sumVal;
  1137. }),
  1138. ];
  1139. }
  1140. #end
  1141. #if(${context.columnData.resizable})
  1142. function handleColumnResizableChange({ resizeColumn, resizeWidth }) {
  1143. if (!resizeColumn.field || !resizeColumn.field.includes('-')) return;
  1144. const tableVModel = resizeColumn.field.split('-')[0];
  1145. setTimeout(() => {
  1146. for (let i = 0; i < state.childColumnList.length; i++) {
  1147. const element = state.childColumnList[i];
  1148. if (element.prop == tableVModel) {
  1149. for (let j = 0; j < element.children.length; j++) {
  1150. const item = element.children[j];
  1151. if (item.prop == resizeColumn.field) {
  1152. item.width = resizeWidth;
  1153. return;
  1154. }
  1155. }
  1156. }
  1157. }
  1158. }, 0);
  1159. }
  1160. #end
  1161. onMounted(() => {
  1162. #if(${context.isFlow})
  1163. getFlowId()
  1164. #else
  1165. init();
  1166. #end
  1167. });
  1168. </script>
  1169. <template>
  1170. <div class="jnpf-content-wrapper">
  1171. ## <!-- 左侧树 -->
  1172. #if(${context.leftTreeTable} == true)
  1173. <div class="jnpf-content-wrapper-left">
  1174. <BasicLeftTree v-bind="getLeftTreeBindValue" ref="leftTreeRef" @reload="getTreeView()"
  1175. @select="handleLeftTreeSelect" />
  1176. </div>
  1177. #end
  1178. ## <!-- 左侧树 -->
  1179. <div class="jnpf-content-wrapper-center">
  1180. ## <!-- 有搜索 -->
  1181. <div class="jnpf-content-wrapper-search-box" v-if="getSearchList.length">
  1182. <BasicForm @register="registerSearchForm" :schemas="getSearchList"
  1183. @advanced-change="redoHeight" @submit="handleSearchSubmit" @reset="handleSearchReset"
  1184. class="search-form">
  1185. </BasicForm>
  1186. </div>
  1187. ## <!-- 有搜索 -->
  1188. <div class="jnpf-content-wrapper-content jnpf-content-wrapper-list">
  1189. ## <!-- 列表标签面板 -->
  1190. #if(${context.tabConfig.createTab})
  1191. <a-tabs v-model:activeKey="state.tabActiveKey" class="jnpf-content-wrapper-tabs"
  1192. destroyInactiveTabPane @change="onTabChange">
  1193. <a-tab-pane v-for="item in state.tabList" :key="item.id" :tab="item.fullName"></a-tab-pane>
  1194. </a-tabs>
  1195. #end
  1196. ## 按键
  1197. <BasicVxeTable @register="registerTable" v-bind="getTableBindValue" ref="tableRef"
  1198. @columns-change="handleColumnChange" #if(${context.columnData.resizable}) @column-resizable-change="handleColumnResizableChange" #end>
  1199. #if(${context.btnPcList.size()}>0)
  1200. <template #tableTitle>
  1201. #foreach($btn in ${context.btnPcList})
  1202. #if(${btn.value}=='add' && ${btn.show})
  1203. <a-button type="primary" preIcon="${btn.icon}" #if(${context.columnData.useBtnPermission}) v-auth="'btn_${btn.value}'" #end
  1204. @click="addHandle()">#if(${btn.labelI18nCode})
  1205. {{$t('${btn.labelI18nCode}','${btn.label}')}}#else${btn.label}#end</a-button>
  1206. #end
  1207. #if(${btn.value}=='download' && ${btn.show})
  1208. <a-button type="link" preIcon="${btn.icon}" #if(${context.columnData.useBtnPermission}) v-auth="'btn_${btn.value}'" #end
  1209. @click="openExportModal(true, { columnList: state.exportList, selectIds: getSelectRowKeys(), showExportSelected:#if(${context.webType} !=4 || ${context.columnData.viewKey}) true #else false #end })">#if(${btn.labelI18nCode})
  1210. {{$t('${btn.labelI18nCode}','${btn.label}')}}#else${btn.label}#end</a-button>
  1211. #end
  1212. #if(${btn.value}=='upload' && ${btn.show})
  1213. <a-button type="link" preIcon="${btn.icon}" #if(${context.columnData.useBtnPermission}) v-auth="'btn_${btn.value}'" #end
  1214. @click="openImportModal(true, { url: '${context.module}/${context.className}', menuId: searchInfo.menuId #if($!{context.isFlow}), flowId: flowId#end })">#if(${btn.labelI18nCode})
  1215. {{$t('${btn.labelI18nCode}','${btn.label}')}}#else${btn.label}#end</a-button>
  1216. #end
  1217. #if(${btn.value}=='batchRemove' && ${btn.show})
  1218. <a-button type="link" preIcon="${btn.icon}" #if(${context.columnData.useBtnPermission}) v-auth="'btn_${btn.value}'" #end
  1219. @click="handelBatchRemove()">#if(${btn.labelI18nCode})
  1220. {{$t('${btn.labelI18nCode}','${btn.label}')}}#else${btn.label}#end</a-button>
  1221. #end
  1222. #if(${btn.value}=='batchPrint' && ${btn.show})
  1223. <a-button type="link" preIcon="${btn.icon}" #if(${context.columnData.useBtnPermission}) v-auth="'btn_${btn.value}'" #end
  1224. @click="handelBatchPrint()">#if(${btn.labelI18nCode})
  1225. {{$t('${btn.labelI18nCode}','${btn.label}')}}#else${btn.label}#end</a-button>
  1226. #end
  1227. #end
  1228. </template>
  1229. #end
  1230. ## <!-- 有高级查询:开始 -->
  1231. #if(${context.superQuery})
  1232. <template #toolbar>
  1233. <a-tooltip placement="top">
  1234. <template #title>
  1235. <span>{{ $t('common.superQuery') }}</span>
  1236. </template>
  1237. <filter-outlined @click="openSuperQuery(true, { columnOptions: superQueryJson })" />
  1238. </a-tooltip>
  1239. </template>
  1240. #end
  1241. <template #toolbarAfter>
  1242. <ViewList :menuId="searchInfo.menuId" :viewList="viewList" @itemClick="handleViewClick" @reload="initViewList" />
  1243. <ViewSetting :menuId="searchInfo.menuId" :viewList="viewList" :currentView="currentView" @reload="initViewList" />
  1244. </template>
  1245. ## <!-- 有高级查询:结束 -->
  1246. ## <!-- 有子表且是折叠展示:开始 -->
  1247. #if(${context.childTableStyle}==2)
  1248. <template #expandedRowRender="{ record }" v-if="childColumnList.length">
  1249. <a-tabs size="small">
  1250. <a-tab-pane :key="cIndex" :tab="child.label" :label="child.label"
  1251. v-for="(child, cIndex) in childColumnList">
  1252. <VxeGrid size="small" :data="record[child.prop]" :columns="child.children" :show-overflow="#if(${context.columnData.showOverflow})${context.columnData.showOverflow} #else false #end" min-height="0">
  1253. <template #[column.dataIndex]="{ row: childRecord }" v-for="column in child.children" :key="column.dataIndex">
  1254. <template v-if="column.jnpfKey === 'relationForm'">
  1255. <p class="link-text" @click="toDetail(column.modelId, childRecord[`${column.dataIndex}_id`], column.propsValue)">
  1256. {{ childRecord[column.dataIndex] }}
  1257. </p>
  1258. </template>
  1259. <template v-if="column.jnpfKey === 'inputNumber'">
  1260. <jnpf-input-number
  1261. v-model:value="childRecord[column.dataIndex]"
  1262. :precision="column.precision"
  1263. :thousands="column.thousands"
  1264. disabled
  1265. detailed />
  1266. </template>
  1267. <template v-if="column.jnpfKey === 'calculate'">
  1268. <jnpf-calculate
  1269. v-model:value="childRecord[column.dataIndex]"
  1270. :is-storage="column.isStorage"
  1271. :precision="column.precision"
  1272. :thousands="column.thousands"
  1273. :round-type="column.roundType"
  1274. :type="column.type"
  1275. :date-cal-config="column.dateCalConfig"
  1276. detailed />
  1277. </template>
  1278. <template v-if="column.jnpfKey === 'sign'">
  1279. <jnpf-sign v-model:value="childRecord[column.dataIndex]" detailed />
  1280. </template>
  1281. <template v-if="column.jnpfKey === 'signature'">
  1282. <jnpf-signature v-model:value="childRecord[column.dataIndex]" detailed />
  1283. </template>
  1284. <template v-if="column.jnpfKey === 'rate'">
  1285. <jnpf-rate v-model:value="childRecord[column.dataIndex]" :count="column.count" :allow-half="column.allowHalf" disabled />
  1286. </template>
  1287. <template v-if="column.jnpfKey === 'slider'">
  1288. <jnpf-slider v-model:value="childRecord[column.dataIndex]" :min="column.min" :max="column.max" :step="column.step" disabled />
  1289. </template>
  1290. <template v-if="column.jnpfKey === 'uploadImg'">
  1291. <jnpf-upload-img v-model:value="childRecord[column.dataIndex]" disabled detailed simple v-if="childRecord[column.dataIndex]?.length" />
  1292. </template>
  1293. <template v-if="column.jnpfKey === 'uploadFile'">
  1294. <jnpf-upload-file v-model:value="childRecord[column.dataIndex]" disabled detailed simple v-if="childRecord[column.dataIndex]?.length" />
  1295. </template>
  1296. <template v-if="column.jnpfKey === 'input'">
  1297. <jnpf-input
  1298. v-model:value="childRecord[column.dataIndex]"
  1299. :use-mask="column.useMask"
  1300. :mask-config="column.maskConfig"
  1301. :show-overflow=#if(${context.columnData.showOverflow})"$!{context.columnData.showOverflow}"#else "false"#end
  1302. detailed />
  1303. </template>
  1304. </template>
  1305. </VxeGrid>
  1306. </a-tab-pane>
  1307. </a-tabs>
  1308. </template>
  1309. #end
  1310. ## <!-- 有子表且是折叠展示:结束 -->
  1311. <template #[column.prop]="{ record }" v-for="column in allColumns" :key="column.prop">
  1312. <template v-if="column.jnpfKey === 'inputNumber'">
  1313. <jnpf-input-number v-model:value="record[column.prop]" :precision="column.precision" :thousands="column.thousands" disabled detailed />
  1314. </template>
  1315. <template v-else-if="column.jnpfKey === 'calculate'">
  1316. <jnpf-calculate
  1317. v-model:value="record[column.prop]"
  1318. :is-storage="column.isStorage"
  1319. :precision="column.precision"
  1320. :thousands="column.thousands"
  1321. :type="column.type"
  1322. :date-cal-config="column.dateCalConfig"
  1323. :round-type="column.roundType"
  1324. detailed />
  1325. </template>
  1326. <template v-else-if="column.jnpfKey === 'sign'">
  1327. <jnpf-sign v-model:value="record[column.prop]" detailed />
  1328. </template>
  1329. <template v-else-if="column.jnpfKey === 'signature'">
  1330. <jnpf-signature v-model:value="record[column.prop]" detailed />
  1331. </template>
  1332. <template v-else-if="column.jnpfKey === 'rate'">
  1333. <jnpf-rate v-model:value="record[column.prop]" :count="column.count" :allow-half="column.allowHalf" disabled />
  1334. </template>
  1335. <template v-else-if="column.jnpfKey === 'slider'">
  1336. <jnpf-slider v-model:value="record[column.prop]" :min="column.min" :max="column.max" :step="column.step" disabled />
  1337. </template>
  1338. <template v-else-if="column.jnpfKey === 'uploadImg'">
  1339. <jnpf-upload-img v-model:value="record[column.prop]" disabled detailed simple v-if="record[column.prop]?.length" />
  1340. </template>
  1341. <template v-else-if="column.jnpfKey === 'uploadFile'">
  1342. <jnpf-upload-file v-model:value="record[column.prop]" disabled detailed simple v-if="record[column.prop]?.length" />
  1343. </template>
  1344. <template v-else-if="column.jnpfKey === 'input'">
  1345. <jnpf-input
  1346. v-model:value="record[column.prop]"
  1347. :use-mask="column.useMask"
  1348. :mask-config="column.maskConfig"
  1349. :show-overflow=#if(${context.columnData.showOverflow})"$!{context.columnData.showOverflow}"#else "false"#end
  1350. detailed />
  1351. </template>
  1352. <template v-else-if="column.jnpfKey === 'relationForm'">
  1353. <p class="link-text" @click="toDetail(column.modelId, record[`${column.prop}_id`], column.propsValue)">
  1354. {{ record[column.prop] || record[column.prop] }}
  1355. </p>
  1356. </template>
  1357. <template v-else-if="systemComponentsList.includes(column.jnpfKey)">
  1358. {{ record[`${column.prop}_name`] || record[column.prop] }}
  1359. </template>
  1360. <template v-else>
  1361. {{ record[column.prop] }}
  1362. </template>
  1363. </template>
  1364. #if(${context.childTableStyle}==1)
  1365. ## <!-- 有子表且是分组展示:开始 -->
  1366. <template #[item.dataIndex]="{ record }" v-for="(item, index) in childColumnList" :key="item.dataIndex">
  1367. <ChildTableColumn
  1368. :data="record[item.prop]"
  1369. :head="item.children"
  1370. @toggle-expand="toggleExpand(record, `${item.prop}Expand`)"
  1371. @to-detail="toDetail"
  1372. :expand="record[`${item.prop}Expand`]"
  1373. :show-overflow="#if(${context.columnData.showOverflow})${context.columnData.showOverflow} #else false #end"
  1374. :key="index" />
  1375. </template>
  1376. ## <!-- 有子表且是分组展示:结束 -->
  1377. #end
  1378. ## <!-- 有工作流:开始 -->
  1379. #if($!{context.isFlow})
  1380. <template #flowState="{ record }">
  1381. <JnpfTextTag :content="getFlowStatusContent(record.flowState)" :color="getFlowStatusColor(record.flowState)" v-if="!record.top"/>
  1382. </template>
  1383. #end
  1384. ## <!-- 有工作流:结束 -->
  1385. <template #action="{ record }">
  1386. <TableAction :actions="getTableActions(record)" v-if="!record.top"/>
  1387. </template>
  1388. </BasicVxeTable>
  1389. </div>
  1390. </div>
  1391. #if(!$context.isFlow && ${context.webType} !=4)
  1392. <Form ref="formRef" @reload="reload" />
  1393. #end
  1394. #foreach($itemBtn in ${context.columnBtnPcList})
  1395. #if(!${context.isFlow} && ${itemBtn.value}=="detail")
  1396. <Detail ref="detailRef" />
  1397. #end
  1398. #if(${itemBtn.value}=="edit")
  1399. #end
  1400. #if(${itemBtn.value}=="remove")
  1401. #end
  1402. #end
  1403. #foreach($itemBtn in ${context.btnPcList})
  1404. #if(${itemBtn.value}=="add")
  1405. #end
  1406. #if(${itemBtn.value}=="upload" && ${itemBtn.show})
  1407. <ImportModal @register="registerImportModal" @reload="reload" />
  1408. #end
  1409. #if(${itemBtn.value}=="download" && ${itemBtn.show})
  1410. <ExportModal @register="registerExportModal" @download="handleDownload" />
  1411. #end
  1412. #if(${itemBtn.value}=="batchRemove")
  1413. #end
  1414. #if(${itemBtn.value}=="batchPrint" && ${itemBtn.show})
  1415. <PrintSelect @register="registerPrintSelect" @change="handleShowBrowse" />
  1416. <PrintBrowse @register="registerPrintBrowse" />
  1417. #end
  1418. #end
  1419. #if(${context.webType}!=4)
  1420. ## <!-- 有关联表单详情:开始 -->
  1421. <RelationDetail ref="relationDetailRef" />
  1422. ## <!-- 有关联表单详情:结束 -->
  1423. #end
  1424. #if(${context.superQuery})
  1425. ## <!-- 有高级查询:开始 -->
  1426. <SuperQueryModal @register="registerSuperQueryModal" @superQuery="handleSuperQuery" />
  1427. ## <!-- 有高级查询:结束 -->
  1428. #end
  1429. #if(${context.isFlow})
  1430. ## <!-- 带流程:开始 -->
  1431. <FlowParser @register="registerFlowParser" @reload="reload" />
  1432. ## <!-- 带流程:结束 -->
  1433. #end
  1434. </div>
  1435. </template>