Commit 220e0316e07a0842664db4355b3c921104c67e22

Authored by xingyu4j
1 parent 2e2cd448

feat: vxe demo

yudao-ui-admin-vue3/src/api/system/post/types.ts
1 1 export type PostVO = {
2   - id: number
  2 + id?: number
3 3 name: string
4 4 code: string
5 5 sort: number
... ... @@ -11,11 +11,13 @@ export type PostVO = {
11 11 export type PostPageReqVO = {
12 12 code: string
13 13 name: string
14   - status: number
  14 + status?: number
  15 + pageSize?: number
  16 + pageNo?: number
15 17 }
16 18  
17 19 export type PostExportReqVO = {
18 20 code: string
19 21 name: string
20   - status: number
  22 + status?: number
21 23 }
... ...
yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts
... ... @@ -53,14 +53,46 @@ VXETable.setup({
53 53 version: 0, // 版本号,对于某些带数据缓存的功能有用到,上升版本号可以用于重置数据
54 54 zIndex: 1008, // 全局 zIndex 起始值,如果项目的的 z-index 样式值过大时就需要跟随设置更大,避免被遮挡
55 55 loadingText: '加载中...', // 全局loading提示内容,如果为null则不显示文本
  56 + height: 600,
56 57 table: {
  58 + border: 'inner',
57 59 // 自动监听父元素的变化去重新计算表格
58 60 autoResize: true,
59 61 emptyText: '暂无数据',
60 62 // 鼠标移到行是否要高亮显示
61 63 highlightHoverRow: true
62 64 },
  65 + grid: {
  66 + toolbarConfig: {
  67 + refresh: true,
  68 + import: true,
  69 + export: true,
  70 + print: true,
  71 + zoom: true,
  72 + custom: true
  73 + },
  74 + pagerConfig: {
  75 + border: false,
  76 + background: true,
  77 + autoHidden: true,
  78 + perfect: true,
  79 + pageSize: 10,
  80 + pagerCount: 7,
  81 + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500],
  82 + layouts: [
  83 + 'PrevJump',
  84 + 'PrevPage',
  85 + 'Jump',
  86 + 'PageCount',
  87 + 'NextPage',
  88 + 'NextJump',
  89 + 'Sizes',
  90 + 'Total'
  91 + ]
  92 + }
  93 + },
63 94 pager: {
  95 + background: true,
64 96 autoHidden: false,
65 97 perfect: true,
66 98 pageSize: 10,
... ...
yudao-ui-admin-vue3/src/views/system/post/index.vue
1 1 <script setup lang="ts">
2   -import { ref, unref } from 'vue'
  2 +import { reactive, ref } from 'vue'
3 3 import dayjs from 'dayjs'
4   -import { ElMessage } from 'element-plus'
5   -import { DICT_TYPE } from '@/utils/dict'
6   -import { useTable } from '@/hooks/web/useTable'
  4 +import XEUtils from 'xe-utils'
7 5 import { useI18n } from '@/hooks/web/useI18n'
8   -import { FormExpose } from '@/components/Form'
9   -import type { PostVO } from '@/api/system/post/types'
10   -import { rules, allSchemas } from './post.data'
  6 +import { VxeFormEvents, VxeFormItemProps, VxeGrid, VxeGridInstance, VxeGridProps } from 'vxe-table'
11 7 import * as PostApi from '@/api/system/post'
12   -const { t } = useI18n() // 国际化
  8 +import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
  9 +import { ContentWrap } from '@/components/ContentWrap'
  10 +import { PostPageReqVO, PostVO } from '@/api/system/post/types'
  11 +import { rules, allSchemas } from './post.data'
  12 +import { ElMessage, ElMessageBox } from 'element-plus'
13 13  
14   -// ========== 列表相关 ==========
15   -const { register, tableObject, methods } = useTable<PostVO>({
16   - getListApi: PostApi.getPostPageApi,
17   - delListApi: PostApi.deletePostApi,
18   - exportListApi: PostApi.exportPostApi
19   -})
20   -const { getList, setSearchParams, delList, exportList } = methods
  14 +const { t } = useI18n() // 国际化
21 15  
22   -// ========== CRUD 相关 ==========
23   -const actionLoading = ref(false) // 遮罩层
24   -const actionType = ref('') // 操作按钮的类型
  16 +const xGrid = ref<VxeGridInstance>()
25 17 const dialogVisible = ref(false) // 是否显示弹出层
26 18 const dialogTitle = ref('edit') // 弹出层标题
27   -const formRef = ref<FormExpose>() // 表单 Ref
  19 +const actionType = ref('') // 操作按钮的类型
  20 +const actionLoading = ref(false) // 遮罩层
28 21  
  22 +const gridOptions = reactive<VxeGridProps>({
  23 + loading: false,
  24 + rowConfig: {
  25 + keyField: 'id',
  26 + isHover: true
  27 + },
  28 + toolbarConfig: {
  29 + buttons: [{ code: 'insert_actived', name: '新增' }]
  30 + },
  31 + printConfig: {
  32 + columns: [
  33 + { field: 'name' },
  34 + { field: 'code' },
  35 + { field: 'sort' },
  36 + { field: 'status' },
  37 + { field: 'createTime' }
  38 + ]
  39 + },
  40 + formConfig: {
  41 + titleWidth: 100,
  42 + titleAlign: 'right',
  43 + items: [
  44 + {
  45 + field: 'name',
  46 + title: '岗位名称',
  47 + span: 8,
  48 + itemRender: { name: '$input', props: { placeholder: '请输入岗位名称' } }
  49 + },
  50 + {
  51 + field: 'code',
  52 + title: '岗位编码',
  53 + span: 8,
  54 + itemRender: { name: '$input', props: { placeholder: '请输入岗位编码' } }
  55 + },
  56 + {
  57 + field: 'status',
  58 + title: t('common.status'),
  59 + span: 8,
  60 + itemRender: { name: '$select', options: getIntDictOptions(DICT_TYPE.COMMON_STATUS) }
  61 + },
  62 + {
  63 + span: 24,
  64 + align: 'center',
  65 + collapseNode: true,
  66 + itemRender: {
  67 + name: '$buttons',
  68 + children: [
  69 + { props: { type: 'submit', content: t('common.query'), status: 'primary' } },
  70 + { props: { type: 'reset', content: t('common.reset') } }
  71 + ]
  72 + }
  73 + }
  74 + ]
  75 + },
  76 + columns: [
  77 + { type: 'seq', title: t('common.index'), width: 100 },
  78 + { field: 'name', title: '岗位名称' },
  79 + { field: 'code', title: '岗位编码' },
  80 + { field: 'sort', title: '岗位顺序' },
  81 + {
  82 + field: 'status',
  83 + title: t('common.status'),
  84 + slots: {
  85 + default: 'status_default'
  86 + }
  87 + },
  88 + {
  89 + field: 'createTime',
  90 + title: t('common.createTime'),
  91 + width: 160,
  92 + sortable: true,
  93 + formatter({ cellValue }) {
  94 + return XEUtils.toDateString(cellValue, 'yyyy-MM-dd HH:ss:mm')
  95 + }
  96 + },
  97 + {
  98 + field: 'action',
  99 + title: t('table.action'),
  100 + width: '240px',
  101 + showOverflow: true,
  102 + slots: {
  103 + default: 'action_default'
  104 + }
  105 + }
  106 + ],
  107 + pagerConfig: {
  108 + border: false,
  109 + background: false,
  110 + perfect: true,
  111 + pageSize: 10,
  112 + pagerCount: 7,
  113 + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500],
  114 + layouts: ['PrevJump', 'PrevPage', 'Jump', 'PageCount', 'NextPage', 'NextJump', 'Sizes', 'Total']
  115 + },
  116 + proxyConfig: {
  117 + seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
  118 + props: {
  119 + result: 'list',
  120 + total: 'total'
  121 + },
  122 + ajax: {
  123 + query: ({ page, form }) => {
  124 + const queryParams: PostPageReqVO = Object.assign({}, form)
  125 + queryParams.pageSize = page.pageSize
  126 + queryParams.pageNo = page.currentPage
  127 + return new Promise(async (resolve) => {
  128 + resolve(await PostApi.getPostPageApi(queryParams))
  129 + })
  130 + }
  131 + }
  132 + }
  133 +})
  134 +const formData = ref<PostVO>({
  135 + name: '',
  136 + code: '',
  137 + sort: 0,
  138 + status: 0,
  139 + remark: '',
  140 + createTime: ''
  141 +})
  142 +const formItems = reactive<VxeFormItemProps[]>([
  143 + {
  144 + field: 'id',
  145 + title: 'id',
  146 + visible: false
  147 + },
  148 + {
  149 + field: 'name',
  150 + title: '岗位名称',
  151 + span: 8,
  152 + itemRender: { name: '$input', props: { placeholder: '请输入岗位名称' } }
  153 + },
  154 + {
  155 + field: 'code',
  156 + title: '岗位编码',
  157 + span: 8,
  158 + itemRender: { name: '$input', props: { placeholder: '请输入岗位编码' } }
  159 + },
  160 + {
  161 + field: 'sort',
  162 + title: '岗位顺序',
  163 + span: 8,
  164 + itemRender: { name: '$input', props: { type: 'number', placeholder: '请输入岗位顺序' } }
  165 + },
  166 + {
  167 + field: 'status',
  168 + title: t('common.status'),
  169 + span: 8,
  170 + itemRender: {
  171 + name: '$select',
  172 + options: getIntDictOptions(DICT_TYPE.COMMON_STATUS),
  173 + props: { placeholder: '请选择' }
  174 + }
  175 + },
  176 + {
  177 + align: 'center',
  178 + span: 24,
  179 + itemRender: {
  180 + name: '$buttons',
  181 + children: [
  182 + { props: { type: 'submit', content: t('action.save'), status: 'primary' } },
  183 + { props: { type: 'reset', content: t('common.reset') } }
  184 + ]
  185 + }
  186 + }
  187 +])
29 188 // 设置标题
30 189 const setDialogTile = (type: string) => {
31 190 dialogTitle.value = t('action.' + type)
32 191 actionType.value = type
33 192 dialogVisible.value = true
34 193 }
35   -
  194 +// ========== 详情相关 ==========
  195 +const detailRef = ref() // 详情 Ref
  196 +// 详情操作
  197 +const handleDetail = (row: PostVO) => {
  198 + setDialogTile('detail')
  199 + detailRef.value = row
  200 +}
36 201 // 新增操作
37 202 const handleCreate = () => {
38 203 setDialogTile('create')
39   - // 重置表单
40   - unref(formRef)?.getElFormRef()?.resetFields()
41 204 }
42 205  
43 206 // 修改操作
44   -const handleUpdate = async (row: PostVO) => {
  207 +const handleUpdate = async (rowId: number) => {
45 208 setDialogTile('update')
46 209 // 设置数据
47   - const res = await PostApi.getPostApi(row.id)
48   - unref(formRef)?.setValues(res)
  210 + const res = await PostApi.getPostApi(rowId)
  211 + formData.value = res
49 212 }
50   -
51   -// 提交按钮
52   -const submitForm = async () => {
53   - const elForm = unref(formRef)?.getElFormRef()
54   - if (!elForm) return
55   - elForm.validate(async (valid) => {
56   - if (valid) {
57   - actionLoading.value = true
58   - // 提交请求
59   - try {
60   - const data = unref(formRef)?.formModel as PostVO
61   - if (actionType.value === 'create') {
62   - await PostApi.createPostApi(data)
63   - ElMessage.success(t('common.createSuccess'))
64   - } else {
65   - await PostApi.updatePostApi(data)
66   - ElMessage.success(t('common.updateSuccess'))
67   - }
68   - // 操作成功,重新加载列表
69   - dialogVisible.value = false
70   - await getList()
71   - } finally {
72   - actionLoading.value = false
73   - }
74   - }
  213 +// 删除操作
  214 +const handleDelete = (rowId: number) => {
  215 + ElMessageBox.confirm(t('common.delMessage'), t('common.confirmTitle'), {
  216 + confirmButtonText: t('common.ok'),
  217 + cancelButtonText: t('common.cancel'),
  218 + type: 'warning'
75 219 })
  220 + .then(async () => {
  221 + await PostApi.deletePostApi(rowId)
  222 + })
  223 + .finally(() => {
  224 + ElMessage.success(t('common.delSuccess'))
  225 + const $grid = xGrid.value
  226 + $grid?.commitProxy('query')
  227 + })
76 228 }
77   -
78   -// ========== 详情相关 ==========
79   -const detailRef = ref() // 详情 Ref
80   -
81   -// 详情操作
82   -const handleDetail = async (row: PostVO) => {
83   - // 设置数据
84   - detailRef.value = row
85   - setDialogTile('detail')
  229 +// 提交按钮
  230 +const submitForm: VxeFormEvents.Submit = async () => {
  231 + actionLoading.value = true
  232 + // 提交请求
  233 + try {
  234 + const data = formData.value as PostVO
  235 + if (actionType.value === 'create') {
  236 + await PostApi.createPostApi(data)
  237 + ElMessage.success(t('common.createSuccess'))
  238 + } else {
  239 + await PostApi.updatePostApi(data)
  240 + ElMessage.success(t('common.updateSuccess'))
  241 + }
  242 + // 操作成功,重新加载列表
  243 + dialogVisible.value = false
  244 + } finally {
  245 + actionLoading.value = false
  246 + const $grid = xGrid.value
  247 + $grid?.commitProxy('query')
  248 + }
86 249 }
87   -
88   -// ========== 初始化 ==========
89   -getList()
90 250 </script>
91   -
92 251 <template>
93   - <!-- 搜索工作区 -->
94 252 <ContentWrap>
95   - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
96   - </ContentWrap>
97   - <ContentWrap>
98   - <!-- 操作工具栏 -->
99   - <div class="mb-10px">
100   - <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate">
101   - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
102   - </el-button>
103   - <el-button
104   - type="warning"
105   - v-hasPermi="['system:post:export']"
106   - :loading="tableObject.exportLoading"
107   - @click="exportList('岗位数据.xls')"
108   - >
109   - <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
110   - </el-button>
111   - </div>
112   - <!-- 列表 -->
113   - <Table
114   - :columns="allSchemas.tableColumns"
115   - :selection="false"
116   - :data="tableObject.tableList"
117   - :loading="tableObject.loading"
118   - :pagination="{
119   - total: tableObject.total
120   - }"
121   - v-model:pageSize="tableObject.pageSize"
122   - v-model:currentPage="tableObject.currentPage"
123   - @register="register"
124   - >
125   - <template #status="{ row }">
126   - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  253 + <vxe-grid ref="xGrid" v-bind="gridOptions">
  254 + <template #toolbar_buttons>
  255 + <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate">
  256 + <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
  257 + </el-button>
127 258 </template>
128   - <template #createTime="{ row }">
129   - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  259 + <template #status_default="{ row }">
  260 + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
130 261 </template>
131   - <template #action="{ row }">
  262 + <template #action_default="{ row }">
132 263 <el-button
133 264 link
134 265 type="primary"
135 266 v-hasPermi="['system:post:update']"
136   - @click="handleUpdate(row)"
  267 + @click="handleUpdate(row.id)"
137 268 >
138 269 <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
139 270 </el-button>
... ... @@ -149,46 +280,52 @@ getList()
149 280 link
150 281 type="primary"
151 282 v-hasPermi="['system:post:delete']"
152   - @click="delList(row.id, false)"
  283 + @click="handleDelete(row.id)"
153 284 >
154 285 <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
155 286 </el-button>
156 287 </template>
157   - </Table>
  288 + </vxe-grid>
158 289 </ContentWrap>
159   -
160   - <Dialog v-model="dialogVisible" :title="dialogTitle">
161   - <!-- 对话框(添加 / 修改) -->
162   - <Form
163   - v-if="['create', 'update'].includes(actionType)"
164   - :schema="allSchemas.formSchema"
165   - :rules="rules"
166   - ref="formRef"
167   - />
168   - <!-- 对话框(详情) -->
169   - <Descriptions
170   - v-if="actionType === 'detail'"
171   - :schema="allSchemas.detailSchema"
172   - :data="detailRef"
173   - >
174   - <template #status="{ row }">
175   - <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
176   - </template>
177   - <template #createTime="{ row }">
178   - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
179   - </template>
180   - </Descriptions>
181   - <!-- 操作按钮 -->
182   - <template #footer>
183   - <el-button
  290 + <vxe-modal
  291 + v-model="dialogVisible"
  292 + id="myModal6"
  293 + width="800"
  294 + height="400"
  295 + min-width="460"
  296 + min-height="320"
  297 + show-zoom
  298 + resize
  299 + remember
  300 + storage
  301 + transfer
  302 + show-footer
  303 + >
  304 + <template #title>
  305 + <span>{{ dialogTitle }}</span>
  306 + </template>
  307 + <template #default>
  308 + <!-- 对话框(添加 / 修改) -->
  309 + <vxe-form
184 310 v-if="['create', 'update'].includes(actionType)"
185   - type="primary"
186   - :loading="actionLoading"
187   - @click="submitForm"
  311 + :data="formData"
  312 + :items="formItems"
  313 + :rules="rules"
  314 + titleColon
  315 + @submit="submitForm"
  316 + />
  317 + <Descriptions
  318 + v-if="actionType === 'detail'"
  319 + :schema="allSchemas.detailSchema"
  320 + :data="detailRef"
188 321 >
189   - {{ t('action.save') }}
190   - </el-button>
191   - <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  322 + <template #status="{ row }">
  323 + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  324 + </template>
  325 + <template #createTime="{ row }">
  326 + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  327 + </template>
  328 + </Descriptions>
192 329 </template>
193   - </Dialog>
  330 + </vxe-modal>
194 331 </template>
... ...
yudao-ui-admin-vue3/src/views/system/post/indexd.vue 0 → 100644
  1 +<script setup lang="ts">
  2 +import { ref, unref } from 'vue'
  3 +import dayjs from 'dayjs'
  4 +import { ElMessage } from 'element-plus'
  5 +import { DICT_TYPE } from '@/utils/dict'
  6 +import { useTable } from '@/hooks/web/useTable'
  7 +import { useI18n } from '@/hooks/web/useI18n'
  8 +import { FormExpose } from '@/components/Form'
  9 +import type { PostVO } from '@/api/system/post/types'
  10 +import { rules, allSchemas } from './post.data'
  11 +import * as PostApi from '@/api/system/post'
  12 +const { t } = useI18n() // 国际化
  13 +
  14 +// ========== 列表相关 ==========
  15 +const { register, tableObject, methods } = useTable<PostVO>({
  16 + getListApi: PostApi.getPostPageApi,
  17 + delListApi: PostApi.deletePostApi,
  18 + exportListApi: PostApi.exportPostApi
  19 +})
  20 +const { getList, setSearchParams, delList, exportList } = methods
  21 +
  22 +// ========== CRUD 相关 ==========
  23 +const actionLoading = ref(false) // 遮罩层
  24 +const actionType = ref('') // 操作按钮的类型
  25 +const dialogVisible = ref(false) // 是否显示弹出层
  26 +const dialogTitle = ref('edit') // 弹出层标题
  27 +const formRef = ref<FormExpose>() // 表单 Ref
  28 +
  29 +// 设置标题
  30 +const setDialogTile = (type: string) => {
  31 + dialogTitle.value = t('action.' + type)
  32 + actionType.value = type
  33 + dialogVisible.value = true
  34 +}
  35 +
  36 +// 新增操作
  37 +const handleCreate = () => {
  38 + setDialogTile('create')
  39 + // 重置表单
  40 + unref(formRef)?.getElFormRef()?.resetFields()
  41 +}
  42 +
  43 +// 修改操作
  44 +const handleUpdate = async (row: PostVO) => {
  45 + setDialogTile('update')
  46 + // 设置数据
  47 + const res = await PostApi.getPostApi(row.id)
  48 + unref(formRef)?.setValues(res)
  49 +}
  50 +
  51 +// 提交按钮
  52 +const submitForm = async () => {
  53 + const elForm = unref(formRef)?.getElFormRef()
  54 + if (!elForm) return
  55 + elForm.validate(async (valid) => {
  56 + if (valid) {
  57 + actionLoading.value = true
  58 + // 提交请求
  59 + try {
  60 + const data = unref(formRef)?.formModel as PostVO
  61 + if (actionType.value === 'create') {
  62 + await PostApi.createPostApi(data)
  63 + ElMessage.success(t('common.createSuccess'))
  64 + } else {
  65 + await PostApi.updatePostApi(data)
  66 + ElMessage.success(t('common.updateSuccess'))
  67 + }
  68 + // 操作成功,重新加载列表
  69 + dialogVisible.value = false
  70 + await getList()
  71 + } finally {
  72 + actionLoading.value = false
  73 + }
  74 + }
  75 + })
  76 +}
  77 +
  78 +// ========== 详情相关 ==========
  79 +const detailRef = ref() // 详情 Ref
  80 +
  81 +// 详情操作
  82 +const handleDetail = async (row: PostVO) => {
  83 + // 设置数据
  84 + detailRef.value = row
  85 + setDialogTile('detail')
  86 +}
  87 +
  88 +// ========== 初始化 ==========
  89 +getList()
  90 +</script>
  91 +
  92 +<template>
  93 + <!-- 搜索工作区 -->
  94 + <ContentWrap>
  95 + <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  96 + </ContentWrap>
  97 + <ContentWrap>
  98 + <!-- 操作工具栏 -->
  99 + <div class="mb-10px">
  100 + <el-button type="primary" v-hasPermi="['system:post:create']" @click="handleCreate">
  101 + <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
  102 + </el-button>
  103 + <el-button
  104 + type="warning"
  105 + v-hasPermi="['system:post:export']"
  106 + :loading="tableObject.exportLoading"
  107 + @click="exportList('岗位数据.xls')"
  108 + >
  109 + <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }}
  110 + </el-button>
  111 + </div>
  112 + <!-- 列表 -->
  113 + <Table
  114 + :columns="allSchemas.tableColumns"
  115 + :selection="false"
  116 + :data="tableObject.tableList"
  117 + :loading="tableObject.loading"
  118 + :pagination="{
  119 + total: tableObject.total
  120 + }"
  121 + v-model:pageSize="tableObject.pageSize"
  122 + v-model:currentPage="tableObject.currentPage"
  123 + @register="register"
  124 + >
  125 + <template #status="{ row }">
  126 + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  127 + </template>
  128 + <template #createTime="{ row }">
  129 + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  130 + </template>
  131 + <template #action="{ row }">
  132 + <el-button
  133 + link
  134 + type="primary"
  135 + v-hasPermi="['system:post:update']"
  136 + @click="handleUpdate(row)"
  137 + >
  138 + <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
  139 + </el-button>
  140 + <el-button
  141 + link
  142 + type="primary"
  143 + v-hasPermi="['system:post:update']"
  144 + @click="handleDetail(row)"
  145 + >
  146 + <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
  147 + </el-button>
  148 + <el-button
  149 + link
  150 + type="primary"
  151 + v-hasPermi="['system:post:delete']"
  152 + @click="delList(row.id, false)"
  153 + >
  154 + <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
  155 + </el-button>
  156 + </template>
  157 + </Table>
  158 + </ContentWrap>
  159 +
  160 + <Dialog v-model="dialogVisible" :title="dialogTitle">
  161 + <!-- 对话框(添加 / 修改) -->
  162 + <Form
  163 + v-if="['create', 'update'].includes(actionType)"
  164 + :schema="allSchemas.formSchema"
  165 + :rules="rules"
  166 + ref="formRef"
  167 + />
  168 + <!-- 对话框(详情) -->
  169 + <Descriptions
  170 + v-if="actionType === 'detail'"
  171 + :schema="allSchemas.detailSchema"
  172 + :data="detailRef"
  173 + >
  174 + <template #status="{ row }">
  175 + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  176 + </template>
  177 + <template #createTime="{ row }">
  178 + <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  179 + </template>
  180 + </Descriptions>
  181 + <!-- 操作按钮 -->
  182 + <template #footer>
  183 + <el-button
  184 + v-if="['create', 'update'].includes(actionType)"
  185 + type="primary"
  186 + :loading="actionLoading"
  187 + @click="submitForm"
  188 + >
  189 + {{ t('action.save') }}
  190 + </el-button>
  191 + <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  192 + </template>
  193 + </Dialog>
  194 +</template>
... ...