diff --git a/.env b/.env
index 3a2e5ff..45ea218 100644
--- a/.env
+++ b/.env
@@ -1,4 +1,4 @@
-VITE_HOME_REDIRECT = '/env' # 默认路由
+VITE_HOME_REDIRECT = '/menu' # 默认路由
VITE_TITLE = '星撰玉衡' # 项目名称
VITE_BASE_URL = '/api' # 请求默认前缀
VITE_HTTP_TIMEOUT = 30000
diff --git a/src/api/Core/CoreDict/index.js b/src/api/Core/CoreDict/index.js
index 8d32e33..46b0bba 100644
--- a/src/api/Core/CoreDict/index.js
+++ b/src/api/Core/CoreDict/index.js
@@ -67,14 +67,13 @@ export const CoreDict = {
isTree: true,
dictKey: undefined
}) => {
- if(data.tree)
- return HTTP({
- method: 'get',
- url: `/coredict/details/${data.dictKey}`,
- params: {
- isTree: data.isTree
- }
- });
+ return HTTP({
+ method: 'get',
+ url: `/coredict/list/${data.dictKey}`,
+ params: {
+ isTree: data.isTree
+ }
+ });
},
/**
diff --git a/src/api/Core/CoreMenu/index.js b/src/api/Core/CoreMenu/index.js
new file mode 100644
index 0000000..60c1ff0
--- /dev/null
+++ b/src/api/Core/CoreMenu/index.js
@@ -0,0 +1,73 @@
+// | ------------------------------------------------------------
+// | @版本: version 0.1
+// | @创建人: 【Nie-x7129】
+// | @E-mail: x71291@outlook.com
+// | @所在项目: hoto-auth-vue3
+// | @文件描述: index.js -
+// | @创建时间: 2024-07-11 14:26
+// | @更新时间: 2024-07-11 14:26
+// | @修改记录:
+// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
+// | =
+// | ------------------------------------------------------------
+
+import HTTP from '@/api/http.js';
+import { PageData } from '@utils/DefaultData.js';
+
+export const CoreMenu = {
+ /**
+ * Name: createMenu
+ * Desc: 新增菜单
+ * Time: 2024-07-11 14:33:50 -
+ * */
+ createMenu: async (data) => {
+ return HTTP({
+ method: 'post',
+ url: '/coremenu',
+ data,
+ });
+ },
+
+ /**
+ * Name: getMenu
+ * Desc: 获取菜单的分页或列表
+ * Time: 2024-07-11 14:33:54 -
+ * */
+ getMenu: async (
+ params = {
+ ...PageData,
+ serviceInfo: undefined,
+ },
+ ) => {
+ return HTTP({
+ method: 'get',
+ url: '/coremenu',
+ params,
+ });
+ },
+
+ /**
+ * Name: removeMenu
+ * Desc: 删除菜单
+ * Time: 2024-07-11 14:33:59 -
+ * */
+ removeMenu: async (menuId) => {
+ return HTTP({
+ method: 'delete',
+ url: `/coremenu/${menuId}`,
+ });
+ },
+
+ /**
+ * Name: updateMenu
+ * Desc: 编辑菜单
+ * Time: 2024-07-11 14:34:03 -
+ * */
+ updateMenu: async (menuId, data) => {
+ return HTTP({
+ method: 'patch',
+ url: `/coremenu/${menuId}`,
+ data,
+ });
+ },
+};
diff --git a/src/api/index.js b/src/api/index.js
index 9732ad3..4f6caea 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -15,5 +15,6 @@ import { DefaultSign } from '@/api/Auth/AuthUser/index.js';
import { CoreService } from '@/api/Core/CoreService/index.js';
import { CoreDict } from '@/api/Core/CoreDict/index.js';
import { CoreEnv } from '@/api/Core/CoreEnv/index.js';
+import { CoreMenu } from '@/api/Core/CoreMenu/index.js';
-export { Sign, DefaultSign, CoreService, CoreDict, CoreEnv };
+export { Sign, DefaultSign, CoreService, CoreDict, CoreEnv, CoreMenu };
diff --git a/src/components/AntDesignVue/CustomAntDesignVue/TablePagination/index.vue b/src/components/AntDesignVue/CustomAntDesignVue/TablePagination/index.vue
new file mode 100644
index 0000000..44eac12
--- /dev/null
+++ b/src/components/AntDesignVue/CustomAntDesignVue/TablePagination/index.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/src/components/AntDesignVue/CustomAntDesignVue/index.js b/src/components/AntDesignVue/CustomAntDesignVue/index.js
index 2e58424..822241d 100644
--- a/src/components/AntDesignVue/CustomAntDesignVue/index.js
+++ b/src/components/AntDesignVue/CustomAntDesignVue/index.js
@@ -13,12 +13,13 @@
import CreateAntdButton from './Button/CreateAntdButton.vue';
import AckCreateAntdButton from './Button/AckCreateAntdButton.vue';
-import AntdModalTemplate from './AntdModalTemplate/index.vue';
+import TableRemoveButton from './Button/TableRemoveButton.vue';
+import TableUpdateButton from './Button/TableUpdateButton.vue';
import IconSelect from './IconSelect/index.vue';
+import AntdModalTemplate from './AntdModalTemplate/index.vue';
import CustomIconSelect from './IconSelect/customIconSelect.vue';
-import TableColumChoose from '@/components/AntDesignVue/CustomAntDesignVue/TableColumChoose/index.vue';
-import TableRemoveButton from '@/components/AntDesignVue/CustomAntDesignVue/Button/TableRemoveButton.vue';
-import TableUpdateButton from '@/components/AntDesignVue/CustomAntDesignVue/Button/TableUpdateButton.vue';
+import TableColumChoose from './TableColumChoose/index.vue';
+import TablePagination from './TablePagination/index.vue';
// console.log(AntdModalTemplate);
@@ -30,7 +31,7 @@ export default function setupCustomAntdComponents(app) {
AntdModalTemplate,
IconSelect,
CustomIconSelect,
- TableColumChoose,TableRemoveButton,TableUpdateButton
+ TableColumChoose,TableRemoveButton,TableUpdateButton,TablePagination
];
for (let component of customComponentList) {
app.component(component.name, component);
diff --git a/src/router/index.js b/src/router/index.js
index e8acbd7..870e3be 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -45,7 +45,7 @@ export default function createRoutering() {
title: '菜单管理',
icon: ''
},
- component: () => import('@/views/Auth/Menu/index.vue')
+ component: () => import('@/views/Auth/Menu/MenuPage.vue')
},
{
path: '/env',
diff --git a/src/stores/baseData.js b/src/stores/baseData.js
index fedeb61..c3a4bf8 100644
--- a/src/stores/baseData.js
+++ b/src/stores/baseData.js
@@ -13,7 +13,7 @@
import { defineStore } from 'pinia';
import { computed, reactive } from 'vue';
-import { CoreDict, CoreEnv, CoreService } from '@/api/index.js';
+import { CoreDict, CoreEnv, CoreMenu, CoreService } from '@/api/index.js';
export const useBaseDataStore = defineStore('baseData', () => {
const state = reactive({
@@ -38,6 +38,15 @@ export const useBaseDataStore = defineStore('baseData', () => {
envList: [],
// ! 环境变量树
envTree: [],
+ // ! 菜单列表
+ menuList: [],
+ // ! 菜单树
+ menuTree: [],
+ // ! 菜单类型列表
+ menuTypeList: [],
+ // ! 菜单类型树
+ menuTypeTree: [],
+
// ! 防抖
// 防抖获取服务列表
canGetServiceList: true,
@@ -45,9 +54,13 @@ export const useBaseDataStore = defineStore('baseData', () => {
canGetDictList: true,
// 防抖获取env列表
canGetEnvList: true,
+ // 防抖获取menu列表
+ canGetMenuList: true,
+ // 防抖获取菜单Menu类型列表
+ canGetMenuTypeList: true,
});
- // 获取服务列表
+ // ! 获取服务列表
async function getServiceList(serviceInfo = undefined) {
if (!state.canGetServiceList) return;
state.canGetServiceList = false;
@@ -61,7 +74,7 @@ export const useBaseDataStore = defineStore('baseData', () => {
state.serviceList = resd;
}
- // 获取字典列表
+ // ! 获取字典列表
const getDictList = async (dictInfo = undefined) => {
if (!state.canGetDictList) return;
state.canGetDictList = false;
@@ -76,6 +89,7 @@ export const useBaseDataStore = defineStore('baseData', () => {
const [list] = getDictTree(resd);
state.dictTree = list;
};
+
// ! 获取Env列表
const getEnvList = async (envInfo = undefined) => {
if (!state.canGetEnvList) return;
@@ -86,17 +100,59 @@ export const useBaseDataStore = defineStore('baseData', () => {
const resd = await CoreEnv.getEnv({
...envInfo,
isList: true,
- })
+ });
state.envList = resd;
const [list] = getEnvTree(resd);
state.envTree = list;
};
+ // ! 获取菜单列表
+ const getMenuList = async (menuInfo = undefined) => {
+ if (!state.canGetMenuList) return;
+ state.canGetMenuList = false;
+ setTimeout(() => {
+ state.canGetMenuList = true;
+ }, 2000);
+ const resd = await CoreMenu.getMenu({
+ ...menuInfo,
+ isList: true,
+ });
+ state.menuList = resd;
+ const [list, otherList] = getMenuTree(resd);
+ list.push({
+ meta: {},
+ label: '其他菜单',
+ value: '-1',
+ id: '-1',
+ disabled: true,
+ children: otherList,
+ });
+ state.menuTree = list;
+ };
+
+ // ! 获取菜单类型
+ const getMenuTypeList = async () => {
+ if (!state.canGetMenuTypeList) return;
+ state.canGetMenuTypeList = false;
+ setTimeout(() => {
+ state.canGetMenuTypeList = true;
+ }, 2000);
+ // ! todo MenuType时固定字段,初始字典
+ const resd = await CoreDict.getDictTree({
+ dictKey: 'MenuType',
+ isTree: true,
+ });
+ state.menuTypeList = resd;
+ const [list] = getDictTree(resd);
+ state.menuTypeTree = Array.isArray(list) && list.length > 0 ? list[0].children : [];
+ };
return {
state,
getServiceList,
getDictList,
- getEnvList
+ getEnvList,
+ getMenuList,
+ getMenuTypeList,
};
});
@@ -149,3 +205,28 @@ function getEnvTree(list, pid = 0) {
}
return [newList, noList];
}
+
+// ! 格式化Menu树
+function getMenuTree(list, pid = 0) {
+ const newList = [];
+ let noList = [];
+ for (let i in list) {
+ const obj = list[i];
+ if (obj.pid == pid) {
+ newList.push({
+ meta: { ...obj },
+ label: obj.menuName,
+ value: obj.menuId,
+ id: obj.menuId,
+ });
+ } else {
+ noList.push(obj);
+ }
+ }
+ for (let obj of newList) {
+ const [children, ls] = getMenuTree(noList, obj.id);
+ obj.children = children;
+ noList = ls;
+ }
+ return [newList, noList];
+}
diff --git a/src/views/Auth/Dict/index.vue b/src/views/Auth/Dict/index.vue
index f879178..dcec82d 100644
--- a/src/views/Auth/Dict/index.vue
+++ b/src/views/Auth/Dict/index.vue
@@ -187,7 +187,7 @@ function clearFormData() {
formData.formData.dictDesc = '';
formData.formData.dictName = '';
formData.formData.dictIcon = '';
- formData.formData.dictType = 1;
+ formData.formData.dictType = '1';
formData.formData.serviceKey = undefined;
formData.formData.root = false;
formData.formData.orderNum = 0;
diff --git a/src/views/Auth/Env/DataModal.js b/src/views/Auth/Env/DataModal.js
index c9cead7..1af6698 100644
--- a/src/views/Auth/Env/DataModal.js
+++ b/src/views/Auth/Env/DataModal.js
@@ -18,14 +18,23 @@ import { h } from 'vue';
export class EnvFormType {
constructor() {
return new Object({
+ // 上级变量
pid: 0,
+ // 变量名
envName: '',
+ // 变量标识
envKey: '',
+ // 变量值
envVal: '',
+ // 变量值来源于字典
valIsDict: 0,
+ // 变量描述
envDesc: '',
+ // 是否是原始数据
root: 0,
+ // 排序
orderNum: 0,
+ // 所属服务
serviceKey: undefined,
});
}
@@ -35,14 +44,23 @@ export class EnvFormType {
export class EnvSearchType {
constructor() {
return new Object({
+ // 每页数量
pageSize: 10,
+ // 页码
pageNumber: 1,
+ // 是否是列表
isList: false,
+ // 排序方式
isAsc: false,
+ // 变量信息
envInfo: undefined,
+ // 是否是原始数据
root: undefined,
+ // 所属服务
serviceKey: undefined,
+ // 状态
status: undefined,
+ // 根据pid查
hierarchy: [],
});
}
diff --git a/src/views/Auth/Env/EnvForm.vue b/src/views/Auth/Env/EnvForm.vue
index d82390d..ac54fe9 100644
--- a/src/views/Auth/Env/EnvForm.vue
+++ b/src/views/Auth/Env/EnvForm.vue
@@ -3,7 +3,6 @@ import { EnvFormRulesType, EnvFormType } from '@/views/Auth/Env/DataModal.js';
import { h, onMounted, ref, watch } from 'vue';
import { ReloadOutlined, SettingOutlined } from '@ant-design/icons-vue';
import { useBaseDataStore } from '@/stores';
-import AntdModalTemplate from '@/components/AntDesignVue/CustomAntDesignVue/AntdModalTemplate/index.vue';
const baseDataStore = useBaseDataStore();
defineOptions({
diff --git a/src/views/Auth/Env/EnvPage.vue b/src/views/Auth/Env/EnvPage.vue
index 20f0ed2..9e33b38 100644
--- a/src/views/Auth/Env/EnvPage.vue
+++ b/src/views/Auth/Env/EnvPage.vue
@@ -7,7 +7,6 @@ import EnvTree from './EnvTree.vue';
import { CoreEnv } from '@/api/index.js';
import { useMessage } from 'naive-ui';
import { useBaseDataStore } from '@/stores/baseData.js';
-import DictTable from '@/views/Auth/Dict/DictTable.vue';
const baseDataStore = useBaseDataStore();
const Message = useMessage();
defineOptions({
@@ -52,6 +51,7 @@ const tableData = reactive({
handleRemoveAck,
handleUpdate,
},
+ handlePageChange,
columnList: new EnvTableColumnChooseType(),
});
// @1确认添加
@@ -97,18 +97,19 @@ async function handleUpdateAck(data) {
}
// @5监听筛选 todo
watch(tableData.pageInfo, () => {
+ getPage();
+});
+// @6获取表格数据
+async function getPage() {
if (searchCount === 0) {
searchCount++;
- getPage();
setTimeout(() => {
searchCount = 0;
- }, 750);
+ }, 500);
} else {
searchCount++;
+ return;
}
-});
-// @6获取表格数据
-async function getPage() {
const pageInfo = {...tableData.pageInfo};
pageInfo.hierarchy = pageInfo.hierarchy.length > 0 ? pageInfo.hierarchy[0] : undefined;
const resd = await CoreEnv.getEnv(pageInfo);
@@ -116,11 +117,10 @@ async function getPage() {
tableData.total = Number(resd.total);
}
// @7页码变动
-const handlePageChange = (page, pageSize) => {
+function handlePageChange(page, pageSize) {
tableData.pageInfo.pageSize = pageSize;
tableData.pageInfo.pageNumber = page;
- getPage();
-};
+}
// @7表格筛选变动
function handleTableChange(page, filter, sorter) {
if (sorter.order == 'ascend') {
@@ -190,16 +190,7 @@ function clearFormData() {
-
+
diff --git a/src/views/Auth/Menu/DataModal.js b/src/views/Auth/Menu/DataModal.js
new file mode 100644
index 0000000..31e014f
--- /dev/null
+++ b/src/views/Auth/Menu/DataModal.js
@@ -0,0 +1,212 @@
+// | ------------------------------------------------------------
+// | @版本: version 0.1
+// | @创建人: 【Nie-x7129】
+// | @E-mail: x71291@outlook.com
+// | @所在项目: hoto-auth-vue3
+// | @文件描述: dataModal.js -
+// | @创建时间: 2024-07-09 14:47
+// | @更新时间: 2024-07-09 14:47
+// | @修改记录:
+// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
+// | =
+// | ------------------------------------------------------------
+
+import { IconPool } from '@/components/AntDesignVue/Icon/index.js';
+import { h } from 'vue';
+
+export class MenuFormType {
+ constructor() {
+ return new Object({
+ // 上级菜单
+ pid: undefined,
+ // 接口路径
+ apiPath: '',
+ // 页面路由
+ webPath: '',
+ // 页面组件路径
+ webComponentPath: '',
+ // 菜单名称
+ menuName: '',
+ // 菜单描述
+ menuDesc: '',
+ // 菜单类型
+ menuType: undefined,
+ // 菜单图标
+ menuIcon: undefined,
+ // 是否链接到外部
+ isFrame: 0,
+ // 是否可见
+ isVisible: 1,
+ // 是否激活
+ isActivate: 1,
+ // 排序
+ orderNum: 0,
+ // 所属服务
+ serviceOf: undefined,
+ });
+ }
+}
+
+// 查询数据
+export class MenuSearchType {
+ constructor() {
+ return new Object({
+ // 每页数量
+ pageSize: 10,
+ // 页码
+ pageNumber: 1,
+ // 是否是列表
+ isList: false,
+ // 排序方式
+ isAsc: false,
+ // 菜单信息
+ menuInfo: undefined,
+ // 菜单类型
+ menuType: undefined,
+ // 是否链接到外部
+ isFrame: undefined,
+ // 是否可见
+ isVisible: undefined,
+ // 是否激活
+ isActivate: undefined,
+ // 是否是原始数据
+ root: undefined,
+ // 所属服务
+ serviceKey: undefined,
+ // 状态
+ status: undefined,
+ // 根据pid查
+ hierarchy: [],
+ });
+ }
+}
+
+// 表单规则
+export class MenuFormRulesType {
+ constructor() {
+ return new Object({});
+ }
+}
+
+// Env表格列数据
+export class MenuTableColumnType {
+ constructor() {
+ return new Object({
+ index: {
+ title: '序号',
+ key: 'index',
+ width: 70, // 你可以根据需要设置列宽
+ customRender: ({ text, record, index, column }) => `${index + 1}`, // 使用索引 + 1 来显示序号
+ },
+ menuName: {
+ title: '菜单名称',
+ dataIndex: 'menuName',
+ key: 'menuName',
+ },
+ menuIcon: {
+ title: '图标',
+ dataIndex: 'menuIcon',
+ customRender: ({ text, record, index, column }) => (text && IconPool[text] ? h(IconPool[text], { style: { fontSize: '20px' } }) : h('div', text)),
+ key: 'menuIcon',
+ },
+ menuType: {
+ title: '类型',
+ dataIndex: 'menuType',
+ key: 'menuType',
+ customRender: ({ text, record, index, column }) => record.menuTypeName,
+ },
+ apiPath: {
+ title: '接口路径',
+ dataIndex: 'apiPath',
+ key: 'apiPath',
+ },
+ // 页面路由
+ webPath: {
+ title: '页面路由',
+ dataIndex: 'webPath',
+ key: 'webPath',
+ },
+ // 页面组件路径
+ webComponentPath: {
+ title: '组件路径',
+ dataIndex: 'webComponentPath',
+ key: 'webComponentPath',
+ },
+ isFrame: {
+ title: '外链',
+ dataIndex: 'isFrame',
+ key: 'isFrame',
+ customRender: ({ text, record, index, column }) => (text == '1' ? '是' : '否'),
+ },
+ isVisible: {
+ title: '可见',
+ dataIndex: 'isVisible',
+ key: 'isVisible',
+ customRender: ({ text, record, index, column }) => (text == '1' ? '是' : '否'),
+ },
+ isActivate: {
+ title: '激活',
+ dataIndex: 'isActivate',
+ key: 'isActivate',
+ customRender: ({ text, record, index, column }) => (text == '1' ? '是' : '否'),
+ },
+ serviceKey: {
+ title: '所属服务',
+ dataIndex: 'serviceKey',
+ key: 'serviceKey',
+ customRender: ({ text, record, index, column }) => record.serviceName,
+ },
+ haveChildren: {
+ title: '子项',
+ dataIndex: 'haveChildren',
+ key: 'haveChildren',
+ width: '50px',
+ },
+ createtime: {
+ title: '创建时间',
+ dataIndex: 'createtime',
+ key: 'createtime',
+ width: '140px',
+ sorter: true,
+ },
+ createName: {
+ title: '创建人',
+ dataIndex: 'createName',
+ key: 'createName',
+ },
+ updatetime: {
+ title: '更新时间',
+ dataIndex: 'updatetime',
+ key: 'updatetime',
+ maxWidth: '140px',
+ minWidth: '140px',
+ },
+ updateName: {
+ title: '更新人',
+ dataIndex: 'updateName',
+ key: 'updateName',
+ },
+ action: {
+ title: '操作',
+ dataIndex: 'action',
+ key: 'action',
+ width: 100,
+ align: 'center',
+ },
+ });
+ }
+}
+
+
+// Env可选表格列
+export class MenuTableColumnChooseType {
+ constructor() {
+ const excludeColumn = ['updateName', 'updatetime', 'createName'];
+ const tableColumn = new MenuTableColumnType();
+ return Object.keys(tableColumn).map((i) => ({
+ title: tableColumn[i].title,
+ key: tableColumn[i].key,
+ status: excludeColumn.includes(i) ? false : true,
+ }));
+ }
+}
diff --git a/src/views/Auth/Menu/MenuForm.vue b/src/views/Auth/Menu/MenuForm.vue
index 5dead0d..aaed6e9 100644
--- a/src/views/Auth/Menu/MenuForm.vue
+++ b/src/views/Auth/Menu/MenuForm.vue
@@ -1,9 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是
+ 否
+
+
+
+
+
+ 是
+ 否
+
+
+
+
+
+ 是
+ 否
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+
+
+
diff --git a/src/views/Auth/Menu/MenuTable.vue b/src/views/Auth/Menu/MenuTable.vue
index e3d139e..96e0cc8 100644
--- a/src/views/Auth/Menu/MenuTable.vue
+++ b/src/views/Auth/Menu/MenuTable.vue
@@ -1,19 +1,64 @@
+
-
-
+
+
-
+
diff --git a/src/views/Auth/Menu/MenuTree.vue b/src/views/Auth/Menu/MenuTree.vue
new file mode 100644
index 0000000..5a97387
--- /dev/null
+++ b/src/views/Auth/Menu/MenuTree.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
diff --git a/src/views/Auth/Menu/dataModal.js b/src/views/Auth/Menu/dataModal.js
deleted file mode 100644
index 07b73e1..0000000
--- a/src/views/Auth/Menu/dataModal.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// | ------------------------------------------------------------
-// | @版本: version 0.1
-// | @创建人: 【Nie-x7129】
-// | @E-mail: x71291@outlook.com
-// | @所在项目: hoto-auth-vue3
-// | @文件描述: dataModal.js -
-// | @创建时间: 2024-07-09 14:47
-// | @更新时间: 2024-07-09 14:47
-// | @修改记录:
-// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
-// | =
-// | ------------------------------------------------------------
-
-export const formType = new Object({
-
-})
diff --git a/src/views/Auth/Menu/index.vue b/src/views/Auth/Menu/index.vue
deleted file mode 100644
index 0a3752f..0000000
--- a/src/views/Auth/Menu/index.vue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-