feat: 添加@types/jest依赖并优化类型安全

refactor: 重构代码减少any类型使用,增加类型定义
fix: 修复TypeScript编译错误和类型不匹配问题
docs: 更新代码审查修复总结文档
style: 优化代码格式和注释
perf: 添加性能优化工具函数和虚拟滚动组件
test: 完善测试相关配置和类型定义
build: 更新package-lock.json文件
This commit is contained in:
2026-03-20 09:53:25 +08:00
parent 48a78137c5
commit 989c4b13a6
22 changed files with 807 additions and 7741 deletions

View File

@@ -1,61 +1,108 @@
import { Router } from 'express';
import { Router, Request, Response, NextFunction } from 'express';
import { OperationAgentController } from '../controllers/OperationAgentController';
import { Container } from 'typedi';
import { z } from 'zod';
// 验证模式
const bindStoreSchema = z.object({
merchantId: z.string().min(1, 'Merchant ID is required'),
platform: z.string().min(1, 'Platform is required'),
platformShopId: z.string().min(1, 'Platform shop ID is required'),
name: z.string().min(1, 'Store name is required'),
description: z.string().optional(),
config: z.record(z.string(), z.any()).optional()
});
const updatePriceSchema = z.object({
price: z.number().positive('Price must be positive')
});
const merchantIdSchema = z.string().min(1, 'Merchant ID is required');
const storeIdSchema = z.string().min(1, 'Store ID is required');
const productIdSchema = z.string().min(1, 'Product ID is required');
// 验证中间件
const validateBody = (schema: z.ZodObject<any>) => {
return (req: Request, res: Response, next: NextFunction) => {
try {
schema.parse(req.body);
next();
} catch (error) {
res.status(400).json({ error: error.message });
}
};
};
const validateParam = (paramName: string, schema: z.ZodString) => {
return (req: Request, res: Response, next: NextFunction) => {
try {
schema.parse(req.params[paramName]);
next();
} catch (error) {
res.status(400).json({ error: error.message });
}
};
};
const router = Router();
const operationAgentController = Container.get(OperationAgentController);
// 绑定店铺
router.post('/stores', (req, res, next) => {
router.post('/stores', validateBody(bindStoreSchema), (req, res, next) => {
operationAgentController.bindStore(req.body)
.then(result => res.json(result))
.catch(next);
});
// 获取商户的店铺列表
router.get('/stores/:merchantId', (req, res, next) => {
router.get('/stores/:merchantId', validateParam('merchantId', merchantIdSchema), (req, res, next) => {
operationAgentController.getStores(req.params.merchantId)
.then(result => res.json(result))
.catch(next);
});
// 获取店铺详情
router.get('/stores/detail/:storeId', (req, res, next) => {
router.get('/stores/detail/:storeId', validateParam('storeId', storeIdSchema), (req, res, next) => {
operationAgentController.getStore(req.params.storeId)
.then(result => res.json(result))
.catch(next);
});
// 同步店铺商品
router.post('/stores/:storeId/products/sync', (req, res, next) => {
router.post('/stores/:storeId/products/sync', validateParam('storeId', storeIdSchema), (req, res, next) => {
operationAgentController.syncProducts(req.params.storeId)
.then(result => res.json(result))
.catch(next);
});
// 同步店铺订单
router.post('/stores/:storeId/orders/sync', (req, res, next) => {
router.post('/stores/:storeId/orders/sync', validateParam('storeId', storeIdSchema), (req, res, next) => {
operationAgentController.syncOrders(req.params.storeId)
.then(result => res.json(result))
.catch(next);
});
// 更新商品价格
router.put('/stores/:storeId/products/:productId/price', (req, res, next) => {
operationAgentController.updateProductPrice(req.params.storeId, req.params.productId, req.body.price)
.then(result => res.json(result))
.catch(next);
});
router.put('/stores/:storeId/products/:productId/price',
validateParam('storeId', storeIdSchema),
validateParam('productId', productIdSchema),
validateBody(updatePriceSchema),
(req, res, next) => {
operationAgentController.updateProductPrice(req.params.storeId, req.params.productId, req.body.price)
.then(result => res.json(result))
.catch(next);
}
);
// 停用店铺
router.put('/stores/:storeId/deactivate', (req, res, next) => {
router.put('/stores/:storeId/deactivate', validateParam('storeId', storeIdSchema), (req, res, next) => {
operationAgentController.deactivateStore(req.params.storeId)
.then(result => res.json(result))
.catch(next);
});
// 重新激活店铺
router.put('/stores/:storeId/reactivate', (req, res, next) => {
router.put('/stores/:storeId/reactivate', validateParam('storeId', storeIdSchema), (req, res, next) => {
operationAgentController.reactivateStore(req.params.storeId)
.then(result => res.json(result))
.catch(next);

View File

@@ -1,8 +1,46 @@
import { Router } from 'express';
import { Router, Request, Response, NextFunction } from 'express';
import { TurboGateway } from '../../core/gateway/TurboGateway';
import { requireTraceContext } from '../../core/guards/trace-context.guard';
import { requirePermission } from '../../core/guards/rbac.guard';
import { ProductController } from '../controllers/ProductController';
import { z } from 'zod';
// 验证模式
const productIdSchema = z.string().min(1, 'Product ID is required');
const batchOperationSchema = z.object({
operation: z.string().min(1, 'Operation is required'),
productIds: z.array(z.string().min(1, 'Product ID is required')),
data: z.record(z.string(), z.any()).optional()
});
const platformMappingSchema = z.object({
productId: z.string().min(1, 'Product ID is required'),
platform: z.string().min(1, 'Platform is required'),
platformProductId: z.string().min(1, 'Platform product ID is required'),
mappingData: z.record(z.string(), z.any()).optional()
});
// 验证中间件
const validateBody = (schema: z.ZodObject<any>) => {
return (req: Request, res: Response, next: NextFunction) => {
try {
schema.parse(req.body);
next();
} catch (error) {
res.status(400).json({ error: error.message });
}
};
};
const validateParam = (paramName: string, schema: z.ZodString) => {
return (req: Request, res: Response, next: NextFunction) => {
try {
schema.parse(req.params[paramName]);
next();
} catch (error) {
res.status(400).json({ error: error.message });
}
};
};
const router = Router();