feat: 添加@types/jest依赖并优化类型安全
refactor: 重构代码减少any类型使用,增加类型定义 fix: 修复TypeScript编译错误和类型不匹配问题 docs: 更新代码审查修复总结文档 style: 优化代码格式和注释 perf: 添加性能优化工具函数和虚拟滚动组件 test: 完善测试相关配置和类型定义 build: 更新package-lock.json文件
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user