浏览代码

格式化代码

wuheng 1 年之前
父节点
当前提交
2c19cd4858
共有 49 个文件被更改,包括 1478 次插入1991 次删除
  1. 9 5
      mock/api/auth.ts
  2. 30 14
      mock/model/auth.ts
  3. 3 3
      mock/model/route.ts
  4. 78 79
      src/components/View/pdfPreview.vue
  5. 0 1
      src/composables/router.ts
  6. 1 1
      src/composables/system.ts
  7. 1 1
      src/hooks/business/use-table.ts
  8. 1 1
      src/layouts/common/global-header/components/user-avatar.vue
  9. 3 3
      src/router/guard/dynamic.ts
  10. 3 3
      src/router/guard/permission.ts
  11. 1 1
      src/router/modules/about.ts
  12. 1 1
      src/router/modules/auth-demo.ts
  13. 1 1
      src/service/api/auth.ts
  14. 22 29
      src/service/api/sort.ts
  15. 0 2
      src/service/api/user.ts
  16. 0 1
      src/service/request/instance.ts
  17. 5 5
      src/service/request/request.ts
  18. 1 2
      src/store/modules/auth/index.ts
  19. 3 4
      src/store/modules/route/index.ts
  20. 3 3
      src/typings/api.d.ts
  21. 2 2
      src/typings/business.d.ts
  22. 1 1
      src/typings/system.d.ts
  23. 22 1
      src/utils/crypto/index.ts
  24. 3 6
      src/utils/form/rule.ts
  25. 1 1
      src/utils/router/auth.ts
  26. 6 6
      src/utils/service/handler.ts
  27. 7 7
      src/utils/storage/local.ts
  28. 3 3
      src/utils/storage/session.ts
  29. 305 327
      src/views/_builtin/login/components/pwd-login/components/validate/Verify.vue
  30. 268 251
      src/views/_builtin/login/components/pwd-login/components/validate/Verify/VerifyPoints.vue
  31. 5 5
      src/views/_builtin/login/components/pwd-login/components/validate/utils/ase.js
  32. 9 8
      src/views/_builtin/login/components/pwd-login/components/validate/utils/axios.js
  33. 27 28
      src/views/_builtin/login/components/pwd-login/components/validate/utils/util.js
  34. 5 11
      src/views/auth-demo/permission/index.vue
  35. 5 5
      src/views/dashboard/analysis/index.vue
  36. 1 1
      src/views/dashboard/workbench/components/workbench-header/index.vue
  37. 0 1
      src/views/management/auth/index.vue
  38. 2 3
      src/views/management/role/index.vue
  39. 68 70
      src/views/management/role/queryUser.vue
  40. 2 9
      src/views/management/role/userPa.vue
  41. 1 3
      src/views/management/route/index.vue
  42. 77 70
      src/views/management/sort/components/column-search.vue
  43. 119 124
      src/views/management/sort/components/table-action-add.vue
  44. 36 37
      src/views/management/sort/crud.tsx
  45. 252 205
      src/views/management/sort/index.vue
  46. 0 315
      src/views/management/sort/indexcopy.vue
  47. 82 83
      src/views/management/user/components/table-action-modal.vue
  48. 2 247
      src/views/management/user/index.vue
  49. 1 1
      tsconfig.json

+ 9 - 5
mock/api/auth.ts

@@ -70,15 +70,19 @@ const apis: MockMethod[] = [
         };
       }
       const userInfo: Auth.UserInfo = {
-        userId: '',
-        userName: '',
-        userRole: 'user'
+        id: 0,
+        username: '',
+        userRole: 'user',
+        phone: '',
+        email: '',
+        permissions: [],
+        departments: []
       };
       const isInUser = userModel.some(item => {
         const flag = item.token === authorization;
         if (flag) {
-          const { userId: itemUserId, userName, userRole } = item;
-          Object.assign(userInfo, { userId: itemUserId, userName, userRole });
+          const { id: itemUserId, username, userRole } = item;
+          Object.assign(userInfo, { userId: itemUserId, username, userRole });
         }
         return flag;
       });

+ 30 - 14
mock/model/auth.ts

@@ -8,33 +8,49 @@ export const userModel: UserModel[] = [
   {
     token: '__TOKEN_SOYBEAN__',
     refreshToken: '__REFRESH_TOKEN_SOYBEAN__',
-    userId: '0',
-    userName: 'Soybean',
-    userRole: 'super',
-    password: 'soybean123'
+    id: 0,
+    username: 'Soybean',
+    userRole: 'admin',
+    password: 'soybean123',
+    phone: '',
+    email: '',
+    permissions: [],
+    departments: []
   },
   {
     token: '__TOKEN_SUPER__',
     refreshToken: '__REFRESH_TOKEN_SUPER__',
-    userId: '1',
-    userName: 'Super',
-    userRole: 'super',
-    password: 'super123'
+    id: 1,
+    username: 'Super',
+    userRole: 'admin',
+    password: 'super123',
+    phone: '',
+    email: '',
+    permissions: [],
+    departments: []
   },
   {
     token: '__TOKEN_ADMIN__',
     refreshToken: '__REFRESH_TOKEN_ADMIN__',
-    userId: '2',
-    userName: 'Admin',
+    id: 2,
+    username: 'Admin',
     userRole: 'admin',
-    password: 'admin123'
+    password: 'admin123',
+    phone: '',
+    email: '',
+    permissions: [],
+    departments: []
   },
   {
     token: '__TOKEN_USER01__',
     refreshToken: '__REFRESH_TOKEN_USER01__',
-    userId: '3',
-    userName: 'User01',
+    id: 3,
+    username: 'User01',
     userRole: 'user',
-    password: 'user01123'
+    password: 'user01123',
+    phone: '',
+    email: '',
+    permissions: [],
+    departments: []
   }
 ];

+ 3 - 3
mock/model/route.ts

@@ -1,5 +1,5 @@
 export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
-  super: [
+  admin: [
     {
       name: 'dashboard',
       path: '/dashboard',
@@ -510,7 +510,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
       }
     }
   ],
-  admin: [
+  user: [
     {
       name: 'dashboard',
       path: '/dashboard',
@@ -1011,7 +1011,7 @@ export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
       }
     }
   ],
-  user: [
+  member: [
     {
       name: 'dashboard',
       path: '/dashboard',

+ 78 - 79
src/components/View/pdfPreview.vue

@@ -1,121 +1,120 @@
 <template>
-	<div class="pdf-preview">
-		<div class="pdf-wrap">
-			<vue-pdf-embed :source="state.source" :style="scale" class="vue-pdf-embed" :page="state.pageNum" />
-		</div>
-		<div class="page-tool">
-			<div class="page-tool-item" @click="lastPage">上一页</div>
-			<div class="page-tool-item" @click="nextPage">下一页</div>
-			<div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
-			<div class="page-tool-item" @click="pageZoomOut">放大</div>
-			<div class="page-tool-item" @click="pageZoomIn">缩小</div>
-		</div>
-	</div>
+  <div class="pdf-preview">
+    <div class="pdf-wrap">
+      <vue-pdf-embed :source="state.source" :style="scale" class="vue-pdf-embed" :page="state.pageNum" />
+    </div>
+    <div class="page-tool">
+      <div class="page-tool-item" @click="lastPage">上一页</div>
+      <div class="page-tool-item" @click="nextPage">下一页</div>
+      <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
+      <div class="page-tool-item" @click="pageZoomOut">放大</div>
+      <div class="page-tool-item" @click="pageZoomIn">缩小</div>
+    </div>
+  </div>
 </template>
 <script setup lang="ts">
-import VuePdfEmbed from "vue-pdf-embed";
-import { createLoadingTask } from "vue3-pdfjs";
-import { reactive, onMounted, computed } from "vue";
+import { reactive, onMounted, computed } from 'vue';
+import VuePdfEmbed from 'vue-pdf-embed';
+import { createLoadingTask } from 'vue3-pdfjs';
 
 const props = defineProps({
-	pdfUrl: {
-		type: String,
-		required: true
-	}
-})
+  pdfUrl: {
+    type: String,
+    required: true
+  }
+});
 const state = reactive({
-	source: props.pdfUrl,
-	pageNum: 1,
-	scale: 1, // 缩放比例
-	numPages: 0, // 总页数
+  source: props.pdfUrl,
+  pageNum: 1,
+  scale: 1, // 缩放比例
+  numPages: 0 // 总页数
 });
 
-const scale = computed(() => `transform:scale(${state.scale})`)
+const scale = computed(() => `transform:scale(${state.scale})`);
 function lastPage() {
-	if (state.pageNum > 1) {
-		state.pageNum -= 1;
-	}
+  if (state.pageNum > 1) {
+    state.pageNum -= 1;
+  }
 }
 function nextPage() {
-	if (state.pageNum < state.numPages) {
-		state.pageNum += 1;
-	}
+  if (state.pageNum < state.numPages) {
+    state.pageNum += 1;
+  }
 }
 function pageZoomOut() {
-	if (state.scale < 2) {
-		state.scale += 0.1;
-	}
+  if (state.scale < 2) {
+    state.scale += 0.1;
+  }
 }
 function pageZoomIn() {
-	if (state.scale > 1) {
-		state.scale -= 0.1;
-	}
+  if (state.scale > 1) {
+    state.scale -= 0.1;
+  }
 }
 
 onMounted(() => {
-	const loadingTask = createLoadingTask(state.source);
-	loadingTask.promise.then((pdf: { numPages: number }) => {
-		state.numPages = pdf.numPages;
-	});
+  const loadingTask = createLoadingTask(state.source);
+  loadingTask.promise.then((pdf: { numPages: number }) => {
+    state.numPages = pdf.numPages;
+  });
 });
-
 </script>
 <style lang="css" scoped>
 .pdf-preview {
-	position: relative;
-	height: 100vh;
-	padding: 20px 0;
-	box-sizing: border-box;
-	background: rgb(66, 66, 66);
+  position: relative;
+  height: 100vh;
+  padding: 20px 0;
+  box-sizing: border-box;
+  background: rgb(66, 66, 66);
 }
 
 .vue-pdf-embed {
-	text-align: center;
-	width: 515px;
-	border: 1px solid #e5e5e5;
-	margin: 0 auto;
-	box-sizing: border-box;
+  text-align: center;
+  width: 515px;
+  border: 1px solid #e5e5e5;
+  margin: 0 auto;
+  box-sizing: border-box;
 }
 
 .pdf-preview {
-	position: relative;
-	height: 100vh;
-	padding: 20px 0;
-	box-sizing: border-box;
-	background-color: e9e9e9;
+  position: relative;
+  height: 100vh;
+  padding: 20px 0;
+  box-sizing: border-box;
+  background-color: e9e9e9;
 }
 
 .pdf-wrap {
-	overflow-y: auto;
+  overflow-y: auto;
 }
 
 .vue-pdf-embed {
-	text-align: center;
-	width: 515px;
-	border: 1px solid #e5e5e5;
-	margin: 0 auto;
-	box-sizing: border-box;
+  text-align: center;
+  width: 515px;
+  border: 1px solid #e5e5e5;
+  margin: 0 auto;
+  box-sizing: border-box;
 }
 
 .page-tool {
-	position: absolute;
-	bottom: 35px;
-	padding-left: 15px;
-	padding-right: 15px;
-	display: flex;
-	align-items: center;
-	background: rgb(66, 66, 66);
-	color: white;
-	border-radius: 19px;
-	z-index: 100;
-	cursor: pointer;
-	margin-left: 50%;
-	transform: translateX(-50%);
+  position: absolute;
+  bottom: 35px;
+  padding-left: 15px;
+  padding-right: 15px;
+  display: flex;
+  align-items: center;
+  background: rgb(66, 66, 66);
+  color: white;
+  border-radius: 19px;
+  z-index: 100;
+  cursor: pointer;
+  margin-left: 50%;
+  transform: translateX(-50%);
 }
 
 .page-tool-item {
-	padding: 8px 15px;
-	padding-left: 10px;
-	cursor: pointer;
+  padding: 8px 15px;
+  padding-left: 10px;
+  cursor: pointer;
 }
 </style>

+ 0 - 1
src/composables/router.ts

@@ -17,7 +17,6 @@ export function useRouterPush(inSetup = true) {
    */
   function routerPush(to: RouteLocationRaw, newTab = false) {
     if (newTab) {
-			console.log(newTab);
       const routerData = router.resolve(to);
       window.open(routerData.href, '_blank');
       return Promise.resolve();

+ 1 - 1
src/composables/system.ts

@@ -36,7 +36,7 @@ export function usePermission() {
   function hasPermission(permission: Auth.RoleType | Auth.RoleType[]) {
     const { userRole } = auth.userInfo;
 
-    let has = userRole === 'super';
+    let has = userRole === 'admin';
     if (!has) {
       if (isArray(permission)) {
         has = (permission as Auth.RoleType[]).includes(userRole);

+ 1 - 1
src/hooks/business/use-table.ts

@@ -32,7 +32,7 @@ type ApiFn<Params = ApiParams, TableData = Record<string, unknown>> = (
  */
 type TransformedTableData<TableData = Record<string, unknown>> = {
   data: TableData[];
-	status:boolean;
+  status: boolean;
   pageNum: number;
   pageSize: number;
   total: number;

+ 1 - 1
src/layouts/common/global-header/components/user-avatar.vue

@@ -2,7 +2,7 @@
   <n-dropdown :options="options" @select="handleDropdown">
     <hover-container class="px-12px" :inverted="theme.header.inverted">
       <icon-local-avatar class="text-32px" />
-      <span class="pl-8px text-16px font-medium">{{ auth.userInfo.userName }}</span>
+      <span class="pl-8px text-16px font-medium">{{ auth.userInfo.username }}</span>
     </hover-container>
   </n-dropdown>
 </template>

+ 3 - 3
src/router/guard/dynamic.ts

@@ -1,7 +1,7 @@
 import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
 import { routeName } from '@/router';
 import { useRouteStore } from '@/store';
-import { localStg } from '@/utils';
+// import { localStg } from '@/utils';
 
 /**
  * 动态路由
@@ -12,8 +12,8 @@ export async function createDynamicRouteGuard(
   next: NavigationGuardNext
 ) {
   const route = useRouteStore();
-  //const isLogin = Boolean(localStg.get('token'));
-	const isLogin = Boolean(localStorage.getItem('token'));
+  // const isLogin = Boolean(localStg.get('token'));
+  const isLogin = Boolean(localStorage.getItem('token'));
 
   // 初始化权限路由
   if (!route.isInitAuthRoute) {

+ 3 - 3
src/router/guard/permission.ts

@@ -1,7 +1,7 @@
 import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
 import { routeName } from '@/router';
 import { useAuthStore } from '@/store';
-import { exeStrategyActions, localStg } from '@/utils';
+import { exeStrategyActions } from '@/utils';
 import { createDynamicRouteGuard } from './dynamic';
 
 /** 处理路由页面的权限 */
@@ -22,8 +22,8 @@ export async function createPermissionGuard(
   }
 
   const auth = useAuthStore();
-  //const isLogin = Boolean(localStg.get('token'));
-	const isLogin = Boolean(localStorage.getItem('token'));
+  // const isLogin = Boolean(localStg.get('token'));
+  const isLogin = Boolean(localStorage.getItem('token'));
   const permissions = to.meta.permissions || [];
   const needLogin = Boolean(to.meta?.requiresAuth) || Boolean(permissions.length);
   const hasPermission = !permissions.length || permissions.includes(auth.userInfo.userRole);

+ 1 - 1
src/router/modules/about.ts

@@ -8,7 +8,7 @@ const about1: AuthRoute.Route = {
     requiresAuth: true,
     keepAlive: true,
     singleLayout: 'basic',
-    permissions: ['super', 'admin', 'user'],
+    permissions: ['admin', 'user'],
     icon: 'fluent:book-information-24-regular',
     order: 10
   }

+ 1 - 1
src/router/modules/auth-demo.ts

@@ -22,7 +22,7 @@ const authDemo: AuthRoute.Route = {
         title: '超级管理员可见',
         i18nTitle: 'message.routes.auth-demo.super',
         requiresAuth: true,
-        permissions: ['super'],
+        permissions: ['admin'],
         icon: 'ic:round-supervisor-account'
       }
     }

+ 1 - 1
src/service/api/auth.ts

@@ -1,4 +1,4 @@
-import { localStg } from '~/src/utils';
+// import { localStg } from '~/src/utils';
 import { request, mockRequest } from '../request';
 
 /**

+ 22 - 29
src/service/api/sort.ts

@@ -1,6 +1,5 @@
 import { request } from '../request';
 
-
 // 查询全部课程类别
 // 响应接口
 export interface SelectAll_1Res {
@@ -17,17 +16,16 @@ export function selectAll_1() {
   return request.get(`/selectAll`);
 }
 
-
 // 添加课程类别
 // 参数接口
 export interface AddEasEduCategoryParams {
-  id?: number|null;
-  name?: string|null;
-  description?: string|null;
+  id?: number | null;
+  name?: string | null;
+  description?: string | null;
   createTime?: string;
   modifyTime?: string;
-  createUid?: number|null;
-  disabled?: string|null;
+  createUid?: number | null;
+  disabled?: string | null;
 }
 
 // 响应接口
@@ -49,11 +47,10 @@ export interface AddEasEduCategoryRes {
  * @param {string} params.disabled 状态
  * @returns
  */
-export function addEasEduCategory(params: AddEasEduCategoryParams){
+export function addEasEduCategory(params: AddEasEduCategoryParams) {
   return request.post(`/addEasEduCategory`, params);
 }
 
-
 // 根据Id删除课程类别
 // 响应接口
 export interface DeleteByIdRes {
@@ -65,24 +62,22 @@ export interface DeleteByIdRes {
 /**
  * 根据Id删除课程类别
  * @param {string} id
-  * @returns
+ * @returns
  */
-export function deleteById(id: number){
+export function deleteById(id: number) {
   return request.delete(`/deleteById/${id}`);
 }
 
-
-
 // 课程类别更新
 // 参数接口
 export interface UpdateEasEduCategoryParams {
-  id?: number|null;
-  name?: string|null;
-  description?: string|null;
-  createTime?:  string|null;
+  id?: number | null;
+  name?: string | null;
+  description?: string | null;
+  createTime?: string | null;
   modifyTime?: string;
-  createUid?: number|null;
-  disabled?: string|null;
+  createUid?: number | null;
+  disabled?: string | null;
 }
 
 // 响应接口
@@ -108,7 +103,6 @@ export function updateEasEduCategory(params: UpdateEasEduCategoryParams) {
   return request.post(`/updateEasEduCategory`, params);
 }
 
-
 // 根据Id查询对应课程类别
 // 响应接口
 export interface SelectById_1Res {
@@ -120,23 +114,22 @@ export interface SelectById_1Res {
 /**
  * 根据Id查询对应课程类别
  * @param {string} id
-  * @returns
+ * @returns
  */
 export function selectById_1(id: number) {
   return request.get(`/selectById?id=${id}`);
 }
 
-
 // 根据条件进行查询课程类别
 // 参数接口
 export interface SelectByCondition_1Params {
   id?: number | null;
-  name?: string|null;
-  description?: string|null;
-  createTime?: null|string;
-  modifyTime?: null|string;
-  createUid?: null|number;
-  disabled?: string|null;
+  name?: string | null;
+  description?: string | null;
+  createTime?: null | string;
+  modifyTime?: null | string;
+  createUid?: null | number;
+  disabled?: string | null;
 }
 
 // 响应接口
@@ -161,6 +154,6 @@ export interface SelectByCondition_1Res {
  * @param {string} params.disabled 状态
  * @returns
  */
-export function selectByCondition_1(pageNum: number, pageSize: number, params: SelectByCondition_1Params){
+export function selectByCondition_1(pageNum: number, pageSize: number, params: SelectByCondition_1Params) {
   return request.post(`/selectByCondition?pageNum=${pageNum}&pageSize=${pageSize}`, params);
 }

+ 0 - 2
src/service/api/user.ts

@@ -112,5 +112,3 @@ export interface Query_1Res {
 export function query_1(pageNum: number, pageSize: number, params: Query_1Params) {
   return request.post(`/department/query?pageNum=${pageNum}&pageSize=${pageSize}`, params);
 }
-
-

+ 0 - 1
src/service/request/instance.ts

@@ -2,7 +2,6 @@ import axios from 'axios';
 import type { AxiosResponse, AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios';
 import { REFRESH_TOKEN_CODE } from '@/config';
 import {
-  localStg,
   handleAxiosError,
   handleBackendError,
   handleResponseError,

+ 5 - 5
src/service/request/request.ts

@@ -27,7 +27,7 @@ export function createRequest(axiosConfig: AxiosRequestConfig, backendConfig?: S
    * - method: 请求方法(默认get)
    * - data: 请求的body的data
    * - axiosConfig: axios配置
-	 * - total
+   * - total
    */
   async function asyncRequest<T>(param: RequestParam): Promise<Service.RequestResult<T>> {
     const { url } = param;
@@ -94,7 +94,7 @@ interface RequestResultHook<T = any> {
   error: Ref<Service.RequestError | null>;
   loading: Ref<boolean>;
   network: Ref<boolean>;
-	total:Ref<number>;
+  total: Ref<number>;
 }
 
 /**
@@ -120,12 +120,12 @@ export function createHookRequest(axiosConfig: AxiosRequestConfig, backendConfig
     startLoading();
     const data = ref<T | null>(null) as Ref<T | null>;
     const error = ref<Service.RequestError | null>(null);
-		const total = ref<number>() as Ref<number>;
+    const total = ref<number>() as Ref<number>;
     function handleRequestResult(response: any) {
       const res = response as Service.RequestResult<T>;
       data.value = res.data;
       error.value = res.error;
-			total.value= Number (res.total)
+      total.value = Number(res.total);
       endLoading();
       setNetwork(window.navigator.onLine);
     }
@@ -143,7 +143,7 @@ export function createHookRequest(axiosConfig: AxiosRequestConfig, backendConfig
       error,
       loading,
       network,
-			total
+      total
     };
   }
 

+ 1 - 2
src/store/modules/auth/index.ts

@@ -91,9 +91,8 @@ export const useAuthStore = defineStore('auth-store', {
       const { token, refreshToken } = backendToken;
       localStorage.setItem('token', token);
       localStorage.setItem('refreshToken', refreshToken);
-      const params = localStorage.getItem('token');
       // 获取用户信息
-      const { data } = await fetchUserInfo(params as string);
+      const { data } = await fetchUserInfo();
       if (data) {
         // 成功后把用户信息存储到缓存中
         localStorage.setItem('userInfo', JSON.stringify(data));

+ 3 - 4
src/store/modules/route/index.ts

@@ -2,7 +2,6 @@ import { defineStore } from 'pinia';
 import { ROOT_ROUTE, constantRoutes, router, routes as staticRoutes } from '@/router';
 import { fetchUserRoutes } from '@/service';
 import {
-  localStg,
   filterAuthRoutesByUserPermission,
   getCacheRoutes,
   getConstantRouteNames,
@@ -109,14 +108,14 @@ export const useRouteStore = defineStore('route-store', {
       const { resetAuthStore } = useAuthStore();
       const { initHomeTab } = useTabStore();
 
-      const { id } = localStorage.getItem('userInfo');
+      const id = localStorage.getItem('userInfo');
       if (!id) {
         throw new Error('userId 不能为空!');
       }
 
-      const { error, data } = await fetchUserRoutes(id);
+      const { error, data } = await fetchUserRoutes(Number(id));
 
-      if (!error) {
+      if (!error && data) {
         this.routeHomeName = data.home;
         this.handleUpdateRootRedirect(data.home);
         this.handleAuthRoute(sortRoutes(data.routes));

+ 3 - 3
src/typings/api.d.ts

@@ -25,7 +25,7 @@ declare namespace ApiRoute {
 declare namespace ApiUserManagement {
   interface User {
     /** 用户id */
-    id: number ;
+    id: number;
     /** 用户名 */
     name: string | null;
     /** 用户年龄 */
@@ -34,12 +34,12 @@ declare namespace ApiUserManagement {
     /** 用户手机号码 */
     modifyTime: string;
     /** 用户邮箱 */
-    createUid: number|null;
+    createUid: number | null;
     /**
      * 用户状态
      * - Y: 启用
      * - N: 禁用
      */
-    disabled: 'Y' | 'N'|null ;
+    disabled: 'Y' | 'N' | null;
   }
 }

+ 2 - 2
src/typings/business.d.ts

@@ -6,7 +6,7 @@ declare namespace Auth {
    * - admin: 管理员
    * - user: 用户
    */
-  type RoleType = 'admin';
+  type RoleType = 'admin' | 'user' | 'member';
 
   /** 用户信息 */
   interface UserInfo {
@@ -14,7 +14,7 @@ declare namespace Auth {
     id: number | null;
     /** 用户名 */
     username: string;
-    phone: number | null;
+    phone: string | null;
     email: string;
     permissions: [];
     departments: [];

+ 1 - 1
src/typings/system.d.ts

@@ -43,7 +43,7 @@ declare namespace Service {
   /** 自定义的请求失败结果 */
   interface FailedResult {
     /** 请求错误 */
-    error: RequestError;
+    error: RequestError | null;
     /** 请求数据 */
     data: null;
     total: null;

+ 22 - 1
src/utils/crypto/index.ts

@@ -29,6 +29,27 @@ export function decryption(cipherText: string) {
     mode: CryptoJS.mode.ECB, // 模式
     padding: CryptoJS.pad.Pkcs7 // 补零
   });
-
   return CryptoJS.enc.Utf8.stringify(cryptoStr).toString();
 }
+
+/**
+ * 加密数据
+ * @param data - 数据
+ */
+export function encryptJson(data: any) {
+  const newData = JSON.stringify(data);
+  return CryptoJS.AES.encrypt(newData, keyword).toString();
+}
+
+/**
+ * 解密数据
+ * @param cipherText - 密文
+ */
+export function decryptJson(cipherText: string) {
+  const bytes = CryptoJS.AES.decrypt(cipherText, keyword);
+  const originalText = bytes.toString(CryptoJS.enc.Utf8);
+  if (originalText) {
+    return JSON.parse(originalText);
+  }
+  return null;
+}

+ 3 - 6
src/utils/form/rule.ts

@@ -11,16 +11,13 @@ export const requiredFormRule = createRequiredFormRule();
 interface CustomFormRules {
   /** 手机号码 */
   createTime: FormItemRule[];
-	pwd:FormItemRule[];
+  pwd: FormItemRule[];
 }
 
 /** 表单规则 */
 export const formRules: CustomFormRules = {
-  createTime: [
-    createRequiredFormRule('请输入创建时间'),
-    { pattern: '', message: '不能为空', trigger: 'input' }
-  ],
-	pwd: [{ pattern: REGEXP_PWD, message: '密码格式错误', trigger: 'blur' }]
+  createTime: [createRequiredFormRule('请输入创建时间'), { pattern: '', message: '不能为空', trigger: 'input' }],
+  pwd: [{ pattern: REGEXP_PWD, message: '密码格式错误', trigger: 'blur' }]
 };
 
 /** 是否为空字符串 */

+ 1 - 1
src/utils/router/auth.ts

@@ -15,7 +15,7 @@ export function filterAuthRoutesByUserPermission(routes: AuthRoute.Route[], perm
 function filterAuthRouteByUserPermission(route: AuthRoute.Route, permission: Auth.RoleType): AuthRoute.Route[] {
   const filterRoute = { ...route };
   const hasPermission =
-    !route.meta.permissions || permission === 'super' || route.meta.permissions.includes(permission);
+    !route.meta.permissions || permission === 'admin' || route.meta.permissions.includes(permission);
   if (filterRoute.children) {
     const filterChildren = filterRoute.children.map(item => filterAuthRouteByUserPermission(item, permission)).flat(1);
     Object.assign(filterRoute, { children: filterChildren });

+ 6 - 6
src/utils/service/handler.ts

@@ -1,17 +1,17 @@
 /** 统一失败和成功的请求结果的数据类型 */
-export async function handleServiceResult<T = any>(error: Service.RequestError | null, data: any,total:any) {
+export async function handleServiceResult<T = any>(error: Service.RequestError | null, data: any, total: any) {
   if (error) {
     const fail: Service.FailedResult = {
       error,
       data: null,
-			total:null,
+      total: null
     };
     return fail;
   }
   const success: Service.SuccessResult<T> = {
     error: null,
     data,
-		total
+    total
   };
   return success;
 }
@@ -29,7 +29,7 @@ export function adapter<T extends Service.ServiceAdapter>(
       result = {
         error: item.error,
         data: null,
-				total:null
+        total: null
       };
     }
     return flag;
@@ -37,11 +37,11 @@ export function adapter<T extends Service.ServiceAdapter>(
 
   if (!hasError) {
     const adapterFunArgs = args.map(item => item.data);
-		const adapterFunArgss=args.map(item => item.total);
+    const adapterFunArgss = args.map(item => item.total);
     result = {
       error: null,
       data: adapterFun(...adapterFunArgs),
-			total:adapterFun(...adapterFunArgss),
+      total: adapterFun(...adapterFunArgss)
     };
   }
 

+ 7 - 7
src/utils/storage/local.ts

@@ -1,4 +1,4 @@
-import { decryption, encryption } from '../crypto';
+import { encryption } from '../crypto';
 interface StorageData<T> {
   value: T;
   expire: number | null;
@@ -19,12 +19,12 @@ function createLocalStorage<T extends StorageInterface.Local = StorageInterface.
   function get<K extends keyof T>(key: K) {
     const json = window.localStorage.getItem(key as string);
     if (json) {
-      let storageData: StorageData<T[K]> | null = null;
-      try {
-        storageData = decryption(json);
-      } catch {
-        // 防止解析失败
-      }
+      const storageData: StorageData<T[K]> | null = null;
+      // try {
+      //   storageData = decryption(json);
+      // } catch {
+      //   // 防止解析失败
+      // }
       if (storageData) {
         const { value, expire } = storageData;
         // 在有效期内直接返回

+ 3 - 3
src/utils/storage/session.ts

@@ -1,8 +1,8 @@
-import { decryption, encryption } from '../crypto';
+import { decryptJson, encryptJson } from '../crypto';
 
 function createSessionStorage<T extends StorageInterface.Session = StorageInterface.Session>() {
   function set<K extends keyof T>(key: K, value: T[K]) {
-    const json = encryption(value);
+    const json = encryptJson(value);
     sessionStorage.setItem(key as string, json);
   }
   function get<K extends keyof T>(key: K) {
@@ -10,7 +10,7 @@ function createSessionStorage<T extends StorageInterface.Session = StorageInterf
     let data: T[K] | null = null;
     if (json) {
       try {
-        data = decryption(json);
+        data = decryptJson(json);
       } catch {
         // 防止解析失败
       }

文件差异内容过多而无法显示
+ 305 - 327
src/views/_builtin/login/components/pwd-login/components/validate/Verify.vue


+ 268 - 251
src/views/_builtin/login/components/pwd-login/components/validate/Verify/VerifyPoints.vue

@@ -1,260 +1,277 @@
 <template>
-    <div style="position: relative"
-        >
-        <div class="verify-img-out">
-            <div class="verify-img-panel" :style="{'width': setSize.imgWidth,
-                                                   'height': setSize.imgHeight,
-                                                   'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
-                                                   'margin-bottom': vSpace + 'px'}"
-                                                    >
-                <div class="verify-refresh" style="z-index:3" @click="refresh" v-show="showRefresh">
-                    <i class="iconfont icon-refresh"></i>
-                </div>
-                <img :src="'data:image/png;base64,'+pointBackImgBase" 
-                ref="canvas"
-                alt=""  style="width:100%;height:100%;display:block"
-                @click="bindingClick?canvasClick($event):undefined">
-
-                <div v-for="(tempPoint, index) in tempPoints" :key="index" class="point-area"
-                     :style="{
-                        'background-color':'#1abd6c',
-                        color:'#fff',
-                        'z-index':9999,
-                        width:'20px',
-                        height:'20px',
-                        'text-align':'center',
-                        'line-height':'20px',
-                        'border-radius': '50%',
-                        position:'absolute',
-                        top:parseInt(tempPoint.y-10) + 'px',
-                        left:parseInt(tempPoint.x-10) + 'px'
-                     }">
-                    {{index + 1}}
-                </div>
-            </div>
+  <div style="position: relative">
+    <div class="verify-img-out">
+      <div
+        class="verify-img-panel"
+        :style="{
+          width: setSize.imgWidth,
+          height: setSize.imgHeight,
+          'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
+          'margin-bottom': vSpace + 'px'
+        }"
+      >
+        <div v-show="showRefresh" class="verify-refresh" style="z-index: 3" @click="refresh">
+          <i class="iconfont icon-refresh"></i>
         </div>
-        <!-- 'height': this.barSize.height, -->
-        <div class="verify-bar-area"
-             :style="{'width': setSize.imgWidth,
-                      'color': this.barAreaColor,
-                      'border-color': this.barAreaBorderColor,
-                      'line-height':this.barSize.height}">
-            <span class="verify-msg">{{text}}</span>
+        <img
+          ref="canvas"
+          :src="'data:image/png;base64,' + pointBackImgBase"
+          alt=""
+          style="width: 100%; height: 100%; display: block"
+          @click="bindingClick ? canvasClick($event) : undefined"
+        />
+
+        <div
+          v-for="(tempPoint, index) in tempPoints"
+          :key="index"
+          class="point-area"
+          :style="{
+            'background-color': '#1abd6c',
+            color: '#fff',
+            'z-index': 9999,
+            width: '20px',
+            height: '20px',
+            'text-align': 'center',
+            'line-height': '20px',
+            'border-radius': '50%',
+            position: 'absolute',
+            top: parseInt(tempPoint.y - 10) + 'px',
+            left: parseInt(tempPoint.x - 10) + 'px'
+          }"
+        >
+          {{ index + 1 }}
         </div>
+      </div>
+    </div>
+    <!-- 'height': this.barSize.height, -->
+    <div
+      class="verify-bar-area"
+      :style="{
+        width: setSize.imgWidth,
+        color: barAreaColor,
+        'border-color': barAreaBorderColor,
+        'line-height': barSize.height
+      }"
+    >
+      <span class="verify-msg">{{ text }}</span>
     </div>
+  </div>
 </template>
 <script type="text/babel">
-    /**
-     * VerifyPoints
-     * @description 点选
-     * */
-    import {resetSize, _code_chars, _code_color1, _code_color2} from './../utils/util'
-    import {aesEncrypt} from "./../utils/ase"
-    import {reqGet,reqCheck}  from "./../api/index"
-    import { computed, onMounted, reactive, ref,watch,nextTick,toRefs, watchEffect,getCurrentInstance} from 'vue';
-    export default {
-        name: 'VerifyPoints',
-        props: {
-            //弹出式pop,固定fixed
-            mode: {
-                type: String,
-                default: 'fixed'
-            },
-            captchaType:{
-                type:String,
-            },
-            //间隔
-            vSpace: {
-                type: Number,
-                default: 5
-            },
-            imgSize: {
-                type: Object,
-                default() {
-                    return {
-                        width: '310px',
-                        height: '155px'
-                    }
-                }
-            },
-            barSize: {
-                type: Object,
-                default() {
-                    return {
-                        width: '310px',
-                        height: '40px'
-                    }
-                }
-            }
-        },
-        setup(props,context){
-            const {mode,captchaType,vSpace,imgSize,barSize} = toRefs(props)
-            const { proxy } = getCurrentInstance();
-            let secretKey = ref(''),           //后端返回的ase加密秘钥
-                checkNum = ref(3),             //默认需要点击的字数
-                fontPos = reactive([]),            //选中的坐标信息
-                checkPosArr = reactive([]),        //用户点击的坐标
-                num = ref(1),                 //点击的记数
-                pointBackImgBase = ref(''),    //后端获取到的背景图片
-                poinTextList = reactive([]),        //后端返回的点击字体顺序
-                backToken = ref(''),           //后端返回的token值
-                setSize = reactive({
-                    imgHeight: 0,
-                    imgWidth: 0,
-                    barHeight: 0,
-                    barWidth: 0
-                }),
-                tempPoints = reactive([]),
-                text = ref(''),
-                barAreaColor = ref(undefined),
-                barAreaBorderColor = ref(undefined),
-                showRefresh = ref(true),
-                bindingClick = ref(true)
-
-                
-               
+/**
+ * VerifyPoints
+ * @description 点选
+ * */
+import { onMounted, reactive, ref, nextTick, toRefs, getCurrentInstance } from 'vue';
+import { resetSize } from './../utils/util';
+import { aesEncrypt } from './../utils/ase';
+import { reqGet, reqCheck } from './../api/index';
+export default {
+  name: 'VerifyPoints',
+  props: {
+    // 弹出式pop,固定fixed
+    mode: {
+      type: String,
+      default: 'fixed'
+    },
+    // 间隔
+    vSpace: {
+      type: Number,
+      default: 5
+    },
+    imgSize: {
+      type: Object,
+      default() {
+        return {
+          width: '310px',
+          height: '155px'
+        };
+      }
+    },
+    barSize: {
+      type: Object,
+      default() {
+        return {
+          width: '310px',
+          height: '40px'
+        };
+      }
+    }
+  },
+  setup(props) {
+    const { mode, captchaType } = toRefs(props);
+    const { proxy } = getCurrentInstance();
+    const secretKey = ref(''); // 后端返回的ase加密秘钥
+    const checkNum = ref(3); // 默认需要点击的字数
+    const fontPos = reactive([]); // 选中的坐标信息
+    const checkPosArr = reactive([]); // 用户点击的坐标
+    const num = ref(1); // 点击的记数
+    const pointBackImgBase = ref(''); // 后端获取到的背景图片
+    const poinTextList = reactive([]); // 后端返回的点击字体顺序
+    const backToken = ref(''); // 后端返回的token值
+    const setSize = reactive({
+      imgHeight: 0,
+      imgWidth: 0,
+      barHeight: 0,
+      barWidth: 0
+    });
+    const tempPoints = reactive([]);
+    const text = ref('');
+    const barAreaColor = ref(undefined);
+    const barAreaBorderColor = ref(undefined);
+    const showRefresh = ref(true);
+    const bindingClick = ref(true);
 
-                const init = ()=>{
-                    //加载页面
-                    fontPos.splice(0, fontPos.length)
-                    checkPosArr.splice(0, checkPosArr.length)
-                    num.value = 1
-                    getPictrue();
-                    nextTick(() => {
-                        let {imgHeight,imgWidth,barHeight,barWidth} = resetSize(proxy)
-                        setSize.imgHeight = imgHeight
-                        setSize.imgWidth = imgWidth
-                        setSize.barHeight = barHeight
-                        setSize.barWidth = barWidth
-                        proxy.$parent.$emit('ready', proxy)
-                    })
-                }
-                 onMounted(()=>{
-                    // 禁止拖拽
-                    init()
-                    proxy.$el.onselectstart = function () {
-                        return false
-                    }
-                })
-                const canvas = ref(null)
-                const canvasClick = (e)=>{
-                    checkPosArr.push(getMousePos(canvas, e));
-                    if (num.value == checkNum.value) {
-                        num.value = createPoint(getMousePos(canvas, e));
-                        //按比例转换坐标值
-                        let arr = pointTransfrom(checkPosArr,setSize)
-                        checkPosArr.length = 0
-                        checkPosArr.push(...arr);
-                        //等创建坐标执行完
-                        setTimeout(() => {
-                            // var flag = this.comparePos(this.fontPos, this.checkPosArr);
-                            //发送后端请求
-                            var captchaVerification = secretKey.value? aesEncrypt(backToken.value+'---'+JSON.stringify(checkPosArr),secretKey.value):backToken.value+'---'+JSON.stringify(checkPosArr)
-                            let data = {
-                                captchaType:captchaType.value,
-                                "pointJson":secretKey.value? aesEncrypt(JSON.stringify(checkPosArr),secretKey.value):JSON.stringify(checkPosArr),
-                                "token":backToken.value
-                            }
-                            reqCheck(data).then(res=>{
-                                if (res.repCode == "0000") {
-                                    barAreaColor.value = '#4cae4c'
-                                    barAreaBorderColor.value = '#5cb85c'
-                                    text.value = '验证成功'
-                                    bindingClick.value = false
-                                    if (mode.value=='pop') {
-                                        setTimeout(()=>{
-                                            proxy.$parent.clickShow = false;
-                                            refresh();
-                                        },1500)
-                                    }
-                                    proxy.$parent.$emit('success', {captchaVerification})
-                                }else{
-                                    proxy.$parent.$emit('error', proxy)
-                                    barAreaColor.value = '#d9534f'
-                                    barAreaBorderColor.value = '#d9534f'
-                                    text.value = '验证失败'
-                                    setTimeout(() => {
-                                        refresh();
-                                    }, 700);
-                                }
-                            })
-                        }, 400);
-                    }
-                    if (num.value < checkNum.value) {
-                        num.value = createPoint(getMousePos(canvas, e));
-                    }
-                }
-                 //获取坐标
-                const getMousePos = function (obj, e) {
-                    var x = e.offsetX 
-                    var y = e.offsetY 
-                    return {x, y}
-                }
-                //创建坐标点
-                const createPoint = function (pos) {
-                    tempPoints.push(Object.assign({}, pos))
-                    return num.value+1;
-                }
-                const refresh = function () {
-                    tempPoints.splice(0, tempPoints.length)
-                    barAreaColor.value = '#000'
-                    barAreaBorderColor.value = '#ddd'
-                    bindingClick.value = true
-                    fontPos.splice(0, fontPos.length)
-                    checkPosArr.splice(0, checkPosArr.length)
-                    num.value = 1
-                    getPictrue();
-                    text.value = '验证失败'
-                    showRefresh.value = true
-                }
+    const init = () => {
+      // 加载页面
+      fontPos.splice(0, fontPos.length);
+      checkPosArr.splice(0, checkPosArr.length);
+      num.value = 1;
+      getPictrue();
+      nextTick(() => {
+        const { imgHeight, imgWidth, barHeight, barWidth } = resetSize(proxy);
+        setSize.imgHeight = imgHeight;
+        setSize.imgWidth = imgWidth;
+        setSize.barHeight = barHeight;
+        setSize.barWidth = barWidth;
+        proxy.$parent.$emit('ready', proxy);
+      });
+    };
+    onMounted(() => {
+      // 禁止拖拽
+      init();
+      proxy.$el.onselectstart = () => {
+        return false;
+      };
+    });
+    const canvas = ref(null);
+    // 获取坐标
+    const getMousePos = e => {
+      const x = e.offsetX;
+      const y = e.offsetY;
+      return { x, y };
+    };
+    // 创建坐标点
+    const createPoint = pos => {
+      tempPoints.push({ ...pos });
+      return num.value + 1;
+    };
+    const refresh = () => {
+      tempPoints.splice(0, tempPoints.length);
+      barAreaColor.value = '#000';
+      barAreaBorderColor.value = '#ddd';
+      bindingClick.value = true;
+      fontPos.splice(0, fontPos.length);
+      checkPosArr.splice(0, checkPosArr.length);
+      num.value = 1;
+      getPictrue();
+      text.value = '验证失败';
+      showRefresh.value = true;
+    };
 
-                // 请求背景图片和验证图片
-                function getPictrue() {
-                    let data = {
-                        captchaType:captchaType.value
-                    }
-                    reqGet(data).then(res=>{
-                        if (res.repCode == "0000") {
-                            pointBackImgBase.value = res.repData.originalImageBase64
-                            backToken.value = res.repData.token
-                            secretKey.value = res.repData.secretKey
-                            poinTextList.value = res.repData.wordList
-                            text.value = '请依次点击【' + poinTextList.value.join(",") + '】'
-                        }else{
-                            text.value = res.repMsg;
-                        }
-                    })
-                }
-                //坐标转换函数
-                const pointTransfrom = function(pointArr,imgSize){
-                    var newPointArr = pointArr.map(p=>{
-                        let x = Math.round(310 * p.x/parseInt(imgSize.imgWidth)) 
-                        let y =Math.round(155 * p.y/parseInt(imgSize.imgHeight)) 
-                        return {x,y}
-                    })
-                    return newPointArr
-                }
-                return {
-                    secretKey,
-                    checkNum,
-                    fontPos,
-                    checkPosArr,
-                    num,
-                    pointBackImgBase,
-                    poinTextList,
-                    backToken,
-                    setSize,
-                    tempPoints,
-                    text,
-                    barAreaColor,
-                    barAreaBorderColor,
-                    showRefresh,
-                    bindingClick,
-                    init,
-                    canvas,
-                    canvasClick,
-                    getMousePos,createPoint,refresh,getPictrue,pointTransfrom
-                }
-        },
+    // 请求背景图片和验证图片
+    function getPictrue() {
+      const data = {
+        captchaType: captchaType.value
+      };
+      reqGet(data).then(res => {
+        if (res.repCode === '0000') {
+          pointBackImgBase.value = res.repData.originalImageBase64;
+          backToken.value = res.repData.token;
+          secretKey.value = res.repData.secretKey;
+          poinTextList.value = res.repData.wordList;
+          text.value = `请依次点击【${poinTextList.value.join(',')}】`;
+        } else {
+          text.value = res.repMsg;
+        }
+      });
+    }
+    // 坐标转换函数
+    function pointTransfrom(pointArr, imgSize) {
+      const newPointArr = pointArr.map(p => {
+        const x = Math.round((310 * p.x) / parseInt(imgSize.imgWidth, 10));
+        const y = Math.round((155 * p.y) / parseInt(imgSize.imgHeight, 10));
+        return { x, y };
+      });
+      return newPointArr;
     }
-</script>
+    const canvasClick = e => {
+      checkPosArr.push(getMousePos(canvas, e));
+      if (num.value === checkNum.value) {
+        num.value = createPoint(getMousePos(canvas, e));
+        // 按比例转换坐标值
+        const arr = pointTransfrom(checkPosArr, setSize);
+        checkPosArr.length = 0;
+        checkPosArr.push(...arr);
+        // 等创建坐标执行完
+        setTimeout(() => {
+          // var flag = this.comparePos(this.fontPos, this.checkPosArr);
+          // 发送后端请求
+          const captchaVerification = secretKey.value
+            ? aesEncrypt(`${backToken.value}---${JSON.stringify(checkPosArr)}`, secretKey.value)
+            : `${backToken.value}---${JSON.stringify(checkPosArr)}`;
+          const data = {
+            captchaType: captchaType.value,
+            pointJson: secretKey.value
+              ? aesEncrypt(JSON.stringify(checkPosArr), secretKey.value)
+              : JSON.stringify(checkPosArr),
+            token: backToken.value
+          };
+          reqCheck(data).then(res => {
+            if (res.repCode === '0000') {
+              barAreaColor.value = '#4cae4c';
+              barAreaBorderColor.value = '#5cb85c';
+              text.value = '验证成功';
+              bindingClick.value = false;
+              if (mode.value === 'pop') {
+                setTimeout(() => {
+                  proxy.$parent.clickShow = false;
+                  refresh();
+                }, 1500);
+              }
+              proxy.$parent.$emit('success', { captchaVerification });
+            } else {
+              proxy.$parent.$emit('error', proxy);
+              barAreaColor.value = '#d9534f';
+              barAreaBorderColor.value = '#d9534f';
+              text.value = '验证失败';
+              setTimeout(() => {
+                refresh();
+              }, 700);
+            }
+          });
+        }, 400);
+      }
+      if (num.value < checkNum.value) {
+        num.value = createPoint(getMousePos(canvas, e));
+      }
+    };
+
+    return {
+      secretKey,
+      checkNum,
+      fontPos,
+      checkPosArr,
+      num,
+      pointBackImgBase,
+      poinTextList,
+      backToken,
+      setSize,
+      tempPoints,
+      text,
+      barAreaColor,
+      barAreaBorderColor,
+      showRefresh,
+      bindingClick,
+      init,
+      canvas,
+      canvasClick,
+      getMousePos,
+      createPoint,
+      refresh,
+      getPictrue,
+      pointTransfrom
+    };
+  }
+};
+</script>

+ 5 - 5
src/views/_builtin/login/components/pwd-login/components/validate/utils/ase.js

@@ -1,11 +1,11 @@
-import CryptoJS from 'crypto-js'
+import CryptoJS from 'crypto-js';
 /**
  * @word 要加密的内容
  * @keyWord String  服务器随机返回的关键字
  *  */
-export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
-  var key = CryptoJS.enc.Utf8.parse(keyWord);
-  var srcs = CryptoJS.enc.Utf8.parse(word);
-  var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
+export function aesEncrypt(word, keyWord = 'XwKsGlMcdPMEhR1B') {
+  const key = CryptoJS.enc.Utf8.parse(keyWord);
+  const srcs = CryptoJS.enc.Utf8.parse(word);
+  const encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
   return encrypted.toString();
 }

+ 9 - 8
src/views/_builtin/login/components/pwd-login/components/validate/utils/axios.js

@@ -7,24 +7,25 @@ const service = axios.create({
   headers: {
     'X-Requested-With': 'XMLHttpRequest',
     'Content-Type': 'application/json; charset=UTF-8'
-  },
-})
+  }
+});
 service.interceptors.request.use(
   config => {
-    return config
+    return config;
   },
   error => {
-    Promise.reject(error)
+    Promise.reject(error);
   }
-)
+);
 
 // response interceptor
 service.interceptors.response.use(
   response => {
     const res = response.data;
-    return res
+    return res;
   },
   error => {
+    return Promise.reject(error);
   }
-)
-export default service
+);
+export default service;

+ 27 - 28
src/views/_builtin/login/components/pwd-login/components/validate/utils/util.js

@@ -1,35 +1,34 @@
 export function resetSize(vm) {
-    var img_width, img_height, bar_width, bar_height;	//图片的宽度、高度,移动条的宽度、高度
+  let bar_height;
+  let bar_width;
+  let img_height;
+  let img_width; // 图片的宽度、高度,移动条的宽度、高度
 
-    var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth
-    var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight
-    if (vm.imgSize.width.indexOf('%') != -1) {
-        img_width = parseInt(vm.imgSize.width) / 100 * parentWidth + 'px'
-    } else {
-        img_width = vm.imgSize.width;
-    }
+  const parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth;
+  const parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight;
+  if (vm.imgSize.width.indexOf('%') !== -1) {
+    img_width = `${(parseInt(vm.imgSize.width, 10) / 100) * parentWidth}px`;
+  } else {
+    img_width = vm.imgSize.width;
+  }
 
-    if (vm.imgSize.height.indexOf('%') != -1) {
-        img_height = parseInt(vm.imgSize.height) / 100 * parentHeight + 'px'
-    } else {
-        img_height = vm.imgSize.height
-    }
+  if (vm.imgSize.height.indexOf('%') !== -1) {
+    img_height = `${(parseInt(vm.imgSize.height, 10) / 100) * parentHeight}px`;
+  } else {
+    img_height = vm.imgSize.height;
+  }
 
-    if (vm.barSize.width.indexOf('%') != -1) {
-        bar_width = parseInt(vm.barSize.width) / 100 * parentWidth + 'px'
-    } else {
-        bar_width = vm.barSize.width
-    }
+  if (vm.barSize.width.indexOf('%') !== -1) {
+    bar_width = `${(parseInt(vm.barSize.width, 10) / 100) * parentWidth}px`;
+  } else {
+    bar_width = vm.barSize.width;
+  }
 
-    if (vm.barSize.height.indexOf('%') != -1) {
-        bar_height = parseInt(vm.barSize.height) / 100 * parentHeight + 'px'
-    } else {
-        bar_height = vm.barSize.height
-    }
+  if (vm.barSize.height.indexOf('%') !== -1) {
+    bar_height = `${(parseInt(vm.barSize.height, 10) / 100) * parentHeight}px`;
+  } else {
+    bar_height = vm.barSize.height;
+  }
 
-    return {imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height}
+  return { imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height };
 }
-
-export const _code_chars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
-export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0']
-export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC']

+ 5 - 11
src/views/auth-demo/permission/index.vue

@@ -4,13 +4,7 @@
       <div class="pb-12px">
         <n-gradient-text type="primary" :size="20">当前用户的权限:{{ auth.userInfo.userRole }}</n-gradient-text>
       </div>
-      <n-select
-        :value="auth.userInfo.userRole"
-        class="w-120px"
-        size="small"
-        :options="options"
-        @update:value="auth.updateUserRole"
-      />
+      <n-select :value="auth.userInfo.userRole" class="w-120px" size="small" />
       <div class="py-12px">
         <n-gradient-text type="primary" :size="20">权限指令 v-permission</n-gradient-text>
       </div>
@@ -23,7 +17,7 @@
         <n-gradient-text type="primary" :size="20">权限函数 hasPermission</n-gradient-text>
       </div>
       <n-space>
-        <n-button v-if="hasPermission('super')">super可见</n-button>
+        <n-button v-if="hasPermission('member')">super可见</n-button>
         <n-button v-if="hasPermission('admin')">admin可见</n-button>
         <n-button v-if="hasPermission(['admin', 'user'])">admin和user可见</n-button>
       </n-space>
@@ -33,8 +27,8 @@
 
 <script setup lang="ts">
 import { watch } from 'vue';
-import type { SelectOption } from 'naive-ui';
-import { userRoleOptions } from '@/constants';
+// import type { SelectOption } from 'naive-ui';
+// import { userRoleOptions } from '@/constants';
 import { useAppStore, useAuthStore } from '@/store';
 import { usePermission } from '@/composables';
 
@@ -42,7 +36,7 @@ const app = useAppStore();
 const auth = useAuthStore();
 const { hasPermission } = usePermission();
 
-const options: SelectOption[] = userRoleOptions;
+// const options: SelectOption[] = userRoleOptions;
 
 watch(
   () => auth.userInfo.userRole,

+ 5 - 5
src/views/dashboard/analysis/index.vue

@@ -2,17 +2,17 @@
   <n-space :vertical="true" :size="16">
     <top-chart />
     <data-card />
-		<div>
-			<PDFView :pdfUrl="jsPdf" />
-		</div>
+    <div>
+      <PDFView :pdf-url="jsPdf" />
+    </div>
     <bottom-part />
   </n-space>
 </template>
 
 <script lang="ts" setup>
+import PDFView from '../../.././components/View/pdfPreview.vue';
+import jsPdf from '../../../java.pdf';
 import { BottomPart, DataCard, TopChart } from './components';
-import PDFView from "../../.././components/View/pdfPreview.vue"
-import jsPdf from "../../../java.pdf"
 </script>
 
 <style scoped></style>

+ 1 - 1
src/views/dashboard/workbench/components/workbench-header/index.vue

@@ -4,7 +4,7 @@
       <div class="flex-y-center">
         <icon-local-avatar class="text-70px" />
         <div class="pl-12px">
-          <h3 class="text-18px font-semibold">早安,{{ auth.userInfo.userName }}, 今天又是充满活力的一天!</h3>
+          <h3 class="text-18px font-semibold">早安,{{ auth.userInfo.username }}, 今天又是充满活力的一天!</h3>
           <p class="leading-30px text-#999">今日多云转晴,20℃ - 25℃!</p>
         </div>
       </div>

+ 0 - 1
src/views/management/auth/index.vue

@@ -33,7 +33,6 @@ async function getTableData() {
   const params: QueryParams = {};
 
   query(pageNum, pageSize, params).then(res => {
-    // console.log(res);
     tableData.value = res.data as [];
   });
 }

+ 2 - 3
src/views/management/role/index.vue

@@ -28,12 +28,11 @@ const pagination: PaginationProps = ref({
 }).value;
 
 async function getTableData() {
-  const pageNum = pagination.page as number;//页码
-  const pageSize = pagination.pageSize as number;//当前所在数
+  const pageNum = pagination.page as number; // 页码
+  const pageSize = pagination.pageSize as number; // 当前所在数
   const params: QueryParams = {};
 
   query(pageNum, pageSize, params).then(res => {
-    // console.log(res);
     tableData.value = res.data as [];
   });
 }

+ 68 - 70
src/views/management/role/queryUser.vue

@@ -15,6 +15,19 @@ import type { QueryParams } from '~/src/service/api/user';
 
 const tableData = ref<QueryParams[]>([]);
 
+const pagination: PaginationProps = ref({
+  page: 1,
+  pageSize: 10,
+  showSizePicker: true,
+  pageSizes: [10, 20, 50],
+  onChange: () => {
+    // 处理页码变化
+  },
+  onUpdatePageSize: () => {
+    // 处理每页显示数量变化
+  }
+}).value;
+
 async function getTableData() {
   const pageNum = pagination.page as number;
   const pageSize = pagination.pageSize as number;
@@ -24,85 +37,70 @@ async function getTableData() {
     description: '',
     isActive: '',
     createTime: '',
-    modifyTime: "" ,
+    modifyTime: '',
     createUid: 0,
-    disabled: '',
+    disabled: ''
   };
 
-	query(pageNum, pageSize, params).then((res) => {
-			console.log(res);
-			tableData.value =  res.data as[]
-		})
+  query(pageNum, pageSize, params).then(res => {
+    tableData.value = res.data as [];
+  });
 }
 
 const columns: Ref<DataTableColumns<QueryParams>> = ref([
-	{
-		type: 'selection',
-		align: 'center'
-	},
-	{
-		key: 'depname',
-		title: '部门名称',
-		align: 'center'
-	},
-	{
-		key: 'address',
-		title: '部门地址',
-		align: 'center'
-	},
-	{
-		key: 'phone',
-		title: '部门电话',
-		align: 'center'
-	},
-	{
-		key: 'email',
-		title: '部门电子邮箱',
-		align: 'center',
-	},
-	{
-		key: 'manager',
-		title: '部门负责人',
-		align: 'center'
-	},
-	{
-		key: 'createTime',
-		title: '创建时间',
-		align: 'center'
-	},
-	{
-		key: 'modifyTime',
-		title: '修改时间',
-		align: 'center'
-	},
-	{
-		key: 'createUid',
-		title: '创建用户ID',
-		align: 'center'
-	},
-	{
-		key: 'disabled',
-		title: '状态',
-		align: 'center'
-	},
-
+  {
+    type: 'selection',
+    align: 'center'
+  },
+  {
+    key: 'depname',
+    title: '部门名称',
+    align: 'center'
+  },
+  {
+    key: 'address',
+    title: '部门地址',
+    align: 'center'
+  },
+  {
+    key: 'phone',
+    title: '部门电话',
+    align: 'center'
+  },
+  {
+    key: 'email',
+    title: '部门电子邮箱',
+    align: 'center'
+  },
+  {
+    key: 'manager',
+    title: '部门负责人',
+    align: 'center'
+  },
+  {
+    key: 'createTime',
+    title: '创建时间',
+    align: 'center'
+  },
+  {
+    key: 'modifyTime',
+    title: '修改时间',
+    align: 'center'
+  },
+  {
+    key: 'createUid',
+    title: '创建用户ID',
+    align: 'center'
+  },
+  {
+    key: 'disabled',
+    title: '状态',
+    align: 'center'
+  }
 ]) as Ref<DataTableColumns<QueryParams>>;
 
-const pagination: PaginationProps = ref({
-	page: 1,
-	pageSize: 10,
-	showSizePicker: true,
-	pageSizes: [10, 20, 50],
-	onChange: (page: number) => {
-		// 处理页码变化
-	},
-	onUpdatePageSize: (pageSize: number) => {
-		// 处理每页显示数量变化
-	}
-}).value;
-
 function init() {
-	getTableData();
+  getTableData();
 }
 
 // 初始化

+ 2 - 9
src/views/management/role/userPa.vue

@@ -5,8 +5,7 @@
 </template>
 
 <script lang="ts">
-import { reactive } from 'vue';
-import { defineComponent, ref } from 'vue';
+import { reactive, defineComponent, ref } from 'vue';
 import type { QueryParams } from '~/src/service/api/user';
 
 export default defineComponent({
@@ -14,13 +13,7 @@ export default defineComponent({
     const pageNum = ref(2);
     const pageSize = ref<any>(10);
     const queryData = reactive<QueryParams>({});
-    function queryList() {
-      console.log(1);
-
-      // query(1, 10, queryData).then(r => {
-      // 	console.log(r);
-      // });
-    }
+    function queryList() {}
 
     return {
       // 每页条数, 可自定义 page-size

+ 1 - 3
src/views/management/route/index.vue

@@ -7,9 +7,7 @@ import type { QueryParams } from '~/src/service/api/user';
 import { query } from '~/src/service/api/user';
 const queryData: QueryParams = {};
 
-query(1, 20, queryData).then(r => {
-  console.log(r);
-});
+query(1, 20, queryData);
 </script>
 
 <style scoped></style>

+ 77 - 70
src/views/management/sort/components/column-search.vue

@@ -1,88 +1,95 @@
 <template>
-	<n-space>
-		<n-input-group>
-			<n-input-group>
-				 <span class="w-80px mr-5px line-height-33.99px">学科名称</span> <n-input :style="{ width: '31%', marginRight: '2%' }"
-					clearable />
-				<span class="w-80px mr-5px line-height-33.99px">学科描述</span> <n-input :style="{ width: '31%' ,marginRight:'2%'}" clearable/>
-    		<span class="w-100px line-height-33.99px">创建用户ID</span> <n-input-number :style="{ width: '22%',marginRight:'10%' }" clearable />
-			</n-input-group>
-			<n-input-group>
-			  <span class="line-height-33.99px mr-5px w-70px">创建时间</span>
-				<n-date-picker :style="{ width: '13%' }" />
-				<n-time-picker :style="{ width: '14.2%', marginRight: '2%' }" />
-				<span class="line-height-33.99px mr-5px w-70px">修改时间</span>
-				<n-date-picker :style="{ width: '13%' }" />
-				<n-time-picker :style="{ width: '14.2%', marginRight: '2%' }" />
-				<span class="w-50px  line-height-33.99px">状态</span>
-				<n-select :options="selectOptions" :style="{ width: '21%', marginRight: '2%' }" clearable />
-			</n-input-group>
-			<span class="w-40px mr-5px line-height-33.99px">页码</span> <n-input-number :style="{ width: '48%', marginRight: '2%' }"
-				placeholder="请输入页码..." clearable v-model="pagination.page" @change="searchCondition" />
-			<span class="w-40px mr-5px line-height-33.99px">条数</span> <n-input-number :style="{ width: '48%' }"
-				placeholder="请输入数据条数..." clearable v-model="pagination.pageSize" @change="searchCondition" />
-			 <n-button type="primary" ghost @click="searchCondition()">
-				搜索
-			</n-button>
-		</n-input-group>
-	</n-space>
+  <n-space>
+    <n-input-group>
+      <n-input-group>
+        <span class="w-80px mr-5px line-height-33.99px">学科名称</span>
+        <n-input :style="{ width: '31%', marginRight: '2%' }" clearable />
+        <span class="w-80px mr-5px line-height-33.99px">学科描述</span>
+        <n-input :style="{ width: '31%', marginRight: '2%' }" clearable />
+        <span class="w-100px line-height-33.99px">创建用户ID</span>
+        <n-input-number :style="{ width: '22%', marginRight: '10%' }" clearable />
+      </n-input-group>
+      <n-input-group>
+        <span class="line-height-33.99px mr-5px w-70px">创建时间</span>
+        <n-date-picker :style="{ width: '13%' }" />
+        <n-time-picker :style="{ width: '14.2%', marginRight: '2%' }" />
+        <span class="line-height-33.99px mr-5px w-70px">修改时间</span>
+        <n-date-picker :style="{ width: '13%' }" />
+        <n-time-picker :style="{ width: '14.2%', marginRight: '2%' }" />
+        <span class="w-50px line-height-33.99px">状态</span>
+        <n-select :options="selectOptions" :style="{ width: '21%', marginRight: '2%' }" clearable />
+      </n-input-group>
+      <span class="w-40px mr-5px line-height-33.99px">页码</span>
+      <n-input-number
+        v-model="pagination.page"
+        :style="{ width: '48%', marginRight: '2%' }"
+        placeholder="请输入页码..."
+        clearable
+        @change="searchCondition"
+      />
+      <span class="w-40px mr-5px line-height-33.99px">条数</span>
+      <n-input-number
+        v-model="pagination.pageSize"
+        :style="{ width: '48%' }"
+        placeholder="请输入数据条数..."
+        clearable
+        @change="searchCondition"
+      />
+      <n-button type="primary" ghost @click="searchCondition()"> 搜索 </n-button>
+    </n-input-group>
+  </n-space>
 </template>
 
 <script lang="ts">
-import { defineComponent, ref } from 'vue'
-import { NButton, NSpace } from 'naive-ui';
+import { defineComponent, ref } from 'vue';
 import type { PaginationProps } from 'naive-ui';
-
 import { selectByCondition_1 } from '~/src/service/api/sort';
 import type { SelectByCondition_1Params } from '~/src/service/api/sort';
 
 const searchData = ref<any[]>([]);
 const pagination: PaginationProps = ref({
-	page: 1,
-	pageSize: 10,
-	showSizePicker: true,
-	pageSizes: [10, 20, 50],
-	onChange: (page: number) => {
-		// 处理页码变化
-		pagination.page = page;
-	},
-	onUpdatePageSize: (pageSize: number) => {
-		// 处理每页显示数量变化
-		pagination.pageSize = pageSize;
-		pagination.page = 1;
-	}
+  page: 1,
+  pageSize: 10,
+  showSizePicker: true,
+  pageSizes: [10, 20, 50],
+  onChange: (page: number) => {
+    // 处理页码变化
+    pagination.page = page;
+  },
+  onUpdatePageSize: (pageSize: number) => {
+    // 处理每页显示数量变化
+    pagination.pageSize = pageSize;
+    pagination.page = 1;
+  }
 }).value;
 
 function searchCondition() {
-	const pageNum = pagination.page as number;
-	const pageSize = pagination.pageSize as number;
-	const params: SelectByCondition_1Params = {};
-	console.log(pageNum, pageSize);
+  const pageNum = pagination.page as number;
+  const pageSize = pagination.pageSize as number;
+  const params: SelectByCondition_1Params = {};
 
-	selectByCondition_1(pageNum, pageSize, params).then(res => {
-		// console.log(res);
-		searchData.value = res.data as [];
-		console.log(searchData.value);
-	});
+  selectByCondition_1(pageNum, pageSize, params).then(res => {
+    searchData.value = res.data as [];
+  });
 }
 
 export default defineComponent({
-	setup() {
-		return {
-			searchCondition,
-			searchData,
-			pagination,
-			selectOptions: ref([
-				{
-					label: 'Y',
-					value: 'Y'
-				},
-				{
-					label: 'N',
-					value: 'N'
-				}
-			]),
-		}
-	}
-})
+  setup() {
+    return {
+      searchCondition,
+      searchData,
+      pagination,
+      selectOptions: ref([
+        {
+          label: 'Y',
+          value: 'Y'
+        },
+        {
+          label: 'N',
+          value: 'N'
+        }
+      ])
+    };
+  }
+});
 </script>

+ 119 - 124
src/views/management/sort/components/table-action-add.vue

@@ -1,61 +1,65 @@
 <template>
-	<n-modal v-model:show="modalVisible" preset="card" :title="title" class="w-700px">
-		<n-form ref="formRef" label-placement="left" :label-width="100" :model="formModel" :rules="rules">
-			<n-grid :cols="24" :x-gap="18">
-				<!-- <n-form-item-grid-item :span="12" label="ID" path="id">
+  <n-modal v-model:show="modalVisible" preset="card" :title="title" class="w-700px">
+    <n-form ref="formRef" label-placement="left" :label-width="100" :model="formModel" :rules="rules">
+      <n-grid :cols="24" :x-gap="18">
+        <!-- <n-form-item-grid-item :span="12" label="ID" path="id">
 					<n-input-number v-model:value="formModel.id" />
 				</n-form-item-grid-item> -->
-				<n-form-item-grid-item :span="12" label="学科名称" path="name">
-					<n-input v-model:value="formModel.name" clearable />
-				</n-form-item-grid-item>
-				<!-- <n-form-item-grid-item :span="12" label="创建时间" path="createTime">
+        <n-form-item-grid-item :span="12" label="学科名称" path="name">
+          <n-input v-model:value="formModel.name" clearable />
+        </n-form-item-grid-item>
+        <!-- <n-form-item-grid-item :span="12" label="创建时间" path="createTime">
 					  <n-date-picker v-model:value="timestamp" type="datetime" clearable />
 					<n-input v-model:value="formModel.createTime" />
 				</n-form-item-grid-item> -->
-				<n-form-item-grid-item :span="12" label="学科描述" path="description">
-					<n-input v-model:value="formModel.description" clearable />
-					<!-- <n-radio-group v-model:value="formModel.description">
+        <n-form-item-grid-item :span="12" label="学科描述" path="description">
+          <n-input v-model:value="formModel.description" clearable />
+          <!-- <n-radio-group v-model:value="formModel.description">
 						<n-radio v-for="item in genderOptions" :key="item.value" :value="item.value">{{ item.label }}</n-radio>
 					</n-radio-group> -->
-				</n-form-item-grid-item>
-				<!-- <n-form-item-grid-item :span="12" label="修改时间" path="email">
+        </n-form-item-grid-item>
+        <!-- <n-form-item-grid-item :span="12" label="修改时间" path="email">
 					<n-date-picker v-show="props.type==='edit'" v-model:value="formModel.modifyTime" type="datetime" clearable />
 				</n-form-item-grid-item> -->
-				<n-form-item-grid-item :span="12" label="创建用户ID" path="createUid">
-					<n-input-number v-model:value="formModel.createUid" />
-				</n-form-item-grid-item>
-				<n-form-item-grid-item :span="12" label="状态" path="disabled">
-					<n-select v-model:value="formModel.disabled" :options="userStatusOptions" />
-				</n-form-item-grid-item>
-			</n-grid>
-			<n-space class="w-full pt-16px" :size="24" justify="end">
-				<n-button class="w-72px" @click="closeModal">取消</n-button>
-				<n-button class="w-72px" type="primary" @click="handleSubmit">确定</n-button>
-			</n-space>
-		</n-form>
-	</n-modal>
+        <n-form-item-grid-item :span="12" label="创建用户ID" path="createUid">
+          <n-input-number v-model:value="formModel.createUid" />
+        </n-form-item-grid-item>
+        <n-form-item-grid-item :span="12" label="状态" path="disabled">
+          <n-select v-model:value="formModel.disabled" :options="userStatusOptions" />
+        </n-form-item-grid-item>
+      </n-grid>
+      <n-space class="w-full pt-16px" :size="24" justify="end">
+        <n-button class="w-72px" @click="closeModal">取消</n-button>
+        <n-button class="w-72px" type="primary" @click="handleSubmit">确定</n-button>
+      </n-space>
+    </n-form>
+  </n-modal>
 </template>
 
 <script setup lang="ts">
 import { ref, computed, reactive, watch } from 'vue';
 import type { FormInst, FormItemRule } from 'naive-ui';
-import { userStatusOptions } from '@/constants';
-import {createRequiredFormRule } from '@/utils';
 import dayjs from 'dayjs';
-import { addEasEduCategory, AddEasEduCategoryParams,updateEasEduCategory,UpdateEasEduCategoryParams,SelectByCondition_1Params } from '~/src/service/api/sort';
-
+import { userStatusOptions } from '@/constants';
+import { createRequiredFormRule } from '@/utils';
+import type {
+  AddEasEduCategoryParams,
+  UpdateEasEduCategoryParams,
+  SelectByCondition_1Params
+} from '~/src/service/api/sort';
+import { addEasEduCategory, updateEasEduCategory } from '~/src/service/api/sort';
 
 export interface Props {
-	/** 弹窗可见性 */
-	visible: boolean;
-	/**
-	 * 弹窗类型
-	 * add: 新增
-	 * edit: 编辑
-	 */
-	type?: 'add' | 'edit' ;
-	/** 编辑的表格行数据 */
-	editData?: SelectByCondition_1Params | null;
+  /** 弹窗可见性 */
+  visible: boolean;
+  /**
+   * 弹窗类型
+   * add: 新增
+   * edit: 编辑
+   */
+  type?: 'add' | 'edit';
+  /** 编辑的表格行数据 */
+  editData?: SelectByCondition_1Params | null;
 }
 
 export type ModalType = NonNullable<Props['type']>;
@@ -63,95 +67,91 @@ export type ModalType = NonNullable<Props['type']>;
 defineOptions({ name: 'TableActionAdd' });
 
 const props = withDefaults(defineProps<Props>(), {
-	type: 'add'||'edit',
-	editData: null,
+  type: 'add',
+  editData: null
 });
 
 interface Emits {
-	(e: 'update:visible', visible: boolean): void;
-	  /** 点击协议 */
-	(e: 'searchCondition'): void;
+  (e: 'update:visible', visible: boolean): void;
+  /** 点击协议 */
+  (e: 'searchCondition'): void;
 }
 
 const emit = defineEmits<Emits>();
 
 const modalVisible = computed({
-	get() {
-		return props.visible;
-	},
-	set(visible) {
-		emit('update:visible', visible);
-	}
+  get() {
+    return props.visible;
+  },
+  set(visible) {
+    emit('update:visible', visible);
+  }
 });
 
 const closeModal = () => {
-	modalVisible.value = false;
+  modalVisible.value = false;
 };
 
 const title = computed(() => {
-	const titles: Record<ModalType, string> = {
-		add: '添加用户',
-		edit: '编辑用户',
-	};
-	// console.log(titles[props.type]);
-	return titles[props.type];
-
+  const titles: Record<ModalType, string> = {
+    add: '添加用户',
+    edit: '编辑用户'
+  };
+  return titles[props.type];
 });
 
 const formRef = ref<HTMLElement & FormInst>();
 
-
-interface FormModel extends Pick<SelectByCondition_1Params, 'id' |'name' | 'description' | 'createUid' | 'disabled'|'createTime'> {
+interface FormModel
+  extends Pick<SelectByCondition_1Params, 'id' | 'name' | 'description' | 'createUid' | 'disabled' | 'createTime'> {
   modifyTime: string;
 }
 
 const formModel = reactive<FormModel>(createDefaultFormModel());
 
 const rules: Record<keyof FormModel, FormItemRule | FormItemRule[]> = {
-	id: createRequiredFormRule('请输入用户名'),
-	name: createRequiredFormRule('请输入学科名称'),
-	description: createRequiredFormRule('请进行部门描述'),
-	createTime:createRequiredFormRule('请输入创建时间'),
-	modifyTime:createRequiredFormRule('请输入修改时间'),
-	createUid: createRequiredFormRule('请输入创建用户ID'),
-	disabled: createRequiredFormRule('请选择用户状态')
+  id: createRequiredFormRule('请输入用户名'),
+  name: createRequiredFormRule('请输入学科名称'),
+  description: createRequiredFormRule('请进行部门描述'),
+  createTime: createRequiredFormRule('请输入创建时间'),
+  modifyTime: createRequiredFormRule('请输入修改时间'),
+  createUid: createRequiredFormRule('请输入创建用户ID'),
+  disabled: createRequiredFormRule('请选择用户状态')
 };
 // 'createTime' |'modifyTime'|
 function createDefaultFormModel(): FormModel {
-	return {
-		id: null,
-		name: '',
-		description: '',
-		createTime: '',
-		modifyTime:'',
-		createUid:null,
-		disabled: null,
-	};
+  return {
+    id: null,
+    name: '',
+    description: '',
+    createTime: '',
+    modifyTime: '',
+    createUid: null,
+    disabled: null
+  };
 }
 
 function handleUpdateFormModel(model: SelectByCondition_1Params) {
-	Object.assign(formModel, model);
+  Object.assign(formModel, model);
 }
 
 function handleUpdateFormModelByModalType() {
-	const handlers: Record<ModalType, () => void> = {
-		add: () => {
-			const defaultFormModel = createDefaultFormModel();
-			handleUpdateFormModel(defaultFormModel);
-		},
-		edit: () => {
-			if (props.editData) {
-				console.log(props.editData);
-				handleUpdateFormModel(props.editData);
-			}
-		},
-	};
-
-	handlers[props.type]();
+  const handlers: Record<ModalType, () => void> = {
+    add: () => {
+      const defaultFormModel = createDefaultFormModel();
+      handleUpdateFormModel(defaultFormModel);
+    },
+    edit: () => {
+      if (props.editData) {
+        handleUpdateFormModel(props.editData);
+      }
+    }
+  };
+
+  handlers[props.type]();
 }
-console.log(props.type);
 async function handleSubmit() {
-	await formRef.value?.validate()
+  await formRef.value?.validate();
   if (props.type === 'add') {
     const params: AddEasEduCategoryParams = {
       // id: formModel.id,
@@ -162,45 +162,40 @@ async function handleSubmit() {
     };
     // 调用新增接口
     addEasEduCategory(params)
-      .then(res => {
-        console.log(res);
+      .then(() => {
         window.$message?.success('新增成功!');
-  			emit('searchCondition')
+        emit('searchCondition');
         closeModal();
       })
-      .catch(error => {
-        console.error(error);
+      .catch(() => {
         window.$message?.error('新增失败!');
       });
   } else {
-	   const currentTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
- 		 handleUpdateFormModel({ modifyTime: currentTime });
-     const params: UpdateEasEduCategoryParams = {
-				id: props.editData?.id, // 编辑数据的id
-				name: formModel.name,
-				description: formModel.description,
-				createTime: formModel.createTime,
-				modifyTime: formModel.modifyTime,
-				createUid: formModel.createUid,
-				disabled: formModel.disabled
-     };
+    const currentTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
+    handleUpdateFormModel({ modifyTime: currentTime });
+    const params: UpdateEasEduCategoryParams = {
+      id: props.editData?.id, // 编辑数据的id
+      name: formModel.name,
+      description: formModel.description,
+      createTime: formModel.createTime,
+      modifyTime: formModel.modifyTime,
+      createUid: formModel.createUid,
+      disabled: formModel.disabled
+    };
     // 调用更新接口
-    updateEasEduCategory(params)
-      .then(res => {
-        console.log(res);
-        window.$message?.success('更新成功!');
-				emit('searchCondition')
-        closeModal();
-      })
+    updateEasEduCategory(params).then(() => {
+      window.$message?.success('更新成功!');
+      emit('searchCondition');
+      closeModal();
+    });
   }
 }
 watch(
-	() => props.visible,
-	newValue => {
-		if (newValue) {
-			handleUpdateFormModelByModalType();
-		}
-	}
+  () => props.visible,
+  newValue => {
+    if (newValue) {
+      handleUpdateFormModelByModalType();
+    }
+  }
 );
 </script>
-

+ 36 - 37
src/views/management/sort/crud.tsx

@@ -1,10 +1,10 @@
-import type { AddReq, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from '@fast-crud/fast-crud';
+import type { AddReq, CreateCrudOptionsRet, DelReq, EditReq } from '@fast-crud/fast-crud';
 import { dict } from '@fast-crud/fast-crud';
 import dayjs from 'dayjs';
 import * as api from './api';
 import { selectAll_1 } from './api';
 export default function createCrudOptions(): CreateCrudOptionsRet {
-	const pageRequest = async (query: any): Promise<any> => {
+  const pageRequest = async (query: any): Promise<any> => {
     // 调用你自己的函数从接口获取数据
     const data = await selectAll_1(query);
     return {
@@ -42,23 +42,23 @@ export default function createCrudOptions(): CreateCrudOptionsRet {
           title: 'ID',
           key: 'id',
           type: 'number',
-					search: { show: true },
+          search: { show: true },
           column: {
             width: 50,
-						align:'center',
+            align: 'center'
           },
           form: {
             show: false
           }
         },
-				name: {
+        name: {
           title: '部门名称',
-					search: { show: true },
+          search: { show: true },
           key: 'name',
           type: 'text',
           column: {
             width: 150,
-						align:'center',
+            align: 'center'
           },
           form: {
             show: true
@@ -68,30 +68,30 @@ export default function createCrudOptions(): CreateCrudOptionsRet {
         //   title: '状态',
         //   search: { show: true },
         //   type: 'dict-select',
-				// 	align: 'center',
+        // 	align: 'center',
         //   // dict: dict({
         //   //   url: '/mock/crud/demo/dict'
         //   // })
         // },
         description: {
           title: '部门地址',
-					key: 'description',
+          key: 'description',
           type: 'text',
           search: { show: true },
-					column: {
+          column: {
             width: 200,
-						align:'center',
-          },
+            align: 'center'
+          }
         },
         createTime: {
-					key: 'createTime',
+          key: 'createTime',
           title: '创建时间',
-					type: 'text',
-					column: {
+          type: 'text',
+          column: {
             width: 250,
-						align:'center',
+            align: 'center'
           },
-					search: { show: true },
+          search: { show: true },
           // naive 默认仅支持数字类型时间戳作为日期输入与输出
           // 字符串类型的时间需要转换格式
           valueBuilder(context) {
@@ -110,12 +110,12 @@ export default function createCrudOptions(): CreateCrudOptionsRet {
         },
         modifyTime: {
           title: '修改时间',
-					key: 'modifyTime',
-					type: 'text',
-					align: 'center',
-					column: {
+          key: 'modifyTime',
+          type: 'text',
+          align: 'center',
+          column: {
             width: 250,
-						align:'center',
+            align: 'center'
           },
           // naive 默认仅支持数字类型时间戳作为日期输入与输出
           // 字符串类型的时间需要转换格式
@@ -133,28 +133,28 @@ export default function createCrudOptions(): CreateCrudOptionsRet {
             }
           }
         },
-				createUid: {
+        createUid: {
           title: '创建用户ID',
-					key: 'createUid',
+          key: 'createUid',
           type: 'file-uploader',
-					column: {
+          column: {
             width: 250,
-						align:'center',
-          },
+            align: 'center'
+          }
         },
-				disabled: {
-					key: 'disabled',
-					title: '状态',
-					type: 'dict-select',
-					column: {
+        disabled: {
+          key: 'disabled',
+          title: '状态',
+          type: 'dict-select',
+          column: {
             width: 100,
-						align:'center',
+            align: 'center'
           },
-					dict: dict({
+          dict: dict({
             url: '/mock/crud/demo/dict'
           }),
           search: { show: true }
-        },
+        }
         // richtext: {
         //   title: '富文本',
         //   type: 'editor-wang5',
@@ -174,8 +174,7 @@ export default function createCrudOptions(): CreateCrudOptionsRet {
         //     }
         //   }
         // }
-      },
-
+      }
     }
   };
 }

+ 252 - 205
src/views/management/sort/index.vue

@@ -1,97 +1,145 @@
 <template>
-	<div class="h-full overflow-hidden">
-		<n-scrollbar>
-			<n-card title="课程分类" :bordered="false" class="rounded-16px shadow-sm">
-				<n-space class="pb-14px" justify="space-between">
-					<!-- 加入查询组件 -->
-					<n-space>
-						<n-button type="primary" @click="addTableData">
-							<icon-ic-round-plus class="mr-4px text-20px" />
-							新增
-						</n-button>
-						<n-button type="error" @click="deleteTableData">
-							<icon-ic-round-delete class="mr-4px text-20px" />
-							删除
-						</n-button>
-						<!-- 添加查询按钮 -->
-						<n-button type="primary" @click="">
-							<icon-simple-line-icons:magnifier class="mr-4px text-16px" />
-							查询
-						</n-button>
-						<div class="mr-5px"></div>
-						<n-input-group>
-							<n-input-number :style="{ width: '98%', marginRight: '2%' }" v-model:value="conditionParams.id"
-								placeholder="请输入ID..." clearable />
-							<n-input :style="{ width: '98%', marginRight: '2%' }" :value="conditionParams.name"
-								@input="event => conditionParams.name = event" placeholder="请输入学科名称..." clearable />
-							<n-input :style="{ width: '98%', marginRight: '2%' }" :value="conditionParams.description"
-								@input="event => conditionParams.description = event" placeholder="请输入学科描述..." clearable />
-							<n-input-number :style="{ width: '120%', marginRight: '2%' }" v-model:value="conditionParams.createUid"
-								placeholder="请输入用户ID..." clearable />
-							<n-input :style="{ width: '98%', marginRight: '2%' }" v-model:value="conditionParams.createTime"
-								@input="event => conditionParams.createTime = event" placeholder="请输入创建时间..." clearable />
-							<n-input :style="{ width: '98%', marginRight: '2%' }" v-model:value="conditionParams.modifyTime"
-								@input="event => conditionParams.modifyTime = event" placeholder="请输入修改时间..." clearable />
-							<n-select :options="userStatusOptions" :style="{ width: '98%', marginRight: '2%' }"
-								v-model:value="conditionParams.disabled" @input="event => conditionParams.disabled = event"
-								placeholder="输入查询状态..." clearable />
-							<n-button type="primary" ghost @click="searchCondition()">
-								搜索
-							</n-button>
-						</n-input-group>
-					</n-space>
-					<n-space align="center" :size="18">
-						<n-button size="small" type="primary" @click="searchCondition">
-							<icon-mdi-refresh class="mr-4px text-16px" :class="{ 'animate-spin': loading }" />
-							刷新表格
-						</n-button>
-					</n-space>
-				</n-space>
-				<n-data-table :columns="columns" :data="tableData" :loading="loading" :row-key="rowKey"
-					@update:checked-row-keys="handleCheck" />
-				<n-pagination  class="flex-justify-end"  v-model:page="pagination.page"  v-model:page-size="pagination.pageSize" :item-count="pagination.itemCount"    show-size-picker :page-sizes="[10, 20, 30, 40]" :on-update:page="(page: number)=>{pagination.page = page; searchCondition()}"  :on-update:page-size="(pageSize: number)=>{pagination.pageSize = pageSize; searchCondition()}" />
-				<table-action-add v-model:visible="visible" :type="modalType" @searchCondition="searchCondition"
-					:pagination="pagination" :edit-data="(editData as SelectByCondition_1Params)" />
-			</n-card>
-		</n-scrollbar>
-	</div>
-		<!-- <div>
+  <div class="h-full overflow-hidden">
+    <n-scrollbar>
+      <n-card title="课程分类" :bordered="false" class="rounded-16px shadow-sm">
+        <n-space class="pb-14px" justify="space-between">
+          <!-- 加入查询组件 -->
+          <n-space>
+            <n-button type="primary" @click="addTableData">
+              <icon-ic-round-plus class="mr-4px text-20px" />
+              新增
+            </n-button>
+            <n-button type="error" @click="deleteTableData">
+              <icon-ic-round-delete class="mr-4px text-20px" />
+              删除
+            </n-button>
+            <!-- 添加查询按钮 -->
+            <n-button type="primary">
+              <icon-simple-line-icons:magnifier class="mr-4px text-16px" />
+              查询
+            </n-button>
+            <div class="mr-5px"></div>
+            <n-input-group>
+              <n-input-number
+                v-model:value="conditionParams.id"
+                :style="{ width: '98%', marginRight: '2%' }"
+                placeholder="请输入ID..."
+                clearable
+              />
+              <n-input
+                :style="{ width: '98%', marginRight: '2%' }"
+                :value="conditionParams.name"
+                placeholder="请输入学科名称..."
+                clearable
+                @input="event => (conditionParams.name = event)"
+              />
+              <n-input
+                :style="{ width: '98%', marginRight: '2%' }"
+                :value="conditionParams.description"
+                placeholder="请输入学科描述..."
+                clearable
+                @input="event => (conditionParams.description = event)"
+              />
+              <n-input-number
+                v-model:value="conditionParams.createUid"
+                :style="{ width: '120%', marginRight: '2%' }"
+                placeholder="请输入用户ID..."
+                clearable
+              />
+              <n-input
+                v-model:value="conditionParams.createTime"
+                :style="{ width: '98%', marginRight: '2%' }"
+                placeholder="请输入创建时间..."
+                clearable
+                @input="event => (conditionParams.createTime = event)"
+              />
+              <n-input
+                v-model:value="conditionParams.modifyTime"
+                :style="{ width: '98%', marginRight: '2%' }"
+                placeholder="请输入修改时间..."
+                clearable
+                @input="event => (conditionParams.modifyTime = event)"
+              />
+              <n-select
+                v-model:value="conditionParams.disabled"
+                :options="userStatusOptions"
+                :style="{ width: '98%', marginRight: '2%' }"
+                placeholder="输入查询状态..."
+                clearable
+                @input="event => (conditionParams.disabled = event)"
+              />
+              <n-button type="primary" ghost @click="searchCondition()"> 搜索 </n-button>
+            </n-input-group>
+          </n-space>
+          <n-space align="center" :size="18">
+            <n-button size="small" type="primary" @click="searchCondition">
+              <icon-mdi-refresh class="mr-4px text-16px" :class="{ 'animate-spin': loading }" />
+              刷新表格
+            </n-button>
+          </n-space>
+        </n-space>
+        <n-data-table
+          :columns="columns"
+          :data="tableData"
+          :loading="loading"
+          :row-key="rowKey"
+          @update:checked-row-keys="handleCheck"
+        />
+        <n-pagination
+          v-model:page="pagination.page"
+          v-model:page-size="pagination.pageSize"
+          class="flex-justify-end"
+          :item-count="pagination.itemCount"
+          show-size-picker
+          :page-sizes="[10, 20, 30, 40]"
+          :on-update:page="(page: number)=>{pagination.page = page; searchCondition()}"
+          :on-update:page-size="(pageSize: number)=>{pagination.pageSize = pageSize; searchCondition()}"
+        />
+        <table-action-add
+          v-model:visible="visible"
+          :type="modalType"
+          :pagination="pagination"
+          :edit-data="(editData as SelectByCondition_1Params)"
+          @search-condition="searchCondition"
+        />
+      </n-card>
+    </n-scrollbar>
+  </div>
+  <!-- <div>
 			<PDFView :pdfUrl="tableData" />
 		</div> -->
 </template>
 
-<script setup lang="tsx" >
-import { userStatusOptions } from '@/constants';
-import { ref, Ref, reactive, watch } from 'vue'
+<script setup lang="tsx">
+import type { Ref } from 'vue';
+import { ref, reactive, watch } from 'vue';
 import { NButton, NSpace, NTag, NPopconfirm } from 'naive-ui';
-import type { DataTableColumns, PaginationProps } from 'naive-ui';
+import type { DataTableColumns, PaginationProps, DataTableRowKey } from 'naive-ui';
+import { userStatusOptions, userStatusLabels } from '@/constants';
 import { useBoolean, useLoading } from '@/hooks';
-import type { DataTableRowKey } from 'naive-ui'
-import TableActionAdd from './components/table-action-add.vue'
-import type { ModalType } from './components/table-action-add.vue';
-import { userStatusLabels } from '@/constants';
-import { deleteById } from '~/src/service/api/sort';
-import { selectByCondition_1 } from '~/src/service/api/sort';
+import { deleteById, selectByCondition_1 } from '~/src/service/api/sort';
 import type { SelectByCondition_1Params } from '~/src/service/api/sort';
+import type { ModalType } from './components/table-action-add.vue';
+import TableActionAdd from './components/table-action-add.vue';
 // import PDFView from "../../.././components/View/pdfPreview.vue"
 type RowData = {
-	key: number
-	id: number
-	name: string
-	description: string
-	createTime: string
-	modifyTime: string
-	createUid: number
-	disabled: string
-}
+  key: number;
+  id: number;
+  name: string;
+  description: string;
+  createTime: string;
+  modifyTime: string;
+  createUid: number;
+  disabled: string;
+};
 const conditionParams: SelectByCondition_1Params = reactive({
-	id: null,
-	name: null,
-	description: null,
-	createUid: null,
-	createTime: null,
-	modifyTime: null,
-	disabled: null
+  id: null,
+  name: null,
+  description: null,
+  createUid: null,
+  createTime: null,
+  modifyTime: null,
+  disabled: null
 });
 
 const { loading, startLoading, endLoading } = useLoading(false);
@@ -99,162 +147,161 @@ const { bool: visible, setTrue: openModal } = useBoolean();
 const tableData = ref<SelectByCondition_1Params[]>([]);
 
 const pagination: PaginationProps = ref({
-	page: 1,
-	pageSize: 10,
-	showSizePicker: true,
-	itemCount: 1,
+  page: 1,
+  pageSize: 10,
+  showSizePicker: true,
+  itemCount: 1
 }).value;
 
 async function searchCondition() {
-	startLoading();
-	const res = await selectByCondition_1(pagination.page as number, pagination.pageSize as number, conditionParams);
-	tableData.value = res.data as [];
-  pagination.itemCount = Number(res.total);
-	endLoading();
+  startLoading();
+  const res = await selectByCondition_1(pagination.page as number, pagination.pageSize as number, conditionParams);
+  tableData.value = res.data as [];
+  if (pagination.itemCount === 1) {
+    pagination.itemCount = Number(res.total);
+  }
+  endLoading();
 }
 
 function init() {
-	searchCondition();
+  searchCondition();
 }
 // 在条件改变时立即触发搜索
 watch(conditionParams, () => {
-	if (Object.values(conditionParams).every(value => value === '' || value === null)) {
-		// 如果所有条件参数都为空,则查询所有数据
-		searchCondition();
-	}
-	searchCondition();
+  if (Object.values(conditionParams).every(value => value === '' || value === null)) {
+    // 如果所有条件参数都为空,则查询所有数据
+    searchCondition();
+  }
+  searchCondition();
 });
 // 初始化
 init();
 
-const checkedRowKeysRef = ref<DataTableRowKey[]>([])
-const s = ref<DataTableRowKey[]>([])
+const checkedRowKeysRef = ref<DataTableRowKey[]>([]);
+const s = ref<DataTableRowKey[]>([]);
 
-const modalType = ref<ModalType>('add' || 'edit');
+const modalType = ref<ModalType>('add');
 
 function setModalType(type: ModalType) {
-	modalType.value = type;
+  modalType.value = type;
 }
 // 添加
 function addTableData() {
-	openModal();
-	setModalType('add');
+  openModal();
+  setModalType('add');
 }
 
 const editData = ref<SelectByCondition_1Params | null>(null);
 function setEditData(data: SelectByCondition_1Params | null) {
-	editData.value = data;
+  editData.value = data;
 }
 function handleEditTable(rowId: number) {
-	const findItem = tableData.value.find(item => item.id === rowId);
-	setModalType('edit');
-	openModal();
-	if (findItem) {
-		setEditData(findItem);
-	}
+  const findItem = tableData.value.find(item => item.id === rowId);
+  setModalType('edit');
+  openModal();
+  if (findItem) {
+    setEditData(findItem);
+  }
 }
 
 function handleDeleteTable(rowId: number) {
-	const rowIdNumber = Number(rowId);
-	deleteById(rowIdNumber).then(() => {
-		searchCondition(); // 删除完成后刷新表格数据
-	})
-
+  const rowIdNumber = Number(rowId);
+  deleteById(rowIdNumber).then(() => {
+    searchCondition(); // 删除完成后刷新表格数据
+  });
 }
-const rowKey = (row: RowData) => row.id
+const rowKey = (row: RowData) => row.id;
 function handleCheck(rowKeys: DataTableRowKey[]) {
-	checkedRowKeysRef.value = rowKeys
+  checkedRowKeysRef.value = rowKeys;
 }
 async function deleteTableData() {
-	const ids = checkedRowKeysRef.value.filter((item) => !s.value?.includes(item));
-	s.value = checkedRowKeysRef.value
-	if (ids.length !== 0) {
-		for (const id of ids) {
-			await deleteById(id as number).then((res) => {
-			})
-		}
-		window.$message?.success('删除成功!');
-		searchCondition(); // 删除完成后刷新表格数据
-	} else {
-		// 没有选择任何行时的操作
-		window.$message?.error('未选择要删除的行');
-	}
+  const ids = checkedRowKeysRef.value.filter(item => !s.value?.includes(item));
+  s.value = checkedRowKeysRef.value;
+  if (ids.length !== 0) {
+    for (const id of ids) {
+      deleteById(id as number);
+    }
+    window.$message?.success('删除成功!');
+    searchCondition(); // 删除完成后刷新表格数据
+  } else {
+    // 没有选择任何行时的操作
+    window.$message?.error('未选择要删除的行');
+  }
 }
 
 const columns: Ref<DataTableColumns<UserManagement.User>> = ref([
-	{
-		type: 'selection',
-		align: 'center',
-	},
-	{
-		key: 'id',
-		title: "ID",
-		align: 'center',
-
-	},
-	{
-		key: 'name',
-		title: '学科名称',
-		align: 'center'
-	},
-	{
-		key: 'description',
-		title: '学科描述',
-		align: 'center'
-	},
-	{
-		key: 'createTime',
-		title: '创建时间',
-		align: 'center'
-	},
-	{
-		key: 'modifyTime',
-		title: '修改时间',
-		align: 'center'
-	},
-	{
-		key: 'createUid',
-		title: '创建用户ID',
-		align: 'center'
-	},
-	{
-		key: 'disabled',
-		title: '状态',
-		align: 'center',
+  {
+    type: 'selection',
+    align: 'center'
+  },
+  {
+    key: 'id',
+    title: 'ID',
+    align: 'center'
+  },
+  {
+    key: 'name',
+    title: '学科名称',
+    align: 'center'
+  },
+  {
+    key: 'description',
+    title: '学科描述',
+    align: 'center'
+  },
+  {
+    key: 'createTime',
+    title: '创建时间',
+    align: 'center'
+  },
+  {
+    key: 'modifyTime',
+    title: '修改时间',
+    align: 'center'
+  },
+  {
+    key: 'createUid',
+    title: '创建用户ID',
+    align: 'center'
+  },
+  {
+    key: 'disabled',
+    title: '状态',
+    align: 'center',
 
-		render: row => {
-			if (row.disabled) {
-				const tagTypes: Record<UserManagement.UserStatusKey, NaiveUI.ThemeColor> = {
-					'N': 'error',
-					'Y': 'success',
-				};
-				return <NTag type={tagTypes[row.disabled]}>{userStatusLabels[row.disabled]}</NTag>;
-			}
-			return
-		}
-	},
-	{
-		key: 'actions',
-		title: '操作',
-		align: 'center',
-		render: row => {
-			return (
-				<NSpace justify={'center'}>
-					<NButton size={'small'} onClick={() => handleEditTable(row.id)} >
-						编辑
-					</NButton>
-					<NPopconfirm onPositiveClick={() => handleDeleteTable(row.id)}>
-						{{
-							default: () => '确认删除',
-							trigger: () => <NButton size={'small'}>删除</NButton>
-						}}
-					</NPopconfirm>
-					<NButton size={'small'} onClick={() => handleEditTable(row.id)} >
-						查看
-					</NButton>
-				</NSpace>
-			);
-		}
-	},
-])
+    render: row => {
+      if (row.disabled) {
+        const tagTypes: Record<UserManagement.UserStatusKey, NaiveUI.ThemeColor> = {
+          N: 'error',
+          Y: 'success'
+        };
+        return <NTag type={tagTypes[row.disabled]}>{userStatusLabels[row.disabled]}</NTag>;
+      }
+      return '';
+    }
+  },
+  {
+    key: 'actions',
+    title: '操作',
+    align: 'center',
+    render: row => {
+      return (
+        <NSpace justify={'center'}>
+          <NButton size={'small'} onClick={() => handleEditTable(row.id)}>
+            编辑
+          </NButton>
+          <NPopconfirm onPositiveClick={() => handleDeleteTable(row.id)}>
+            {{
+              default: () => '确认删除',
+              trigger: () => <NButton size={'small'}>删除</NButton>
+            }}
+          </NPopconfirm>
+          <NButton size={'small'} onClick={() => handleEditTable(row.id)}>
+            查看
+          </NButton>
+        </NSpace>
+      );
+    }
+  }
+]);
 </script>

+ 0 - 315
src/views/management/sort/indexcopy.vue

@@ -1,315 +0,0 @@
-<template>
-	<div class="h-full overflow-hidden">
-		<n-card title="课程分类" :bordered="false" class="rounded-16px shadow-sm">
-			<n-space class="pb-12px" justify="space-between">
-				<!-- 加入查询组件 -->
-				<column-search v-if="showSearch" @close="handleCloseSearch" />
-				<n-space v-else>
-					<n-button type="primary" :data="addData" @click="addTableData">
-						<icon-ic-round-plus class="mr-4px text-20px" />
-						新增
-					</n-button>
-					<n-button type="error" @click="deleteTableData" @update:checked-row-keys="handleCheck">
-						<icon-ic-round-delete class="mr-4px text-20px" />
-						删除
-					</n-button>
-					<n-button type="success">
-						<icon-uil:export class="mr-4px text-20px" />
-						导出Excel
-					</n-button>
-					<!-- 添加查询按钮 -->
-					<n-button size="small" type="primary" @click="handleOpenSearch">
-						<icon-simple-line-icons:magnifier class="mr-4px text-16px" />
-						查询
-					</n-button>
-				</n-space>
-				<n-space align="center" :size="18">
-					<n-button size="small" type="primary" @click="getTableData">
-						<icon-mdi-refresh class="mr-4px text-16px" :class="{ 'animate-spin': loading }" />
-						刷新表格
-					</n-button>
-					<column-search v-model:columns="columns" />
-				</n-space>
-			</n-space>
-			<n-data-table :columns="columns" :data="tableData" :loading="loading" :pagination="pagination" :row-key="rowKey"
-				@update:checked-row-keys="handleCheck" />
-			<table-action-add v-model:visible="visible" :type="modalType" :edit-data="editData" />
-		</n-card>
-		<!-- <n-input-group>
-      <n-input :style="{ width: '100%' }" clearable/>
-    </n-input-group>
-		<n-input-group>
-			<span class="line-height-33.99px mr-5px w-70px">创建时间</span>
-      <n-date-picker :style="{ width: '13%' }"/>
-      <n-time-picker :style="{ width: '14.2%' ,marginRight:'2%'}"/>
-			<span class="line-height-33.99px mr-5px w-70px">修改时间</span>
-      <n-date-picker :style="{ width: '13%' }"/>
-      <n-time-picker :style="{ width: '14.2%' ,marginRight:'2%'}"/>
-				<span class="w-50px  line-height-33.99px">状态</span>
-				<n-select  :options="selectOptions" :style="{ width: '21%' ,marginRight:'2%'}"  clearable/>
-				<n-button type="primary" ghost>
-      	  搜索
-    		</n-button>
-    </n-input-group> -->
-	</div>
-</template>
-
-<script lang="tsx" >
-import { defineComponent, ref } from 'vue'
-import { NButton, NSpace, NTag, NPopconfirm } from 'naive-ui';
-import type { DataTableColumns, PaginationProps } from 'naive-ui';
-import { useBoolean, useLoading } from '@/hooks';
-import type { DataTableRowKey } from 'naive-ui'
-import TableActionAdd from './components/table-action-add.vue'
-import type { ModalType } from './components/table-action-add.vue';
-// import {  userStatusLabels } from '@/constants';
-import { userStatusLabels } from '@/constants';
-import { selectAll_1, deleteById } from '~/src/service/api/sort';
-import type { AddEasEduCategoryParams } from '~/src/service/api/sort';
-import ColumnSearch from './components/column-search.vue';
-type RowData = {
-	key: number
-	id: number
-	name: string
-	description: string
-	createTime: string
-	modifyTime: string
-	createUid: number
-	disabled: string
-}
-const { loading, startLoading, endLoading } = useLoading(false);
-const { bool: visible, setTrue: openModal } = useBoolean();
-
-const tableData = ref<any[]>([]);
-
-// const checkedRowKeysRef = ref<DataTableRowKey[]>([])
-const pagination: PaginationProps = ref({
-	page: 1,
-	pageSize: 10,
-	showSizePicker: true,
-	pageSizes: [10, 20, 50],
-	onChange: (page: number) => {
-		// 处理页码变化
-		pagination.page = page;
-	},
-	onUpdatePageSize: (pageSize: number) => {
-		// 处理每页显示数量变化
-		pagination.pageSize = pageSize;
-		pagination.page = 1;
-	}
-}).value;
-
-
-export async function getTableData() {
-	startLoading();
-	selectAll_1().then(res => {
-		setTimeout(() => {
-			tableData.value = res.data as [];
-			endLoading();
-		}, 1000);
-	});
-}
-
-const checkedRowKeysRef = ref<DataTableRowKey[]>([])
-
-async function deleteTableData() {
-	const ids = checkedRowKeysRef.value;
-	// console.log(ids);
-	if (ids.length !== 0) {
-		console.log(ids);
-		for (let id of ids) {
-			// 调用删除接口
-			console.log(id);
-			await deleteById(id as number)
-				.then((res) => {
-					const deleteRes = res.data;
-					if (!deleteRes)
-						console.log(`成功删除课程,ID: ${id}`);
-					window.$message?.success('删除成功!');
-				})
-				.catch((error) => {
-					// 错误处理
-					console.error(`删除课程发生错误,ID: ${id}`, error);
-					window.$message?.error('删除失败!');
-				});
-		}
-		getTableData(); // 删除完成后刷新表格数据
-	} else {
-		// 没有选择任何行时的操作
-		console.warn('未选择要删除的行');
-	}
-}
-
-const createColumns = (): DataTableColumns<UserManagement.User> => [
-	{
-		type: 'selection',
-		align: 'center',
-	},
-	{
-		key: 'id',
-		title: "ID",
-		align: 'center'
-	},
-	{
-		key: 'name',
-		title: '学科名称',
-		align: 'center'
-	},
-	{
-		key: 'description',
-		title: '学科描述',
-		align: 'center'
-	},
-	{
-		key: 'createTime',
-		title: '创建时间',
-		align: 'center'
-	},
-	{
-		key: 'modifyTime',
-		title: '修改时间',
-		align: 'center'
-	},
-	{
-		key: 'createUid',
-		title: '创建用户ID',
-		align: 'center'
-	},
-	{
-		key: 'disabled',
-		title: '状态',
-		align: 'center',
-
-		render: row => {
-			if (row.disabled) {
-				const tagTypes: Record<UserManagement.UserStatusKey, NaiveUI.ThemeColor> = {
-					'N': 'error',
-					'Y': 'success',
-				};
-				return <NTag type={tagTypes[row.disabled]}>{userStatusLabels[row.disabled]}</NTag>;
-			}
-			return
-		}
-	},
-	{
-		key: 'actions',
-		title: '操作',
-		align: 'center',
-		render: row => {
-			return (
-				<NSpace justify={'center'}>
-					<NButton size={'small'} onClick={() => handleEditTable(row.id)} >
-						编辑
-					</NButton>
-					<NPopconfirm onPositiveClick={() => handleDeleteTable(row.id)}>
-						{{
-							default: () => '确认删除',
-							trigger: () => <NButton size={'small'}>删除</NButton>
-						}}
-					</NPopconfirm>
-				</NSpace>
-			);
-		}
-
-	},
-]
-
-const modalType = ref<ModalType>('add' || 'edit');
-
-function setModalType(type: ModalType) {
-	modalType.value = type;
-	// console.log(modalType.value);
-}
-
-const addData = ref<AddEasEduCategoryParams[]>([]);
-function addTableData() {
-	openModal();
-	setModalType('add');
-	getTableData(); // 删除完成后刷新表格数据
-	// const params: AddEasEduCategoryParams = {};
-	// addEasEduCategory(params).then(res => {
-	// 	console.log(res);
-	// 	addData.value = res.data as [];
-	// });
-}
-
-const editData = ref<UserManagement.User | null>(null);
-function setEditData(data: UserManagement.User | null) {
-	editData.value = data;
-}
-console.log(tableData.value);
-function handleEditTable(rowId: number | null) {
-	const findItem = tableData.value.find(item => item.id === rowId);
-	setModalType('edit');
-	openModal();
-	if (findItem) {
-		setEditData(findItem);
-	}
-	// console.log(findItem);
-	getTableData(); // 编辑完成后刷新表格数据
-}
-
-function handleDeleteTable(rowId: number | null) {
-	const findItem = tableData.value.find(item => item.id === rowId);
-	if (findItem) {
-		deleteById(findItem.id).then((r) => {
-			console.log(r);
-			getTableData(); // 编辑完成后刷新表格数据
-		})
-	}
-}
-
-const showSearch = ref(false)
-
-function handleOpenSearch() {
-	// 点击查询时显示搜索框
-	showSearch.value = true;
-}
-function handleCloseSearch() {
-	// 关闭搜索框,并重新显示主页面
-	showSearch.value = false;
-}
-
-
-function init() {
-	getTableData();
-}
-
-// 初始化
-init();
-
-export default defineComponent({
-	components: {
-		TableActionAdd,
-		ColumnSearch
-	},
-	setup() {
-		// const checkedRowKeysRef = ref<DataTableRowKey[]>([])
-		return {
-			showSearch,
-			tableData,
-			addData,
-			loading,
-			modalType,
-			setEditData,
-			editData,
-			handleCloseSearch,
-			getTableData,
-			addTableData,
-			setModalType,
-			deleteTableData,
-			handleEditTable,
-			handleOpenSearch,
-			visible,
-			columns: createColumns(),
-			checkedRowKeys: checkedRowKeysRef,
-			pagination,
-			rowKey: (row: RowData) => row.id,
-			handleCheck(rowKeys: DataTableRowKey[]) {
-				checkedRowKeysRef.value = rowKeys
-				console.log(checkedRowKeysRef.value);
-			}
-		}
-	}
-})
-</script>

+ 82 - 83
src/views/management/user/components/table-action-modal.vue

@@ -1,46 +1,47 @@
 <template>
-	<n-modal v-model:show="modalVisible" preset="card" :title="title" class="w-700px">
-		<n-form ref="formRef" label-placement="left" :label-width="100" :model="formModel" :rules="rules">
-			<n-grid :cols="24" :x-gap="18">
-				<n-form-item-grid-item :span="12" label="学科名称" path="name">
-					<n-input v-model:value="formModel.name" clearable />
-				</n-form-item-grid-item>
-				<n-form-item-grid-item :span="12" label="学科描述" path="description">
-					<n-input v-model:value="formModel.description" clearable />
-				</n-form-item-grid-item>
-				<n-form-item-grid-item :span="12" label="创建用户ID" path="createUid">
-					<n-input-number v-model:value="formModel.createUid" />
-				</n-form-item-grid-item>
-				<n-form-item-grid-item :span="12" label="状态" path="disabled">
-					<n-select v-model:value="formModel.disabled" :options="userStatusOptions" />
-				</n-form-item-grid-item>
-			</n-grid>
-			<n-space class="w-full pt-16px" :size="24" justify="end">
-				<n-button class="w-72px" @click="closeModal">取消</n-button>
-				<n-button class="w-72px" type="primary" @click="handleSubmit">确定</n-button>
-			</n-space>
-		</n-form>
-	</n-modal>
+  <n-modal v-model:show="modalVisible" preset="card" :title="title" class="w-700px">
+    <n-form ref="formRef" label-placement="left" :label-width="100" :model="formModel" :rules="rules">
+      <n-grid :cols="24" :x-gap="18">
+        <n-form-item-grid-item :span="12" label="学科名称" path="name">
+          <n-input v-model:value="formModel.name" clearable />
+        </n-form-item-grid-item>
+        <n-form-item-grid-item :span="12" label="学科描述" path="description">
+          <n-input v-model:value="formModel.description" clearable />
+        </n-form-item-grid-item>
+        <n-form-item-grid-item :span="12" label="创建用户ID" path="createUid">
+          <n-input-number v-model:value="formModel.createUid" />
+        </n-form-item-grid-item>
+        <n-form-item-grid-item :span="12" label="状态" path="disabled">
+          <n-select v-model:value="formModel.disabled" :options="userStatusOptions" />
+        </n-form-item-grid-item>
+      </n-grid>
+      <n-space class="w-full pt-16px" :size="24" justify="end">
+        <n-button class="w-72px" @click="closeModal">取消</n-button>
+        <n-button class="w-72px" type="primary" @click="handleSubmit">确定</n-button>
+      </n-space>
+    </n-form>
+  </n-modal>
 </template>
 
 <script setup lang="ts">
 import { ref, computed, reactive, watch } from 'vue';
 import type { FormInst, FormItemRule } from 'naive-ui';
 import { userStatusOptions } from '@/constants';
-import {createRequiredFormRule } from '@/utils';
-import { addEasEduCategory, AddEasEduCategoryParams } from '~/src/service/api/sort';
+import { createRequiredFormRule } from '@/utils';
+import type { AddEasEduCategoryParams } from '~/src/service/api/sort';
+import { addEasEduCategory } from '~/src/service/api/sort';
 
 export interface Props {
-	/** 弹窗可见性 */
-	visible: boolean;
-	/**
-	 * 弹窗类型
-	 * add: 新增
-	 * edit: 编辑
-	 */
-	type?: 'add' | 'edit' ;
-	/** 编辑的表格行数据 */
-	editData?: UserManagement.User | null;
+  /** 弹窗可见性 */
+  visible: boolean;
+  /**
+   * 弹窗类型
+   * add: 新增
+   * edit: 编辑
+   */
+  type?: 'add' | 'edit';
+  /** 编辑的表格行数据 */
+  editData?: UserManagement.User | null;
 }
 
 export type ModalType = NonNullable<Props['type']>;
@@ -48,74 +49,73 @@ export type ModalType = NonNullable<Props['type']>;
 defineOptions({ name: 'TableActionAdd' });
 
 const props = withDefaults(defineProps<Props>(), {
-	type: 'add',
-	editData: null,
+  type: 'add',
+  editData: null
 });
 
 interface Emits {
-	(e: 'update:visible', visible: boolean): void;
+  (e: 'update:visible', visible: boolean): void;
 }
 const emit = defineEmits<Emits>();
 
 const modalVisible = computed({
-	get() {
-		return props.visible;
-	},
-	set(visible) {
-		emit('update:visible', visible);
-	}
+  get() {
+    return props.visible;
+  },
+  set(visible) {
+    emit('update:visible', visible);
+  }
 });
 const closeModal = () => {
-	modalVisible.value = false;
+  modalVisible.value = false;
 };
 
 const title = computed(() => {
-	const titles: Record<ModalType, string> = {
-		add: '添加用户',
-		edit: '编辑用户',
-	};
-	return titles[props.type];
+  const titles: Record<ModalType, string> = {
+    add: '添加用户',
+    edit: '编辑用户'
+  };
+  return titles[props.type];
 });
 
 const formRef = ref<HTMLElement & FormInst>();
 
-type FormModel = Pick<UserManagement.User,  | 'name' | 'description' |  'createUid' | 'disabled'>;
+type FormModel = Pick<UserManagement.User, 'name' | 'description' | 'createUid' | 'disabled'>;
 
 const formModel = reactive<FormModel>(createDefaultFormModel());
 
 const rules: Record<keyof FormModel, FormItemRule | FormItemRule[]> = {
-	name: createRequiredFormRule('请输入学科名称'),
-	description: createRequiredFormRule('请进行部门描述'),
-	createUid: createRequiredFormRule('请输入创建用户ID'),
-	disabled: createRequiredFormRule('请选择用户状态')
-
+  name: createRequiredFormRule('请输入学科名称'),
+  description: createRequiredFormRule('请进行部门描述'),
+  createUid: createRequiredFormRule('请输入创建用户ID'),
+  disabled: createRequiredFormRule('请选择用户状态')
 };
 function createDefaultFormModel(): FormModel {
-	return {
-		name: '',
-		description: '',
-		createUid:null,
-		disabled: null,
-	};
+  return {
+    name: '',
+    description: '',
+    createUid: null,
+    disabled: null
+  };
 }
 
 function handleUpdateFormModel(model: Partial<FormModel>) {
-	Object.assign(formModel, model);
+  Object.assign(formModel, model);
 }
 
 function handleUpdateFormModelByModalType() {
-	const handlers: Record<ModalType, () => void> = {
-		add: () => {
-			const defaultFormModel = createDefaultFormModel();
-			handleUpdateFormModel(defaultFormModel);
-		},
-		edit: () => {
-			if (props.editData) {
-				handleUpdateFormModel(props.editData);
-			}
-		},
-	};
-	handlers[props.type]();
+  const handlers: Record<ModalType, () => void> = {
+    add: () => {
+      const defaultFormModel = createDefaultFormModel();
+      handleUpdateFormModel(defaultFormModel);
+    },
+    edit: () => {
+      if (props.editData) {
+        handleUpdateFormModel(props.editData);
+      }
+    }
+  };
+  handlers[props.type]();
 }
 
 async function handleSubmit() {
@@ -127,22 +127,21 @@ async function handleSubmit() {
     disabled: formModel.disabled
   };
   addEasEduCategory(params)
-    .then(res => {
+    .then(() => {
       window.$message?.success('新增成功!');
       closeModal();
     })
-    .catch(error => {
-      console.error(error);
+    .catch(() => {
       window.$message?.error('新增失败!');
     });
 }
 watch(
-	() => props.visible,
-	newValue => {
-		if (newValue) {
-			handleUpdateFormModelByModalType();
-		}
-	}
+  () => props.visible,
+  newValue => {
+    if (newValue) {
+      handleUpdateFormModelByModalType();
+    }
+  }
 );
 </script>
 <style scoped></style>

+ 2 - 247
src/views/management/user/index.vue

@@ -1,252 +1,7 @@
 <template>
-	<div class="h-full overflow-hidden">
-		<n-card title="用户管理" :bordered="false" class="rounded-16px shadow-sm">
-			<n-space class="pb-12px" justify="space-between">
-				<n-space>
-					<n-button type="primary" @click="addTableData">
-						<icon-ic-round-plus class="mr-4px text-20px" />
-						新增
-					</n-button>
-					<n-button type="error" @click="deleteTableData">
-						<icon-ic-round-delete class="mr-4px text-20px" />
-						删除
-					</n-button>
-					<n-button type="success">
-						<icon-uil:export class="mr-4px text-20px" />
-						导出Excel
-					</n-button>
-				</n-space>
-				<n-space align="center" :size="18">
-					<n-button size="small" type="primary" @click="getTableData">
-						<icon-mdi-refresh class="mr-4px text-16px" :class="{ 'animate-spin': loading }" />
-						刷新表格
-					</n-button>
-					<column-setting v-model:columns="columns" />
-				</n-space>
-			</n-space>
-			<n-data-table :columns="columns" :data="tableData" :loading="loading" :pagination="pagination" :row-key="rowKey"
-				@update:checked-row-keys="handleCheck"/>
-			<table-action-modal v-model:visible="visible" :type="modalType" :edit-data="editData" />
-		</n-card>
-	</div>
+  <div class="h-full overflow-hidden"></div>
 </template>
 
-<script setup lang="tsx">
-import {  ref } from 'vue';
-import type { Ref } from 'vue';
-import { NButton, NPopconfirm, NSpace, NTag } from 'naive-ui';
-import type { DataTableColumns, PaginationProps } from 'naive-ui';
-import {  userStatusLabels } from '@/constants';
-// import { fetchUserList } from '@/service';
-import { useBoolean, useLoading } from '@/hooks';
-import type { DataTableRowKey } from 'naive-ui'
-import TableActionModal from './components/table-action-modal.vue';
-import type { ModalType } from './components/table-action-modal.vue';
-import ColumnSetting from './components/column-setting.vue';
-import { selectAll_1,deleteById } from '~/src/service/api/sort';
-// import type { AddEasEduCategoryParams } from '~/src/service/api/sort';
-const { loading, startLoading, endLoading } = useLoading(false);
-const { bool: visible, setTrue: openModal } = useBoolean();
-
-const tableData = ref<UserManagement.User[]>([]);
-// function setTableData(data: UserManagement.User[]) {
-// 	tableData.value = data;
-// }
-
- async function getTableData() {
-	startLoading();
-	selectAll_1().then(res => {
-		setTimeout(() => {
-			// console.log(res);
-			tableData.value = res.data as [];
-			endLoading();
-		}, 1000);
-	});
-}
-
-
-type RowData = {
-	key: number
-	id: number
-	name: string
-	description: string
-	createTime: string
-	modifyTime: string
-	createUid: number
-	disabled: string
-}
-
-const rowKey= (row: RowData) => row.id
-
-function	handleCheck(rowKeys: DataTableRowKey[]) {
-	checkedRowKeysRef.value = rowKeys
-	console.log(checkedRowKeysRef.value);
-}
-
-
-const checkedRowKeysRef = ref<DataTableRowKey[]>([])
-
-async function deleteTableData() {
-  const ids = checkedRowKeysRef.value;
-	// console.log(ids);
-  if (ids.length !== 0) {
-		console.log(ids);
-    for (let id of ids) {
-      // 调用删除接口
-			console.log(id);
-      await deleteById(id as number)
-        .then((res) => {
-          const deleteRes = res.data;
-					if(!deleteRes)
-            console.log(`成功删除课程,ID: ${id}`);
-            window.$message?.success('删除成功!');
-        })
-        .catch((error) => {
-          // 错误处理
-          console.error(`删除课程发生错误,ID: ${id}`, error);
-          window.$message?.error('删除失败!');
-        });
-    }
-    getTableData(); // 删除完成后刷新表格数据
-  } else {
-    // 没有选择任何行时的操作
-    console.warn('未选择要删除的行');
-  }
-}
-
-const columns: Ref<DataTableColumns<UserManagement.User>> = ref([
-	{
-		type: 'selection',
-		align: 'center',
-	},
-	{
-		key: 'id',
-		title: "ID",
-		align: 'center'
-	},
-	{
-		key: 'name',
-		title: '学科名称',
-		align: 'center'
-	},
-	{
-		key: 'description',
-		title: '学科描述',
-		align: 'center'
-	},
-	{
-		key: 'createTime',
-		title: '创建时间',
-		align: 'center'
-	},
-	{
-		key: 'modifyTime',
-		title: '修改时间',
-		align: 'center'
-	},
-	{
-		key: 'createUid',
-		title: '创建用户ID',
-		align: 'center'
-	},
-	{
-		key: 'disabled',
-		title: '状态',
-		align: 'center',
-		render: row => {
-			if (row.disabled) {
-				const tagTypes: Record<UserManagement.UserStatusKey, NaiveUI.ThemeColor> = {
-					'Y': 'success',
-					'N': 'error',
-				};
-
-				return <NTag type={tagTypes[row.disabled]}>{userStatusLabels[row.disabled]}</NTag>;
-			}
-			return <span></span>;
-		}
-	},
-	{
-		key: 'actions',
-		title: '操作',
-		align: 'center',
-		render: row => {
-			return (
-				<NSpace justify={'center'}>
-					<NButton size={'small'} onClick={() => handleEditTable(row.id)}>
-						编辑
-					</NButton>
-					<NPopconfirm onPositiveClick={() => handleDeleteTable(row.id)}>
-						{{
-							default: () => '确认删除',
-							trigger: () => <NButton size={'small'}>删除</NButton>
-						}}
-					</NPopconfirm>
-				</NSpace>
-			);
-		}
-	}
-]) as Ref<DataTableColumns<UserManagement.User>>;
-
-const modalType = ref<ModalType>('add');
-
-function setModalType(type: ModalType) {
-	modalType.value = type;
-}
-
-function addTableData() {
-	openModal();
-	getTableData(); // 删除完成后刷新表格数据
-	setModalType('add');
-}
-
-
-const editData = ref<UserManagement.User | null>(null);
-
-function setEditData(data: UserManagement.User | null) {
-	editData.value = data;
-}
-
-// function handleAddTable() {
-// 	openModal();
-// 	setModalType('add');
-// }
-
-function handleEditTable(rowId: string) {
-	const findItem = tableData.value.find(item => item.id === rowId);
-	if (findItem) {
-		setEditData(findItem);
-	}
-	setModalType('edit');
-	openModal();
-}
-
-function handleDeleteTable(rowId: string) {
-	window.$message?.info(`点击了删除,rowId为${rowId}`);
-}
-
-const pagination: PaginationProps = ref({
-	page: 1,
-
-	pageSize: 10,
-	showSizePicker: true,
-	pageSizes: [10, 20, 50],
-	onChange: (page: number) => {
-		// 处理页码变化
-		pagination.page = page;
-	},
-	onUpdatePageSize: (pageSize: number) => {
-		// 处理每页显示数量变化
-		pagination.pageSize = pageSize;
-		pagination.page = 1;
-	}
-}).value;
-
-function init() {
-	getTableData();
-}
-
-// 初始化
-init();
-</script>
+<script setup lang="tsx"></script>
 
 <style scoped></style>

+ 1 - 1
tsconfig.json

@@ -5,7 +5,7 @@
     "target": "ESNext",
     "lib": ["DOM", "ESNext"],
     "strict": true,
-		"allowJs": true,
+    "allowJs": true,
     "esModuleInterop": true,
     "allowSyntheticDefaultImports": true,
     "jsx": "preserve",

部分文件因为文件数量过多而无法显示