Commit 49237ad9666e2dfe9208abaf338a8dc1fdf466e8

Authored by xingyu4j
1 parent e1b4ab2d

feat: add vxe crud schemas

yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts 0 → 100644
  1 +import { DescriptionsSchema } from '@/types/descriptions'
  2 +import { getIntDictOptions } from '@/utils/dict'
  3 +import { reactive } from 'vue'
  4 +import {
  5 + FormItemRenderOptions,
  6 + VxeFormItemProps,
  7 + VxeGridPropTypes,
  8 + VxeTableDefines
  9 +} from 'vxe-table'
  10 +import { eachTree } from 'xe-utils'
  11 +import { useI18n } from '@/hooks/web/useI18n'
  12 +import { VxeTableColumn } from '@/types/table'
  13 +
  14 +export type VxeCrudSchema = Omit<VxeTableColumn, 'children'> & {
  15 + field: string
  16 + title?: string
  17 + search?: CrudSearchParams
  18 + table?: CrudTableParams
  19 + form?: CrudFormParams
  20 + detail?: CrudDescriptionsParams
  21 + print?: boolean
  22 + children?: VxeCrudSchema[]
  23 + dictType?: string
  24 +}
  25 +type CrudSearchParams = {
  26 + // 是否显示在查询项
  27 + show?: boolean
  28 +} & Omit<VxeFormItemProps, 'field'>
  29 +
  30 +type CrudTableParams = {
  31 + // 是否显示表头
  32 + show?: boolean
  33 +} & Omit<VxeTableDefines.ColumnOptions, 'field'>
  34 +
  35 +type CrudFormParams = {
  36 + // 是否显示表单项
  37 + show?: boolean
  38 +} & Omit<VxeFormItemProps, 'field'>
  39 +
  40 +type CrudDescriptionsParams = {
  41 + // 是否显示表单项
  42 + show?: boolean
  43 +} & Omit<DescriptionsSchema, 'field'>
  44 +
  45 +interface VxeAllSchemas {
  46 + searchSchema: VxeFormItemProps[]
  47 + tableSchema: VxeGridPropTypes.Columns
  48 + formSchema: VxeFormItemProps[]
  49 + detailSchema: DescriptionsSchema[]
  50 + printSchema: VxeTableDefines.ColumnInfo[]
  51 +}
  52 +
  53 +// 过滤所有结构
  54 +export const useVxeCrudSchemas = (
  55 + crudSchema: VxeCrudSchema[]
  56 +): {
  57 + allSchemas: VxeAllSchemas
  58 +} => {
  59 + // 所有结构数据
  60 + const allSchemas = reactive<VxeAllSchemas>({
  61 + searchSchema: [],
  62 + tableSchema: [],
  63 + formSchema: [],
  64 + detailSchema: [],
  65 + printSchema: []
  66 + })
  67 +
  68 + const searchSchema = filterSearchSchema(crudSchema)
  69 + allSchemas.searchSchema = searchSchema || []
  70 +
  71 + const tableSchema = filterTableSchema(crudSchema)
  72 + allSchemas.tableSchema = tableSchema || []
  73 +
  74 + const formSchema = filterFormSchema(crudSchema)
  75 + allSchemas.formSchema = formSchema
  76 +
  77 + const detailSchema = filterDescriptionsSchema(crudSchema)
  78 + allSchemas.detailSchema = detailSchema
  79 +
  80 + const printSchema = filterPrintSchema(crudSchema)
  81 + allSchemas.printSchema = printSchema
  82 +
  83 + return {
  84 + allSchemas
  85 + }
  86 +}
  87 +
  88 +// 过滤 Search 结构
  89 +const filterSearchSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] => {
  90 + const searchSchema: VxeFormItemProps[] = []
  91 + const { t } = useI18n()
  92 + eachTree(crudSchema, (schemaItem: VxeCrudSchema) => {
  93 + // 判断是否显示
  94 + if (schemaItem?.search?.show) {
  95 + let itemRenderName = schemaItem?.search?.itemRender?.name || '$input'
  96 + const options: any[] = []
  97 + let itemRender: FormItemRenderOptions = {
  98 + name: itemRenderName,
  99 + props: { placeholder: t('common.inputText') }
  100 + }
  101 + if (schemaItem.dictType) {
  102 + const allOptions = { label: '全部', value: '' }
  103 + options.push(allOptions)
  104 + getIntDictOptions(schemaItem.dictType).forEach((dict) => {
  105 + options.push(dict)
  106 + })
  107 + itemRender.options = options
  108 + if (!schemaItem.search.itemRender?.name) itemRenderName = '$select'
  109 + itemRender = {
  110 + name: itemRenderName,
  111 + options: options,
  112 + props: { placeholder: t('common.selectText') }
  113 + }
  114 + }
  115 +
  116 + const searchSchemaItem = {
  117 + // 默认为 input
  118 + span: 6,
  119 + itemRender: itemRender,
  120 + ...schemaItem.search,
  121 + field: schemaItem.field,
  122 + title: schemaItem.search?.title || schemaItem.title
  123 + }
  124 + // 删除不必要的字段
  125 + delete searchSchemaItem.show
  126 +
  127 + searchSchema.push(searchSchemaItem)
  128 + }
  129 + })
  130 + // 添加搜索按钮
  131 + const buttons: VxeFormItemProps = {
  132 + span: 24,
  133 + align: 'center',
  134 + collapseNode: true,
  135 + itemRender: {
  136 + name: '$buttons',
  137 + children: [
  138 + { props: { type: 'submit', content: t('common.query'), status: 'primary' } },
  139 + { props: { type: 'reset', content: t('common.reset') } }
  140 + ]
  141 + }
  142 + }
  143 + searchSchema.push(buttons)
  144 + return searchSchema
  145 +}
  146 +
  147 +// 过滤 table 结构
  148 +const filterTableSchema = (crudSchema: VxeCrudSchema[]): VxeGridPropTypes.Columns => {
  149 + const tableSchema: VxeGridPropTypes.Columns = []
  150 + eachTree(crudSchema, (schemaItem: VxeCrudSchema) => {
  151 + // 判断是否显示
  152 + if (schemaItem?.table?.show !== false) {
  153 + const tableSchemaItem = {
  154 + ...schemaItem.table,
  155 + field: schemaItem.field,
  156 + title: schemaItem.table?.title || schemaItem.title
  157 + }
  158 +
  159 + // 删除不必要的字段
  160 + delete tableSchemaItem.show
  161 +
  162 + tableSchema.push(tableSchemaItem)
  163 + }
  164 + })
  165 + return tableSchema
  166 +}
  167 +
  168 +// 过滤 form 结构
  169 +const filterFormSchema = (crudSchema: VxeCrudSchema[]): VxeFormItemProps[] => {
  170 + const formSchema: VxeFormItemProps[] = []
  171 + const { t } = useI18n()
  172 + eachTree(crudSchema, (schemaItem: VxeCrudSchema) => {
  173 + // 判断是否显示
  174 + if (schemaItem?.form?.show !== false) {
  175 + let itemRenderName = schemaItem?.form?.itemRender?.name || '$input'
  176 + let itemRender: FormItemRenderOptions = {
  177 + name: itemRenderName,
  178 + props: { placeholder: t('common.inputText') }
  179 + }
  180 + if (schemaItem.dictType) {
  181 + if (!(schemaItem.form && schemaItem.form.itemRender?.name)) itemRenderName = '$select'
  182 + itemRender = {
  183 + name: itemRenderName,
  184 + options: getIntDictOptions(schemaItem.dictType),
  185 + props: { placeholder: t('common.selectText') }
  186 + }
  187 + }
  188 + const formSchemaItem = {
  189 + // 默认为 input
  190 + itemRender: itemRender,
  191 + ...schemaItem.form,
  192 + field: schemaItem.field,
  193 + title: schemaItem.form?.title || schemaItem.title
  194 + }
  195 +
  196 + // 删除不必要的字段
  197 + delete formSchemaItem.show
  198 +
  199 + formSchema.push(formSchemaItem)
  200 + }
  201 + })
  202 +
  203 + return formSchema
  204 +}
  205 +
  206 +// 过滤 descriptions 结构
  207 +const filterDescriptionsSchema = (crudSchema: VxeCrudSchema[]): DescriptionsSchema[] => {
  208 + const descriptionsSchema: DescriptionsSchema[] = []
  209 +
  210 + eachTree(crudSchema, (schemaItem: VxeCrudSchema) => {
  211 + // 判断是否显示
  212 + if (schemaItem?.detail?.show !== false) {
  213 + const descriptionsSchemaItem = {
  214 + ...schemaItem.detail,
  215 + field: schemaItem.field,
  216 + label: schemaItem.detail?.label || schemaItem.title
  217 + }
  218 +
  219 + // 删除不必要的字段
  220 + delete descriptionsSchemaItem.show
  221 +
  222 + descriptionsSchema.push(descriptionsSchemaItem)
  223 + }
  224 + })
  225 +
  226 + return descriptionsSchema
  227 +}
  228 +
  229 +// 过滤 打印 结构
  230 +const filterPrintSchema = (crudSchema: VxeCrudSchema[]): any[] => {
  231 + const printSchema: any[] = []
  232 +
  233 + eachTree(crudSchema, (schemaItem: VxeCrudSchema) => {
  234 + // 判断是否显示
  235 + if (schemaItem?.detail?.show !== false) {
  236 + const printSchemaItem = {
  237 + field: schemaItem.field
  238 + }
  239 +
  240 + printSchema.push(printSchemaItem)
  241 + }
  242 + })
  243 +
  244 + return printSchema
  245 +}
yudao-ui-admin-vue3/src/hooks/web/useVxeGrid.ts 0 → 100644
  1 +import { reactive } from 'vue'
  2 +import { VxeGridProps } from 'vxe-table'
  3 +
  4 +export const useVxeGrid = (allSchemas, getPageApi) => {
  5 + const gridOptions = reactive<VxeGridProps>({
  6 + loading: false,
  7 + rowConfig: {
  8 + keyField: 'id',
  9 + isHover: true
  10 + },
  11 + toolbarConfig: {
  12 + custom: true,
  13 + slots: { buttons: 'toolbar_buttons' }
  14 + },
  15 + printConfig: {
  16 + columns: allSchemas.printSchema
  17 + },
  18 + formConfig: {
  19 + titleWidth: 100,
  20 + titleAlign: 'right',
  21 + items: allSchemas.searchSchema
  22 + },
  23 + columns: allSchemas.tableSchema,
  24 + pagerConfig: {
  25 + border: false,
  26 + background: false,
  27 + perfect: true,
  28 + pageSize: 10,
  29 + pagerCount: 7,
  30 + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500],
  31 + layouts: [
  32 + 'PrevJump',
  33 + 'PrevPage',
  34 + 'Jump',
  35 + 'PageCount',
  36 + 'NextPage',
  37 + 'NextJump',
  38 + 'Sizes',
  39 + 'Total'
  40 + ]
  41 + },
  42 + proxyConfig: {
  43 + seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)
  44 + form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
  45 + props: { result: 'list', total: 'total' },
  46 + ajax: {
  47 + query: ({ page, form }) => {
  48 + const queryParams = Object.assign({}, form)
  49 + queryParams.pageSize = page.pageSize
  50 + queryParams.pageNo = page.currentPage
  51 + return new Promise(async (resolve) => {
  52 + resolve(await getPageApi(queryParams))
  53 + })
  54 + }
  55 + }
  56 + }
  57 + })
  58 + return gridOptions
  59 +}
yudao-ui-admin-vue3/src/types/table.d.ts
@@ -4,6 +4,12 @@ export type TableColumn = { @@ -4,6 +4,12 @@ export type TableColumn = {
4 children?: TableColumn[] 4 children?: TableColumn[]
5 } & Recordable 5 } & Recordable
6 6
  7 +export type VxeTableColumn = {
  8 + field: string
  9 + title?: string
  10 + children?: TableColumn[]
  11 +} & Recordable
  12 +
7 export type TableSlotDefault = { 13 export type TableSlotDefault = {
8 row: Recordable 14 row: Recordable
9 column: TableColumn 15 column: TableColumn
yudao-ui-admin-vue3/src/views/system/post/index.vue
1 <script setup lang="ts"> 1 <script setup lang="ts">
2 -import { reactive, ref } from 'vue' 2 +import { ref } from 'vue'
3 import dayjs from 'dayjs' 3 import dayjs from 'dayjs'
4 import { useI18n } from '@/hooks/web/useI18n' 4 import { useI18n } from '@/hooks/web/useI18n'
5 -import {  
6 - VxeFormEvents,  
7 - VxeFormInstance,  
8 - VxeFormItemProps,  
9 - VxeGrid,  
10 - VxeGridInstance,  
11 - VxeGridProps  
12 -} from 'vxe-table' 5 +import { VxeFormEvents, VxeFormInstance, VxeFormItemProps, VxeGridInstance } from 'vxe-table'
13 import * as PostApi from '@/api/system/post' 6 import * as PostApi from '@/api/system/post'
14 -import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' 7 +import { DICT_TYPE } from '@/utils/dict'
15 import { ContentWrap } from '@/components/ContentWrap' 8 import { ContentWrap } from '@/components/ContentWrap'
16 -import { PostPageReqVO, PostVO } from '@/api/system/post/types' 9 +import { PostVO } from '@/api/system/post/types'
17 import { rules, allSchemas } from './post.data' 10 import { rules, allSchemas } from './post.data'
18 -import { ElMessage, ElMessageBox } from 'element-plus' 11 +import { useMessage } from '@/hooks/web/useMessage'
  12 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
19 13
20 const { t } = useI18n() // 国际化 14 const { t } = useI18n() // 国际化
21 - 15 +const message = useMessage()
22 const xGrid = ref<VxeGridInstance>() 16 const xGrid = ref<VxeGridInstance>()
23 const xForm = ref<VxeFormInstance>() 17 const xForm = ref<VxeFormInstance>()
24 const dialogVisible = ref(false) // 是否显示弹出层 18 const dialogVisible = ref(false) // 是否显示弹出层
@@ -26,158 +20,9 @@ const dialogTitle = ref(&#39;edit&#39;) // 弹出层标题 @@ -26,158 +20,9 @@ const dialogTitle = ref(&#39;edit&#39;) // 弹出层标题
26 const actionType = ref('') // 操作按钮的类型 20 const actionType = ref('') // 操作按钮的类型
27 const actionLoading = ref(false) // 遮罩层 21 const actionLoading = ref(false) // 遮罩层
28 22
29 -const gridOptions = reactive<VxeGridProps>({  
30 - loading: false,  
31 - rowConfig: {  
32 - keyField: 'id',  
33 - isHover: true  
34 - },  
35 - toolbarConfig: {  
36 - custom: true,  
37 - slots: { buttons: 'toolbar_buttons' }  
38 - },  
39 - printConfig: {  
40 - columns: [  
41 - { field: 'name' },  
42 - { field: 'code' },  
43 - { field: 'sort' },  
44 - { field: 'status' },  
45 - { field: 'createTime' }  
46 - ]  
47 - },  
48 - formConfig: {  
49 - titleWidth: 100,  
50 - titleAlign: 'right',  
51 - items: [  
52 - {  
53 - field: 'name',  
54 - title: '岗位名称',  
55 - span: 6,  
56 - itemRender: { name: '$input', props: { placeholder: '请输入岗位名称' } }  
57 - },  
58 - {  
59 - field: 'code',  
60 - title: '岗位编码',  
61 - span: 6,  
62 - itemRender: { name: '$input', props: { placeholder: '请输入岗位编码' } }  
63 - },  
64 - {  
65 - field: 'status',  
66 - title: t('common.status'),  
67 - span: 6,  
68 - itemRender: { name: '$select', options: getIntDictOptions(DICT_TYPE.COMMON_STATUS) }  
69 - },  
70 - {  
71 - span: 24,  
72 - align: 'center',  
73 - collapseNode: true,  
74 - itemRender: {  
75 - name: '$buttons',  
76 - children: [  
77 - { props: { type: 'submit', content: t('common.query'), status: 'primary' } },  
78 - { props: { type: 'reset', content: t('common.reset') } }  
79 - ]  
80 - }  
81 - }  
82 - ]  
83 - },  
84 - columns: [  
85 - { type: 'seq', title: t('common.index'), width: 100 },  
86 - { field: 'name', title: '岗位名称' },  
87 - { field: 'code', title: '岗位编码' },  
88 - { field: 'sort', title: '岗位顺序' },  
89 - {  
90 - field: 'status',  
91 - title: t('common.status'),  
92 - slots: {  
93 - default: 'status_default'  
94 - }  
95 - },  
96 - {  
97 - field: 'createTime',  
98 - title: t('common.createTime'),  
99 - width: 160,  
100 - sortable: true,  
101 - formatter: 'formatDate'  
102 - },  
103 - {  
104 - field: 'action',  
105 - title: t('table.action'),  
106 - width: '240px',  
107 - showOverflow: true,  
108 - slots: {  
109 - default: 'action_default'  
110 - }  
111 - }  
112 - ],  
113 - pagerConfig: {  
114 - border: false,  
115 - background: false,  
116 - perfect: true,  
117 - pageSize: 10,  
118 - pagerCount: 7,  
119 - pageSizes: [5, 10, 15, 20, 50, 100, 200, 500],  
120 - layouts: ['PrevJump', 'PrevPage', 'Jump', 'PageCount', 'NextPage', 'NextJump', 'Sizes', 'Total']  
121 - },  
122 - proxyConfig: {  
123 - seq: true, // 启用动态序号代理(分页之后索引自动计算为当前页的起始序号)  
124 - form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为  
125 - props: { result: 'list', total: 'total' },  
126 - ajax: {  
127 - query: ({ page, form }) => {  
128 - const queryParams: PostPageReqVO = Object.assign({}, form)  
129 - queryParams.pageSize = page.pageSize  
130 - queryParams.pageNo = page.currentPage  
131 - return new Promise(async (resolve) => {  
132 - resolve(await PostApi.getPostPageApi(queryParams))  
133 - })  
134 - }  
135 - }  
136 - }  
137 -}) 23 +const gridOptions = useVxeGrid(allSchemas, PostApi.getPostPageApi)
138 const formData = ref<PostVO>() 24 const formData = ref<PostVO>()
139 -const formItems = ref<VxeFormItemProps[]>([  
140 - { field: 'id', title: 'id', visible: false },  
141 - {  
142 - field: 'name',  
143 - title: '岗位名称',  
144 - span: 12,  
145 - itemRender: { name: '$input', props: { placeholder: '请输入岗位名称' } }  
146 - },  
147 - {  
148 - field: 'code',  
149 - title: '岗位编码',  
150 - span: 12,  
151 - itemRender: { name: '$input', props: { placeholder: '请输入岗位编码' } }  
152 - },  
153 - {  
154 - field: 'sort',  
155 - title: '岗位顺序',  
156 - span: 12,  
157 - itemRender: { name: '$input', props: { type: 'number', placeholder: '请输入岗位顺序' } }  
158 - },  
159 - {  
160 - field: 'status',  
161 - title: t('common.status'),  
162 - span: 12,  
163 - itemRender: {  
164 - name: '$select',  
165 - options: getIntDictOptions(DICT_TYPE.COMMON_STATUS),  
166 - props: { placeholder: '请选择' }  
167 - }  
168 - },  
169 - {  
170 - align: 'center',  
171 - span: 24,  
172 - itemRender: {  
173 - name: '$buttons',  
174 - children: [  
175 - { props: { type: 'submit', content: t('action.save'), status: 'primary' } },  
176 - { props: { type: 'reset', content: t('common.reset') } }  
177 - ]  
178 - }  
179 - }  
180 -]) 25 +const formItems = ref<VxeFormItemProps[]>(allSchemas.formSchema)
181 // 设置标题 26 // 设置标题
182 const setDialogTile = (type: string) => { 27 const setDialogTile = (type: string) => {
183 dialogTitle.value = t('action.' + type) 28 dialogTitle.value = t('action.' + type)
@@ -206,16 +51,13 @@ const handleUpdate = async (rowId: number) =&gt; { @@ -206,16 +51,13 @@ const handleUpdate = async (rowId: number) =&gt; {
206 } 51 }
207 // 删除操作 52 // 删除操作
208 const handleDelete = (rowId: number) => { 53 const handleDelete = (rowId: number) => {
209 - ElMessageBox.confirm(t('common.delMessage'), t('common.confirmTitle'), {  
210 - confirmButtonText: t('common.ok'),  
211 - cancelButtonText: t('common.cancel'),  
212 - type: 'warning'  
213 - }) 54 + message
  55 + .confirm(t('common.delMessage'), t('common.confirmTitle'))
214 .then(async () => { 56 .then(async () => {
215 await PostApi.deletePostApi(rowId) 57 await PostApi.deletePostApi(rowId)
  58 + message.success(t('common.delSuccess'))
216 }) 59 })
217 .finally(() => { 60 .finally(() => {
218 - ElMessage.success(t('common.delSuccess'))  
219 xGrid.value?.commitProxy('query') 61 xGrid.value?.commitProxy('query')
220 }) 62 })
221 } 63 }
@@ -227,10 +69,10 @@ const submitForm: VxeFormEvents.Submit = async () =&gt; { @@ -227,10 +69,10 @@ const submitForm: VxeFormEvents.Submit = async () =&gt; {
227 const data = formData.value as PostVO 69 const data = formData.value as PostVO
228 if (actionType.value === 'create') { 70 if (actionType.value === 'create') {
229 await PostApi.createPostApi(data) 71 await PostApi.createPostApi(data)
230 - ElMessage.success(t('common.createSuccess')) 72 + message.success(t('common.createSuccess'))
231 } else { 73 } else {
232 await PostApi.updatePostApi(data) 74 await PostApi.updatePostApi(data)
233 - ElMessage.success(t('common.updateSuccess')) 75 + message.success(t('common.updateSuccess'))
234 } 76 }
235 // 操作成功,重新加载列表 77 // 操作成功,重新加载列表
236 dialogVisible.value = false 78 dialogVisible.value = false
yudao-ui-admin-vue3/src/views/system/post/indexd.vue deleted
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 (rowId: number) => {  
45 - setDialogTile('update')  
46 - // 设置数据  
47 - const res = await PostApi.getPostApi(rowId)  
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.id)"  
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>  
yudao-ui-admin-vue3/src/views/system/post/post.data.ts
1 import { reactive } from 'vue' 1 import { reactive } from 'vue'
2 import { useI18n } from '@/hooks/web/useI18n' 2 import { useI18n } from '@/hooks/web/useI18n'
3 import { required } from '@/utils/formRules' 3 import { required } from '@/utils/formRules'
4 -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas' 4 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
5 import { DICT_TYPE } from '@/utils/dict' 5 import { DICT_TYPE } from '@/utils/dict'
6 const { t } = useI18n() // 国际化 6 const { t } = useI18n() // 国际化
7 7
@@ -13,9 +13,9 @@ export const rules = reactive({ @@ -13,9 +13,9 @@ export const rules = reactive({
13 }) 13 })
14 14
15 // CrudSchema 15 // CrudSchema
16 -const crudSchemas = reactive<CrudSchema[]>([ 16 +const crudSchemas = reactive<VxeCrudSchema[]>([
17 { 17 {
18 - label: t('common.index'), 18 + title: t('common.index'),
19 field: 'id', 19 field: 'id',
20 type: 'index', 20 type: 'index',
21 form: { 21 form: {
@@ -26,42 +26,54 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([ @@ -26,42 +26,54 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
26 } 26 }
27 }, 27 },
28 { 28 {
29 - label: '岗位名称', 29 + title: '岗位名称',
30 field: 'name', 30 field: 'name',
31 search: { 31 search: {
32 show: true 32 show: true
33 } 33 }
34 }, 34 },
35 { 35 {
36 - label: '岗位编码', 36 + title: '岗位编码',
37 field: 'code', 37 field: 'code',
38 search: { 38 search: {
39 show: true 39 show: true
40 } 40 }
41 }, 41 },
42 { 42 {
43 - label: '岗位顺序', 43 + title: '岗位顺序',
44 field: 'sort' 44 field: 'sort'
45 }, 45 },
46 { 46 {
47 - label: t('common.status'), 47 + title: t('common.status'),
48 field: 'status', 48 field: 'status',
49 dictType: DICT_TYPE.COMMON_STATUS, 49 dictType: DICT_TYPE.COMMON_STATUS,
  50 + table: {
  51 + slots: {
  52 + default: 'status_default'
  53 + }
  54 + },
50 search: { 55 search: {
51 show: true 56 show: true
52 } 57 }
53 }, 58 },
54 { 59 {
55 - label: t('common.createTime'), 60 + title: t('common.createTime'),
56 field: 'createTime', 61 field: 'createTime',
57 form: { 62 form: {
58 show: false 63 show: false
59 } 64 }
60 }, 65 },
61 { 66 {
62 - label: t('table.action'), 67 + title: t('table.action'),
63 field: 'action', 68 field: 'action',
64 width: '240px', 69 width: '240px',
  70 + table: {
  71 + width: '240px',
  72 + showOverflow: true,
  73 + slots: {
  74 + default: 'action_default'
  75 + }
  76 + },
65 form: { 77 form: {
66 show: false 78 show: false
67 }, 79 },
@@ -70,4 +82,4 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([ @@ -70,4 +82,4 @@ const crudSchemas = reactive&lt;CrudSchema[]&gt;([
70 } 82 }
71 } 83 }
72 ]) 84 ])
73 -export const { allSchemas } = useCrudSchemas(crudSchemas) 85 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)