diff --git a/locales/en.yaml b/locales/en.yaml index 37830a4e3..af00d37e5 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -130,6 +130,7 @@ menus: hsdanmaku: Danmaku hsPureTableBase: Base Usage hsPureTableHigh: High Usage + hsPureTableEdit: Edit Usage hsboard: Paint Board hsMenuoverflow: Menu Overflow Show Tooltip Text hsChildMenuoverflow: Child Menu Overflow Show Tooltip Text diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index 9c8ef14bf..1731212f9 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -129,8 +129,9 @@ menus: hsSensitive: 敏感词过滤 hsPinyin: 汉语拼音 hsdanmaku: 弹幕 - hsPureTableBase: 基础用法(23个示例) - hsPureTableHigh: 高级用法(11个示例) + hsPureTableBase: 基础用法 + hsPureTableHigh: 高级用法 + hsPureTableEdit: 可编辑用法 hsboard: 艺术画板 hsMenuoverflow: 目录超出显示 Tooltip 文字提示 hsChildMenuoverflow: 菜单超出显示 Tooltip 文字提示 diff --git a/mock/system.ts b/mock/system.ts index f1ea4718e..0b4486582 100644 --- a/mock/system.ts +++ b/mock/system.ts @@ -140,6 +140,234 @@ export default defineFakeRoute([ }; } }, + // 角色管理-权限-菜单权限 + { + url: "/role-menu", + method: "post", + response: () => { + return { + success: true, + data: [ + // 外部页面 + { + parentId: 0, + id: 100, + menuType: 0, // 菜单类型(0代表菜单、1代表iframe、2代表外链、3代表按钮) + title: "menus.hsExternalPage" + }, + { + parentId: 100, + id: 101, + menuType: 0, + title: "menus.hsExternalDoc" + }, + { + parentId: 101, + id: 102, + menuType: 2, + title: "menus.externalLink" + }, + { + parentId: 101, + id: 103, + menuType: 2, + title: "menus.pureutilsLink" + }, + { + parentId: 100, + id: 104, + menuType: 1, + title: "menus.hsEmbeddedDoc" + }, + { + parentId: 104, + id: 105, + menuType: 1, + title: "menus.hsEpDocument" + }, + { + parentId: 104, + id: 106, + menuType: 1, + title: "menus.hsTailwindcssDocument" + }, + { + parentId: 104, + id: 107, + menuType: 1, + title: "menus.hsVueDocument" + }, + { + parentId: 104, + id: 108, + menuType: 1, + title: "menus.hsViteDocument" + }, + { + parentId: 104, + id: 109, + menuType: 1, + title: "menus.hsPiniaDocument" + }, + { + parentId: 104, + id: 110, + menuType: 1, + title: "menus.hsRouterDocument" + }, + // 权限管理 + { + parentId: 0, + id: 200, + menuType: 0, + title: "menus.permission" + }, + { + parentId: 200, + id: 201, + menuType: 0, + title: "menus.permissionPage" + }, + { + parentId: 200, + id: 202, + menuType: 0, + title: "menus.permissionButton" + }, + { + parentId: 202, + id: 203, + menuType: 3, + title: "添加" + }, + { + parentId: 202, + id: 204, + menuType: 3, + title: "修改" + }, + { + parentId: 202, + id: 205, + menuType: 3, + title: "删除" + }, + // 系统管理 + { + parentId: 0, + id: 300, + menuType: 0, + title: "menus.hssysManagement" + }, + { + parentId: 300, + id: 301, + menuType: 0, + title: "menus.hsUser" + }, + { + parentId: 300, + id: 302, + menuType: 0, + title: "menus.hsRole" + }, + { + parentId: 300, + id: 303, + menuType: 0, + title: "menus.hsSystemMenu" + }, + { + parentId: 300, + id: 304, + menuType: 0, + title: "menus.hsDept" + }, + // 系统监控 + { + parentId: 0, + id: 400, + menuType: 0, + title: "menus.hssysMonitor" + }, + { + parentId: 400, + id: 401, + menuType: 0, + title: "menus.hsOnlineUser" + }, + { + parentId: 400, + id: 402, + menuType: 0, + title: "menus.hsLoginLog" + }, + { + parentId: 400, + id: 403, + menuType: 0, + title: "menus.hsOperationLog" + }, + { + parentId: 400, + id: 404, + menuType: 0, + title: "menus.hsSystemLog" + }, + // 标签页操作 + { + parentId: 0, + id: 500, + menuType: 0, + title: "menus.hstabs" + }, + { + parentId: 500, + id: 501, + menuType: 0, + title: "menus.hstabs" + }, + { + parentId: 500, + id: 502, + menuType: 0, + title: "query传参模式" + }, + { + parentId: 500, + id: 503, + menuType: 0, + title: "params传参模式" + } + ] + }; + } + }, + // 角色管理-权限-菜单权限-根据角色 id 查对应菜单 + { + url: "/role-menu-ids", + method: "post", + response: ({ body }) => { + if (body.id == 1) { + return { + success: true, + data: [ + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 200, 201, + 202, 203, 204, 205, 300, 301, 302, 303, 304, 400, 401, 402, 403, + 404, 500, 501, 502, 503 + ] + }; + } else if (body.id == 2) { + return { + success: true, + data: [ + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 404, 500, + 501, 502, 503 + ] + }; + } + } + }, // 菜单管理 { url: "/menu", diff --git a/package.json b/package.json index 99d00e671..d97c6b499 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@logicflow/extension": "^1.2.22", "@pureadmin/descriptions": "^1.2.1", "@pureadmin/table": "^3.1.2", - "@pureadmin/utils": "^2.4.6", + "@pureadmin/utils": "^2.4.7", "@vueuse/core": "^10.9.0", "@vueuse/motion": "^2.1.0", "@wangeditor/editor": "^5.1.23", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f77db5288..cc7ee20d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ dependencies: specifier: ^3.1.2 version: 3.1.2(element-plus@2.6.1)(typescript@5.4.2) '@pureadmin/utils': - specifier: ^2.4.6 - version: 2.4.6(echarts@5.5.0)(vue@3.4.21) + specifier: ^2.4.7 + version: 2.4.7(echarts@5.5.0)(vue@3.4.21) '@vueuse/core': specifier: ^10.9.0 version: 10.9.0(vue@3.4.21) @@ -1758,7 +1758,7 @@ packages: element-plus: ^2.0.0 dependencies: '@element-plus/icons-vue': 2.3.1(vue@3.4.21) - '@pureadmin/utils': 2.4.6(echarts@5.5.0)(vue@3.4.21) + '@pureadmin/utils': 2.4.7(echarts@5.5.0)(vue@3.4.21) element-plus: 2.6.1(vue@3.4.21) vue: 3.4.21(typescript@5.4.2) transitivePeerDependencies: @@ -1785,8 +1785,8 @@ packages: string-hash: 1.1.3 dev: true - /@pureadmin/utils@2.4.6(echarts@5.5.0)(vue@3.4.21): - resolution: {integrity: sha512-TBN9fJhqrsjATvSHR1tDC4ZCQTvC6zMl2xj76lEJW7/VAX3OtNlb5073BAQBBMg7fXsAUXkMyBTwagsOZM5grg==} + /@pureadmin/utils@2.4.7(echarts@5.5.0)(vue@3.4.21): + resolution: {integrity: sha512-fUHwZm9wEtcxUk//bs8xoDe0XYAeoU/FbvAF9CM4Y5xBmaaXvzN+sSFCUyUKC08q4tmCyaHBeLNolO3I4t3X6Q==} peerDependencies: echarts: '*' vue: '*' diff --git a/src/api/system.ts b/src/api/system.ts index 015854b69..e4db23811 100644 --- a/src/api/system.ts +++ b/src/api/system.ts @@ -73,3 +73,13 @@ export const getSystemLogsList = (data?: object) => { export const getSystemLogsDetail = (data?: object) => { return http.request("post", "/system-logs-detail", { data }); }; + +/** 获取角色管理-权限-菜单权限 */ +export const getRoleMenu = (data?: object) => { + return http.request("post", "/role-menu", { data }); +}; + +/** 获取角色管理-权限-菜单权限-根据角色 id 查对应菜单 */ +export const getRoleMenuIds = (data?: object) => { + return http.request("post", "/role-menu-ids", { data }); +}; diff --git a/src/components/ReDialog/index.vue b/src/components/ReDialog/index.vue index aa9ad3834..15b6c1073 100644 --- a/src/components/ReDialog/index.vue +++ b/src/components/ReDialog/index.vue @@ -64,9 +64,10 @@ const fullscreenClass = computed(() => { function eventsCallBack( event: EventType, options: DialogOptions, - index: number + index: number, + isClickFullScreen = false ) { - fullscreen.value = options?.fullscreen ?? false; + if (!isClickFullScreen) fullscreen.value = options?.fullscreen ?? false; if (options?.[event] && isFunction(options?.[event])) { return options?.[event]({ options, index }); } @@ -108,7 +109,17 @@ function handleClose( void; -type EventType = "open" | "close" | "openAutoFocus" | "closeAutoFocus"; +type EventType = + | "open" + | "close" + | "openAutoFocus" + | "closeAutoFocus" + | "fullscreenCallBack"; type ArgsType = { /** `cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了esc键 */ command: "cancel" | "sure" | "close"; @@ -175,6 +180,14 @@ interface DialogOptions extends DialogProps { index: number; args: any; }) => void; + /** 点击全屏按钮时的回调 */ + fullscreenCallBack?: ({ + options, + index + }: { + options: DialogOptions; + index: number; + }) => void; /** 输入焦点聚焦在 `Dialog` 内容时的回调 */ openAutoFocus?: ({ options, diff --git a/src/router/modules/table.ts b/src/router/modules/table.ts index b02329606..fe360605d 100644 --- a/src/router/modules/table.ts +++ b/src/router/modules/table.ts @@ -25,6 +25,15 @@ export default { meta: { title: $t("menus.hsPureTableHigh") } + }, + { + path: "/pure-table/edit", + name: "PureTableEdit", + component: () => import("@/views/pure-table/edit.vue"), + meta: { + title: $t("menus.hsPureTableEdit"), + extraIcon: "IF-pure-iconfont-new svg" + } } ] } satisfies RouteConfigsTable; diff --git a/src/views/components/dialog/index.vue b/src/views/components/dialog/index.vue index 0df0df694..5a8f59e04 100644 --- a/src/views/components/dialog/index.vue +++ b/src/views/components/dialog/index.vue @@ -43,9 +43,11 @@ function onFullscreenClick() { function onFullscreenIconClick() { addDialog({ - title: "全屏按钮", + title: "全屏按钮和全屏事件", fullscreenIcon: true, - contentRenderer: () =>

弹框内容-全屏按钮

+ fullscreenCallBack: ({ options, index }) => + message(options.fullscreen ? "全屏" : "非全屏"), + contentRenderer: () =>

弹框内容-全屏按钮和全屏事件

}); } @@ -468,7 +470,7 @@ function onBeforeSureClick() { 基础用法 可拖拽 全屏 - 全屏按钮 + 全屏按钮和全屏事件 无背景遮罩层 自定义弹出位置 延时2秒打开弹框 diff --git a/src/views/monitor/logs/login/index.vue b/src/views/monitor/logs/login/index.vue index 729957026..c65e6dbff 100644 --- a/src/views/monitor/logs/login/index.vue +++ b/src/views/monitor/logs/login/index.vue @@ -39,7 +39,7 @@ const { ref="formRef" :inline="true" :model="form" - class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]" + class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto" > +import { ref } from "vue"; +import { list } from "./edit/list"; + +defineOptions({ + name: "PureTableEdit" +}); + +const selected = ref(0); + +function tabClick({ index }) { + selected.value = index; +} + + + + + diff --git a/src/views/pure-table/edit/data.ts b/src/views/pure-table/edit/data.ts new file mode 100644 index 000000000..1fbeaf340 --- /dev/null +++ b/src/views/pure-table/edit/data.ts @@ -0,0 +1,74 @@ +const tableData = [ + { + id: 1, + name: "Tom", + sex: 0, // 0代表男 1代表女 + hobby: 2, + date: "2024-03-17" + }, + { + id: 2, + name: "Jack", + sex: 0, + hobby: 1, + date: "2024-03-18" + }, + { + id: 3, + name: "Lily", + sex: 1, + hobby: 1, + date: "2024-03-19" + }, + { + id: 4, + name: "Mia", + sex: 1, + hobby: 3, + date: "2024-03-20" + } +]; + +const options = [ + { + value: 0, + label: "上午写代码" + }, + { + value: 1, + label: "下午写代码" + }, + { + value: 2, + label: "晚上写代码" + }, + { + value: 3, + label: "凌晨休息了" + } +]; + +const tableDataEdit = [ + { + id: 1, + name: "Tom", + address: "home" + }, + { + id: 2, + name: "Jack", + address: "office" + }, + { + id: 3, + name: "Lily", + address: "library" + }, + { + id: 4, + name: "Mia", + address: "playground" + } +]; + +export { tableData, tableDataEdit, options }; diff --git a/src/views/pure-table/edit/demo1/columns.tsx b/src/views/pure-table/edit/demo1/columns.tsx new file mode 100644 index 000000000..30efd47e3 --- /dev/null +++ b/src/views/pure-table/edit/demo1/columns.tsx @@ -0,0 +1,87 @@ +import { ref } from "vue"; +import { options } from "../data"; + +export function useColumns() { + const dataList = ref([]); + + const columns: TableColumnList = [ + { + label: "姓名", + prop: "name", + cellRenderer: ({ row }) => + }, + { + label: "性别", + prop: "sex", + cellRenderer: ({ row }) => ( + + ) + }, + { + label: "爱好", + prop: "hobby", + cellRenderer: ({ row }) => ( + + {options.map(item => { + return ( + + ); + })} + + ) + }, + { + label: "日期", + prop: "date", + cellRenderer: ({ row }) => ( + + ), + minWidth: 110 + }, + { + label: "操作", + fixed: "right", + width: 90, + slot: "operation" + } + ]; + + function onAdd() { + dataList.value.push({ + id: dataList.value.length + 1, + name: "", + sex: 0, + hobby: "", + date: "" + }); + } + + function onDel(row) { + const index = dataList.value.indexOf(row); + if (index !== -1) dataList.value.splice(index, 1); + } + + return { + columns, + dataList, + onAdd, + onDel + }; +} diff --git a/src/views/pure-table/edit/demo1/index.vue b/src/views/pure-table/edit/demo1/index.vue new file mode 100644 index 000000000..6beea0cd3 --- /dev/null +++ b/src/views/pure-table/edit/demo1/index.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/src/views/pure-table/edit/demo2/columns.tsx b/src/views/pure-table/edit/demo2/columns.tsx new file mode 100644 index 000000000..4d955f6aa --- /dev/null +++ b/src/views/pure-table/edit/demo2/columns.tsx @@ -0,0 +1,116 @@ +import { ref } from "vue"; +import { tableData, options } from "../data"; +import { clone, delObjectProperty } from "@pureadmin/utils"; + +export function useColumns() { + const editMap = ref({}); + const dataList = ref(clone(tableData, true)); + + const columns: TableColumnList = [ + { + label: "姓名", + prop: "name", + cellRenderer: ({ row, index }) => ( + <> + {editMap.value[index]?.editable ? ( + + ) : ( +

{row.name}

+ )} + + ) + }, + { + label: "性别", + prop: "sex", + cellRenderer: ({ row, index }) => ( + <> + {editMap.value[index]?.editable ? ( + + ) : ( +

{row.sex === 0 ? "男" : "女"}

+ )} + + ) + }, + { + label: "爱好", + prop: "hobby", + cellRenderer: ({ row, index }) => ( + <> + {editMap.value[index]?.editable ? ( + + {options.map(item => { + return ( + + ); + })} + + ) : ( + + {options.filter(opt => opt.value == row.hobby)[0]?.label} + + )} + + ) + }, + { + label: "日期", + prop: "date", + cellRenderer: ({ row, index }) => ( + <> + {editMap.value[index]?.editable ? ( + + ) : ( +

{row.date}

+ )} + + ), + minWidth: 110 + }, + { + label: "操作", + fixed: "right", + slot: "operation" + } + ]; + + function onEdit(row, index) { + editMap.value[index] = Object.assign({ ...row, editable: true }); + } + + function onSave(index) { + editMap.value[index].editable = false; + } + + function onCancel(index) { + editMap.value[index].editable = false; + dataList.value[index] = delObjectProperty(editMap.value[index], "editable"); + } + + return { + editMap, + columns, + dataList, + onEdit, + onSave, + onCancel + }; +} diff --git a/src/views/pure-table/edit/demo2/index.vue b/src/views/pure-table/edit/demo2/index.vue new file mode 100644 index 000000000..c2d242b73 --- /dev/null +++ b/src/views/pure-table/edit/demo2/index.vue @@ -0,0 +1,50 @@ + + + diff --git a/src/views/pure-table/edit/demo3/columns.tsx b/src/views/pure-table/edit/demo3/columns.tsx new file mode 100644 index 000000000..776941663 --- /dev/null +++ b/src/views/pure-table/edit/demo3/columns.tsx @@ -0,0 +1,87 @@ +import { ref, computed } from "vue"; +import { tableDataEdit } from "../data"; + +import EditPen from "@iconify-icons/ep/edit-pen"; +import Check from "@iconify-icons/ep/check"; + +export function useColumns() { + const editMap = ref({}); + const activeIndex = ref(-1); + const dataList = ref(tableDataEdit); + + const editing = computed(() => { + return index => { + return editMap.value[index]?.editing; + }; + }); + + const iconClass = computed(() => { + return (index, other = false) => { + return [ + "cursor-pointer", + "ml-2", + "transition", + "delay-100", + other + ? ["hover:scale-110", "hover:text-red-500"] + : editing.value(index) && ["scale-150", "text-red-500"] + ]; + }; + }); + + const columns: TableColumnList = [ + { + label: "姓名(可修改)", + prop: "name", + cellRenderer: ({ row, index }) => ( +
(activeIndex.value = index)} + onMouseleave={() => onMouseleave(index)} + > + {!editing.value(index) ? ( +

{row.name}

+ ) : ( + <> + + onSave(index)} + /> + + )} + onEdit(row, index)} + /> +
+ ) + }, + { + label: "地址", + prop: "address" + } + ]; + + function onMouseleave(index) { + editing.value[index] + ? (activeIndex.value = index) + : (activeIndex.value = -1); + } + + function onEdit(row, index) { + editMap.value[index] = Object.assign({ ...row, editing: true }); + } + + function onSave(index) { + editMap.value[index].editing = false; + } + + return { + columns, + dataList + }; +} diff --git a/src/views/pure-table/edit/demo3/index.vue b/src/views/pure-table/edit/demo3/index.vue new file mode 100644 index 000000000..1c4610129 --- /dev/null +++ b/src/views/pure-table/edit/demo3/index.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/views/pure-table/edit/empty.svg b/src/views/pure-table/edit/empty.svg new file mode 100644 index 000000000..5c8b211ce --- /dev/null +++ b/src/views/pure-table/edit/empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/views/pure-table/edit/list.tsx b/src/views/pure-table/edit/list.tsx new file mode 100644 index 000000000..3be8b36eb --- /dev/null +++ b/src/views/pure-table/edit/list.tsx @@ -0,0 +1,27 @@ +import Demo1 from "./demo1/index.vue"; +import Demo2 from "./demo2/index.vue"; +import Demo3 from "./demo3/index.vue"; + +const rendContent = (val: string) => + `代码位置:src/views/pure-table/edit/${val}/index.vue`; + +export const list = [ + { + key: "demo1", + content: rendContent("demo1"), + title: "整体编辑", + component: Demo1 + }, + { + key: "demo2", + content: rendContent("demo2"), + title: "单行编辑", + component: Demo2 + }, + { + key: "demo3", + content: rendContent("demo3"), + title: "单元格编辑", + component: Demo3 + } +]; diff --git a/src/views/pure-table/high/edit/columns.tsx b/src/views/pure-table/high/edit/columns.tsx deleted file mode 100644 index 9bdb85581..000000000 --- a/src/views/pure-table/high/edit/columns.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import { tableDataEdit } from "../data"; -import { message } from "@/utils/message"; -import { ref, computed, Transition } from "vue"; -import { clone, delay } from "@pureadmin/utils"; -import EditPen from "@iconify-icons/ep/edit-pen"; -import Check from "@iconify-icons/ep/check"; - -// 温馨提示:修改整行方法雷同,将cellRenderer后面渲染的组件抽出来做对应处理即可 -export function useColumns() { - // 修改值(可多个) - const inputValMap = ref({}); - // 是否正处于修改状态(可多个) - const editStatus = ref({}); - // 当前激活的单元格(唯一) - const activeIndex = ref(-1); - const dataList = ref(clone(tableDataEdit, true)); - - const comVal = computed(() => { - return index => { - return inputValMap.value[index]?.value; - }; - }); - - const editing = computed(() => { - return index => { - return editStatus.value[index]?.editing; - }; - }); - - const iconClass = computed(() => { - return (index, other = false) => { - return [ - "cursor-pointer", - "ml-2", - "transition", - "delay-100", - other - ? ["hover:scale-110", "hover:text-red-500"] - : editing.value(index) && ["scale-150", "text-red-500"] - ]; - }; - }); - - const columns: TableColumnList = [ - { - label: "ID(可修改)", - prop: "id", - // class="flex-bc" flex-bc 代表 flex justify-between items-center 具体看 src/style/tailwind.css 文件 - cellRenderer: ({ row, index }) => ( -
(activeIndex.value = index)} - onMouseleave={() => onMouseleave(index)} - > -

{row.id}

- - onChange(value, index)} - /> - - onSure(index)} - /> - onEdit(row, index)} - /> -
- ) - }, - { - label: "日期", - prop: "date" - }, - { - label: "姓名", - prop: "name" - }, - { - label: "地址", - prop: "address" - } - ]; - - function onEdit({ id }, index) { - inputValMap.value[index] = Object.assign({}, inputValMap.value[index], { - value: id - }); - // 处于修改状态 - editStatus.value[index] = Object.assign({}, editStatus.value[index], { - editing: true - }); - } - - function onMouseleave(index) { - inputValMap.value[index]?.value - ? (activeIndex.value = index) - : (activeIndex.value = -1); - } - - function onChange(value, index) { - inputValMap.value[index].value = value; - } - - function onSure(index) { - dataList.value[index].id = inputValMap.value[index].value; - message( - `您修改了第 ${index + 1} 行,修改后数据为:${JSON.stringify( - dataList.value[index] - )}`, - { - type: "success" - } - ); - // 修改状态关闭 - editStatus.value[index] = Object.assign({}, editStatus.value[index], { - editing: false - }); - delay().then(() => (inputValMap.value[index].value = null)); - } - - return { - columns, - dataList - }; -} diff --git a/src/views/pure-table/high/edit/index.vue b/src/views/pure-table/high/edit/index.vue deleted file mode 100644 index 03b8484f0..000000000 --- a/src/views/pure-table/high/edit/index.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/src/views/pure-table/high/list.tsx b/src/views/pure-table/high/list.tsx index 30fca023b..67a21f5ea 100644 --- a/src/views/pure-table/high/list.tsx +++ b/src/views/pure-table/high/list.tsx @@ -4,7 +4,6 @@ import RowDrag from "./drag/row/index.vue"; import ColumnDrag from "./drag/column/index.vue"; import Contextmenu from "./contextmenu/index.vue"; import Excel from "./excel/index.vue"; -import Edit from "./edit/index.vue"; import Watermark from "./watermark/index.vue"; import Print from "./prints/index.vue"; import Echarts from "./echarts/index.vue"; @@ -50,12 +49,6 @@ export const list = [ title: "右键菜单", component: Contextmenu }, - { - key: "edit", - content: rendContent("edit"), - title: "单元格修改", - component: Edit - }, { key: "excel", content: rendContent("excel"), diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue index d9d3e2e7a..917d52e5e 100644 --- a/src/views/system/dept/index.vue +++ b/src/views/system/dept/index.vue @@ -34,7 +34,7 @@ const { ref="formRef" :inline="true" :model="form" - class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]" + class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto" > h(editForm, { ref: formRef }), diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue index fe40f7038..ebd0d1c40 100644 --- a/src/views/system/menu/index.vue +++ b/src/views/system/menu/index.vue @@ -35,7 +35,7 @@ const { ref="formRef" :inline="true" :model="form" - class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px]" + class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto" > h(editForm, { ref: formRef }), diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index c5926d194..6037ff079 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -1,8 +1,14 @@ - + + + diff --git a/src/views/system/role/utils/hook.tsx b/src/views/system/role/utils/hook.tsx index f4591b936..b589d35a9 100644 --- a/src/views/system/role/utils/hook.tsx +++ b/src/views/system/role/utils/hook.tsx @@ -1,25 +1,41 @@ import dayjs from "dayjs"; import editForm from "../form.vue"; +import { handleTree } from "@/utils/tree"; import { message } from "@/utils/message"; -import { getRoleList } from "@/api/system"; import { ElMessageBox } from "element-plus"; import { usePublicHooks } from "../../hooks"; +import { transformI18n } from "@/plugins/i18n"; import { addDialog } from "@/components/ReDialog"; import type { FormItemProps } from "../utils/types"; import type { PaginationProps } from "@pureadmin/table"; -import { reactive, ref, onMounted, h, toRaw } from "vue"; +import { getKeyList, deviceDetection } from "@pureadmin/utils"; +import { getRoleList, getRoleMenu, getRoleMenuIds } from "@/api/system"; +import { type Ref, reactive, ref, onMounted, h, toRaw, watch } from "vue"; -export function useRole() { +export function useRole(treeRef: Ref) { const form = reactive({ name: "", code: "", status: "" }); + const curRow = ref(); const formRef = ref(); const dataList = ref([]); + const treeIds = ref([]); + const treeData = ref([]); + const isShow = ref(false); const loading = ref(true); + const isLinkage = ref(false); + const treeSearchValue = ref(); const switchLoadMap = ref({}); + const isExpandAll = ref(false); + const isSelectAll = ref(false); const { switchStyle } = usePublicHooks(); + const treeProps = { + value: "id", + label: "title", + children: "children" + }; const pagination = reactive({ total: 0, pageSize: 10, @@ -29,22 +45,18 @@ export function useRole() { const columns: TableColumnList = [ { label: "角色编号", - prop: "id", - minWidth: 100 + prop: "id" }, { label: "角色名称", - prop: "name", - minWidth: 120 + prop: "name" }, { label: "角色标识", - prop: "code", - minWidth: 150 + prop: "code" }, { label: "状态", - minWidth: 130, cellRenderer: scope => ( onChange(scope as any)} /> - ) + ), + minWidth: 90 }, { label: "备注", prop: "remark", - minWidth: 150 + minWidth: 160 }, { label: "创建时间", - minWidth: 180, prop: "createTime", + minWidth: 160, formatter: ({ createTime }) => dayjs(createTime).format("YYYY-MM-DD HH:mm:ss") }, { label: "操作", fixed: "right", - width: 240, + width: 210, slot: "operation" } ]; @@ -179,6 +192,7 @@ export function useRole() { }, width: "40%", draggable: true, + fullscreen: deviceDetection(), fullscreenIcon: true, closeOnClickModal: false, contentRenderer: () => h(editForm, { ref: formRef }), @@ -210,29 +224,92 @@ export function useRole() { } /** 菜单权限 */ - function handleMenu() { - message("等菜单管理页面开发后完善"); + async function handleMenu(row?: any) { + const { id } = row; + if (id) { + curRow.value = row; + isShow.value = true; + const { data } = await getRoleMenuIds({ id }); + treeRef.value.setCheckedKeys(data); + } else { + curRow.value = null; + isShow.value = false; + } + } + + /** 高亮当前权限选中行 */ + function rowStyle({ row: { id } }) { + return { + cursor: "pointer", + background: id === curRow.value?.id ? "var(--el-fill-color-light)" : "" + }; + } + + /** 菜单权限-保存 */ + function handleSave() { + const { id, name } = curRow.value; + // 根据用户 id 调用实际项目中菜单权限修改接口 + console.log(id, treeRef.value.getCheckedKeys()); + message(`角色名称为${name}的菜单权限修改成功`, { + type: "success" + }); } /** 数据权限 可自行开发 */ // function handleDatabase() {} - onMounted(() => { + const onQueryChanged = (query: string) => { + treeRef.value!.filter(query); + }; + + const filterMethod = (query: string, node) => { + return transformI18n(node.title)!.includes(query); + }; + + onMounted(async () => { onSearch(); + const { data } = await getRoleMenu(); + treeIds.value = getKeyList(data, "id"); + treeData.value = handleTree(data); + }); + + watch(isExpandAll, val => { + val + ? treeRef.value.setExpandedKeys(treeIds.value) + : treeRef.value.setExpandedKeys([]); + }); + + watch(isSelectAll, val => { + val + ? treeRef.value.setCheckedKeys(treeIds.value) + : treeRef.value.setCheckedKeys([]); }); return { form, + isShow, + curRow, loading, columns, + rowStyle, dataList, + treeData, + treeProps, + isLinkage, pagination, + isExpandAll, + isSelectAll, + treeSearchValue, // buttonClass, onSearch, resetForm, openDialog, handleMenu, + handleSave, handleDelete, + filterMethod, + transformI18n, + onQueryChanged, // handleDatabase, handleSizeChange, handleCurrentChange, diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index 8b97a28c1..0cfc100e7 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -32,6 +32,7 @@ const { selectedNum, pagination, buttonClass, + deviceDetection, onSearch, resetForm, onbatchDel, @@ -50,20 +51,22 @@ const {