index.vue.vm 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <script lang="ts" setup name="@(Model.LowerClassName)">
  2. import { ref, reactive, onMounted } from "vue";
  3. import { auth } from '/@@/utils/authFunction';
  4. import { ElMessageBox, ElMessage } from "element-plus";
  5. import { downloadStreamFile } from "/@@/utils/download";
  6. @if(Model.PrintType == "custom") {
  7. @:// 推荐设置操作 width 为 200
  8. @:import { hiprint } from 'vue-plugin-hiprint';
  9. @:import { getAPI } from '/@@/utils/axios-utils';
  10. @:import { SysPrintApi } from '/@@/api-services/api';
  11. @:import { SysPrint } from '/@@/api-services/models';
  12. @:import { formatDate } from '/@@/utils/formatTime';
  13. }
  14. import { use@(Model.ClassName)Api } from '/@@/api/@(Model.PagePath)/@(Model.LowerClassName)';
  15. @if(Model.HasConstField) {
  16. @:import { useUserInfo } from "/@@/stores/userInfo";
  17. }
  18. import editDialog from '/@@/views/@(Model.PagePath)/@(Model.LowerClassName)/component/editDialog.vue'
  19. import printDialog from '/@@/views/system/print/component/hiprint/preview.vue'
  20. import ModifyRecord from '/@@/components/table/modifyRecord.vue';
  21. @if(Model.ImportFieldList.Count > 0) {
  22. @:import ImportData from "/@@/components/table/importData.vue";
  23. }
  24. const @(Model.LowerClassName)Api = use@(Model.ClassName)Api();
  25. const printDialogRef = ref();
  26. const editDialogRef = ref();
  27. @if (Model.ImportFieldList.Count > 0) {
  28. @:const importDataRef = ref();
  29. }
  30. const state = reactive({
  31. exportLoading: false,
  32. tableLoading: false,
  33. stores: @(Model.HasConstField ? "useUserInfo()" : "{}"),
  34. showAdvanceQueryUI: @(Model.HasLikeQuery ? "false" : "true"),
  35. dropdownData: {} as any,
  36. selectData: [] as any[],
  37. tableQueryParams: {} as any,
  38. tableParams: {
  39. page: 1,
  40. pageSize: 20,
  41. total: 0,
  42. field: '@(Model.HasJoinTable ? "u.createTime" : "createTime")', // 默认的排序字段
  43. order: 'descending', // 排序方向
  44. descStr: 'descending', // 降序排序的关键字符
  45. },
  46. tableData: [],
  47. });
  48. // 页面加载时
  49. onMounted(async () => {
  50. @if (Model.DropdownFieldList.Count > 0) {
  51. @:const data = await @(Model.LowerClassName)Api.getDropdownData(true).then(res => res.data.result) ?? {};
  52. @foreach (var column in Model.DropdownFieldList) {
  53. @:state.dropdownData.@(column.LowerPropertyName) = data.@(column.LowerPropertyName);
  54. }
  55. }
  56. });
  57. // 查询操作
  58. const handleQuery = async (params: any = {}) => {
  59. state.tableLoading = true;
  60. state.tableParams = Object.assign(state.tableParams, params);
  61. const result = await @(Model.LowerClassName)Api.page(Object.assign(state.tableQueryParams, state.tableParams)).then(res => res.data.result);
  62. state.tableParams.total = result?.total;
  63. state.tableData = result?.items ?? [];
  64. state.tableLoading = false;
  65. };
  66. // 列排序
  67. const sortChange = async (column: any) => {
  68. state.tableParams.field = column.prop;
  69. state.tableParams.order = column.order;
  70. await handleQuery();
  71. };
  72. // 删除
  73. const del@(Model.ClassName) = (row: any) => {
  74. ElMessageBox.confirm(`确定要删除吗?`, "提示", {
  75. confirmButtonText: "确定",
  76. cancelButtonText: "取消",
  77. type: "warning",
  78. }).then(async () => {
  79. await @(Model.LowerClassName)Api.delete({ @(Model.PrimaryKeysFormat(", ", "{0}: row.{0}", true)) });
  80. handleQuery();
  81. ElMessage.success("删除成功");
  82. }).catch(() => {});
  83. };
  84. // 批量删除
  85. const batchDel@(Model.ClassName) = () => {
  86. ElMessageBox.confirm(`确定要删除${state.selectData.length}条记录吗?`, "提示", {
  87. confirmButtonText: "确定",
  88. cancelButtonText: "取消",
  89. type: "warning",
  90. }).then(async () => {
  91. await @(Model.LowerClassName)Api.batchDelete(state.selectData.map(u => ({ @(Model.PrimaryKeysFormat(", ", "{0}: u.{0}", true)) }) )).then(res => {
  92. ElMessage.success(`成功批量删除${res.data.result}条记录`);
  93. handleQuery();
  94. });
  95. }).catch(() => {});
  96. };
  97. @if(Model.PrintType == "custom") {
  98. @:
  99. @:// 打开打印页面
  100. @:const openPrint@(Model.ClassName) = async (row: any) => {
  101. @:var res = await getAPI(SysPrintApi).apiSysPrintPrintNameGet('@Model.PrintName');
  102. @:var printTemplate = res.data.result as SysPrint;
  103. @:var template = JSON.parse(printTemplate.template);
  104. @:row['printDate'] = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS')
  105. @:printDialogRef.value.showDialog(new hiprint.PrintTemplate({template: template}), row, template.panels[0].width);
  106. @:}
  107. }
  108. @if (Model.HasSetStatus) {
  109. @:
  110. @:// 设置状态
  111. @:const change@(Model.ClassName)Status = async (row: any) => {
  112. @:await @(Model.LowerClassName)Api.setStatus({ @(Model.PrimaryKeysFormat(", ", "{0}: row.{0}", true)), status: row.status }).then(() => ElMessage.success('状态设置成功'));
  113. @:};
  114. }
  115. @if (Model.ImportFieldList.Count > 0) {
  116. @:
  117. @:// 导出数据
  118. @:const export@(Model.ClassName)Command = async (command: string) => {
  119. @:try {
  120. @:state.exportLoading = true;
  121. @:if (command === 'select') {
  122. @:const params = Object.assign({}, state.tableQueryParams, state.tableParams, { selectKeyList: state.selectData.map(u => u.@(Model.PrimaryKeyFieldList.First().LowerPropertyName)) });
  123. @:await @(Model.LowerClassName)Api.exportData(params).then(res => downloadStreamFile(res));
  124. @:} else if (command === 'current') {
  125. @:const params = Object.assign({}, state.tableQueryParams, state.tableParams);
  126. @:await @(Model.LowerClassName)Api.exportData(params).then(res => downloadStreamFile(res));
  127. @:} else if (command === 'all') {
  128. @:const params = Object.assign({}, state.tableQueryParams, state.tableParams, { page: 1, pageSize: 99999999 });
  129. @:await @(Model.LowerClassName)Api.exportData(params).then(res => downloadStreamFile(res));
  130. @:}
  131. @:} finally {
  132. @:state.exportLoading = false;
  133. @:}
  134. @:}
  135. }
  136. handleQuery();
  137. </script>
  138. <template>
  139. <div class="@(Model.LowerClassName)-container" v-loading="state.exportLoading">
  140. <el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
  141. <el-form :model="state.tableQueryParams" ref="queryForm" labelWidth="90">
  142. <el-row>
  143. @if(Model.QueryWhetherList.Count > 0) {
  144. if(Model.HasLikeQuery) {
  145. @:<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10">
  146. @:<el-form-item label="关键字">
  147. @:<el-input v-model="state.tableQueryParams.keyword" clearable placeholder="请输入模糊查询关键字"/>
  148. @:</el-form-item>
  149. @:</el-col>
  150. }
  151. foreach (var column in Model.QueryWhetherList) {
  152. @:<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10" v-if="state.showAdvanceQueryUI">
  153. @:<el-form-item label="@column.ColumnComment">
  154. if(column.EffectType == "Input" || column.EffectType == "InputTextArea"){
  155. @:<el-input v-model="state.tableQueryParams.@(column.LowerPropertyName)" clearable placeholder="请输入@(column.ColumnComment)"/>
  156. }else if(column.EffectType == "InputTextArea"){
  157. @:<el-input-number v-model="state.tableQueryParams.@(column.LowerPropertyName)" clearable placeholder="请输入@(column.ColumnComment)"/>
  158. }else if(column.EffectType == "InputNumber"){
  159. @:<el-input-number v-model="state.tableQueryParams.@(column.LowerPropertyName)" clearable placeholder="请输入@(column.ColumnComment)"/>
  160. }else if(column.IsSelectorEffectType || column.EffectType == "ForeignKey") {
  161. if (column.EffectType == "DictSelector" || column.EffectType == "EnumSelector") {
  162. @:<g-sys-dict v-model="state.tableQueryParams.@(column.LowerPropertyName)" code="@(column.DictTypeCode)" render-as="select" placeholder="请选择@(column.ColumnComment)" clearable filterable />
  163. } else {
  164. @:<el-select clearable filterable v-model="state.tableQueryParams.@(column.LowerPropertyName)" placeholder="请选择@(column.ColumnComment)">
  165. if (column.EffectType == "ForeignKey") {
  166. @:<el-option v-for="(item,index) in state.dropdownData.@(column.LowerPropertyName) ?? []" :key="index" :value="item.value" :label="item.label" />
  167. } else if (column.EffectType == "ConstSelector") {
  168. @:<el-option v-for="(item, index) in state.stores.getConstDataByTypeCode('@column.DictTypeCode')" :key="index" :label="item.name" :value="item.code" />
  169. }
  170. @:</el-select>
  171. }
  172. }else if(column.EffectType == "ApiTreeSelector"){
  173. @:<el-cascader
  174. @::options="state.dropdownData.@(column.LowerPropertyName) ?? []"
  175. @:@:props="{ checkStrictly: true, emitPath: false }"
  176. @:placeholder="请选择@(column.ColumnComment)"
  177. @:clearable
  178. @:filterable
  179. @:class="w100"
  180. @:v-model="state.tableQueryParams.@(column.LowerPropertyName)"
  181. @:>
  182. @:<template #default="{ node, data }">
  183. @:<span>{{ data.label }}</span>
  184. @:<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
  185. @:</template>
  186. @:</el-cascader>
  187. } else if (column.EffectType == "DatePicker"){
  188. if (column.QueryType == "~") {
  189. @:<el-date-picker type="daterange" v-model="state.tableQueryParams.@(column.LowerPropertyName)Range" value-format="YYYY-MM-DD HH:mm:ss" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" />
  190. } else {
  191. @:<el-date-picker placeholder="请选择@(column.ColumnComment)" value-format="YYYY/MM/DD" v-model="state.tableQueryParams.@(column.LowerPropertyName)" />
  192. }
  193. } else {
  194. @:<el-input v-model="state.tableQueryParams.@(column.LowerPropertyName)" clearable placeholder="请输入@(column.ColumnComment)"/>
  195. }
  196. @:</el-form-item>
  197. @:</el-col>
  198. }
  199. }
  200. <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="4" class="mb10">
  201. <el-form-item @(Model.QueryWhetherList.Count > 0 ? "" : "label-width=\"0px\"")>
  202. <el-button-group style="display: flex; align-items: center;">
  203. <el-button type="primary" icon="ele-Search" @@click="handleQuery" v-auth="'@(Model.LowerClassName):page'" v-reclick="1000"> @(Model.QueryWhetherList.Count > 0 ? "查询" : "刷新") </el-button>
  204. @if (Model.QueryWhetherList.Count > 0) {
  205. @:<el-button icon="ele-Refresh" @@click="() => state.tableQueryParams = {}"> 重置 </el-button>
  206. @if (Model.HasLikeQuery) {
  207. @:<el-button icon="ele-ZoomIn" @@click="() => state.showAdvanceQueryUI = true" v-if="!state.showAdvanceQueryUI" style="margin-left:5px;"> 高级查询 </el-button>
  208. @:<el-button icon="ele-ZoomOut" @@click="() => state.showAdvanceQueryUI = false" v-if="state.showAdvanceQueryUI" style="margin-left:5px;"> 隐藏 </el-button>
  209. }
  210. }
  211. <el-button type="danger" style="margin-left:5px;" icon="ele-Delete" @@click="batchDel@(Model.ClassName)" :disabled="state.selectData.length == 0" v-auth="'@(Model.LowerClassName):batchDelete'"> 删除 </el-button>
  212. <el-button type="primary" style="margin-left:5px;" icon="ele-Plus" @@click="editDialogRef.openDialog(null, '新增@(Model.BusName)')" v-auth="'@(Model.LowerClassName):add'"> 新增 </el-button>
  213. @if (Model.ImportFieldList.Count > 0) {
  214. @:<el-dropdown :show-timeout="70" :hide-timeout="50" @@command="export@(Model.ClassName)Command">
  215. @:<el-button type="primary" style="margin-left:5px;" icon="ele-FolderOpened" v-reclick="20000" v-auth="'@(Model.LowerClassName):export'"> 导出 </el-button>
  216. @:<template #dropdown>
  217. @:<el-dropdown-menu>
  218. @:<el-dropdown-item command="select" :disabled="state.selectData.length == 0">导出选中</el-dropdown-item>
  219. @:<el-dropdown-item command="current">导出本页</el-dropdown-item>
  220. @:<el-dropdown-item command="all">导出全部</el-dropdown-item>
  221. @:</el-dropdown-menu>
  222. @:</template>
  223. @:</el-dropdown>
  224. @:<el-button type="warning" style="margin-left:5px;" icon="ele-MostlyCloudy" @@click="importDataRef.openDialog()" v-auth="'@(Model.LowerClassName):import'"> 导入 </el-button>
  225. }
  226. </el-button-group>
  227. </el-form-item>
  228. </el-col>
  229. </el-row>
  230. @* 操作区另起一行
  231. @:<el-row>
  232. @:<el-col>
  233. @:<el-button-group style="margin-left:20px;margin-bottom:5px;">
  234. @:<el-button type="primary" icon="ele-Plus" @@click="editDialogRef.openDialog(null, '新增@(Model.BusName)')" v-auth="'@(Model.LowerClassName):add'"> 新增 </el-button>
  235. </el-button-group>
  236. @:</el-col>
  237. @:</el-row>
  238. *@
  239. </el-form>
  240. </el-card>
  241. <el-card class="full-table" shadow="hover" style="margin-top: 5px">
  242. <el-table :data="state.tableData" @@selection-change="(val: any[]) => { state.selectData = val; }" style="width: 100%" v-loading="state.tableLoading" tooltip-effect="light" row-key="@Model.PrimaryKeyFieldList.First().LowerPropertyName" @@sort-change="sortChange" border>
  243. <el-table-column type="selection" width="40" align="center" v-if="auth('@(Model.LowerClassName):batchDelete') || auth('@(Model.LowerClassName):export')" />
  244. <el-table-column type="index" label="序号" width="55" align="center"/>
  245. @foreach (var column in Model.TableField.Where(u => u.WhetherTable == "Y")){
  246. if(column.EffectType == "DictSelector" || column.EffectType == "EnumSelector" || column.EffectType == "Upload" || @column.EffectType == "Switch") {
  247. @:<el-table-column @(Model.GetElTableColumnCustomProperty(column)) show-overflow-tooltip>
  248. @:<template #default="scope">
  249. if (column.EffectType == "Upload") {
  250. @:<el-image
  251. @:v-if="scope.row.@column.LowerPropertyName"
  252. @:style="width: 60px; height: 60px"
  253. @::src="scope.row.@column.LowerPropertyName"
  254. @::lazy="true"
  255. @::hide-on-click-modal="true"
  256. @::preview-src-list="[scope.row.@column.LowerPropertyName]"
  257. @::initial-index="0"
  258. @:fit="scale-down"
  259. @:preview-teleported />
  260. } else if (column.EffectType == "Switch") {
  261. @:<el-tag v-if="scope.row.@(column.LowerPropertyName)"> 是 </el-tag>
  262. @:<el-tag type="danger" v-else> 否 </el-tag>
  263. } else if (Model.IsStatus(column)) {
  264. @:<el-switch v-model="scope.row.@column.LowerPropertyName" :active-value="1" :inactive-value="2" size="small" @@change="change@(Model.ClassName)Status(scope.row)" />
  265. } else {
  266. @:<g-sys-dict v-model="scope.row.@column.LowerPropertyName" code="@(column.DictTypeCode)" />
  267. }
  268. @:</template>
  269. @:</el-table-column>
  270. } else if (column.EffectType == "ConstSelector" || column.EffectType == "ForeignKey" || column.EffectType == "ApiTreeSelector") {
  271. var formatter = column.EffectType == "ConstSelector" ? $"state.stores.getConstItemNameByType('{column.DictTypeCode}', row.{column.LowerPropertyName})" : $"row.{column.LowerExtendedPropertyName}";
  272. @:<el-table-column @(Model.GetElTableColumnCustomProperty(column)) :formatter="(row: any) => @(formatter)" show-overflow-tooltip />
  273. } else {
  274. @:<el-table-column @(Model.GetElTableColumnCustomProperty(column)) show-overflow-tooltip />
  275. }
  276. }
  277. <el-table-column label="修改记录" width="100" align="center" show-overflow-tooltip>
  278. <template #default="scope">
  279. <ModifyRecord :data="scope.row" />
  280. </template>
  281. </el-table-column>
  282. <el-table-column label="操作" width="@(Model.PrintType == "custom" ? "200" : "140")" align="center" fixed="right" show-overflow-tooltip v-if="auth('@(Model.LowerClassName):update') || auth('@(Model.LowerClassName):delete')">
  283. <template #default="scope">
  284. @if (Model.PrintType == "custom") {
  285. @:<el-button icon="ele-Printer" size="small" text type="primary" @@click="openPrint@(Model.ClassName)(scope.row)" v-auth="'@(Model.LowerClassName):print'"> 打印 </el-button>
  286. }
  287. <el-button icon="ele-Edit" size="small" text type="primary" @@click="editDialogRef.openDialog(scope.row, '编辑@(Model.BusName)')" v-auth="'@(Model.LowerClassName):update'"> 编辑 </el-button>
  288. <el-button icon="ele-Delete" size="small" text type="primary" @@click="del@(Model.ClassName)(scope.row)" v-auth="'@(Model.LowerClassName):delete'"> 删除 </el-button>
  289. </template>
  290. </el-table-column>
  291. </el-table>
  292. <el-pagination
  293. v-model:currentPage="state.tableParams.page"
  294. v-model:page-size="state.tableParams.pageSize"
  295. @@size-change="(val: any) => handleQuery({ pageSize: val })"
  296. @@current-change="(val: any) => handleQuery({ page: val })"
  297. layout="total, sizes, prev, pager, next, jumper"
  298. :page-sizes="[10, 20, 50, 100, 200, 500]"
  299. :total="state.tableParams.total"
  300. size="small"
  301. background />
  302. @if (Model.ImportFieldList.Count > 0) {
  303. @:<ImportData ref="importDataRef" :import="@(Model.LowerClassName)Api.importData" :download="@(Model.LowerClassName)Api.downloadTemplate" v-auth="'@(Model.LowerClassName):import'" @@refresh="handleQuery"/>
  304. }
  305. <printDialog ref="printDialogRef" :title="'打印@(Model.BusName)'" @@reloadTable="handleQuery" />
  306. <editDialog ref="editDialogRef" @@reloadTable="handleQuery" />
  307. </el-card>
  308. </div>
  309. </template>
  310. <style scoped>
  311. :deep(.el-input), :deep(.el-select), :deep(.el-input-number) {
  312. width: 100%;
  313. }
  314. </style>