indexEdit.vue.vm 66 KB

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