表格.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <template>
  2. <div class="layout-padding">
  3. <div class="layout-padding-auto layout-padding-view">
  4. #if($queryList)
  5. <!-- 查询表单区域 -->
  6. <el-row v-show="showSearch">
  7. <el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
  8. #foreach($field in $queryList)
  9. #if($field.queryFormType == 'select')
  10. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
  11. <el-select v-model="state.queryForm.${field.attrName}" placeholder="请选择#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">
  12. #if($field.fieldDict)
  13. <el-option
  14. :label="item.label"
  15. :value="item.value"
  16. v-for="(item, index) in ${field.fieldDict}"
  17. :key="index"
  18. />
  19. #else
  20. <el-option label="请选择" value="0" />
  21. #end
  22. </el-select>
  23. </el-form-item>
  24. #elseif($field.queryFormType == 'date')
  25. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
  26. <el-date-picker
  27. type="date"
  28. placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
  29. v-model="state.queryForm.${field.attrName}"
  30. :value-format="dateStr"
  31. />
  32. </el-form-item>
  33. #elseif($field.queryFormType == 'daterange')
  34. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">
  35. <el-date-picker
  36. type="daterange"
  37. range-separator="至"
  38. start-placeholder="开始日期"
  39. end-placeholder="结束日期"
  40. v-model="state.queryForm.${field.attrName}Range"
  41. :value-format="dateStr"
  42. />
  43. </el-form-item>
  44. #elseif($field.queryFormType == 'datetime')
  45. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
  46. <el-date-picker
  47. type="datetime"
  48. placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
  49. v-model="state.queryForm.${field.attrName}"
  50. :value-format="dateTimeStr"
  51. />
  52. </el-form-item>
  53. #elseif($field.queryFormType == 'datetimerange')
  54. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">
  55. <el-date-picker
  56. type="datetimerange"
  57. range-separator="至"
  58. start-placeholder="开始时间"
  59. end-placeholder="结束时间"
  60. v-model="state.queryForm.${field.attrName}Range"
  61. :value-format="dateTimeStr"
  62. />
  63. </el-form-item>
  64. #elseif($field.formType == 'radio')
  65. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
  66. <el-radio-group v-model="state.queryForm.${field.attrName}">
  67. #if($field.fieldDict)
  68. <el-radio
  69. :label="item.value"
  70. v-for="(item, index) in ${field.fieldDict}"
  71. border
  72. :key="index"
  73. >
  74. {{ item.label }}
  75. </el-radio>
  76. #else
  77. <el-radio label="${field.fieldComment}" border>
  78. ${field.fieldComment}
  79. </el-radio>
  80. #end
  81. </el-radio-group>
  82. </el-form-item>
  83. #else
  84. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
  85. <el-input
  86. placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
  87. v-model="state.queryForm.${field.attrName}"
  88. />
  89. </el-form-item>
  90. #end
  91. #end
  92. <el-form-item>
  93. <el-button icon="search" type="primary" @click="getDataList">
  94. 查询
  95. </el-button>
  96. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  97. </el-form-item>
  98. </el-form>
  99. </el-row>
  100. #end
  101. <!-- 操作按钮区域 -->
  102. <el-row>
  103. <div class="mb8" style="width: 100%">
  104. <el-button
  105. icon="folder-add"
  106. type="primary"
  107. class="ml10"
  108. @click="formDialogRef.openDialog()"
  109. v-auth="'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add'"
  110. >
  111. 新增
  112. </el-button>
  113. <el-button
  114. plain
  115. icon="upload-filled"
  116. type="primary"
  117. class="ml10"
  118. @click="excelUploadRef.show()"
  119. v-auth="'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_add'"
  120. >
  121. 导入
  122. </el-button>
  123. <el-button
  124. plain
  125. :disabled="multiple"
  126. icon="Delete"
  127. type="primary"
  128. v-auth="'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del'"
  129. @click="handleDelete(selectObjs.value)"
  130. >
  131. 删除
  132. </el-button>
  133. <right-toolbar
  134. v-model:showSearch="showSearch"
  135. :export="'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_export'"
  136. @exportExcel="exportExcel"
  137. class="ml10 mr20"
  138. style="float: right;"
  139. @queryTable="getDataList"
  140. />
  141. </div>
  142. </el-row>
  143. <!-- 数据表格区域 -->
  144. <el-table
  145. :data="state.dataList"
  146. v-loading="state.loading"
  147. border
  148. :cell-style="tableStyle.cellStyle"
  149. :header-cell-style="tableStyle.headerCellStyle"
  150. @selection-change="selectionChangeHandle"
  151. @sort-change="sortChangeHandle"
  152. >
  153. <el-table-column type="selection" width="40" align="center" />
  154. <el-table-column type="index" label="#" width="40" />
  155. #foreach($field in $gridList)
  156. #if($field.fieldDict)
  157. <el-table-column prop="${field.attrName}" label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" show-overflow-tooltip>
  158. <template #default="scope">
  159. <dict-tag :options="$field.fieldDict" :value="scope.row.${field.attrName}" />
  160. </template>
  161. </el-table-column>
  162. #elseif(${field.formType} == 'upload-img')
  163. <el-table-column prop="${field.attrName}" label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end">
  164. <template #default="{ row }">
  165. <upload-img disabled v-model:imageUrl="row.${field.attrName}"></upload-img>
  166. </template>
  167. </el-table-column>
  168. #else
  169. <el-table-column
  170. prop="${field.attrName}"
  171. label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
  172. #if(${field.gridSort} == '1')
  173. sortable="custom"
  174. #end
  175. show-overflow-tooltip
  176. />
  177. #end
  178. #end
  179. <el-table-column label="操作" width="150">
  180. <template #default="scope">
  181. <el-button
  182. icon="edit-pen"
  183. text
  184. type="primary"
  185. v-auth="'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_edit'"
  186. @click="formDialogRef.openDialog(scope.row.${pk.attrName})"
  187. >
  188. 编辑
  189. </el-button>
  190. <el-button
  191. icon="delete"
  192. text
  193. type="primary"
  194. v-auth="'$str.lowerCase($moduleName)_$str.lowerCase($functionName)_del'"
  195. @click="handleDelete([scope.row.${pk.attrName}])"
  196. >
  197. 删除
  198. </el-button>
  199. </template>
  200. </el-table-column>
  201. </el-table>
  202. <!-- 分页组件 -->
  203. <pagination
  204. @size-change="sizeChangeHandle"
  205. @current-change="currentChangeHandle"
  206. v-bind="state.pagination"
  207. />
  208. </div>
  209. <!-- 编辑、新增弹窗 -->
  210. <form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
  211. <!-- 导入excel弹窗 (需要在 upms-biz/resources/file 下维护模板) -->
  212. <upload-excel
  213. ref="excelUploadRef"
  214. title="导入"
  215. url="/${moduleName}/${functionName}/import"
  216. temp-url="/admin/sys-file/local/file/${functionName}.xlsx"
  217. @refreshDataList="getDataList"
  218. />
  219. </div>
  220. </template>
  221. <script setup lang="ts" name="system${ClassName}">
  222. // ========== 导入声明 ==========
  223. import { BasicTableProps, useTable } from "/@/hooks/table";
  224. import { fetchList, delObjs } from "/@/api/${moduleName}/${functionName}";
  225. import { useMessage, useMessageBox } from "/@/hooks/message";
  226. import { useDict } from '/@/hooks/dict';
  227. // ========== 组件声明 ==========
  228. // 异步加载表单弹窗组件
  229. const FormDialog = defineAsyncComponent(() => import('./form.vue'));
  230. // ========== 字典数据 ==========
  231. #set($fieldDict=[])
  232. #foreach($field in $queryList)
  233. #if($field.fieldDict)
  234. #set($void=$fieldDict.add($field.fieldDict))
  235. #end
  236. #end
  237. #foreach($field in $gridList)
  238. #if($field.fieldDict)
  239. #set($void=$fieldDict.add($field.fieldDict))
  240. #end
  241. #end
  242. #if($fieldDict)
  243. // 加载字典数据
  244. const { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));
  245. #end
  246. // ========== 组件引用 ==========
  247. const formDialogRef = ref(); // 表单弹窗引用
  248. const excelUploadRef = ref(); // Excel上传弹窗引用
  249. const queryRef = ref(); // 查询表单引用
  250. // ========== 响应式数据 ==========
  251. const showSearch = ref(true); // 是否显示搜索区域
  252. const selectObjs = ref([]) as any; // 表格多选数据
  253. const multiple = ref(true); // 是否多选
  254. // ========== 表格状态 ==========
  255. const state: BasicTableProps = reactive<BasicTableProps>({
  256. queryForm: {}, // 查询参数
  257. pageList: fetchList // 分页查询方法
  258. });
  259. // ========== Hook引用 ==========
  260. // 表格相关Hook
  261. const {
  262. getDataList,
  263. currentChangeHandle,
  264. sizeChangeHandle,
  265. sortChangeHandle,
  266. downBlobFile,
  267. tableStyle
  268. } = useTable(state);
  269. // ========== 方法定义 ==========
  270. /**
  271. * 重置查询条件
  272. */
  273. const resetQuery = () => {
  274. // 清空搜索条件
  275. queryRef.value?.resetFields();
  276. // 清空多选
  277. selectObjs.value = [];
  278. // 重新查询
  279. getDataList();
  280. };
  281. /**
  282. * 导出Excel文件
  283. */
  284. const exportExcel = () => {
  285. downBlobFile(
  286. '/${moduleName}/${functionName}/export',
  287. { ...state.queryForm, ids: selectObjs.value },
  288. '${functionName}.xlsx'
  289. );
  290. };
  291. /**
  292. * 表格多选事件处理
  293. * @param objs 选中的数据行
  294. */
  295. const selectionChangeHandle = (objs: { $pk.attrName: string }[]) => {
  296. selectObjs.value = objs.map(({ $pk.attrName }) => $pk.attrName);
  297. multiple.value = !objs.length;
  298. };
  299. /**
  300. * 删除数据处理
  301. * @param ids 要删除的数据ID数组
  302. */
  303. const handleDelete = async (ids: string[]) => {
  304. try {
  305. await useMessageBox().confirm('此操作将永久删除');
  306. } catch {
  307. return;
  308. }
  309. try {
  310. await delObjs(ids);
  311. getDataList();
  312. useMessage().success('删除成功');
  313. } catch (err: any) {
  314. useMessage().error(err.msg);
  315. }
  316. };
  317. </script>