Commit 120417b792576d87f1b94b27340d351bc47b2c79
1 parent
7cbd6cfb
refactor: vxe crud
Showing
16 changed files
with
190 additions
and
119 deletions
yudao-ui-admin-vue3/src/api/system/menu/index.ts
| 1 | 1 | import request from '@/config/axios' |
| 2 | -import type { MenuVO } from './types' | |
| 3 | 2 | |
| 3 | +export interface MenuVO { | |
| 4 | + id: number | |
| 5 | + name: string | |
| 6 | + permission: string | |
| 7 | + type: number | |
| 8 | + sort: number | |
| 9 | + parentId: number | |
| 10 | + path: string | |
| 11 | + icon: string | |
| 12 | + component: string | |
| 13 | + status: number | |
| 14 | + visible: boolean | |
| 15 | + keepAlive: boolean | |
| 16 | + createTime: string | |
| 17 | +} | |
| 18 | + | |
| 19 | +export interface MenuPageReqVO { | |
| 20 | + name?: string | |
| 21 | + status?: number | |
| 22 | +} | |
| 4 | 23 | // 查询菜单(精简)列表 |
| 5 | 24 | export const listSimpleMenusApi = () => { |
| 6 | 25 | return request.get({ url: '/system/menu/list-all-simple' }) |
| 7 | 26 | } |
| 8 | 27 | |
| 9 | 28 | // 查询菜单列表 |
| 10 | -export const getMenuListApi = (params) => { | |
| 29 | +export const getMenuListApi = (params: MenuPageReqVO) => { | |
| 11 | 30 | return request.get({ url: '/system/menu/list', params }) |
| 12 | 31 | } |
| 13 | 32 | ... | ... |
yudao-ui-admin-vue3/src/api/system/menu/types.ts deleted
yudao-ui-admin-vue3/src/api/system/notice/index.ts
| 1 | 1 | import request from '@/config/axios' |
| 2 | -import type { NoticeVO } from './types' | |
| 2 | +export interface NoticeVO { | |
| 3 | + id: number | |
| 4 | + title: string | |
| 5 | + type: number | |
| 6 | + content: string | |
| 7 | + status: number | |
| 8 | + remark: string | |
| 9 | + creator: string | |
| 10 | + createTime: string | |
| 11 | + updater: string | |
| 12 | + updateTime: string | |
| 13 | +} | |
| 14 | + | |
| 15 | +export interface NoticePageReqVO extends BasePage { | |
| 16 | + title?: string | |
| 17 | + status?: number | |
| 18 | +} | |
| 3 | 19 | |
| 4 | 20 | // 查询公告列表 |
| 5 | -export const getNoticePageApi = (params) => { | |
| 21 | +export const getNoticePageApi = (params: NoticePageReqVO) => { | |
| 6 | 22 | return request.get({ url: '/system/notice/page', params }) |
| 7 | 23 | } |
| 8 | 24 | ... | ... |
yudao-ui-admin-vue3/src/api/system/notice/types.ts deleted
yudao-ui-admin-vue3/src/api/system/post/index.ts
| 1 | 1 | import request from '@/config/axios' |
| 2 | -import type { PostVO, PostPageReqVO, PostExportReqVO } from './types' | |
| 2 | + | |
| 3 | +export interface PostVO { | |
| 4 | + id?: number | |
| 5 | + name: string | |
| 6 | + code: string | |
| 7 | + sort: number | |
| 8 | + status: number | |
| 9 | + remark: string | |
| 10 | + createTime?: string | |
| 11 | +} | |
| 12 | + | |
| 13 | +export interface PostPageReqVO extends BasePage { | |
| 14 | + code?: string | |
| 15 | + name?: string | |
| 16 | + status?: number | |
| 17 | +} | |
| 18 | + | |
| 19 | +export interface PostExportReqVO { | |
| 20 | + code?: string | |
| 21 | + name?: string | |
| 22 | + status?: number | |
| 23 | +} | |
| 3 | 24 | |
| 4 | 25 | // 查询岗位列表 |
| 5 | 26 | export const getPostPageApi = async (params: PostPageReqVO) => { |
| ... | ... | @@ -31,7 +52,6 @@ export const deletePostApi = async (id: number) => { |
| 31 | 52 | } |
| 32 | 53 | |
| 33 | 54 | // 导出岗位 |
| 34 | -// TODO @星语:导出这块,咱怎么弄哈 | |
| 35 | 55 | export const exportPostApi = async (params: PostExportReqVO) => { |
| 36 | 56 | return await request.download({ url: '/system/post/export', params }) |
| 37 | 57 | } | ... | ... |
yudao-ui-admin-vue3/src/api/system/post/types.ts deleted
| 1 | -export type PostVO = { | |
| 2 | - id?: number | |
| 3 | - name: string | |
| 4 | - code: string | |
| 5 | - sort: number | |
| 6 | - status: number | |
| 7 | - remark: string | |
| 8 | - createTime?: string | |
| 9 | -} | |
| 10 | - | |
| 11 | -// TODO @星语:要不要搞个 Page 基类呀?和后端对应 | |
| 12 | -export type PostPageReqVO = { | |
| 13 | - code: string | |
| 14 | - name: string | |
| 15 | - status?: number | |
| 16 | - pageSize?: number | |
| 17 | - pageNo?: number | |
| 18 | -} | |
| 19 | - | |
| 20 | -export type PostExportReqVO = { | |
| 21 | - code: string | |
| 22 | - name: string | |
| 23 | - status?: number | |
| 24 | -} |
yudao-ui-admin-vue3/src/components/DictTag/src/DictTag.vue
yudao-ui-admin-vue3/src/hooks/web/useMessage.ts
| ... | ... | @@ -71,6 +71,18 @@ export const useMessage = () => { |
| 71 | 71 | } |
| 72 | 72 | ) |
| 73 | 73 | }, |
| 74 | + // 导出窗体 | |
| 75 | + exportConfirm(content?: string, tip?: string) { | |
| 76 | + return ElMessageBox.confirm( | |
| 77 | + content ? content : t('common.exportMessage'), | |
| 78 | + tip ? tip : t('common.confirmTitle'), | |
| 79 | + { | |
| 80 | + confirmButtonText: t('common.ok'), | |
| 81 | + cancelButtonText: t('common.cancel'), | |
| 82 | + type: 'warning' | |
| 83 | + } | |
| 84 | + ) | |
| 85 | + }, | |
| 74 | 86 | // 提交内容 |
| 75 | 87 | prompt(content: string, tip: string) { |
| 76 | 88 | return ElMessageBox.prompt(content, tip, { | ... | ... |
yudao-ui-admin-vue3/src/hooks/web/useVxeGrid.ts
| ... | ... | @@ -13,6 +13,7 @@ interface UseVxeGridConfig<T = any> { |
| 13 | 13 | getListApi: (option: any) => Promise<T> |
| 14 | 14 | delListApi?: (option: any) => Promise<T> |
| 15 | 15 | exportListApi?: (option: any) => Promise<T> |
| 16 | + exportName?: string | |
| 16 | 17 | } |
| 17 | 18 | |
| 18 | 19 | const appStore = useAppStore() |
| ... | ... | @@ -88,10 +89,29 @@ export const useVxeGrid = <T = any>(config?: UseVxeGridConfig<T>) => { |
| 88 | 89 | return new Promise(async (resolve) => { |
| 89 | 90 | resolve(await config?.getListApi(queryParams)) |
| 90 | 91 | }) |
| 92 | + }, | |
| 93 | + queryAll: ({ form }) => { | |
| 94 | + const queryParams = Object.assign({}, JSON.parse(JSON.stringify(form))) | |
| 95 | + return new Promise(async (resolve) => { | |
| 96 | + if (config?.exportListApi) { | |
| 97 | + resolve(await config?.exportListApi(queryParams)) | |
| 98 | + } else { | |
| 99 | + resolve(await config?.getListApi(queryParams)) | |
| 100 | + } | |
| 101 | + }) | |
| 91 | 102 | } |
| 92 | 103 | } |
| 104 | + }, | |
| 105 | + exportConfig: { | |
| 106 | + filename: config?.exportName, | |
| 107 | + // 默认选中类型 | |
| 108 | + type: 'csv', | |
| 109 | + // 自定义数据量列表 | |
| 110 | + modes: ['current', 'all'], | |
| 111 | + columns: config?.allSchemas.printSchema | |
| 93 | 112 | } |
| 94 | 113 | }) |
| 114 | + | |
| 95 | 115 | const delList = (ids: string | number | string[] | number[]) => { |
| 96 | 116 | return new Promise(async () => { |
| 97 | 117 | message.delConfirm().then(() => { | ... | ... |
yudao-ui-admin-vue3/src/store/modules/dict.ts
yudao-ui-admin-vue3/src/utils/dict.ts
| ... | ... | @@ -15,7 +15,7 @@ const dictStore = useDictStoreWithOut() |
| 15 | 15 | export interface DictDataType { |
| 16 | 16 | dictType: string |
| 17 | 17 | label: string |
| 18 | - value: string | number | |
| 18 | + value: string | number | boolean | |
| 19 | 19 | colorType: ElementPlusInfoType | '' | 'default' | 'primary' |
| 20 | 20 | cssClass: string |
| 21 | 21 | } |
| ... | ... | @@ -34,10 +34,10 @@ export const getDictOptions = (dictType: string) => { |
| 34 | 34 | export const getIntDictOptions = (dictType: string) => { |
| 35 | 35 | const dictOptions: DictDataType[] = [] |
| 36 | 36 | dictStore.getDictMap.forEach((dict: DictDataType) => { |
| 37 | - if (dict.dictType + '' === dictType) { | |
| 37 | + if (dict.dictType.toString() === dictType) { | |
| 38 | 38 | dictOptions.push({ |
| 39 | 39 | ...dict, |
| 40 | - value: parseInt(dict.value + '') | |
| 40 | + value: dict.value | |
| 41 | 41 | }) |
| 42 | 42 | } |
| 43 | 43 | }) | ... | ... |
yudao-ui-admin-vue3/src/views/system/menu/index.vue
| ... | ... | @@ -42,7 +42,6 @@ |
| 42 | 42 | </template> |
| 43 | 43 | </vxe-toolbar> |
| 44 | 44 | <!-- 列表 --> |
| 45 | - <!-- TODO 星语:是不是也搞成 grid 会好点,后续代码就统一走 grid 风格? --> | |
| 46 | 45 | <vxe-table |
| 47 | 46 | show-overflow |
| 48 | 47 | keep-source |
| ... | ... | @@ -84,14 +83,14 @@ |
| 84 | 83 | preIcon="ep:edit" |
| 85 | 84 | :title="t('action.edit')" |
| 86 | 85 | v-hasPermi="['system:menu:update']" |
| 87 | - @click="handleUpdate(row)" | |
| 86 | + @click="handleUpdate(row.id)" | |
| 88 | 87 | /> |
| 89 | 88 | <!-- 操作:删除 --> |
| 90 | 89 | <XTextButton |
| 91 | 90 | preIcon="ep:delete" |
| 92 | 91 | :title="t('action.del')" |
| 93 | 92 | v-hasPermi="['system:menu:delete']" |
| 94 | - @click="handleDelete(row)" | |
| 93 | + @click="handleDelete(row.id)" | |
| 95 | 94 | /> |
| 96 | 95 | </template> |
| 97 | 96 | </vxe-column> |
| ... | ... | @@ -102,6 +101,7 @@ |
| 102 | 101 | <template #default> |
| 103 | 102 | <!-- 对话框(添加 / 修改) --> |
| 104 | 103 | <el-form |
| 104 | + ref="formRef" | |
| 105 | 105 | :model="menuForm" |
| 106 | 106 | :rules="rules" |
| 107 | 107 | :inline="true" |
| ... | ... | @@ -254,7 +254,6 @@ |
| 254 | 254 | import { onMounted, reactive, ref } from 'vue' |
| 255 | 255 | import { useI18n } from '@/hooks/web/useI18n' |
| 256 | 256 | import { useMessage } from '@/hooks/web/useMessage' |
| 257 | -// TODO @星语:是不是 'element-plus' 和 '@/components/Tooltip' 和 '@/components/Icon' 全局直接引入 | |
| 258 | 257 | import { |
| 259 | 258 | ElRow, |
| 260 | 259 | ElCol, |
| ... | ... | @@ -266,14 +265,14 @@ import { |
| 266 | 265 | ElTreeSelect, |
| 267 | 266 | ElOption, |
| 268 | 267 | ElRadioGroup, |
| 269 | - ElRadioButton | |
| 268 | + ElRadioButton, | |
| 269 | + FormInstance | |
| 270 | 270 | } from 'element-plus' |
| 271 | 271 | import { Tooltip } from '@/components/Tooltip' |
| 272 | 272 | import { IconSelect } from '@/components/Icon' |
| 273 | 273 | import { VxeTableInstance } from 'vxe-table' |
| 274 | 274 | // 业务相关的 import |
| 275 | 275 | import * as MenuApi from '@/api/system/menu' |
| 276 | -import { MenuVO } from '@/api/system/menu/types' | |
| 277 | 276 | import { required } from '@/utils/formRules.js' |
| 278 | 277 | import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' |
| 279 | 278 | import { SystemMenuTypeEnum, CommonStatusEnum } from '@/utils/constants' |
| ... | ... | @@ -291,7 +290,8 @@ const dialogTitle = ref('edit') // 弹出层标题 |
| 291 | 290 | const actionType = ref('') // 操作按钮的类型 |
| 292 | 291 | const actionLoading = ref(false) // 遮罩层 |
| 293 | 292 | // 新增和修改的表单值 |
| 294 | -const menuForm = ref<MenuVO>({ | |
| 293 | +const formRef = ref<FormInstance>() | |
| 294 | +const menuForm = ref<MenuApi.MenuVO>({ | |
| 295 | 295 | id: 0, |
| 296 | 296 | name: '', |
| 297 | 297 | permission: '', |
| ... | ... | @@ -316,19 +316,12 @@ const rules = reactive({ |
| 316 | 316 | |
| 317 | 317 | // ========== 下拉框[上级菜单] ========== |
| 318 | 318 | // 下拉框[上级菜单]的配置项目 |
| 319 | -// TODO @星语:menuProps 貌似也可以抽到全局? | |
| 320 | 319 | const menuProps = { |
| 321 | 320 | checkStrictly: true, |
| 322 | 321 | children: 'children', |
| 323 | 322 | label: 'name', |
| 324 | 323 | value: 'id' |
| 325 | 324 | } |
| 326 | -// TODO @星语:Tree 可以是全局的 | |
| 327 | -interface Tree { | |
| 328 | - id: number | |
| 329 | - name: string | |
| 330 | - children?: Tree[] | any[] | |
| 331 | -} | |
| 332 | 325 | const menuOptions = ref<any[]>([]) // 树形结构 |
| 333 | 326 | const getTree = async () => { |
| 334 | 327 | menuOptions.value = [] |
| ... | ... | @@ -339,9 +332,9 @@ const getTree = async () => { |
| 339 | 332 | } |
| 340 | 333 | |
| 341 | 334 | // ========== 查询 ========== |
| 342 | -const queryParams = reactive({ | |
| 343 | - name: null, | |
| 344 | - status: null | |
| 335 | +const queryParams = reactive<MenuApi.MenuPageReqVO>({ | |
| 336 | + name: undefined, | |
| 337 | + status: undefined | |
| 345 | 338 | }) |
| 346 | 339 | const getList = async () => { |
| 347 | 340 | tableLoading.value = true |
| ... | ... | @@ -357,31 +350,47 @@ const handleQuery = async () => { |
| 357 | 350 | |
| 358 | 351 | // 重置操作 |
| 359 | 352 | const resetQuery = async () => { |
| 360 | - queryParams.name = null | |
| 361 | - queryParams.status = null | |
| 353 | + queryParams.name = undefined | |
| 354 | + queryParams.status = undefined | |
| 362 | 355 | await getList() |
| 363 | 356 | } |
| 364 | 357 | |
| 365 | 358 | // ========== 新增/修改 ========== |
| 366 | 359 | |
| 367 | 360 | // 设置标题 |
| 368 | -const setDialogTile = (type: string) => { | |
| 361 | +const setDialogTile = async (type: string) => { | |
| 362 | + await getTree() | |
| 369 | 363 | dialogTitle.value = t('action.' + type) |
| 370 | 364 | actionType.value = type |
| 371 | 365 | dialogVisible.value = true |
| 372 | 366 | } |
| 373 | 367 | |
| 374 | -// 新建操作 | |
| 368 | +// 新增操作 | |
| 375 | 369 | const handleCreate = () => { |
| 376 | 370 | setDialogTile('create') |
| 377 | - // TODO @星语:重置表单 | |
| 371 | + formRef.value?.resetFields() | |
| 372 | + menuForm.value = { | |
| 373 | + id: 0, | |
| 374 | + name: '', | |
| 375 | + permission: '', | |
| 376 | + type: SystemMenuTypeEnum.DIR, | |
| 377 | + sort: 1, | |
| 378 | + parentId: 0, | |
| 379 | + path: '', | |
| 380 | + icon: '', | |
| 381 | + component: '', | |
| 382 | + status: CommonStatusEnum.ENABLE, | |
| 383 | + visible: true, | |
| 384 | + keepAlive: true, | |
| 385 | + createTime: '' | |
| 386 | + } | |
| 378 | 387 | } |
| 379 | 388 | |
| 380 | 389 | // 修改操作 |
| 381 | -const handleUpdate = async (row: MenuVO) => { | |
| 390 | +const handleUpdate = async (rowId: number) => { | |
| 382 | 391 | setDialogTile('update') |
| 383 | 392 | // 设置数据 |
| 384 | - const res = await MenuApi.getMenuApi(row.id) | |
| 393 | + const res = await MenuApi.getMenuApi(rowId) | |
| 385 | 394 | menuForm.value = res |
| 386 | 395 | } |
| 387 | 396 | |
| ... | ... | @@ -411,11 +420,11 @@ const submitForm = async () => { |
| 411 | 420 | await MenuApi.updateMenuApi(menuForm.value) |
| 412 | 421 | message.success(t('common.updateSuccess')) |
| 413 | 422 | } |
| 414 | - // 操作成功,重新加载列表 | |
| 415 | - dialogVisible.value = false | |
| 416 | - await getList() | |
| 417 | 423 | } finally { |
| 424 | + dialogVisible.value = false | |
| 418 | 425 | actionLoading.value = false |
| 426 | + // 操作成功,重新加载列表 | |
| 427 | + await getList() | |
| 419 | 428 | } |
| 420 | 429 | } |
| 421 | 430 | |
| ... | ... | @@ -426,9 +435,9 @@ const isExternal = (path: string) => { |
| 426 | 435 | |
| 427 | 436 | // ========== 删除 ========== |
| 428 | 437 | // 删除操作 |
| 429 | -const handleDelete = async (row: MenuVO) => { | |
| 430 | - message.confirm(t('common.delDataMessage'), t('common.confirmTitle')).then(async () => { | |
| 431 | - await MenuApi.deleteMenuApi(row.id) | |
| 438 | +const handleDelete = async (rowId: number) => { | |
| 439 | + message.delConfirm().then(async () => { | |
| 440 | + await MenuApi.deleteMenuApi(rowId) | |
| 432 | 441 | message.success(t('common.delSuccess')) |
| 433 | 442 | await getList() |
| 434 | 443 | }) |
| ... | ... | @@ -437,7 +446,5 @@ const handleDelete = async (row: MenuVO) => { |
| 437 | 446 | // ========== 初始化 ========== |
| 438 | 447 | onMounted(async () => { |
| 439 | 448 | await getList() |
| 440 | - // TODO @星语:这个告警解决下;是不是改成新增和修改点击的时候,去加载下好一点哈? | |
| 441 | - getTree() | |
| 442 | 449 | }) |
| 443 | 450 | </script> | ... | ... |
yudao-ui-admin-vue3/src/views/system/notice/index.vue
| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | preIcon="ep:view" |
| 22 | 22 | :title="t('action.detail')" |
| 23 | 23 | v-hasPermi="['system:notice:update']" |
| 24 | - @click="handleDetail(row)" | |
| 24 | + @click="handleDetail(row.id)" | |
| 25 | 25 | /> |
| 26 | 26 | <XTextButton |
| 27 | 27 | preIcon="ep:delete" |
| ... | ... | @@ -36,10 +36,10 @@ |
| 36 | 36 | <template #default> |
| 37 | 37 | <!-- 对话框(添加 / 修改) --> |
| 38 | 38 | <Form |
| 39 | + ref="formRef" | |
| 39 | 40 | v-if="['create', 'update'].includes(actionType)" |
| 40 | 41 | :schema="allSchemas.formSchema" |
| 41 | 42 | :rules="rules" |
| 42 | - ref="formRef" | |
| 43 | 43 | /> |
| 44 | 44 | <!-- 对话框(详情) --> |
| 45 | 45 | <Descriptions |
| ... | ... | @@ -63,30 +63,31 @@ |
| 63 | 63 | </template> |
| 64 | 64 | <script setup lang="ts"> |
| 65 | 65 | import { ref, unref } from 'vue' |
| 66 | -import * as NoticeApi from '@/api/system/notice' | |
| 67 | -import { NoticeVO } from '@/api/system/notice/types' | |
| 68 | -import { rules, allSchemas } from './notice.data' | |
| 69 | 66 | import { useI18n } from '@/hooks/web/useI18n' |
| 70 | 67 | import { useMessage } from '@/hooks/web/useMessage' |
| 71 | 68 | import { useVxeGrid } from '@/hooks/web/useVxeGrid' |
| 72 | 69 | import { VxeGridInstance } from 'vxe-table' |
| 73 | 70 | import { FormExpose } from '@/components/Form' |
| 74 | 71 | |
| 72 | +import * as NoticeApi from '@/api/system/notice' | |
| 73 | +import { rules, allSchemas } from './notice.data' | |
| 74 | + | |
| 75 | 75 | const { t } = useI18n() // 国际化 |
| 76 | 76 | const message = useMessage() // 消息弹窗 |
| 77 | + | |
| 78 | +const xGrid = ref<VxeGridInstance>() // grid Ref | |
| 79 | +const { gridOptions } = useVxeGrid<NoticeApi.NoticeVO>({ | |
| 80 | + allSchemas: allSchemas, | |
| 81 | + getListApi: NoticeApi.getNoticePageApi | |
| 82 | +}) | |
| 83 | + | |
| 77 | 84 | const dialogVisible = ref(false) // 是否显示弹出层 |
| 78 | 85 | const dialogTitle = ref('edit') // 弹出层标题 |
| 79 | 86 | const actionType = ref('') // 操作按钮的类型 |
| 80 | 87 | const actionLoading = ref(false) // 按钮Loading |
| 81 | -const xGrid = ref<VxeGridInstance>() // grid Ref | |
| 82 | 88 | const formRef = ref<FormExpose>() // 表单 Ref |
| 83 | 89 | const detailRef = ref() // 详情 Ref |
| 84 | 90 | |
| 85 | -const { gridOptions } = useVxeGrid<NoticeVO>({ | |
| 86 | - allSchemas: allSchemas, | |
| 87 | - getListApi: NoticeApi.getNoticePageApi | |
| 88 | -}) | |
| 89 | - | |
| 90 | 91 | // 设置标题 |
| 91 | 92 | const setDialogTile = (type: string) => { |
| 92 | 93 | dialogTitle.value = t('action.' + type) |
| ... | ... | @@ -110,9 +111,11 @@ const handleUpdate = async (rowId: number) => { |
| 110 | 111 | } |
| 111 | 112 | |
| 112 | 113 | // 详情操作 |
| 113 | -const handleDetail = (row: NoticeVO) => { | |
| 114 | +const handleDetail = async (rowId: number) => { | |
| 114 | 115 | setDialogTile('detail') |
| 115 | - detailRef.value = row | |
| 116 | + // 设置数据 | |
| 117 | + const res = await NoticeApi.getNoticeApi(rowId) | |
| 118 | + detailRef.value = res | |
| 116 | 119 | } |
| 117 | 120 | |
| 118 | 121 | // 删除操作 |
| ... | ... | @@ -137,7 +140,7 @@ const submitForm = async () => { |
| 137 | 140 | actionLoading.value = true |
| 138 | 141 | // 提交请求 |
| 139 | 142 | try { |
| 140 | - const data = unref(formRef)?.formModel as NoticeVO | |
| 143 | + const data = unref(formRef)?.formModel as NoticeApi.NoticeVO | |
| 141 | 144 | if (actionType.value === 'create') { |
| 142 | 145 | await NoticeApi.createNoticeApi(data) |
| 143 | 146 | message.success(t('common.createSuccess')) | ... | ... |
yudao-ui-admin-vue3/src/views/system/notice/notice.data.ts
yudao-ui-admin-vue3/src/views/system/post/index.vue
| ... | ... | @@ -11,6 +11,13 @@ |
| 11 | 11 | v-hasPermi="['system:post:create']" |
| 12 | 12 | @click="handleCreate()" |
| 13 | 13 | /> |
| 14 | + <XButton | |
| 15 | + type="primary" | |
| 16 | + preIcon="ep:download" | |
| 17 | + :title="t('action.export')" | |
| 18 | + v-hasPermi="['system:post:export']" | |
| 19 | + @click="handleExport()" | |
| 20 | + /> | |
| 14 | 21 | </template> |
| 15 | 22 | <template #actionbtns_default="{ row }"> |
| 16 | 23 | <!-- 操作:修改 --> |
| ... | ... | @@ -25,7 +32,7 @@ |
| 25 | 32 | preIcon="ep:view" |
| 26 | 33 | :title="t('action.detail')" |
| 27 | 34 | v-hasPermi="['system:post:update']" |
| 28 | - @click="handleDetail(row)" | |
| 35 | + @click="handleDetail(row.id)" | |
| 29 | 36 | /> |
| 30 | 37 | <!-- 操作:删除 --> |
| 31 | 38 | <XTextButton |
| ... | ... | @@ -42,10 +49,10 @@ |
| 42 | 49 | <template #default> |
| 43 | 50 | <!-- 表单:添加/修改 --> |
| 44 | 51 | <Form |
| 52 | + ref="formRef" | |
| 45 | 53 | v-if="['create', 'update'].includes(actionType)" |
| 46 | 54 | :schema="allSchemas.formSchema" |
| 47 | 55 | :rules="rules" |
| 48 | - ref="formRef" | |
| 49 | 56 | /> |
| 50 | 57 | <!-- 表单:详情 --> |
| 51 | 58 | <Descriptions |
| ... | ... | @@ -78,14 +85,14 @@ import { VxeGridInstance } from 'vxe-table' |
| 78 | 85 | import { FormExpose } from '@/components/Form' |
| 79 | 86 | // 业务相关的 import |
| 80 | 87 | import * as PostApi from '@/api/system/post' |
| 81 | -import { PostVO } from '@/api/system/post/types' | |
| 82 | 88 | import { rules, allSchemas } from './post.data' |
| 89 | +import download from '@/utils/download' | |
| 83 | 90 | |
| 84 | 91 | const { t } = useI18n() // 国际化 |
| 85 | 92 | const message = useMessage() // 消息弹窗 |
| 86 | 93 | // 列表相关的变量 |
| 87 | 94 | const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref |
| 88 | -const { gridOptions } = useVxeGrid<PostVO>({ | |
| 95 | +const { gridOptions } = useVxeGrid<PostApi.PostVO>({ | |
| 89 | 96 | allSchemas: allSchemas, |
| 90 | 97 | getListApi: PostApi.getPostPageApi |
| 91 | 98 | }) |
| ... | ... | @@ -111,6 +118,16 @@ const handleCreate = () => { |
| 111 | 118 | unref(formRef)?.getElFormRef()?.resetFields() |
| 112 | 119 | } |
| 113 | 120 | |
| 121 | +// 导出操作 | |
| 122 | +const handleExport = async () => { | |
| 123 | + const queryParams = Object.assign( | |
| 124 | + {}, | |
| 125 | + JSON.parse(JSON.stringify(xGrid.value?.getRefMaps().refForm.value.data)) | |
| 126 | + ) | |
| 127 | + const res = await PostApi.exportPostApi(queryParams) | |
| 128 | + download.excel(res, '岗位列表.xls') | |
| 129 | +} | |
| 130 | + | |
| 114 | 131 | // 修改操作 |
| 115 | 132 | const handleUpdate = async (rowId: number) => { |
| 116 | 133 | setDialogTile('update') |
| ... | ... | @@ -120,10 +137,10 @@ const handleUpdate = async (rowId: number) => { |
| 120 | 137 | } |
| 121 | 138 | |
| 122 | 139 | // 详情操作 |
| 123 | -const handleDetail = (row: PostVO) => { | |
| 140 | +const handleDetail = async (rowId: number) => { | |
| 124 | 141 | setDialogTile('detail') |
| 125 | - // TODO @星语:要不读取下后端? | |
| 126 | - detailRef.value = row | |
| 142 | + const res = await PostApi.getPostApi(rowId) | |
| 143 | + detailRef.value = res | |
| 127 | 144 | } |
| 128 | 145 | |
| 129 | 146 | // 删除操作 |
| ... | ... | @@ -144,13 +161,12 @@ const handleDelete = async (rowId: number) => { |
| 144 | 161 | const submitForm = async () => { |
| 145 | 162 | const elForm = unref(formRef)?.getElFormRef() |
| 146 | 163 | if (!elForm) return |
| 147 | - // TODO @星语:这个告警,要不要解决下? | |
| 148 | 164 | elForm.validate(async (valid) => { |
| 149 | 165 | if (valid) { |
| 150 | 166 | actionLoading.value = true |
| 151 | 167 | // 提交请求 |
| 152 | 168 | try { |
| 153 | - const data = unref(formRef)?.formModel as PostVO | |
| 169 | + const data = unref(formRef)?.formModel as PostApi.PostVO | |
| 154 | 170 | if (actionType.value === 'create') { |
| 155 | 171 | await PostApi.createPostApi(data) |
| 156 | 172 | message.success(t('common.createSuccess')) | ... | ... |
yudao-ui-admin-vue3/types/global.d.ts
| ... | ... | @@ -36,4 +36,14 @@ declare global { |
| 36 | 36 | code: string |
| 37 | 37 | data: T extends any ? T : T & any |
| 38 | 38 | } |
| 39 | + | |
| 40 | + declare interface BasePage { | |
| 41 | + pageSize?: number | |
| 42 | + pageNo?: number | |
| 43 | + } | |
| 44 | + declare interface Tree { | |
| 45 | + id: number | |
| 46 | + name: string | |
| 47 | + children?: Tree[] | any[] | |
| 48 | + } | |
| 39 | 49 | } | ... | ... |