From b068518ba6db6de3b79b0113cd6e5b447f0e0fd1 Mon Sep 17 00:00:00 2001 From: Lyp Date: Sun, 23 Jul 2023 20:58:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E3=80=81=E5=B2=97=E4=BD=8D=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/system/menu.ts | 3 +- src/api/system/post.ts | 70 +++++++++ src/api/system/role.ts | 65 ++++++++ src/assets/svg/FullScreenMaximize.svg | 1 + src/assets/svg/FullScreenMinimize.svg | 1 + src/components/VDialog/VDialog.vue | 173 ++++++++++++++++++++++ src/components/VDialog/dialog.css | 62 ++++++++ src/components/VDialog/dialog.ts | 47 ++++++ src/main.ts | 1 + src/store/modules/types.ts | 2 +- src/utils/tree.ts | 22 +++ src/views/system/post/index.vue | 81 +++++++--- src/views/system/post/post-form-modal.vue | 131 ++++++++++++++++ src/views/system/post/utils/hook.tsx | 133 +++++++++-------- src/views/system/role/form.vue | 55 ------- src/views/system/role/index.vue | 68 +++++---- src/views/system/role/role-form-modal.vue | 158 ++++++++++++++++++++ src/views/system/role/utils/hook.tsx | 146 +++++++----------- src/views/system/role/utils/rule.ts | 8 - src/views/system/role/utils/types.ts | 15 -- 20 files changed, 950 insertions(+), 292 deletions(-) create mode 100644 src/api/system/post.ts create mode 100644 src/api/system/role.ts create mode 100644 src/assets/svg/FullScreenMaximize.svg create mode 100644 src/assets/svg/FullScreenMinimize.svg create mode 100644 src/components/VDialog/VDialog.vue create mode 100644 src/components/VDialog/dialog.css create mode 100644 src/components/VDialog/dialog.ts create mode 100644 src/views/system/post/post-form-modal.vue delete mode 100644 src/views/system/role/form.vue create mode 100644 src/views/system/role/role-form-modal.vue delete mode 100644 src/views/system/role/utils/rule.ts delete mode 100644 src/views/system/role/utils/types.ts diff --git a/src/api/system/menu.ts b/src/api/system/menu.ts index 57d7600..ad74096 100644 --- a/src/api/system/menu.ts +++ b/src/api/system/menu.ts @@ -1,4 +1,5 @@ import { http } from "@/utils/http"; +import { Tree } from "@/utils/tree"; export interface MenuQuery { isButton: boolean; @@ -7,7 +8,7 @@ export interface MenuQuery { /** * MenuDTO */ -export interface MenuDTO { +export interface MenuDTO extends Tree { createTime?: Date; isButton?: number; id?: number; diff --git a/src/api/system/post.ts b/src/api/system/post.ts new file mode 100644 index 0000000..914e55f --- /dev/null +++ b/src/api/system/post.ts @@ -0,0 +1,70 @@ +import { http } from "@/utils/http"; + +export interface PostListCommand extends BasePageQuery { + postCode?: string; + postName?: string; + status?: number; +} + +export interface PostPageResponse { + createTime: string; + postCode: string; + postId: number; + postName: string; + postSort: number; + remark: string; + status: number; + statusStr: string; +} + +export function getPostListApi(params: PostListCommand) { + return http.request>>( + "get", + "/system/post/list", + { + params + } + ); +} + +export const exportPostExcelApi = ( + params: PostListCommand, + fileName: string +) => { + return http.download("/system/post/excel", fileName, { + params + }); +}; + +export const deletePostApi = (data: Array) => { + return http.request>("delete", "/system/post", { + params: { + // 需要将数组转换为字符串 否则Axios会将参数变成 noticeIds[0]:1 noticeIds[1]:2 这种格式,后端接收参数不成功 + ids: data.toString() + } + }); +}; + +export interface AddPostCommand { + postCode: string; + postName: string; + postSort: number; + remark?: string; + status?: string; +} + +export const addPostApi = (data: AddPostCommand) => { + return http.request>("post", "/system/post", { + data + }); +}; + +export interface UpdatePostCommand extends AddPostCommand { + postId: number; +} + +export const updatePostApi = (data: UpdatePostCommand) => { + return http.request>("put", "/system/post", { + data + }); +}; diff --git a/src/api/system/role.ts b/src/api/system/role.ts new file mode 100644 index 0000000..41771a9 --- /dev/null +++ b/src/api/system/role.ts @@ -0,0 +1,65 @@ +import { http } from "@/utils/http"; + +export interface RoleQuery extends BasePageQuery { + roleKey?: string; + roleName?: string; + status?: string; + timeRangeColumn?: string; +} + +export interface RoleDTO { + createTime: Date; + dataScope: number; + remark: string; + roleId: number; + roleKey: string; + roleName: string; + roleSort: number; + selectedDeptList: number[]; + selectedMenuList: number[]; + status: number; +} + +export function getRoleListApi(params: RoleQuery) { + return http.request>>( + "get", + "/system/role/list", + { + params + } + ); +} + +export function getRoleInfoApi(roleId: number) { + return http.request>("get", "/system/role/" + roleId); +} + +export interface AddRoleCommand { + dataScope?: string; + menuIds: number[]; + remark?: string; + roleKey: string; + roleName: string; + roleSort: number; + status?: string; +} + +export function addRoleApi(data: AddRoleCommand) { + return http.request("post", "/system/role", { + data + }); +} + +export interface UpdateRoleCommand extends AddRoleCommand { + roleId: number; +} + +export function updateRoleApi(data: UpdateRoleCommand) { + return http.request("put", "/system/role", { + data + }); +} + +export function deleteRoleApi(roleId: number) { + return http.request("delete", "/system/role/" + roleId); +} diff --git a/src/assets/svg/FullScreenMaximize.svg b/src/assets/svg/FullScreenMaximize.svg new file mode 100644 index 0000000..eb519ef --- /dev/null +++ b/src/assets/svg/FullScreenMaximize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svg/FullScreenMinimize.svg b/src/assets/svg/FullScreenMinimize.svg new file mode 100644 index 0000000..f059c76 --- /dev/null +++ b/src/assets/svg/FullScreenMinimize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/VDialog/VDialog.vue b/src/components/VDialog/VDialog.vue new file mode 100644 index 0000000..3f1812d --- /dev/null +++ b/src/components/VDialog/VDialog.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/components/VDialog/dialog.css b/src/components/VDialog/dialog.css new file mode 100644 index 0000000..278ab4e --- /dev/null +++ b/src/components/VDialog/dialog.css @@ -0,0 +1,62 @@ +html.dark .v-dialog { + --header-bg-color: #171d1e; + --footer-bg-color: #171d1e; +} + +.v-dialog { + --header-bg-color: #f5f7fa; + --footer-bg-color: #f5f7fa; +} + +.v-dialog.el-dialog.hidden-footer .el-dialog__footer { + padding: 0; + border: none; +} + +.el-dialog__footer { + padding: 10px; + /*border-top: 1px solid var(--el-border-color);*/ + /*border-bottom: 1px solid var(--el-border-color);*/ + box-sizing: border-box; + background-color: var(--header-bg-color); + position: relative; /* 防止被表单覆盖底部 */ + z-index: calc(var(--el-index-normal) + 1); +} + +.v-dialog.el-dialog { + box-sizing: border-box; + margin: 15dvh auto; +} + +.v-dialog.el-dialog.is-fullscreen { + box-sizing: border-box; + margin: auto; +} + +.v-dialog.el-dialog .el-dialog__header { + padding: 10px 16px; + /*border-bottom: 1px solid var(--el-border-color);*/ + margin-right: 0; + box-sizing: border-box; + background-color: var(--header-bg-color); +} + +.v-dialog.el-dialog--center .el-dialog__body, +.el-dialog__body { + padding: 16px 20px; + box-sizing: border-box; +} + +.v-dialog.el-dialog.is-fullscreen .el-dialog__body { + height: calc(100dvh - 44px - 52px); + max-height: calc(100dvh - 44px - 52px); +} + +.v-dialog.el-dialog .el-dialog__body { + height: calc(70dvh - 44px - 52px); +} + +.v-dialog.el-dialog.flex-body:not(.is-fullscreen) .el-dialog__body { + height: initial; + max-height: calc(70dvh - 44px - 52px); +} diff --git a/src/components/VDialog/dialog.ts b/src/components/VDialog/dialog.ts new file mode 100644 index 0000000..7505c74 --- /dev/null +++ b/src/components/VDialog/dialog.ts @@ -0,0 +1,47 @@ +export interface DialogProps { + /** + * 标题 + */ + title: string; + /** + * 显隐 + */ + modelValue: boolean; + + /** + * 初始化全屏状态 + */ + initFullScreen?: boolean | undefined; + + /** + * 展示全屏按钮 + */ + showFullScreen?: boolean; + + /** + * 全屏 + */ + fullScreen?: boolean | undefined; + confirmText?: string; + cancelText?: string; + loading?: boolean; + /** + * 使用el-scrollbar包裹对话框body + */ + useBodyScrolling?: boolean; + /** + * 固定对话框body高度 + */ + fixedBodyHeight?: boolean; + + draggable?: boolean; + + hiddenFooter?: boolean; +} + +export type DialogEmits = { + "update:modelValue": [val: boolean]; + "update:fullScreen": [val: boolean]; + confirm: []; + cancel: []; +}; diff --git a/src/main.ts b/src/main.ts index f16cbaf..188581c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -21,6 +21,7 @@ import "element-plus/dist/index.css"; // 导入字体图标 import "./assets/iconfont/iconfont.js"; import "./assets/iconfont/iconfont.css"; +import "@/components/VDialog/dialog.css"; const app = createApp(App); diff --git a/src/store/modules/types.ts b/src/store/modules/types.ts index 9ceeb72..cdf679b 100644 --- a/src/store/modules/types.ts +++ b/src/store/modules/types.ts @@ -42,5 +42,5 @@ export type userType = { /** 字典ListMap 用于下拉框直接展示 */ dictionaryList: Map>; /** 字典MapMap 用于匹配值展示 */ - dictionaryMap: Map>; + dictionaryMap: Record>; }; diff --git a/src/utils/tree.ts b/src/utils/tree.ts index 586e1c6..e0ae9ad 100644 --- a/src/utils/tree.ts +++ b/src/utils/tree.ts @@ -205,3 +205,25 @@ export const handleTree = ( } return tree; }; + +export interface Tree { + children?: this[]; +} + +export function toTree( + src: T[], + keyField: keyof T, + parentField: keyof T +): T[] { + const map = new Map(src.map(it => [it[keyField], it])); + src.forEach(it => { + if (map.has(it[parentField])) { + const parent = map.get(it[parentField])!; + if (!parent.children) { + parent.children = []; + } + parent.children.push(it); + } + }); + return src.filter(it => !it[parentField]); +} diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue index ab32c30..c080705 100644 --- a/src/views/system/post/index.vue +++ b/src/views/system/post/index.vue @@ -1,6 +1,6 @@