表格.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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 == 'datetime')
  34. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}">
  35. <el-date-picker
  36. type="datetime"
  37. placeholder="请输入#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
  38. v-model="state.queryForm.${field.attrName}"
  39. :value-format="dateTimeStr"
  40. />
  41. </el-form-item>
  42. #elseif($field.queryFormType == 'date-range')
  43. <el-form-item label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end" prop="${field.attrName}Range">
  44. <el-date-picker
  45. type="daterange"
  46. start-placeholder="开始日期"
  47. end-placeholder="结束日期"
  48. v-model="state.queryForm.${field.attrName}Range"
  49. :value-format="dateStr"
  50. range-separator="至"
  51. />
  52. </el-form-item>
  53. #elseif($field.queryFormType == 'datetime-range')
  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. start-placeholder="开始时间"
  58. end-placeholder="结束时间"
  59. v-model="state.queryForm.${field.attrName}Range"
  60. :value-format="dateTimeStr"
  61. range-separator="至"
  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="'${moduleName}_${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="'${moduleName}_${functionName}_add'"
  120. >
  121. 导入
  122. </el-button>
  123. <el-button
  124. plain
  125. :disabled="multiple"
  126. icon="Delete"
  127. type="primary"
  128. v-auth="'${moduleName}_${functionName}_del'"
  129. @click="handleDelete(selectObjs)"
  130. >
  131. 删除
  132. </el-button>
  133. <right-toolbar
  134. v-model:showSearch="showSearch"
  135. :export="'${moduleName}_${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="selectionChangHandle"
  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" width="120">
  164. <template #default="scope">
  165. <el-image
  166. v-if="scope.row.${field.attrName}"
  167. :src="baseURL + scope.row.${field.attrName}"
  168. fit="cover"
  169. class="w-20 h-20 rounded"
  170. :preview-teleported="true"
  171. />
  172. <span v-else class="text-gray-400">暂无图片</span>
  173. </template>
  174. </el-table-column>
  175. #else
  176. <el-table-column
  177. prop="${field.attrName}"
  178. label="#if(${field.fieldComment})${field.fieldComment}#else${field.attrName}#end"
  179. #if(${field.gridSort} == '1')
  180. sortable="custom"
  181. #end
  182. show-overflow-tooltip
  183. />
  184. #end
  185. #end
  186. <el-table-column label="操作" width="150">
  187. <template #default="scope">
  188. <el-button
  189. icon="edit-pen"
  190. text
  191. type="primary"
  192. v-auth="'${moduleName}_${functionName}_edit'"
  193. @click="formDialogRef.openDialog(scope.row.${pk.attrName})"
  194. >
  195. 编辑
  196. </el-button>
  197. <el-button
  198. icon="delete"
  199. text
  200. type="primary"
  201. v-auth="'${moduleName}_${functionName}_del'"
  202. @click="handleDelete([scope.row.${pk.attrName}])"
  203. >
  204. 删除
  205. </el-button>
  206. </template>
  207. </el-table-column>
  208. </el-table>
  209. <!-- 分页组件 -->
  210. <pagination
  211. @size-change="sizeChangeHandle"
  212. @current-change="currentChangeHandle"
  213. v-bind="state.pagination"
  214. />
  215. </div>
  216. <!-- 编辑、新增弹窗 -->
  217. <form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
  218. <!-- 导入excel弹窗 (需要在 upms-biz/resources/file 下维护模板) -->
  219. <upload-excel
  220. ref="excelUploadRef"
  221. title="导入"
  222. url="/${moduleName}/${functionName}/import"
  223. temp-url="/admin/sys-file/local/file/${functionName}.xlsx"
  224. @refreshDataList="getDataList"
  225. />
  226. </div>
  227. </template>
  228. <script setup lang="ts" name="system${ClassName}">
  229. // ========== 导入声明 ==========
  230. import { BasicTableProps, useTable } from "/@/hooks/table";
  231. import { fetchList, delObjs } from "/@/api/${moduleName}/${functionName}";
  232. import { useMessage, useMessageBox } from "/@/hooks/message";
  233. import { useDict } from '/@/hooks/dict';
  234. // ========== 组件声明 ==========
  235. // 异步加载表单弹窗组件
  236. const FormDialog = defineAsyncComponent(() => import('./form.vue'));
  237. // ========== 字典数据 ==========
  238. #set($fieldDict=[])
  239. #foreach($field in $queryList)
  240. #if($field.fieldDict)
  241. #set($void=$fieldDict.add($field.fieldDict))
  242. #end
  243. #end
  244. #foreach($field in $gridList)
  245. #if($field.fieldDict)
  246. #set($void=$fieldDict.add($field.fieldDict))
  247. #end
  248. #end
  249. #if($fieldDict)
  250. // 加载字典数据
  251. const { $dict.format($fieldDict) } = useDict($dict.quotation($fieldDict));
  252. #end
  253. // ========== 组件引用 ==========
  254. const formDialogRef = ref(); // 表单弹窗引用
  255. const excelUploadRef = ref(); // Excel上传弹窗引用
  256. const queryRef = ref(); // 查询表单引用
  257. // ========== 响应式数据 ==========
  258. const showSearch = ref(true); // 是否显示搜索区域
  259. const selectObjs = ref([]) as any; // 表格多选数据
  260. const multiple = ref(true); // 是否多选
  261. // ========== 表格状态 ==========
  262. const state: BasicTableProps = reactive<BasicTableProps>({
  263. queryForm: {}, // 查询参数
  264. pageList: fetchList // 分页查询方法
  265. });
  266. // ========== Hook引用 ==========
  267. // 表格相关Hook
  268. const {
  269. getDataList,
  270. currentChangeHandle,
  271. sizeChangeHandle,
  272. sortChangeHandle,
  273. downBlobFile,
  274. tableStyle
  275. } = useTable(state);
  276. // ========== 方法定义 ==========
  277. /**
  278. * 重置查询条件
  279. */
  280. const resetQuery = () => {
  281. // 清空搜索条件
  282. queryRef.value?.resetFields();
  283. // 清空多选
  284. selectObjs.value = [];
  285. // 重新查询
  286. getDataList();
  287. };
  288. /**
  289. * 导出Excel文件
  290. */
  291. const exportExcel = () => {
  292. downBlobFile(
  293. '/${moduleName}/${functionName}/export',
  294. Object.assign(state.queryForm, { ids: selectObjs }),
  295. '${functionName}.xlsx'
  296. );
  297. };
  298. /**
  299. * 表格多选事件处理
  300. * @param objs 选中的数据行
  301. */
  302. const selectionChangHandle = (objs: { $pk.attrName: string }[]) => {
  303. selectObjs.value = objs.map(({ $pk.attrName }) => $pk.attrName);
  304. multiple.value = !objs.length;
  305. };
  306. /**
  307. * 删除数据处理
  308. * @param ids 要删除的数据ID数组
  309. */
  310. const handleDelete = async (ids: string[]) => {
  311. try {
  312. await useMessageBox().confirm('此操作将永久删除');
  313. } catch {
  314. return;
  315. }
  316. try {
  317. await delObjs(ids);
  318. getDataList();
  319. useMessage().success('删除成功');
  320. } catch (err: any) {
  321. useMessage().error(err.msg);
  322. }
  323. };
  324. </script>