index.vue.vm 63 KB

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