feat: 新增多模块功能与服务实现
新增广告计划、用户资产、B2B交易、合规规则等核心模型 实现爬虫工作器、贸易服务、现金流预测等业务服务 添加RBAC权限测试、压力测试等测试用例 完善扩展程序的消息处理与内容脚本功能 重构应用入口与文档生成器 更新项目规则与业务闭环分析文档
This commit is contained in:
@@ -254,4 +254,250 @@ router.get('/inventory/hotmap', requireTraceContext, requirePermission('inventor
|
||||
}
|
||||
});
|
||||
|
||||
import { B2BTradeService } from '../../services/B2BTradeService';
|
||||
|
||||
/**
|
||||
* [BE-TOB001] 阶梯价计算接口
|
||||
*/
|
||||
router.post('/b2b/tiered-price', requireTraceContext, requirePermission('trade:read'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const { productId, quantity, customerId } = req.body;
|
||||
|
||||
const result = await B2BTradeService.calculateTieredPrice(
|
||||
productId,
|
||||
quantity,
|
||||
customerId,
|
||||
{ tenantId, shopId, traceId, businessType: 'TOB' }
|
||||
);
|
||||
|
||||
res.json({ success: true, data: result });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB001] 信用额度检查
|
||||
*/
|
||||
router.get('/b2b/credit/:customerId', requireTraceContext, requirePermission('trade:read'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId } = (req as any).traceContext;
|
||||
const { customerId } = req.params;
|
||||
|
||||
const result = await B2BTradeService.checkCreditLimit(customerId, tenantId);
|
||||
res.json({ success: true, data: result });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB002] 批量订单处理
|
||||
*/
|
||||
router.post('/b2b/batch-order', requireTraceContext, requirePermission('trade:write'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const { customerId, items } = req.body;
|
||||
|
||||
const result = await B2BTradeService.createBatchOrder(
|
||||
customerId,
|
||||
items,
|
||||
{ tenantId, shopId, traceId, businessType: 'TOB' }
|
||||
);
|
||||
|
||||
res.json({ success: true, data: result });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB002] 获取批量订单详情
|
||||
*/
|
||||
router.get('/b2b/batch-order/:orderId', requireTraceContext, requirePermission('trade:read'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId } = (req as any).traceContext;
|
||||
const { orderId } = req.params;
|
||||
|
||||
const result = await B2BTradeService.getBatchOrderById(orderId, tenantId);
|
||||
if (!result) {
|
||||
return res.status(404).json({ success: false, error: 'Order not found' });
|
||||
}
|
||||
res.json({ success: true, data: result });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB002] 更新支付状态
|
||||
*/
|
||||
router.put('/b2b/batch-order/:orderId/payment-status', requireTraceContext, requirePermission('trade:write'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const { orderId } = req.params;
|
||||
const { status } = req.body;
|
||||
|
||||
await B2BTradeService.updatePaymentStatus(orderId, status, { tenantId, shopId, traceId });
|
||||
res.json({ success: true, message: 'Payment status updated' });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB003] 账期管理 - 设置账期
|
||||
*/
|
||||
router.post('/b2b/payment-terms', requireTraceContext, requirePermission('trade:write'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const { customerId, days, autoApprove } = req.body;
|
||||
|
||||
const result = await B2BTradeService.setPaymentTerms(
|
||||
customerId,
|
||||
{ days, autoApprove },
|
||||
{ tenantId, shopId, traceId, businessType: 'TOB' }
|
||||
);
|
||||
|
||||
res.json({ success: true, data: result });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB003] 检查逾期订单
|
||||
*/
|
||||
router.post('/b2b/check-overdue', requireTraceContext, requirePermission('trade:admin'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId } = (req as any).traceContext;
|
||||
|
||||
const overdueIds = await B2BTradeService.checkOverdueOrders(tenantId);
|
||||
res.json({ success: true, data: { overdueCount: overdueIds.length, overdueIds } });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB] 创建B2B客户
|
||||
*/
|
||||
router.post('/b2b/customers', requireTraceContext, requirePermission('trade:write'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const customerData = req.body;
|
||||
|
||||
const customerId = await B2BTradeService.createCustomer(customerData, { tenantId, shopId, traceId });
|
||||
res.json({ success: true, data: { customerId } });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB] 创建阶梯价格
|
||||
*/
|
||||
router.post('/b2b/tiered-prices', requireTraceContext, requirePermission('trade:write'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const priceData = req.body;
|
||||
|
||||
const priceId = await B2BTradeService.createTieredPrice(priceData, { tenantId, shopId, traceId });
|
||||
res.json({ success: true, data: { priceId } });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-TOB] 初始化B2B数据库表
|
||||
*/
|
||||
router.post('/b2b/init-tables', requireTraceContext, requirePermission('admin'), async (req, res) => {
|
||||
try {
|
||||
await B2BTradeService.initTables();
|
||||
res.json({ success: true, message: 'B2B tables initialized' });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
import { LogisticsService } from '../../services/LogisticsService';
|
||||
|
||||
/**
|
||||
* [BE-LOG001] 物流策略引擎 - 获取物流策略
|
||||
*/
|
||||
router.post('/logistics/strategy', requireTraceContext, requirePermission('trade:read'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const { orderId, destination } = req.body;
|
||||
|
||||
const result = await LogisticsService.getLogisticsStrategy({
|
||||
orderId,
|
||||
destination,
|
||||
tenantId,
|
||||
shopId,
|
||||
traceId,
|
||||
businessType: 'TOC',
|
||||
});
|
||||
|
||||
res.json({ success: true, data: result });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-LOG002] 渠道选择算法 - 选择物流渠道
|
||||
*/
|
||||
router.post('/logistics/channel', requireTraceContext, requirePermission('trade:write'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const { orderId, logisticsOption } = req.body;
|
||||
|
||||
const result = await LogisticsService.selectChannel(
|
||||
orderId,
|
||||
logisticsOption,
|
||||
{ tenantId, shopId, traceId }
|
||||
);
|
||||
|
||||
res.json({ success: true, data: result });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-LOG003] 运费计算接口 - 计算运费
|
||||
*/
|
||||
router.post('/logistics/freight', requireTraceContext, requirePermission('trade:read'), async (req, res) => {
|
||||
try {
|
||||
const { tenantId, shopId, traceId } = (req as any).traceContext;
|
||||
const { productId, quantity, destination } = req.body;
|
||||
|
||||
const result = await LogisticsService.calculateFreight(
|
||||
productId,
|
||||
quantity,
|
||||
destination,
|
||||
{ tenantId, shopId, traceId }
|
||||
);
|
||||
|
||||
res.json({ success: true, data: result });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* [BE-LOG] 初始化物流数据库表
|
||||
*/
|
||||
router.post('/logistics/init-tables', requireTraceContext, requirePermission('admin'), async (req, res) => {
|
||||
try {
|
||||
await LogisticsService.initTables();
|
||||
res.json({ success: true, message: 'Logistics tables initialized' });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
Reference in New Issue
Block a user