indexEdit.vue.vm 71 KB

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