Ver Fonte

fix(@vben/backend-mock): fix all ts type errors in this module (#6613)

* fix(@vben/backend-mock): 修复所有 ts 类型报错

* fix(@vben/backend-mock): 修复该模块所有 ts 类型报错

* fix(@vben/backend-mock): 解决 coderabbitai

* fix(@vben/backend-mock): 解决 coderabbitai

* fix(@vben/backend-mock): 解决 coderabbitai
谦元吉 há 1 mês atrás
pai
commit
ab7e363279

+ 3 - 1
apps/backend-mock/api/auth/codes.ts

@@ -1,5 +1,7 @@
+import { eventHandler } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
-import { unAuthorizedResponse } from '~/utils/response';
+import { MOCK_CODES } from '~/utils/mock-data';
+import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
 
 export default eventHandler((event) => {
   const userinfo = verifyAccessToken(event);

+ 7 - 1
apps/backend-mock/api/auth/login.post.ts

@@ -1,9 +1,15 @@
+import { defineEventHandler, readBody, setResponseStatus } from 'h3';
 import {
   clearRefreshTokenCookie,
   setRefreshTokenCookie,
 } from '~/utils/cookie-utils';
 import { generateAccessToken, generateRefreshToken } from '~/utils/jwt-utils';
-import { forbiddenResponse } from '~/utils/response';
+import { MOCK_USERS } from '~/utils/mock-data';
+import {
+  forbiddenResponse,
+  useResponseError,
+  useResponseSuccess,
+} from '~/utils/response';
 
 export default defineEventHandler(async (event) => {
   const { password, username } = await readBody(event);

+ 2 - 0
apps/backend-mock/api/auth/logout.post.ts

@@ -1,7 +1,9 @@
+import { defineEventHandler } from 'h3';
 import {
   clearRefreshTokenCookie,
   getRefreshTokenFromCookie,
 } from '~/utils/cookie-utils';
+import { useResponseSuccess } from '~/utils/response';
 
 export default defineEventHandler(async (event) => {
   const refreshToken = getRefreshTokenFromCookie(event);

+ 3 - 1
apps/backend-mock/api/auth/refresh.post.ts

@@ -1,9 +1,11 @@
+import { defineEventHandler } from 'h3';
 import {
   clearRefreshTokenCookie,
   getRefreshTokenFromCookie,
   setRefreshTokenCookie,
 } from '~/utils/cookie-utils';
-import { verifyRefreshToken } from '~/utils/jwt-utils';
+import { generateAccessToken, verifyRefreshToken } from '~/utils/jwt-utils';
+import { MOCK_USERS } from '~/utils/mock-data';
 import { forbiddenResponse } from '~/utils/response';
 
 export default defineEventHandler(async (event) => {

+ 4 - 0
apps/backend-mock/api/demo/bigint.ts

@@ -1,3 +1,7 @@
+import { eventHandler, setHeader } from 'h3';
+import { verifyAccessToken } from '~/utils/jwt-utils';
+import { unAuthorizedResponse } from '~/utils/response';
+
 export default eventHandler(async (event) => {
   const userinfo = verifyAccessToken(event);
   if (!userinfo) {

+ 3 - 1
apps/backend-mock/api/menu/all.ts

@@ -1,5 +1,7 @@
+import { eventHandler } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
-import { unAuthorizedResponse } from '~/utils/response';
+import { MOCK_MENUS } from '~/utils/mock-data';
+import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
 
 export default eventHandler(async (event) => {
   const userinfo = verifyAccessToken(event);

+ 3 - 0
apps/backend-mock/api/status.ts

@@ -1,3 +1,6 @@
+import { eventHandler, getQuery, setResponseStatus } from 'h3';
+import { useResponseError } from '~/utils/response';
+
 export default eventHandler((event) => {
   const { status } = getQuery(event);
   setResponseStatus(event, Number(status));

+ 3 - 0
apps/backend-mock/api/system/dept/.post.ts

@@ -13,3 +13,6 @@ export default eventHandler(async (event) => {
   await sleep(600);
   return useResponseSuccess(null);
 });
+function eventHandler(_: (event: any) => Promise<any>) {
+  throw new Error('Function not implemented.');
+}

+ 1 - 0
apps/backend-mock/api/system/dept/[id].delete.ts

@@ -1,3 +1,4 @@
+import { eventHandler } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
 import {
   sleep,

+ 1 - 0
apps/backend-mock/api/system/dept/[id].put.ts

@@ -1,3 +1,4 @@
+import { eventHandler } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
 import {
   sleep,

+ 1 - 0
apps/backend-mock/api/system/dept/list.ts

@@ -1,4 +1,5 @@
 import { faker } from '@faker-js/faker';
+import { eventHandler } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
 import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
 

+ 1 - 0
apps/backend-mock/api/system/menu/list.ts

@@ -1,3 +1,4 @@
+import { eventHandler } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
 import { MOCK_MENU_LIST } from '~/utils/mock-data';
 import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

+ 2 - 1
apps/backend-mock/api/system/menu/name-exists.ts

@@ -1,6 +1,7 @@
+import { eventHandler, getQuery } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
 import { MOCK_MENU_LIST } from '~/utils/mock-data';
-import { unAuthorizedResponse } from '~/utils/response';
+import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
 
 const namesMap: Record<string, any> = {};
 

+ 2 - 1
apps/backend-mock/api/system/menu/path-exists.ts

@@ -1,6 +1,7 @@
+import { eventHandler, getQuery } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
 import { MOCK_MENU_LIST } from '~/utils/mock-data';
-import { unAuthorizedResponse } from '~/utils/response';
+import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
 
 const pathMap: Record<string, any> = { '/': 0 };
 

+ 1 - 0
apps/backend-mock/api/system/role/list.ts

@@ -1,4 +1,5 @@
 import { faker } from '@faker-js/faker';
+import { eventHandler, getQuery } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
 import { getMenuIds, MOCK_MENU_LIST } from '~/utils/mock-data';
 import { unAuthorizedResponse, usePageResponseSuccess } from '~/utils/response';

+ 62 - 18
apps/backend-mock/api/table/list.ts

@@ -1,6 +1,11 @@
 import { faker } from '@faker-js/faker';
+import { eventHandler, getQuery } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
-import { unAuthorizedResponse, usePageResponseSuccess } from '~/utils/response';
+import {
+  sleep,
+  unAuthorizedResponse,
+  usePageResponseSuccess,
+} from '~/utils/response';
 
 function generateMockDataList(count: number) {
   const dataList = [];
@@ -44,30 +49,69 @@ export default eventHandler(async (event) => {
   await sleep(600);
 
   const { page, pageSize, sortBy, sortOrder } = getQuery(event);
+  // 规范化分页参数,处理 string[]
+  const pageRaw = Array.isArray(page) ? page[0] : page;
+  const pageSizeRaw = Array.isArray(pageSize) ? pageSize[0] : pageSize;
+  const pageNumber = Math.max(
+    1,
+    Number.parseInt(String(pageRaw ?? '1'), 10) || 1,
+  );
+  const pageSizeNumber = Math.min(
+    100,
+    Math.max(1, Number.parseInt(String(pageSizeRaw ?? '10'), 10) || 10),
+  );
   const listData = structuredClone(mockData);
-  if (sortBy && Reflect.has(listData[0], sortBy as string)) {
+
+  // 规范化 query 入参,兼容 string[]
+  const sortKeyRaw = Array.isArray(sortBy) ? sortBy[0] : sortBy;
+  const sortOrderRaw = Array.isArray(sortOrder) ? sortOrder[0] : sortOrder;
+  // 检查 sortBy 是否是 listData 元素的合法属性键
+  if (
+    typeof sortKeyRaw === 'string' &&
+    listData[0] &&
+    Object.prototype.hasOwnProperty.call(listData[0], sortKeyRaw)
+  ) {
+    // 定义数组元素的类型
+    type ItemType = (typeof listData)[0];
+    const sortKey = sortKeyRaw as keyof ItemType; // 将 sortBy 断言为合法键
+    const isDesc = sortOrderRaw === 'desc';
     listData.sort((a, b) => {
-      if (sortOrder === 'asc') {
-        if (sortBy === 'price') {
-          return (
-            Number.parseFloat(a[sortBy as string]) -
-            Number.parseFloat(b[sortBy as string])
-          );
+      const aValue = a[sortKey] as unknown;
+      const bValue = b[sortKey] as unknown;
+
+      let result = 0;
+
+      if (typeof aValue === 'number' && typeof bValue === 'number') {
+        result = aValue - bValue;
+      } else if (aValue instanceof Date && bValue instanceof Date) {
+        result = aValue.getTime() - bValue.getTime();
+      } else if (typeof aValue === 'boolean' && typeof bValue === 'boolean') {
+        if (aValue === bValue) {
+          result = 0;
         } else {
-          return a[sortBy as string] > b[sortBy as string] ? 1 : -1;
+          result = aValue ? 1 : -1;
         }
       } else {
-        if (sortBy === 'price') {
-          return (
-            Number.parseFloat(b[sortBy as string]) -
-            Number.parseFloat(a[sortBy as string])
-          );
-        } else {
-          return a[sortBy as string] < b[sortBy as string] ? 1 : -1;
-        }
+        const aStr = String(aValue);
+        const bStr = String(bValue);
+        const aNum = Number(aStr);
+        const bNum = Number(bStr);
+        result =
+          Number.isFinite(aNum) && Number.isFinite(bNum)
+            ? aNum - bNum
+            : aStr.localeCompare(bStr, undefined, {
+                numeric: true,
+                sensitivity: 'base',
+              });
       }
+
+      return isDesc ? -result : result;
     });
   }
 
-  return usePageResponseSuccess(page as string, pageSize as string, listData);
+  return usePageResponseSuccess(
+    String(pageNumber),
+    String(pageSizeNumber),
+    listData,
+  );
 });

+ 2 - 0
apps/backend-mock/api/test.get.ts

@@ -1 +1,3 @@
+import { defineEventHandler } from 'h3';
+
 export default defineEventHandler(() => 'Test get handler');

+ 2 - 0
apps/backend-mock/api/test.post.ts

@@ -1 +1,3 @@
+import { defineEventHandler } from 'h3';
+
 export default defineEventHandler(() => 'Test post handler');

+ 2 - 1
apps/backend-mock/api/upload.ts

@@ -1,5 +1,6 @@
+import { eventHandler } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
-import { unAuthorizedResponse } from '~/utils/response';
+import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
 
 export default eventHandler((event) => {
   const userinfo = verifyAccessToken(event);

+ 2 - 1
apps/backend-mock/api/user/info.ts

@@ -1,5 +1,6 @@
+import { eventHandler } from 'h3';
 import { verifyAccessToken } from '~/utils/jwt-utils';
-import { unAuthorizedResponse } from '~/utils/response';
+import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
 
 export default eventHandler((event) => {
   const userinfo = verifyAccessToken(event);

+ 1 - 0
apps/backend-mock/middleware/1.api.ts

@@ -1,3 +1,4 @@
+import { defineEventHandler } from 'h3';
 import { forbiddenResponse, sleep } from '~/utils/response';
 
 export default defineEventHandler(async (event) => {

+ 2 - 0
apps/backend-mock/routes/[...].ts

@@ -1,3 +1,5 @@
+import { defineEventHandler } from 'h3';
+
 export default defineEventHandler(() => {
   return `
 <h1>Hello Vben Admin</h1>

+ 12 - 1
apps/backend-mock/tsconfig.json

@@ -1,3 +1,14 @@
 {
-  "extends": "./.nitro/types/tsconfig.json"
+  "$schema": "https://json.schemastore.org/tsconfig",
+  "extends": "@vben/tsconfig/node.json",
+  "compilerOptions": {
+    "composite": true,
+    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+    "baseUrl": ".",
+    "paths": {
+      "~/utils/*": ["utils/*"]
+    },
+    "noEmit": false
+  },
+  "include": ["**/*.ts", "**/*.*.ts"]
 }

+ 2 - 0
apps/backend-mock/utils/cookie-utils.ts

@@ -1,5 +1,7 @@
 import type { EventHandlerRequest, H3Event } from 'h3';
 
+import { deleteCookie, getCookie, setCookie } from 'h3';
+
 export function clearRefreshTokenCookie(event: H3Event<EventHandlerRequest>) {
   deleteCookie(event, 'jwt', {
     httpOnly: true,

+ 22 - 4
apps/backend-mock/utils/jwt-utils.ts

@@ -1,8 +1,11 @@
 import type { EventHandlerRequest, H3Event } from 'h3';
 
+import type { UserInfo } from './mock-data';
+
+import { getHeader } from 'h3';
 import jwt from 'jsonwebtoken';
 
-import { UserInfo } from './mock-data';
+import { MOCK_USERS } from './mock-data';
 
 // TODO: Replace with your own secret key
 const ACCESS_TOKEN_SECRET = 'access_token_secret';
@@ -31,12 +34,22 @@ export function verifyAccessToken(
     return null;
   }
 
-  const token = authHeader.split(' ')[1];
+  const tokenParts = authHeader.split(' ');
+  if (tokenParts.length !== 2) {
+    return null;
+  }
+  const token = tokenParts[1] as string;
   try {
-    const decoded = jwt.verify(token, ACCESS_TOKEN_SECRET) as UserPayload;
+    const decoded = jwt.verify(
+      token,
+      ACCESS_TOKEN_SECRET,
+    ) as unknown as UserPayload;
 
     const username = decoded.username;
     const user = MOCK_USERS.find((item) => item.username === username);
+    if (!user) {
+      return null;
+    }
     const { password: _pwd, ...userinfo } = user;
     return userinfo;
   } catch {
@@ -50,7 +63,12 @@ export function verifyRefreshToken(
   try {
     const decoded = jwt.verify(token, REFRESH_TOKEN_SECRET) as UserPayload;
     const username = decoded.username;
-    const user = MOCK_USERS.find((item) => item.username === username);
+    const user = MOCK_USERS.find(
+      (item) => item.username === username,
+    ) as UserInfo;
+    if (!user) {
+      return null;
+    }
     const { password: _pwd, ...userinfo } = user;
     return userinfo;
   } catch {

+ 2 - 0
apps/backend-mock/utils/response.ts

@@ -1,5 +1,7 @@
 import type { EventHandlerRequest, H3Event } from 'h3';
 
+import { setResponseStatus } from 'h3';
+
 export function useResponseSuccess<T = any>(data: T) {
   return {
     code: 0,