Browse Source

左侧菜单动态修改

wangwei 4 years ago
parent
commit
b0b58f2369
40 changed files with 363 additions and 324 deletions
  1. 38 0
      src/api/sys/general.ts
  2. 1 1
      src/api/sys/menu.ts
  3. 27 0
      src/api/sys/model/generalModel.ts
  4. 1 1
      src/api/sys/model/userModel.ts
  5. 14 5
      src/api/sys/user.ts
  6. 0 1
      src/components/Table/src/BasicTable.vue
  7. 5 1
      src/components/Table/src/hooks/useDataSource.ts
  8. 11 2
      src/hooks/web/usePermission.ts
  9. 2 2
      src/locales/lang/en/routes/admin.ts
  10. 2 2
      src/locales/lang/zh_CN/routes/admin.ts
  11. 6 6
      src/router/menus/modules/permission.ts
  12. 1 1
      src/settings/projectSetting.ts
  13. 31 1
      src/store/modules/permission.ts
  14. 2 2
      src/utils/validTools.ts
  15. 0 0
      src/views/admin/admin/data.ts
  16. 4 4
      src/views/admin/admin/index.vue
  17. 0 0
      src/views/admin/admin/popup.vue
  18. 0 0
      src/views/admin/group/data.ts
  19. 4 4
      src/views/admin/group/index.vue
  20. 0 0
      src/views/admin/group/popup.vue
  21. 0 0
      src/views/admin/logs/data.ts
  22. 3 3
      src/views/admin/logs/index.vue
  23. 0 0
      src/views/admin/logs/popup.vue
  24. 18 112
      src/views/admin/rule/data.ts
  25. 21 15
      src/views/admin/rule/index.vue
  26. 16 23
      src/views/admin/rule/popup.vue
  27. 2 5
      src/views/general/config/customComponents/ArrayCom.vue
  28. 0 0
      src/views/general/config/customComponents/Checkbox.vue
  29. 0 0
      src/views/general/config/customComponents/DatePicker.vue
  30. 0 0
      src/views/general/config/customComponents/Input.vue
  31. 0 0
      src/views/general/config/customComponents/InputNumber.vue
  32. 0 0
      src/views/general/config/customComponents/InputTextArea.vue
  33. 68 0
      src/views/general/config/customComponents/MultipleSelect.vue
  34. 0 0
      src/views/general/config/customComponents/Radio.vue
  35. 0 2
      src/views/general/config/customComponents/Select.vue
  36. 0 0
      src/views/general/config/customComponents/Switch.vue
  37. 0 0
      src/views/general/config/customComponents/TimePicker.vue
  38. 22 14
      src/views/general/config/data.ts
  39. 64 117
      src/views/general/config/index.vue
  40. 0 0
      src/views/general/person/index.vue

+ 38 - 0
src/api/sys/general.ts

@@ -0,0 +1,38 @@
+import { defHttp } from '/@/utils/http/axios';
+import { CommonRowModel, GroupModel, AddConfigInfoParams } from './model/generalModel';
+
+enum Api {
+  GroupUrl = 'general/group/', // 系统配置分组
+  ConfigUrl = 'general/config/', // 系统配置表
+  FileUrl = 'general/file/', // 上传文件
+}
+
+/**
+ * @description: 获取系统配置分组
+ */
+export function getConfigGroup() {
+  return defHttp.request<GroupModel>({
+    url: Api.GroupUrl,
+    method: 'GET',
+  });
+}
+
+/**
+ * @description: 获取系统配置表
+ */
+export function getConfigInfo() {
+  return defHttp.request<CommonRowModel>({
+    url: Api.ConfigUrl,
+    method: 'GET',
+  });
+}
+/**
+ * @description: 获取系统配置表
+ */
+export function addConfigInfo(params: AddConfigInfoParams) {
+  return defHttp.request<CommonRowModel>({
+    url: Api.ConfigUrl,
+    method: 'POST',
+    params,
+  });
+}

+ 1 - 1
src/api/sys/menu.ts

@@ -2,7 +2,7 @@ import { defHttp } from '/@/utils/http/axios';
 import { getMenuListResultModel } from './model/menuModel';
 
 enum Api {
-  GetMenuList = '/menu/',
+  GetMenuList = 'admin/menu/',
 }
 
 /**

+ 27 - 0
src/api/sys/model/generalModel.ts

@@ -0,0 +1,27 @@
+/**
+ * @description: Get common information return value
+ */
+export interface CommonRowModel {
+  row: object[];
+}
+
+/**
+ * @description: Get group information return value
+ */
+export interface GroupModel {
+  group: object[];
+}
+
+/**
+ * @description: 添加系统配置参数
+ */
+export interface AddConfigInfoParams {
+  type: string;
+  group: string;
+  name: string;
+  title: string;
+  tip?: string;
+  value?: string;
+  rule?: string;
+  expend?: string;
+}

+ 1 - 1
src/api/sys/model/userModel.ts

@@ -158,5 +158,5 @@ export interface RuleIdParams {
 }
 
 export interface DeleteBatchesParams {
-  id: string | string[] | number[];
+  ids: string | string[] | number[];
 }

+ 14 - 5
src/api/sys/user.ts

@@ -22,11 +22,11 @@ import {
 import { ErrorMessageMode } from '/@/utils/http/axios/types';
 
 enum Api {
-  LoginUrl = '/login',
-  AdminUrl = '/',
-  GroupUrl = '/group/',
-  RuleUrl = '/rule/',
-  MenuUrl = '/menu/', // 允许访问的规则 <pid>
+  LoginUrl = 'admin/login',
+  AdminUrl = 'admin/',
+  GroupUrl = 'admin/group/',
+  RuleUrl = 'admin/rule/',
+  MenuUrl = 'admin/menu/',
 }
 
 /**
@@ -180,6 +180,15 @@ export function getRuleById(params: RuleIdParams) {
     method: 'GET',
   });
 }
+
+// //获取左侧菜单路由
+// export function getMenuList() {
+//   return defHttp.request<getGroupTreeModel>({
+//     url: Api.MenuUrl,
+//     method: 'GET',
+//   });
+// }
+
 //请求允许访问的规则 params 角色组pid
 export function getAllowRule(params: RuleIdParams) {
   return defHttp.request<getGroupTreeModel>({

+ 0 - 1
src/components/Table/src/BasicTable.vue

@@ -298,7 +298,6 @@
       // 初始化 sortable 实现拖动
       function initSortable() {
         const el = document.querySelector('.mytable tbody') as any;
-        console.log(el);
         Sortable.create(el, {
           handle: '.ant-table-row',
           sort: true, // boolean 定义是否列表单元是否可以在列表容器内进行拖拽排序

+ 5 - 1
src/components/Table/src/hooks/useDataSource.ts

@@ -221,8 +221,9 @@ export function useDataSource(
 
       console.log('=======api - params ======');
       const res_data = await api(params);
-      const res = res_data.list || res_data.tree;
+      const res = res_data.list || res_data.tree || res_data.row;
       console.log('=====表格 api ==========');
+      console.log(`res`, res);
       console.log(res_data);
       console.log(params);
 
@@ -231,6 +232,9 @@ export function useDataSource(
       const isArrayResult = Array.isArray(res);
 
       let resultItems: Recordable[] = isArrayResult ? res : get(res, listField);
+      if (!resultItems) {
+        resultItems = res;
+      }
       const resultTotal: number = isArrayResult ? 0 : get(res, totalField);
 
       // 假如数据变少,导致总页数变少并小于当前选中页码,通过getPaginationRef获取到的页码是不正确的,需获取正确的页码再次执行

+ 11 - 2
src/hooks/web/usePermission.ts

@@ -106,8 +106,17 @@ export function usePermission() {
    * refresh menu data
    */
   async function refreshMenu() {
-    resume();
+    await resume();
+  }
+
+  /**
+   * refresh menu data
+   */
+  async function reloadMenu() {
+    const path = router.currentRoute.value.path;
+    await resume();
+    router.push(path);
   }
 
-  return { changeRole, hasPermission, togglePermissionMode, refreshMenu };
+  return { changeRole, hasPermission, togglePermissionMode, refreshMenu, reloadMenu };
 }

+ 2 - 2
src/locales/lang/en/routes/permission.ts → src/locales/lang/en/routes/admin.ts

@@ -1,6 +1,6 @@
 export default {
-  management: 'permission',
-  admin: 'admin',
+  admin: 'permission',
+  index: 'admin',
   logs: 'admin log',
   group: 'group',
   rule: 'rule',

+ 2 - 2
src/locales/lang/zh_CN/routes/permission.ts → src/locales/lang/zh_CN/routes/admin.ts

@@ -1,6 +1,6 @@
 export default {
-  management: '权限管理',
-  admin: '管理员管理',
+  admin: '权限管理',
+  index: '管理员管理',
   logs: '管理员日志',
   group: '角色组',
   rule: '菜单规则',

+ 6 - 6
src/router/menus/modules/permission.ts

@@ -4,24 +4,24 @@ import { t } from '/@/hooks/web/useI18n';
 const menu: MenuModule = {
   orderNo: 1,
   menu: {
-    path: '/permission',
-    name: t('routes.permission.management'),
+    path: '/admin',
+    name: t('routes.admin.admin'),
     children: [
       {
         path: 'admin',
-        name: t('routes.permission.admin'),
+        name: t('routes.admin.index'),
       },
       {
         path: 'logs',
-        name: t('routes.permission.logs'),
+        name: t('routes.admin.logs'),
       },
       {
         path: 'group',
-        name: t('routes.permission.group'),
+        name: t('routes.admin.group'),
       },
       {
         path: 'rule',
-        name: t('routes.permission.rule'),
+        name: t('routes.admin.rule'),
         tag: {
           type: 'success',
           content: '菜单',

+ 1 - 1
src/settings/projectSetting.ts

@@ -23,7 +23,7 @@ const setting: ProjectConfig = {
   settingButtonPosition: SettingButtonPositionEnum.AUTO,
 
   // Permission mode ROLE--前端权限 BACK--后端权限
-  permissionMode: PermissionModeEnum.ROLE,
+  permissionMode: PermissionModeEnum.BACK,
 
   // Permission-related cache is stored in sessionStorage or localStorage
   permissionCacheType: CacheTypeEnum.LOCAL,

+ 31 - 1
src/store/modules/permission.ts

@@ -121,7 +121,37 @@ export const usePermissionStore = defineStore({
         try {
           // this.changePermissionCode();
           routeList = (await getMenuList()).tree as AppRouteRecordRaw[]; //请求后端路由菜单数组
-          console.log(`routeList`, routeList);
+          // 默认路由
+          const dashboard = {
+            path: '/dashboard',
+            name: 'Dashboard',
+            component: 'LAYOUT',
+            redirect: '/dashboard/analysis',
+            meta: {
+              icon: 'ion:grid-outline',
+              title: 'routes.dashboard.dashboard',
+            },
+            children: [
+              {
+                path: 'analysis',
+                name: 'Analysis',
+                component: '/dashboard/analysis/index',
+                meta: {
+                  affix: true,
+                  title: 'routes.dashboard.analysis',
+                },
+              },
+              {
+                path: 'workbench',
+                name: 'Workbench',
+                component: '/dashboard/workbench/index',
+                meta: {
+                  title: 'routes.dashboard.workbench',
+                },
+              },
+            ],
+          };
+          routeList.unshift(dashboard);
           console.log(`routeList==tree`, routeList);
         } catch (error) {
           console.error(error);

+ 2 - 2
src/utils/validTools.ts

@@ -21,7 +21,7 @@ const regexEnum = {
   zipcode: '^\\d{6}$', // 邮编
   mobile: '^(13|15|18|14)[0-9]{9}$', // 手机
   ip4: '^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$', // ip地址
-  require: '^\\S+$', // 非空
+  required: '^\\S+$', // 非空
   picture: '(.*)\\.(jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$', // 图片
   jpg: '(.*)\\.(jpg|gif)$', // 图片
   rar: '(.*)\\.(rar|zip|7zip|tgz)$', // 压缩文件
@@ -40,7 +40,7 @@ const regexEnum = {
   uploadFile: '(.*)\\.(jpg|bmp|gif|png|jpeg|tif|pdf|doc|docx|xls|xlsx|ppt|pptx)$', // 图片
 };
 const errMsg = {
-  require: '必填',
+  required: '必填',
   digits: '请填写数字',
   letters: '请填写字母',
   date: '日期格式错误:YYYY-MM-DD',

+ 0 - 0
src/views/permission/admin/data.ts → src/views/admin/admin/data.ts


+ 4 - 4
src/views/permission/admin/index.vue → src/views/admin/admin/index.vue

@@ -22,7 +22,7 @@
     >
       <template #toolbar>
         <a-button type="primary" @click="addRole"> 添加 </a-button>
-        <a-button type="danger" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
+        <a-button color="error" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
         <a-button @click="openModal"> 导出 </a-button>
       </template>
       <template #form-custom> custom-slot </template>
@@ -215,11 +215,11 @@
       }
 
       async function deleteBatches() {
-        const id = getTableAction().getSelectRowKeys().toString();
-        if (!id) {
+        const ids = getTableAction().getSelectRowKeys().toString();
+        if (!ids) {
           return;
         }
-        await deleteBatchesUser({ id }).then((res) => {
+        await deleteBatchesUser({ ids }).then((res) => {
           console.log(res);
           getTableAction().reload();
           success('删除成功!');

+ 0 - 0
src/views/permission/admin/popup.vue → src/views/admin/admin/popup.vue


+ 0 - 0
src/views/permission/group/data.ts → src/views/admin/group/data.ts


+ 4 - 4
src/views/permission/group/index.vue → src/views/admin/group/index.vue

@@ -18,7 +18,7 @@
       <template #toolbar>
         <a-button type="primary" @click="toggleRowShow">{{ btn_text }}</a-button>
         <a-button type="primary" @click="addGroupFn"> 添加 </a-button>
-        <a-button type="danger" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
+        <a-button color="error" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
         <a-button @click="openModal"> 导出 </a-button>
       </template>
       <template #action="{ record, column }">
@@ -183,11 +183,11 @@
       }
 
       async function deleteBatches() {
-        const id = getTableAction().getSelectRowKeys().toString();
-        if (!id) {
+        const ids = getTableAction().getSelectRowKeys().toString();
+        if (!ids) {
           return;
         }
-        await deleteBatchesGroup({ id }).then((res) => {
+        await deleteBatchesGroup({ ids }).then((res) => {
           console.log(res);
           getTableAction().reload();
           ExpandAllRows();

+ 0 - 0
src/views/permission/group/popup.vue → src/views/admin/group/popup.vue


+ 0 - 0
src/views/permission/admin_log/data.ts → src/views/admin/logs/data.ts


+ 3 - 3
src/views/permission/admin_log/index.vue → src/views/admin/logs/index.vue

@@ -6,7 +6,7 @@
     helpMessage="管理员可以查看自己所拥有的权限的管理员日志"
     ><BasicTable ref="tableRef" @register="registerTable" rowKey="id" @rowDbClick="handleDetail">
       <template #toolbar>
-        <a-button type="danger" @click="deleteA"> 删除 </a-button>
+        <a-button color="error" @click="deleteA"> 删除 </a-button>
         <a-button type="primary" @click="openModal"> 导出 </a-button>
       </template>
       <template #action="{ record, column }">
@@ -74,7 +74,7 @@
       const popupData = reactive({
         title: '详情',
       });
-      const { refreshMenu } = usePermission();
+      const { reloadMenu } = usePermission();
       const [register, { openModal }] = useModal();
       const [registerTable] = useTable({
         // title: '管理员日志',
@@ -151,7 +151,7 @@
       }
       function deleteA() {
         // document.location.reload();
-        refreshMenu();
+        reloadMenu();
       }
 
       function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {

+ 0 - 0
src/views/permission/admin_log/popup.vue → src/views/admin/logs/popup.vue


+ 18 - 112
src/views/permission/rule/data.ts → src/views/admin/rule/data.ts

@@ -5,116 +5,11 @@ import { FormSchema } from '/@/components/Form/index';
 import { Icon } from '/@/components/Icon';
 import { adapt } from '/@/utils/adapt';
 import { editRule } from '/@/api/sys/user';
+import { usePermission } from '/@/hooks/web/usePermission';
 
+const { reloadMenu } = usePermission();
 const adaptWidth = adapt();
 
-export const fakeTree = [
-  {
-    id: 1,
-    title: 'Dashboard',
-    status: true,
-    icon: 'ion:layers-outline',
-    create_time: '2021-01-01',
-    detail: '',
-    children: [
-      {
-        id: 2,
-        title: '工作台',
-        status: true,
-        icon: 'ion:git-compare-outline',
-        create_time: '2021-01-01',
-        detail: '',
-        children: [
-          {
-            id: 8,
-            title: '天然光',
-            status: true,
-            icon: 'ion:git-compare-outline',
-            create_time: '2021-01-01',
-            detail: '',
-          },
-          {
-            id: 9,
-            title: '小苏打粉',
-            status: false,
-            icon: 'ion:tv-outline',
-            create_time: '2021-01-01',
-            detail: '',
-          },
-          {
-            id: 22,
-            title: '士大夫',
-            status: true,
-            icon: 'ion:git-compare-outline',
-            create_time: '2021-01-01',
-            detail: '',
-          },
-          {
-            id: 95,
-            title: '小苏打粉',
-            status: false,
-            icon: 'ion:tv-outline',
-            create_time: '2021-01-01',
-            detail: '',
-          },
-        ],
-      },
-      {
-        id: 3,
-        title: '分析页',
-        status: false,
-        icon: 'ion:tv-outline',
-        create_time: '2021-01-01',
-        detail: '',
-        children: [
-          {
-            id: 10,
-            title: '略略略',
-            status: true,
-            icon: 'ion:git-compare-outline',
-            create_time: '2021-01-01',
-            detail: '',
-          },
-          {
-            id: 19,
-            title: '嘻嘻嘻',
-            status: false,
-            icon: 'ion:tv-outline',
-            create_time: '2021-01-01',
-            detail: '',
-          },
-        ],
-      },
-    ],
-  },
-  {
-    id: 4,
-    title: '权限管理',
-    status: true,
-    icon: 'bx:bx-lock',
-    create_time: '2021-01-01',
-    detail: '',
-    children: [
-      {
-        id: 5,
-        title: '角色管理',
-        status: true,
-        icon: 'bx:bx-lock',
-        create_time: '2021-01-01',
-        detail: '',
-      },
-      {
-        id: 6,
-        title: '菜单管理',
-        status: true,
-        icon: 'bx:bx-lock',
-        create_time: '2021-01-01',
-        detail: '',
-      },
-    ],
-  },
-];
-
 export const columns: BasicColumn[] = [
   {
     title: 'ID',
@@ -148,12 +43,12 @@ export const columns: BasicColumn[] = [
     dataIndex: 'ismenu',
     width: 80,
     customRender: ({ record }) => {
-      function onChange(val) {
+      async function onChange(val) {
         console.log(val, record.id);
         record.ismenu = val;
         const data = { id: record.id, ismenu: val };
-        console.log(`data11`, data);
-        editRule(data);
+        await editRule(data);
+        reloadMenu();
       }
       return h(Switch, { checked: record.ismenu, onChange: onChange });
     },
@@ -215,13 +110,24 @@ export const schemas: FormSchema[] = [
     },
   },
   {
-    field: 'rules',
+    field: 'weigh',
+    component: 'InputNumber',
+    label: '权重',
+    labelWidth: adaptWidth.labelWidth,
+    colProps: {
+      span: adaptWidth.elContainer,
+    },
+    required: true,
+  },
+  {
+    field: 'redirect',
     component: 'Input',
-    label: '规则',
+    label: '重定向',
     labelWidth: adaptWidth.labelWidth,
     colProps: {
       span: adaptWidth.elContainer,
     },
+    required: true,
   },
   {
     field: 'icon',

+ 21 - 15
src/views/permission/rule/index.vue → src/views/admin/rule/index.vue

@@ -19,7 +19,7 @@
       <template #toolbar>
         <a-button type="primary" @click="toggleRowShow">{{ btn_text }}</a-button>
         <a-button type="primary" @click="addRuleFn"> 添加 </a-button>
-        <a-button type="danger" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
+        <a-button color="error" :disabled="disable_btn" @click="deleteBatches"> 删除 </a-button>
         <a-button @click="openModal"> 导出 </a-button>
       </template>
       <template #action="{ record, column }">
@@ -31,6 +31,7 @@
   </CollapseContainer>
 </template>
 <script lang="ts">
+  import { usePermission } from '/@/hooks/web/usePermission';
   import { defineComponent, reactive, ref, toRefs, unref, nextTick } from 'vue';
   import { CollapseContainer } from '/@/components/Container/index';
   import Popup from './popup.vue';
@@ -62,6 +63,7 @@
   export default defineComponent({
     components: { CollapseContainer, BasicTable, TableAction, Popup, ExpExcelModel },
     setup() {
+      const { reloadMenu } = usePermission();
       const { createMessage } = useMessage();
       const { success /*, error */ } = createMessage;
       const tableRef = ref<Nullable<TableActionType>>(null);
@@ -76,12 +78,8 @@
         disable_btn: true,
       });
       const [registerTable, { expandAll, collapseAll }] = useTable({
-        // title: '菜单规则',
-        // titleHelpMessage:
-        //   '',
         rowSelection: { type: 'checkbox' },
         columns: columns,
-        // clickToRowSelect: false, // 点击行不勾选
         isTreeTable: true,
         pagination: false, // 树列表不显示分页
         api: getRuleTree,
@@ -133,14 +131,12 @@
       }
 
       function addRuleFn() {
-        console.log('添加');
         popupData.title = '添加';
         openAdd(true, {});
       }
 
       function handleEdit(record: EditRecordRow) {
         currentEditKeyRef.value = record.id; // record.key
-        console.log(record);
         popupData.title = '编辑';
 
         const data = getTableAction().getDataSource();
@@ -155,9 +151,12 @@
       async function handleDelete(record: Recordable) {
         console.log('点击了删除', record.id);
         console.log(record);
-        await deleteRule({ id: record.id }).then((res) => {
-          console.log(res);
+        await deleteRule({ id: record.id }).then(() => {
           getTableAction().reload();
+          if (record.ismenu) {
+            // 只有删除的是菜单才重新加载菜单
+            reloadMenu();
+          }
           ExpandAllRows();
           success('删除成功!');
         });
@@ -173,14 +172,14 @@
       }
 
       async function deleteBatches() {
-        const id = getTableAction().getSelectRowKeys().toString();
-        if (!id) {
+        const ids = getTableAction().getSelectRowKeys().toString();
+        if (!ids) {
           return;
         }
-        await deleteBatchesRule({ id }).then((res) => {
-          console.log(res);
+        await deleteBatchesRule({ ids }).then(() => {
           getTableAction().reload();
           getTableAction().setSelectedRowKeys([]);
+          reloadMenu();
           ExpandAllRows();
           success('删除成功!');
         });
@@ -191,10 +190,13 @@
         const data = params.data;
         const closeModel = params.closeModal;
         if (!data.id) {
-          await addRule(data).then((res) => {
-            console.log(res);
+          await addRule(data).then(() => {
             getTableAction().reload();
             closeModel();
+            if (data.ismenu) {
+              // 只有添加的是菜单才重新加载菜单
+              reloadMenu();
+            }
           });
           ExpandAllRows();
           success('创建成功!');
@@ -204,6 +206,10 @@
             console.log(res);
             getTableAction().reload();
             closeModel();
+            if (params.menuChange || data.ismenu) {
+              // 修改了菜单切换按钮 或者本身是菜单才重新加载菜单
+              reloadMenu();
+            }
           });
           ExpandAllRows();
           success('修改成功!');

+ 16 - 23
src/views/permission/rule/popup.vue → src/views/admin/rule/popup.vue

@@ -1,17 +1,6 @@
 <template>
   <BasicModal v-bind="$attrs" @register="register" @ok="confirm" :title="title">
     <BasicForm @register="registerForm" :model="model" />
-    <!-- <MenuTree /> -->
-    <div class="tree-wrap">
-      <p class="tree-label">权限</p>
-      <a-tree
-        checkable
-        :tree-data="fakeTree"
-        showLine
-        defaultExpandAll
-        :replace-fields="replaceFields"
-      />
-    </div>
   </BasicModal>
 </template>
 <script lang="ts">
@@ -19,14 +8,15 @@
   import { defineComponent, PropType, reactive, ref, toRefs } from 'vue';
   import { BasicModal, useModalInner } from '/@/components/Modal';
   import { BasicForm, useForm } from '/@/components/Form/index';
-  import { schemas, fakeTree } from './data';
+  import { schemas } from './data';
 
   interface PopupData {
     title: string;
     treeData: object[];
   }
-  interface Role {
-    id: string | number;
+  interface State {
+    rule_id: string | number;
+    ismenu: boolean;
   }
 
   export default defineComponent({
@@ -39,8 +29,9 @@
     },
     emits: ['saveData'],
     setup(props, { emit }) {
-      const role = reactive<Role>({
-        id: 0,
+      const state = reactive<State>({
+        rule_id: 0,
+        ismenu: false,
       });
       const popupData = props.popupData as PopupData;
       console.log(popupData);
@@ -59,14 +50,13 @@
         actionColOptions: { span: 24 },
       });
       const [register, { closeModal }] = useModalInner((data) => {
-        console.log(data);
-        console.log('data=========================');
         resetFields();
         // if (unref(isUpdate)) {
         //   setFieldsValue(data);
         // }
         if (data.id) {
-          role.id = data.id;
+          state.rule_id = data.id;
+          state.ismenu = data.ismenu;
         }
         setFieldsValue(data);
         updateSchema({
@@ -78,10 +68,14 @@
       function confirm() {
         console.log('确定');
         const data = getFieldsValue();
-        if (role.id) {
-          data.id = role.id;
+        let menuChange = false;
+        if (state.rule_id) {
+          data.id = state.rule_id;
+          if (data.ismenu !== state.ismenu) {
+            menuChange = true;
+          }
         }
-        const popupData = { closeModal, data };
+        const popupData = { closeModal, data, menuChange };
         emit('saveData', popupData);
       }
       return {
@@ -91,7 +85,6 @@
         replaceFields,
         model: modelRef,
         confirm,
-        fakeTree,
         ...toRefs(popupData),
       };
     },

+ 2 - 5
src/views/conventional/system/customComponents/ArrayCom.vue → src/views/general/config/customComponents/ArrayCom.vue

@@ -13,11 +13,11 @@
         <div class="value-content">
           <Input v-model:value="item.value" />
         </div>
-        <a-button class="mr-2" preIcon="mdi:close-thick" type="danger" @click="remove(index)" />
+        <a-button class="mr-2" preIcon="mdi:close-thick" color="error" @click="remove(index)" />
         <a-button class="mr-2 drag-btn" preIcon="ri:drag-move-2-fill" type="primary" />
       </div>
     </div>
-    <a-button class="add-btn mr-2" size="small" type="success" @click="create"> 追加 </a-button>
+    <a-button class="add-btn mr-2" size="small" color="success" @click="create"> 追加 </a-button>
   </div>
 </template>
 <script lang="ts">
@@ -37,10 +37,7 @@
 
       // 初始化 sortable 实现拖动
       function initSortable() {
-        console.log('===========init----dfsadf=======');
-        console.log(`document`, document);
         const el = document.querySelector('.array-item') as any;
-        console.log(el);
         Sortable.create(el, {
           handle: '.drag-btn',
           sort: true, // boolean 定义是否列表单元是否可以在列表容器内进行拖拽排序

+ 0 - 0
src/views/conventional/system/customComponents/Checkbox.vue → src/views/general/config/customComponents/Checkbox.vue


+ 0 - 0
src/views/conventional/system/customComponents/DatePicker.vue → src/views/general/config/customComponents/DatePicker.vue


+ 0 - 0
src/views/conventional/system/customComponents/Input.vue → src/views/general/config/customComponents/Input.vue


+ 0 - 0
src/views/conventional/system/customComponents/InputNumber.vue → src/views/general/config/customComponents/InputNumber.vue


+ 0 - 0
src/views/conventional/system/customComponents/InputTextArea.vue → src/views/general/config/customComponents/InputTextArea.vue


+ 68 - 0
src/views/general/config/customComponents/MultipleSelect.vue

@@ -0,0 +1,68 @@
+<template>
+  <div class="wrap">
+    <Select
+      class="select"
+      :value="value"
+      :options="options"
+      mode="multiple"
+      @focus="onFocus"
+      @change="onChange"
+      @blur="onBlur"
+    />
+    <span>{{ reactData.tip }}</span>
+  </div>
+</template>
+<script lang="ts">
+  import { Select } from 'ant-design-vue';
+  import { defineComponent, reactive, toRefs } from 'vue';
+
+  const props = {
+    value: { type: Array, default: [] },
+    tip: { type: String, default: '' },
+    options: { type: Array, default: [] },
+  };
+
+  export default defineComponent({
+    components: { Select },
+    props,
+    emits: ['change'],
+    setup(props, { emit }) {
+      const reactData = reactive({
+        tip: '',
+      });
+      function onFocus() {
+        reactData.tip = props.tip;
+      }
+      function onBlur() {
+        reactData.tip = '';
+      }
+
+      function onChange(val) {
+        emit('change', val);
+      }
+      return {
+        onFocus,
+        onBlur,
+        onChange,
+        reactData,
+        ...toRefs(props),
+      };
+    },
+  });
+</script>
+<style scoped>
+  .wrap {
+    display: flex;
+  }
+
+  .select {
+    width: 55%;
+    margin-right: 10px;
+  }
+
+  span {
+    font-size: 13px;
+    line-height: 250%;
+    color: gray;
+  }
+</style>

+ 0 - 0
src/views/conventional/system/customComponents/Radio.vue → src/views/general/config/customComponents/Radio.vue


+ 0 - 2
src/views/conventional/system/customComponents/Select.vue → src/views/general/config/customComponents/Select.vue

@@ -2,7 +2,6 @@
   <div class="wrap">
     <Select
       class="select"
-      :mode="mode"
       :value="value"
       :options="options"
       @focus="onFocus"
@@ -19,7 +18,6 @@
   const props = {
     value: { type: String, default: '' },
     tip: { type: String, default: '' },
-    mode: { type: String, default: '' },
     options: { type: Array, default: [] },
   };
 

+ 0 - 0
src/views/conventional/system/customComponents/Switch.vue → src/views/general/config/customComponents/Switch.vue


+ 0 - 0
src/views/conventional/system/customComponents/TimePicker.vue → src/views/general/config/customComponents/TimePicker.vue


+ 22 - 14
src/views/conventional/system/data.ts → src/views/general/config/data.ts

@@ -6,6 +6,7 @@ import InputTextArea from './customComponents/InputTextArea.vue';
 import InputNumber from './customComponents/InputNumber.vue';
 import ArrayCom from './customComponents/ArrayCom.vue';
 import Select from './customComponents/Select.vue';
+import MultipleSelect from './customComponents/MultipleSelect.vue';
 import Checkbox from './customComponents/Checkbox.vue';
 import Radio from './customComponents/Radio.vue';
 import DatePicker from './customComponents/DatePicker.vue';
@@ -26,7 +27,7 @@ export const columns: BasicColumn[] = [
     width: 300,
     customRender: ({ record }) => {
       switch (record.type) {
-        case 'Input':
+        case 'string':
           const onchange = (val) => {
             console.log(val);
             record.value = val;
@@ -35,11 +36,11 @@ export const columns: BasicColumn[] = [
             value: record.value,
             tip: record.tip,
             errMsg: record.errMsg || '',
-            rules: record.rules || [],
+            rules: record.rule.split(';') || [],
             style: { width: '100%' },
             onChange: onchange,
           });
-        case 'InputNumber':
+        case 'number':
           const onNumberChange = (val) => {
             record.value = val;
           };
@@ -47,17 +48,23 @@ export const columns: BasicColumn[] = [
             value: record.value,
             tip: record.tip,
             errMsg: record.errMsg || '',
-            rules: record.rules || [],
+            rules: record.rule.split(';') || [],
             style: { width: '100%' },
             onChange: onNumberChange,
           });
-        case 'Select':
+        case 'select':
           const onSelectChange = (val) => {
-            record.value = val;
+            record.value = [val.toString()];
           };
+          const opt: object[] = [];
+          record.content.map((item, index) => {
+            if (index) {
+              opt.push({ label: item, value: index });
+            }
+          });
           return h(Select, {
-            value: record.value,
-            options: record.option,
+            value: opt[record.value[0] - 1]['label'],
+            options: opt,
             tip: record.tip,
             mode: 'SECRET_COMBOBOX_MODE_DO_NOT_USE',
             placeholder: '没有选中任何项',
@@ -67,9 +74,8 @@ export const columns: BasicColumn[] = [
           const onMultipleChange = (val) => {
             record.value = val;
           };
-          return h(Select, {
+          return h(MultipleSelect, {
             value: record.value,
-            mode: 'multiple',
             options: record.option,
             tip: record.tip,
             placeholder: '没有选中任何项',
@@ -95,7 +101,7 @@ export const columns: BasicColumn[] = [
             tip: record.tip,
             onChange: onTimePickerChange,
           });
-        case 'InputTextArea':
+        case 'text':
           const onTextAreaChange = (val) => {
             console.log(val);
             record.value = val;
@@ -138,7 +144,7 @@ export const columns: BasicColumn[] = [
             tip: record.tip,
             onChange: onRadioChange,
           });
-        case 'ArrayCom':
+        case 'array':
           // const onRadioChange = (evt) => {
           //   record.value = evt.target.value;
           // };
@@ -213,7 +219,7 @@ export const schemas: FormSchema[] = [
     colProps: {
       span: 20,
     },
-    required: true,
+    rules: [{ required: true, trigger: 'blur' }],
   },
   {
     field: 'title',
@@ -222,12 +228,13 @@ export const schemas: FormSchema[] = [
     colProps: {
       span: 20,
     },
-    rules: [{ required: true, type: 'email', trigger: 'blur' }],
+    rules: [{ required: true, trigger: 'blur' }],
   },
   {
     field: 'value',
     component: 'Input',
     label: '变量值',
+    defaultValue: '',
     colProps: {
       span: 20,
     },
@@ -236,6 +243,7 @@ export const schemas: FormSchema[] = [
     field: 'tip',
     component: 'Input',
     label: '提示信息',
+    defaultValue: '',
     colProps: {
       span: 20,
     },

+ 64 - 117
src/views/conventional/system/index.vue → src/views/general/config/index.vue

@@ -5,10 +5,19 @@
     :canExpan="false"
     helpMessage="可以在此增改系统的变量和分组,也可以自定义分组和变量"
   >
-    <a-button type="default" class="mr-2" @click="onBasicConfig"> 基础配置 </a-button>
-    <a-button type="default" class="mr-2" @click="onBasicConfig"> 邮件配置 </a-button>
-    <a-button type="default" class="mr-2" @click="onBasicConfig"> 字典配置 </a-button>
-    <a-button type="default" class="mr-2" @click="onBasicConfig"> 会员配置 </a-button>
+    <a-button
+      v-for="(group, index) in groupList"
+      :key="index"
+      type="default"
+      class="mr-2"
+      @click="handleGroupBtn(group)"
+    >
+      <!-- 基础配置 -->
+      {{ group }}
+    </a-button>
+    <!-- <a-button type="default" class="mr-2" @click="onEmailConfig"> 邮件配置 </a-button>
+    <a-button type="default" class="mr-2" @click="handleGroupBtn"> 字典配置 </a-button>
+    <a-button type="default" class="mr-2" @click="handleGroupBtn"> 会员配置 </a-button> -->
     <a-button
       preIcon="bx:bx-plus-medical"
       @mouseenter="showTip"
@@ -22,20 +31,20 @@
       class="config-form"
       v-if="formShow"
       @register="registerForm"
-      @submit="handleSubmit"
+      @submit="handleFormSubmit"
     />
     <div v-if="tableShow" class="actions">
-      <a-button class="mr-2" type="default" @click="onBasicConfig">
+      <a-button class="mr-2" type="default" @click="handleGroupBtn">
         {{ t('common.resetText') }}
       </a-button>
-      <a-button class="mr-2" type="primary" @click="onSubmit">
+      <a-button class="mr-2" type="primary" @click="handleTableSubmit">
         {{ t('common.submitText') }}
       </a-button>
     </div>
   </CollapseContainer>
 </template>
 <script lang="ts">
-  import { defineComponent, reactive, ref, toRefs, unref } from 'vue';
+  import { defineComponent, nextTick, reactive, ref, toRefs, unref } from 'vue';
   import { CollapseContainer } from '/@/components/Container/index';
   import { BasicForm, useForm } from '/@/components/Form/index';
   import { schemas } from './data';
@@ -51,6 +60,7 @@
     // EditRecordRow,
     TableActionType,
   } from '/@/components/Table';
+  import { getConfigGroup, getConfigInfo, addConfigInfo } from '/@/api/sys/general';
   import { columns } from './data';
 
   export default defineComponent({
@@ -62,109 +72,15 @@
         tipShow: false,
         tableShow: true,
         formShow: false,
+        groupList: [] as object[],
+        group: 'basic',
       });
       const tableRef = ref<Nullable<TableActionType>>(null);
       const [registerTable] = useTable({
         columns: columns,
         maxHeight: tableHeight,
-        dataSource: [
-          {
-            title: 'helloWorld',
-            name: 'helloworld',
-            value: 'helloWorld',
-            type: 'Input',
-            tip: '我是helloworld字段的提示',
-            rules: [],
-          },
-          {
-            title: 'test',
-            name: 'test',
-            value: 'test',
-            type: 'Input',
-            tip: '我是test字段的提示',
-            rules: ['require', 'url'],
-          },
-          {
-            title: 'hello1',
-            name: 'hello1',
-            value: 'hello1',
-            type: 'Select',
-            tip: 'hello select',
-            option: [{ value: 'hello1' }, { value: 'world' }, { value: 'java' }],
-          },
-          {
-            title: 'hello1',
-            name: 'hello1',
-            value: ['hello1'],
-            type: 'MultipleSelect',
-            tip: 'MultipleSelect',
-            option: [{ value: 'hello1' }, { value: 'world' }, { value: 'java' }],
-          },
-          {
-            title: 'hello1',
-            name: 'hello1',
-            value: 'Orange',
-            type: 'Radio',
-            option: [
-              { label: 'Apple', value: 'Apple' },
-              { label: 'Pear', value: 'Pear' },
-              { label: 'Orange', value: 'Orange' },
-            ],
-          },
-          {
-            title: 'hello1',
-            name: 'hello1',
-            value: ['Apple', 'Orange'],
-            type: 'Checkbox',
-            option: [
-              { label: 'Apple', value: 'Apple' },
-              { label: 'Pear', value: 'Pear' },
-              { label: 'Orange', value: 'Orange' },
-            ],
-          },
-          {
-            title: 'hello2',
-            name: 'hello2',
-            value: '2021-10-25',
-            type: 'DatePicker',
-            tip: '日期选择',
-          },
-          {
-            title: 'time',
-            name: 'timename',
-            value: '11:12:25',
-            type: 'TimePicker',
-            tip: '时间选择',
-          },
-          {
-            title: 'hello3',
-            name: 'hello3',
-            value: 10,
-            type: 'InputNumber',
-            tip: '我是test字段的提示',
-            rules: ['require', 'qq'],
-          },
-          {
-            title: 'hello4',
-            name: 'hello4',
-            value: 'InputTextAreasdafasdf',
-            type: 'InputTextArea',
-            tip: '我是InputTextArea字段的提示123456789112',
-            rules: ['require', 'email'],
-          },
-          {
-            title: 'hello4',
-            name: 'hello4',
-            value: true,
-            type: 'Switch',
-          },
-          {
-            title: 'hello4',
-            name: 'hello4',
-            value: true,
-            type: 'ArrayCom',
-          },
-        ],
+        api: getConfigInfo,
+        afterFetch: afterFetch,
         showIndexColumn: false,
         pagination: false,
       });
@@ -190,6 +106,25 @@
         return tableAction;
       }
 
+      // 处理请求数据
+      function afterFetch(result) {
+        console.log(`result`, result);
+        // let obj = result.dictionary.list[0].value;
+        // console.log(`result.dictionary.list[0].value`, obj)
+        // var keys = Object.keys(obj);
+        // console.log(`keys`, keys);
+        result = result[state.group].list;
+        console.log(`result----after`, result);
+        return result;
+      }
+      getGroupList();
+      async function getGroupList() {
+        const res = await getConfigGroup();
+        console.log(`res.group`, res.group);
+        state.groupList = Object.values(res.group);
+        console.log(`state.groupList`, state.groupList);
+      }
+
       function showTip() {
         state.tipShow = true;
       }
@@ -198,9 +133,13 @@
         state.tipShow = false;
       }
 
-      function onBasicConfig() {
+      async function handleGroupBtn(group) {
         state.tableShow = true;
         state.formShow = false;
+        await nextTick();
+        getTableAction().reload();
+        state.group = group.toLowerCase();
+        console.log(`state.group`, state.group);
       }
 
       function addConfig() {
@@ -208,24 +147,32 @@
         state.formShow = true;
       }
 
-      function onSubmit() {
-        console.log('==========onSubmit=========');
+      function handleTableSubmit() {
+        console.log('==========handleTableSubmit=========');
         const data = getTableAction().getDataSource();
         let flag = true;
+        console.log(`data`, data);
         data.map((item) => {
-          if (item.rules && item.rules.length) {
-            console.log(`item`, item.rules);
-            const res = validateType(item.rules, item.value);
+          if (item.rule) {
+            const rule = item.rule.split(',');
+            const res = validateType(rule, item.value);
             item.errMsg = res.errMsg;
-            flag = res.isValid;
+            if (!res.isValid) {
+              console.log(`item`, item);
+              flag = res.isValid;
+            }
           }
         });
         if (flag) {
           console.log('=======全部校验通过========');
+          return;
         }
+        console.log('======未通过校验====');
       }
 
-      function handleSubmit(e) {
+      async function handleFormSubmit(e) {
+        return;
+        await addConfigInfo(e);
         console.log('=======values =======');
         console.log(`e`, e);
       }
@@ -236,10 +183,10 @@
         registerForm,
         showTip,
         hideTip,
-        onBasicConfig,
+        handleGroupBtn,
         addConfig,
-        onSubmit,
-        handleSubmit,
+        handleTableSubmit,
+        handleFormSubmit,
         ...toRefs(state),
       };
     },

+ 0 - 0
src/views/conventional/person/index.vue → src/views/general/person/index.vue