Commit 7cabf0ead5ba81586de20d360bac7e5379f97aec
1 parent
83954241
feat: dept vxe table
Showing
6 changed files
with
270 additions
and
201 deletions
yudao-ui-admin-vue3/package.json
| @@ -43,7 +43,7 @@ | @@ -43,7 +43,7 @@ | ||
| 43 | "lodash-es": "^4.17.21", | 43 | "lodash-es": "^4.17.21", |
| 44 | "mitt": "^3.0.0", | 44 | "mitt": "^3.0.0", |
| 45 | "nprogress": "^0.2.0", | 45 | "nprogress": "^0.2.0", |
| 46 | - "pinia": "^2.0.23", | 46 | + "pinia": "^2.0.24", |
| 47 | "qrcode": "^1.5.1", | 47 | "qrcode": "^1.5.1", |
| 48 | "qs": "^6.11.0", | 48 | "qs": "^6.11.0", |
| 49 | "url": "^0.11.0", | 49 | "url": "^0.11.0", |
yudao-ui-admin-vue3/pnpm-lock.yaml
| @@ -42,7 +42,7 @@ specifiers: | @@ -42,7 +42,7 @@ specifiers: | ||
| 42 | lodash-es: ^4.17.21 | 42 | lodash-es: ^4.17.21 |
| 43 | mitt: ^3.0.0 | 43 | mitt: ^3.0.0 |
| 44 | nprogress: ^0.2.0 | 44 | nprogress: ^0.2.0 |
| 45 | - pinia: ^2.0.23 | 45 | + pinia: ^2.0.24 |
| 46 | plop: ^3.1.1 | 46 | plop: ^3.1.1 |
| 47 | postcss: ^8.4.19 | 47 | postcss: ^8.4.19 |
| 48 | postcss-html: ^1.5.0 | 48 | postcss-html: ^1.5.0 |
| @@ -99,7 +99,7 @@ dependencies: | @@ -99,7 +99,7 @@ dependencies: | ||
| 99 | lodash-es: 4.17.21 | 99 | lodash-es: 4.17.21 |
| 100 | mitt: 3.0.0 | 100 | mitt: 3.0.0 |
| 101 | nprogress: 0.2.0 | 101 | nprogress: 0.2.0 |
| 102 | - pinia: 2.0.23_zwu2zepfy3m6u2gunxlolp35gi | 102 | + pinia: 2.0.24_zwu2zepfy3m6u2gunxlolp35gi |
| 103 | qrcode: 1.5.1 | 103 | qrcode: 1.5.1 |
| 104 | qs: 6.11.0 | 104 | qs: 6.11.0 |
| 105 | url: 0.11.0 | 105 | url: 0.11.0 |
| @@ -1565,10 +1565,6 @@ packages: | @@ -1565,10 +1565,6 @@ packages: | ||
| 1565 | /@vue/devtools-api/6.4.3: | 1565 | /@vue/devtools-api/6.4.3: |
| 1566 | resolution: {integrity: sha512-9WCRwdROJvWcHAdyrR7SZMM/qUvllDZnpndHXokThkUsjnJ2xe4/pvsH9FZrxFe22L+JmDKczL79HjLJ7DK9rg==} | 1566 | resolution: {integrity: sha512-9WCRwdROJvWcHAdyrR7SZMM/qUvllDZnpndHXokThkUsjnJ2xe4/pvsH9FZrxFe22L+JmDKczL79HjLJ7DK9rg==} |
| 1567 | 1567 | ||
| 1568 | - /@vue/devtools-api/6.4.4: | ||
| 1569 | - resolution: {integrity: sha512-Ku31WzpOV/8cruFaXaEZKF81WkNnvCSlBY4eOGtz5WMSdJvX1v1WWlSMGZeqUwPtQ27ZZz7B62erEMq8JDjcXw==} | ||
| 1570 | - dev: false | ||
| 1571 | - | ||
| 1572 | /@vue/devtools-api/6.4.5: | 1568 | /@vue/devtools-api/6.4.5: |
| 1573 | resolution: {integrity: sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==} | 1569 | resolution: {integrity: sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==} |
| 1574 | dev: false | 1570 | dev: false |
| @@ -5564,8 +5560,8 @@ packages: | @@ -5564,8 +5560,8 @@ packages: | ||
| 5564 | dev: true | 5560 | dev: true |
| 5565 | optional: true | 5561 | optional: true |
| 5566 | 5562 | ||
| 5567 | - /pinia/2.0.23_zwu2zepfy3m6u2gunxlolp35gi: | ||
| 5568 | - resolution: {integrity: sha512-N15hFf4o5STrxpNrib1IEb1GOArvPYf1zPvQVRGOO1G1d74Ak0J0lVyalX/SmrzdT4Q0nlEFjbURsmBmIGUR5Q==} | 5563 | + /pinia/2.0.24_zwu2zepfy3m6u2gunxlolp35gi: |
| 5564 | + resolution: {integrity: sha512-DDLd4Iphyc+6PYYYbx7jkb6WP9gecgu9bz9huyB5rb7CdJI3DhzYiZI+/Ih8MLewRrP9DSpslF/BgSNrJtZU7A==} | ||
| 5569 | peerDependencies: | 5565 | peerDependencies: |
| 5570 | '@vue/composition-api': ^1.4.0 | 5566 | '@vue/composition-api': ^1.4.0 |
| 5571 | typescript: '>=4.4.4' | 5567 | typescript: '>=4.4.4' |
| @@ -5576,7 +5572,7 @@ packages: | @@ -5576,7 +5572,7 @@ packages: | ||
| 5576 | typescript: | 5572 | typescript: |
| 5577 | optional: true | 5573 | optional: true |
| 5578 | dependencies: | 5574 | dependencies: |
| 5579 | - '@vue/devtools-api': 6.4.4 | 5575 | + '@vue/devtools-api': 6.4.5 |
| 5580 | typescript: 4.8.4 | 5576 | typescript: 4.8.4 |
| 5581 | vue: 3.2.45 | 5577 | vue: 3.2.45 |
| 5582 | vue-demi: 0.13.11_vue@3.2.45 | 5578 | vue-demi: 0.13.11_vue@3.2.45 |
yudao-ui-admin-vue3/src/api/system/dept/index.ts
| 1 | import request from '@/config/axios' | 1 | import request from '@/config/axios' |
| 2 | -import type { DeptVO, DeptListReqVO } from './types' | 2 | +export type DeptVO = { |
| 3 | + id: number | ||
| 4 | + name: string | ||
| 5 | + parentId: number | ||
| 6 | + status: number | ||
| 7 | + sort: number | ||
| 8 | + leaderUserId: number | ||
| 9 | + phone: string | ||
| 10 | + email: string | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +export interface DeptPageReqVO { | ||
| 14 | + name?: string | ||
| 15 | + status?: number | ||
| 16 | +} | ||
| 3 | 17 | ||
| 4 | // 查询部门(精简)列表 | 18 | // 查询部门(精简)列表 |
| 5 | -export const listSimpleDeptApi = () => { | ||
| 6 | - return request.get({ url: '/system/dept/list-all-simple' }) | 19 | +export const listSimpleDeptApi = async () => { |
| 20 | + return await request.get({ url: '/system/dept/list-all-simple' }) | ||
| 7 | } | 21 | } |
| 8 | 22 | ||
| 9 | // 查询部门列表 | 23 | // 查询部门列表 |
| 10 | -export const getDeptPageApi = (params: DeptListReqVO) => { | ||
| 11 | - return request.get({ url: '/system/dept/list', params }) | 24 | +export const getDeptPageApi = async (params: DeptPageReqVO) => { |
| 25 | + return await request.get({ url: '/system/dept/list', params }) | ||
| 12 | } | 26 | } |
| 13 | 27 | ||
| 14 | // 查询部门详情 | 28 | // 查询部门详情 |
| 15 | -export const getDeptApi = (id: number) => { | ||
| 16 | - return request.get({ url: '/system/dept/get?id=' + id }) | 29 | +export const getDeptApi = async (id: number) => { |
| 30 | + return await request.get({ url: '/system/dept/get?id=' + id }) | ||
| 17 | } | 31 | } |
| 18 | 32 | ||
| 19 | // 新增部门 | 33 | // 新增部门 |
| 20 | -export const createDeptApi = (data: DeptVO) => { | ||
| 21 | - return request.post({ url: '/system/dept/create', data: data }) | 34 | +export const createDeptApi = async (data: DeptVO) => { |
| 35 | + return await request.post({ url: '/system/dept/create', data: data }) | ||
| 22 | } | 36 | } |
| 23 | 37 | ||
| 24 | // 修改部门 | 38 | // 修改部门 |
| 25 | -export const updateDeptApi = (params: DeptVO) => { | ||
| 26 | - return request.put({ url: '/system/dept/update', data: params }) | 39 | +export const updateDeptApi = async (params: DeptVO) => { |
| 40 | + return await request.put({ url: '/system/dept/update', data: params }) | ||
| 27 | } | 41 | } |
| 28 | 42 | ||
| 29 | // 删除部门 | 43 | // 删除部门 |
| 30 | -export const deleteDeptApi = (id: number) => { | ||
| 31 | - return request.delete({ url: '/system/dept/delete?id=' + id }) | 44 | +export const deleteDeptApi = async (id: number) => { |
| 45 | + return await request.delete({ url: '/system/dept/delete?id=' + id }) | ||
| 32 | } | 46 | } |
yudao-ui-admin-vue3/src/views/system/dept/dept.data.ts
| @@ -49,7 +49,7 @@ export const modelSchema = reactive<FormSchema[]>([ | @@ -49,7 +49,7 @@ export const modelSchema = reactive<FormSchema[]>([ | ||
| 49 | { | 49 | { |
| 50 | label: '显示排序', | 50 | label: '显示排序', |
| 51 | field: 'sort', | 51 | field: 'sort', |
| 52 | - component: 'InputNumber' | 52 | + component: 'Input' |
| 53 | }, | 53 | }, |
| 54 | { | 54 | { |
| 55 | label: '状态', | 55 | label: '状态', |
yudao-ui-admin-vue3/src/views/system/dept/index.vue
| 1 | <template> | 1 | <template> |
| 2 | - <div class="flex"> | ||
| 3 | - <el-card class="w-1/3 dept" :gutter="12" shadow="always"> | ||
| 4 | - <template #header> | ||
| 5 | - <div class="card-header"> | ||
| 6 | - <span>部门列表</span> | ||
| 7 | - <XButton | ||
| 8 | - type="primary" | ||
| 9 | - preIcon="ep:zoom-in" | ||
| 10 | - title="新增根节点" | ||
| 11 | - v-hasPermi="['system:dept:create']" | ||
| 12 | - @click="handleCreate" | 2 | + <ContentWrap> |
| 3 | + <!-- 搜索工作栏 --> | ||
| 4 | + <el-form :model="queryParams" ref="queryForm" :inline="true"> | ||
| 5 | + <el-form-item label="部门名称" prop="name"> | ||
| 6 | + <el-input v-model="queryParams.name" placeholder="请输入部门名称" /> | ||
| 7 | + </el-form-item> | ||
| 8 | + <el-form-item label="状态" prop="status"> | ||
| 9 | + <el-select v-model="queryParams.status" placeholder="请选择部门状态"> | ||
| 10 | + <el-option | ||
| 11 | + v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" | ||
| 12 | + :key="dict.value" | ||
| 13 | + :label="dict.label" | ||
| 14 | + :value="dict.value" | ||
| 13 | /> | 15 | /> |
| 14 | - </div> | 16 | + </el-select> |
| 17 | + </el-form-item> | ||
| 18 | + <el-form-item> | ||
| 19 | + <!-- 操作:搜索 --> | ||
| 20 | + <XButton | ||
| 21 | + type="primary" | ||
| 22 | + preIcon="ep:search" | ||
| 23 | + :title="t('common.query')" | ||
| 24 | + @click="handleQuery()" | ||
| 25 | + /> | ||
| 26 | + <!-- 操作:重置 --> | ||
| 27 | + <XButton preIcon="ep:refresh-right" :title="t('common.reset')" @click="resetQuery()" /> | ||
| 28 | + </el-form-item> | ||
| 29 | + </el-form> | ||
| 30 | + <vxe-toolbar> | ||
| 31 | + <template #buttons> | ||
| 32 | + <!-- 操作:新增 --> | ||
| 33 | + <XButton | ||
| 34 | + type="primary" | ||
| 35 | + preIcon="ep:zoom-in" | ||
| 36 | + :title="t('action.add')" | ||
| 37 | + v-hasPermi="['system:dept:create']" | ||
| 38 | + @click="handleCreate()" | ||
| 39 | + /> | ||
| 40 | + <XButton title="展开所有" @click="xTable?.setAllTreeExpand(true)" /> | ||
| 41 | + <XButton title="关闭所有" @click="xTable?.clearTreeExpand()" /> | ||
| 15 | </template> | 42 | </template> |
| 16 | - <div class="custom-tree-container"> | ||
| 17 | - <!-- <p>部门列表</p> --> | ||
| 18 | - <!-- 操作工具栏 --> | ||
| 19 | - <el-input v-model="filterText" placeholder="搜索部门" /> | ||
| 20 | - <el-tree | ||
| 21 | - ref="treeRef" | 43 | + </vxe-toolbar> |
| 44 | + <!-- 列表 --> | ||
| 45 | + <vxe-table | ||
| 46 | + show-overflow | ||
| 47 | + keep-source | ||
| 48 | + ref="xTable" | ||
| 49 | + :loading="tableLoading" | ||
| 50 | + :row-config="{ keyField: 'id' }" | ||
| 51 | + :column-config="{ resizable: true }" | ||
| 52 | + :tree-config="{ transform: true, rowField: 'id', parentField: 'parentId' }" | ||
| 53 | + :print-config="{}" | ||
| 54 | + :export-config="{}" | ||
| 55 | + :data="tableData" | ||
| 56 | + class="xtable" | ||
| 57 | + > | ||
| 58 | + <vxe-column title="部门名称" field="name" width="200" tree-node /> | ||
| 59 | + <vxe-column title="负责人" field="leaderUserId" :formatter="userNicknameFormat" /> | ||
| 60 | + <vxe-column title="排序" field="sort" /> | ||
| 61 | + <vxe-column title="状态" field="status"> | ||
| 62 | + <template #default="{ row }"> | ||
| 63 | + <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" /> | ||
| 64 | + </template> | ||
| 65 | + </vxe-column> | ||
| 66 | + <vxe-column title="创建时间" field="createTime" formatter="formatDate" /> | ||
| 67 | + <vxe-column title="操作" width="200"> | ||
| 68 | + <template #default="{ row }"> | ||
| 69 | + <!-- 操作:修改 --> | ||
| 70 | + <XTextButton | ||
| 71 | + preIcon="ep:edit" | ||
| 72 | + :title="t('action.edit')" | ||
| 73 | + v-hasPermi="['system:dept:update']" | ||
| 74 | + @click="handleUpdate(row.id)" | ||
| 75 | + /> | ||
| 76 | + <!-- 操作:删除 --> | ||
| 77 | + <XTextButton | ||
| 78 | + preIcon="ep:delete" | ||
| 79 | + :title="t('action.del')" | ||
| 80 | + v-hasPermi="['system:dept:delete']" | ||
| 81 | + @click="handleDelete(row.id)" | ||
| 82 | + /> | ||
| 83 | + </template> | ||
| 84 | + </vxe-column> | ||
| 85 | + </vxe-table> | ||
| 86 | + </ContentWrap> | ||
| 87 | + <!-- 添加或修改菜单对话框 --> | ||
| 88 | + <XModal id="deptModel" v-model="dialogVisible" :title="dialogTitle"> | ||
| 89 | + <!-- 对话框(添加 / 修改) --> | ||
| 90 | + <!-- 操作工具栏 --> | ||
| 91 | + <Form ref="formRef" :schema="modelSchema" :rules="rules"> | ||
| 92 | + <template #parentId> | ||
| 93 | + <el-tree-select | ||
| 22 | node-key="id" | 94 | node-key="id" |
| 23 | - :data="deptOptions" | 95 | + v-model="deptParentId" |
| 24 | :props="defaultProps" | 96 | :props="defaultProps" |
| 25 | - :highlight-current="true" | ||
| 26 | - default-expand-all | ||
| 27 | - :filter-node-method="filterNode" | ||
| 28 | - :expand-on-click-node="false" | ||
| 29 | - > | ||
| 30 | - <template #default="{ node, data }"> | ||
| 31 | - <span class="custom-tree-node"> | ||
| 32 | - <span>{{ node.label }}</span> | ||
| 33 | - <span> | ||
| 34 | - <XTextButton | ||
| 35 | - preIcon="ep:zoom-in" | ||
| 36 | - :title="t('action.add')" | ||
| 37 | - v-hasPermi="['system:dept:create']" | ||
| 38 | - @click="handleCreate(data)" | ||
| 39 | - /> | ||
| 40 | - <XTextButton | ||
| 41 | - preIcon="ep:edit" | ||
| 42 | - :title="t('action.edit')" | ||
| 43 | - v-hasPermi="['system:dept:update']" | ||
| 44 | - @click="handleUpdate(data)" | ||
| 45 | - /> | ||
| 46 | - <XTextButton | ||
| 47 | - preIcon="ep:delete" | ||
| 48 | - :title="t('action.del')" | ||
| 49 | - v-hasPermi="['system:dept:delete']" | ||
| 50 | - @click="handleDelete(data)" | ||
| 51 | - /> | ||
| 52 | - </span> | ||
| 53 | - </span> | ||
| 54 | - </template> | ||
| 55 | - </el-tree> | ||
| 56 | - </div> | ||
| 57 | - </el-card> | ||
| 58 | - <el-card class="w-2/3 dept" style="margin-left: 10px" :gutter="12" shadow="hover"> | ||
| 59 | - <template #header> | ||
| 60 | - <div class="card-header"> | ||
| 61 | - <span>{{ formTitle }}</span> | ||
| 62 | - </div> | ||
| 63 | - </template> | ||
| 64 | - <div v-if="!showForm"> | ||
| 65 | - <span><p>请从左侧选择部门</p></span> | ||
| 66 | - </div> | ||
| 67 | - <div v-if="showForm"> | ||
| 68 | - <!-- 操作工具栏 --> | ||
| 69 | - <Form ref="formRef" :schema="modelSchema" :rules="rules"> | ||
| 70 | - <template #parentId> | ||
| 71 | - <el-tree-select | ||
| 72 | - node-key="id" | ||
| 73 | - v-model="deptParentId" | ||
| 74 | - :props="defaultProps" | ||
| 75 | - :data="deptOptions" | ||
| 76 | - check-strictly | ||
| 77 | - /> | ||
| 78 | - </template> | ||
| 79 | - <template #leaderUserId> | ||
| 80 | - <el-select v-model="leaderUserId"> | ||
| 81 | - <el-option | ||
| 82 | - v-for="item in userOption" | ||
| 83 | - :key="parseInt(item.id)" | ||
| 84 | - :label="item.nickname" | ||
| 85 | - :value="parseInt(item.id)" | ||
| 86 | - /> | ||
| 87 | - </el-select> | ||
| 88 | - </template> | ||
| 89 | - </Form> | ||
| 90 | - <!-- 按钮:保存 --> | ||
| 91 | - <XButton | ||
| 92 | - type="primary" | ||
| 93 | - :title="t('action.save')" | ||
| 94 | - v-hasPermi="['system:dept:update']" | ||
| 95 | - :loading="loading" | ||
| 96 | - @click="submitForm()" | 97 | + :data="deptOptions" |
| 98 | + :default-expanded-keys="[100]" | ||
| 99 | + check-strictly | ||
| 97 | /> | 100 | /> |
| 98 | - <!-- 按钮:关闭 --> | ||
| 99 | - <XButton :loading="loading" :title="t('dialog.close')" @click="showForm = false" /> | ||
| 100 | - </div> | ||
| 101 | - </el-card> | ||
| 102 | - </div> | 101 | + </template> |
| 102 | + <template #leaderUserId> | ||
| 103 | + <el-select v-model="leaderUserId"> | ||
| 104 | + <el-option | ||
| 105 | + v-for="item in userOption" | ||
| 106 | + :key="parseInt(item.id)" | ||
| 107 | + :label="item.nickname" | ||
| 108 | + :value="parseInt(item.id)" | ||
| 109 | + /> | ||
| 110 | + </el-select> | ||
| 111 | + </template> | ||
| 112 | + </Form> | ||
| 113 | + <template #footer> | ||
| 114 | + <!-- 按钮:保存 --> | ||
| 115 | + <XButton | ||
| 116 | + v-if="['create', 'update'].includes(actionType)" | ||
| 117 | + type="primary" | ||
| 118 | + :loading="actionLoading" | ||
| 119 | + @click="submitForm()" | ||
| 120 | + :title="t('action.save')" | ||
| 121 | + /> | ||
| 122 | + <!-- 按钮:关闭 --> | ||
| 123 | + <XButton :loading="actionLoading" @click="dialogVisible = false" :title="t('dialog.close')" /> | ||
| 124 | + </template> | ||
| 125 | + </XModal> | ||
| 103 | </template> | 126 | </template> |
| 104 | <script setup lang="ts"> | 127 | <script setup lang="ts"> |
| 128 | +import { nextTick, onMounted, reactive, ref, unref } from 'vue' | ||
| 105 | import { useI18n } from '@/hooks/web/useI18n' | 129 | import { useI18n } from '@/hooks/web/useI18n' |
| 106 | -import { ElInput, ElCard, ElTree, ElTreeSelect, ElSelect, ElOption } from 'element-plus' | ||
| 107 | -import { handleTree } from '@/utils/tree' | ||
| 108 | -import { onMounted, ref, unref, watch } from 'vue' | ||
| 109 | -import * as DeptApi from '@/api/system/dept' | ||
| 110 | -import { Form, FormExpose } from '@/components/Form' | ||
| 111 | -import { modelSchema, rules } from './dept.data' | ||
| 112 | -import { DeptVO } from '@/api/system/dept/types' | ||
| 113 | import { useMessage } from '@/hooks/web/useMessage' | 130 | import { useMessage } from '@/hooks/web/useMessage' |
| 131 | +import { ElForm, ElFormItem, ElInput, ElSelect, ElTreeSelect, ElOption } from 'element-plus' | ||
| 132 | +import { VxeColumn, VxeTable, VxeTableInstance, VxeToolbar } from 'vxe-table' | ||
| 133 | +import { modelSchema } from './dept.data' | ||
| 134 | +import * as DeptApi from '@/api/system/dept' | ||
| 114 | import { getListSimpleUsersApi } from '@/api/system/user' | 135 | import { getListSimpleUsersApi } from '@/api/system/user' |
| 115 | -const message = useMessage() | 136 | +import { required } from '@/utils/formRules.js' |
| 137 | +import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||
| 138 | +import { handleTree } from '@/utils/tree' | ||
| 139 | +import { FormExpose } from '@/components/Form' | ||
| 116 | 140 | ||
| 141 | +const { t } = useI18n() // 国际化 | ||
| 142 | +const message = useMessage() // 消息弹窗 | ||
| 143 | +// 列表相关的变量 | ||
| 144 | +const xTable = ref<VxeTableInstance>() | ||
| 145 | +const tableLoading = ref(false) | ||
| 146 | +const tableData = ref() | ||
| 147 | +// 弹窗相关的变量 | ||
| 148 | +const dialogVisible = ref(false) // 是否显示弹出层 | ||
| 149 | +const dialogTitle = ref('edit') // 弹出层标题 | ||
| 150 | +const actionType = ref('') // 操作按钮的类型 | ||
| 151 | +const actionLoading = ref(false) // 遮罩层 | ||
| 152 | +const deptParentId = ref(0) // 上级ID | ||
| 153 | +const leaderUserId = ref() | ||
| 154 | +const formRef = ref<FormExpose>() // 表单 Ref | ||
| 155 | +const deptOptions = ref() // 树形结构 | ||
| 156 | +const userOption = ref() | ||
| 157 | +// 新增和修改的表单校验 | ||
| 158 | +const rules = reactive({ | ||
| 159 | + name: [required], | ||
| 160 | + sort: [required], | ||
| 161 | + path: [required], | ||
| 162 | + status: [required] | ||
| 163 | +}) | ||
| 164 | + | ||
| 165 | +// 下拉框[上级]的配置项目 | ||
| 117 | const defaultProps = { | 166 | const defaultProps = { |
| 167 | + checkStrictly: true, | ||
| 118 | children: 'children', | 168 | children: 'children', |
| 119 | label: 'name', | 169 | label: 'name', |
| 120 | value: 'id' | 170 | value: 'id' |
| 121 | } | 171 | } |
| 122 | -const { t } = useI18n() // 国际化 | ||
| 123 | -const loading = ref(false) // 遮罩层 | ||
| 124 | -const dialogVisible = ref(false) // 是否显示弹出层 | ||
| 125 | -const showForm = ref(false) // 显示form表单 | ||
| 126 | -const formTitle = ref('部门信息') // 显示form标题 | ||
| 127 | -const deptParentId = ref(0) // 上级ID | ||
| 128 | -// 创建form表单 | ||
| 129 | -const formRef = ref<FormExpose>() | ||
| 130 | - | ||
| 131 | -// ========== 创建部门树结构 ========== | ||
| 132 | -const filterText = ref('') | ||
| 133 | -const deptOptions = ref() // 树形结构 | ||
| 134 | -const treeRef = ref<InstanceType<typeof ElTree>>() | 172 | +// 获取下拉框[上级]的数据 |
| 135 | const getTree = async () => { | 173 | const getTree = async () => { |
| 136 | const res = await DeptApi.listSimpleDeptApi() | 174 | const res = await DeptApi.listSimpleDeptApi() |
| 137 | deptOptions.value = handleTree(res) | 175 | deptOptions.value = handleTree(res) |
| 176 | + console.info(deptOptions.value) | ||
| 138 | } | 177 | } |
| 139 | -const filterNode = (value: string, data: Tree) => { | ||
| 140 | - if (!value) return true | ||
| 141 | - return data.name.includes(value) | ||
| 142 | -} | ||
| 143 | -watch(filterText, (val) => { | ||
| 144 | - treeRef.value!.filter(val) | ||
| 145 | -}) | ||
| 146 | -// 用户列表 | ||
| 147 | -const userOption = ref() | ||
| 148 | -const leaderUserId = ref() | ||
| 149 | const getUserList = async () => { | 178 | const getUserList = async () => { |
| 150 | const res = await getListSimpleUsersApi() | 179 | const res = await getListSimpleUsersApi() |
| 151 | userOption.value = res | 180 | userOption.value = res |
| 152 | } | 181 | } |
| 153 | -// 新增 | ||
| 154 | -const handleCreate = (data: { id: number }) => { | ||
| 155 | - // 重置表单 | ||
| 156 | - deptParentId.value = data.id | ||
| 157 | - formTitle.value = '新增部门' | ||
| 158 | - showForm.value = true | 182 | +// ========== 查询 ========== |
| 183 | +const queryParams = reactive<DeptApi.DeptPageReqVO>({ | ||
| 184 | + name: undefined, | ||
| 185 | + status: undefined | ||
| 186 | +}) | ||
| 187 | +// 执行查询 | ||
| 188 | +const getList = async () => { | ||
| 189 | + tableLoading.value = true | ||
| 190 | + const res = await DeptApi.getDeptPageApi(queryParams) | ||
| 191 | + tableData.value = res | ||
| 192 | + tableLoading.value = false | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | +// 查询操作 | ||
| 196 | +const handleQuery = async () => { | ||
| 197 | + await getList() | ||
| 198 | +} | ||
| 199 | + | ||
| 200 | +// 重置操作 | ||
| 201 | +const resetQuery = async () => { | ||
| 202 | + queryParams.name = undefined | ||
| 203 | + queryParams.status = undefined | ||
| 204 | + await getList() | ||
| 205 | +} | ||
| 206 | + | ||
| 207 | +// ========== 新增/修改 ========== | ||
| 208 | + | ||
| 209 | +// 设置标题 | ||
| 210 | +const setDialogTile = (type: string) => { | ||
| 211 | + dialogTitle.value = t('action.' + type) | ||
| 212 | + actionType.value = type | ||
| 213 | + dialogVisible.value = true | ||
| 214 | +} | ||
| 215 | + | ||
| 216 | +// 新增操作 | ||
| 217 | +const handleCreate = async () => { | ||
| 218 | + deptParentId.value = 0 | ||
| 219 | + leaderUserId.value = null | ||
| 220 | + setDialogTile('create') | ||
| 159 | } | 221 | } |
| 160 | -// 编辑 | ||
| 161 | -const handleUpdate = async (data: { id: number }) => { | ||
| 162 | - const res = await DeptApi.getDeptApi(data.id) | ||
| 163 | - formTitle.value = '修改- ' + res?.name | ||
| 164 | - deptParentId.value = res.parentId | 222 | + |
| 223 | +// 修改操作 | ||
| 224 | +const handleUpdate = async (rowId: number) => { | ||
| 225 | + setDialogTile('update') | ||
| 226 | + // 设置数据 | ||
| 227 | + const res = await DeptApi.getDeptApi(rowId) | ||
| 228 | + console.info(res) | ||
| 229 | + deptParentId.value = res.deptParentId | ||
| 165 | leaderUserId.value = res.leaderUserId | 230 | leaderUserId.value = res.leaderUserId |
| 231 | + await nextTick() | ||
| 166 | unref(formRef)?.setValues(res) | 232 | unref(formRef)?.setValues(res) |
| 167 | - showForm.value = true | ||
| 168 | -} | ||
| 169 | -// 删除 | ||
| 170 | -const handleDelete = async (data: { id: number }) => { | ||
| 171 | - message | ||
| 172 | - .confirm(t('common.delDataMessage'), t('common.confirmTitle')) | ||
| 173 | - .then(async () => { | ||
| 174 | - await DeptApi.deleteDeptApi(data.id) | ||
| 175 | - message.success(t('common.delSuccess')) | ||
| 176 | - }) | ||
| 177 | - .catch(() => {}) | ||
| 178 | - await getTree() | ||
| 179 | } | 233 | } |
| 180 | -// 提交按钮 | 234 | + |
| 235 | +// 提交新增/修改的表单 | ||
| 181 | const submitForm = async () => { | 236 | const submitForm = async () => { |
| 182 | const elForm = unref(formRef)?.getElFormRef() | 237 | const elForm = unref(formRef)?.getElFormRef() |
| 183 | if (!elForm) return | 238 | if (!elForm) return |
| 184 | elForm.validate(async (valid) => { | 239 | elForm.validate(async (valid) => { |
| 185 | if (valid) { | 240 | if (valid) { |
| 186 | - loading.value = true | 241 | + actionLoading.value = true |
| 187 | // 提交请求 | 242 | // 提交请求 |
| 188 | try { | 243 | try { |
| 189 | - const data = unref(formRef)?.formModel as DeptVO | 244 | + const data = unref(formRef)?.formModel as DeptApi.DeptVO |
| 190 | data.parentId = deptParentId.value | 245 | data.parentId = deptParentId.value |
| 191 | data.leaderUserId = leaderUserId.value | 246 | data.leaderUserId = leaderUserId.value |
| 192 | - if (formTitle.value.startsWith('新增')) { | 247 | + if (dialogTitle.value.startsWith('新增')) { |
| 193 | await DeptApi.createDeptApi(data) | 248 | await DeptApi.createDeptApi(data) |
| 194 | - } else if (formTitle.value.startsWith('修改')) { | 249 | + } else if (dialogTitle.value.startsWith('修改')) { |
| 195 | await DeptApi.updateDeptApi(data) | 250 | await DeptApi.updateDeptApi(data) |
| 196 | } | 251 | } |
| 197 | // 操作成功,重新加载列表 | 252 | // 操作成功,重新加载列表 |
| 198 | dialogVisible.value = false | 253 | dialogVisible.value = false |
| 199 | } finally { | 254 | } finally { |
| 200 | - loading.value = false | 255 | + actionLoading.value = false |
| 201 | } | 256 | } |
| 202 | } | 257 | } |
| 203 | }) | 258 | }) |
| 204 | } | 259 | } |
| 260 | + | ||
| 261 | +// 删除操作 | ||
| 262 | +const handleDelete = async (rowId: number) => { | ||
| 263 | + message.delConfirm().then(async () => { | ||
| 264 | + await DeptApi.deleteDeptApi(rowId) | ||
| 265 | + message.success(t('common.delSuccess')) | ||
| 266 | + await getList() | ||
| 267 | + }) | ||
| 268 | +} | ||
| 269 | + | ||
| 270 | +const userNicknameFormat = (row) => { | ||
| 271 | + if (!row && !row.row && !row.row.leaderUserId) { | ||
| 272 | + return '未设置' | ||
| 273 | + } | ||
| 274 | + for (const user of userOption.value) { | ||
| 275 | + if (row.row.leaderUserId === user.id) { | ||
| 276 | + return user.nickname | ||
| 277 | + } | ||
| 278 | + } | ||
| 279 | + return '未知【' + row.row.leaderUserId + '】' | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +// ========== 初始化 ========== | ||
| 205 | onMounted(async () => { | 283 | onMounted(async () => { |
| 206 | await getTree() | 284 | await getTree() |
| 207 | await getUserList() | 285 | await getUserList() |
| 286 | + await getList() | ||
| 208 | }) | 287 | }) |
| 209 | </script> | 288 | </script> |
| 210 | - | ||
| 211 | -<style scoped> | ||
| 212 | -.dept { | ||
| 213 | - height: 600px; | ||
| 214 | - max-height: 1800px; | ||
| 215 | -} | ||
| 216 | -.card-header { | ||
| 217 | - display: flex; | ||
| 218 | - justify-content: space-between; | ||
| 219 | - align-items: center; | ||
| 220 | -} | ||
| 221 | -.custom-tree-node { | ||
| 222 | - flex: 1; | ||
| 223 | - display: flex; | ||
| 224 | - align-items: center; | ||
| 225 | - justify-content: space-between; | ||
| 226 | - font-size: 14px; | ||
| 227 | - padding-right: 8px; | ||
| 228 | -} | ||
| 229 | -</style> |
yudao-ui-admin-vue3/vite.config.ts
| @@ -13,7 +13,7 @@ import { createHtmlPlugin } from 'vite-plugin-html' | @@ -13,7 +13,7 @@ import { createHtmlPlugin } from 'vite-plugin-html' | ||
| 13 | import viteCompression from 'vite-plugin-compression' | 13 | import viteCompression from 'vite-plugin-compression' |
| 14 | import VueMarcos from 'unplugin-vue-macros/vite' | 14 | import VueMarcos from 'unplugin-vue-macros/vite' |
| 15 | 15 | ||
| 16 | -// 当前执行node命令时文件夹的地址(工作目录) | 16 | +// 当前执行node命令时文件夹的地址(工作目录) |
| 17 | const root = process.cwd() | 17 | const root = process.cwd() |
| 18 | 18 | ||
| 19 | // 路径查找 | 19 | // 路径查找 |