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
pull/201/head^2
谦元吉 2025-08-12 17:23:39 +08:00 committed by GitHub
parent 9fc594434f
commit ab7e363279
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 148 additions and 31 deletions

View File

@ -1,5 +1,7 @@
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils'; 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) => { export default eventHandler((event) => {
const userinfo = verifyAccessToken(event); const userinfo = verifyAccessToken(event);

View File

@ -1,9 +1,15 @@
import { defineEventHandler, readBody, setResponseStatus } from 'h3';
import { import {
clearRefreshTokenCookie, clearRefreshTokenCookie,
setRefreshTokenCookie, setRefreshTokenCookie,
} from '~/utils/cookie-utils'; } from '~/utils/cookie-utils';
import { generateAccessToken, generateRefreshToken } from '~/utils/jwt-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) => { export default defineEventHandler(async (event) => {
const { password, username } = await readBody(event); const { password, username } = await readBody(event);

View File

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

View File

@ -1,9 +1,11 @@
import { defineEventHandler } from 'h3';
import { import {
clearRefreshTokenCookie, clearRefreshTokenCookie,
getRefreshTokenFromCookie, getRefreshTokenFromCookie,
setRefreshTokenCookie, setRefreshTokenCookie,
} from '~/utils/cookie-utils'; } 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'; import { forbiddenResponse } from '~/utils/response';
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {

View File

@ -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) => { export default eventHandler(async (event) => {
const userinfo = verifyAccessToken(event); const userinfo = verifyAccessToken(event);
if (!userinfo) { if (!userinfo) {

View File

@ -1,5 +1,7 @@
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils'; 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) => { export default eventHandler(async (event) => {
const userinfo = verifyAccessToken(event); const userinfo = verifyAccessToken(event);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,11 @@
import { faker } from '@faker-js/faker'; import { faker } from '@faker-js/faker';
import { eventHandler, getQuery } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils'; import { verifyAccessToken } from '~/utils/jwt-utils';
import { unAuthorizedResponse, usePageResponseSuccess } from '~/utils/response'; import {
sleep,
unAuthorizedResponse,
usePageResponseSuccess,
} from '~/utils/response';
function generateMockDataList(count: number) { function generateMockDataList(count: number) {
const dataList = []; const dataList = [];
@ -44,30 +49,69 @@ export default eventHandler(async (event) => {
await sleep(600); await sleep(600);
const { page, pageSize, sortBy, sortOrder } = getQuery(event); 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); 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) => { listData.sort((a, b) => {
if (sortOrder === 'asc') { const aValue = a[sortKey] as unknown;
if (sortBy === 'price') { const bValue = b[sortKey] as unknown;
return (
Number.parseFloat(a[sortBy as string]) - let result = 0;
Number.parseFloat(b[sortBy as string])
); 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 { } else {
return a[sortBy as string] > b[sortBy as string] ? 1 : -1; result = aValue ? 1 : -1;
} }
} else { } else {
if (sortBy === 'price') { const aStr = String(aValue);
return ( const bStr = String(bValue);
Number.parseFloat(b[sortBy as string]) - const aNum = Number(aStr);
Number.parseFloat(a[sortBy as string]) const bNum = Number(bStr);
); result =
} else { Number.isFinite(aNum) && Number.isFinite(bNum)
return a[sortBy as string] < b[sortBy as string] ? 1 : -1; ? 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,
);
}); });

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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"]
} }

View File

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

View File

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

View File

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