版本: v1.0 日期: 2026-06-24 优先级: P0+P1
原计划将 DanShop(dan/danshop/)作为独立 Spring Boot 模块部署在 9081 端口,与 cfc-backend(9082)通过 Feign 跨服务通信。经评估:
| 方案 | 优势 | 劣势 |
|---|---|---|
| 独立模块 (DanShop) | 代码隔离、独立部署 | 双 JVM 运维、Feign 网络开销、共享 DB 仍耦合、重复认证逻辑 |
| CFC 原生扩展 | 单 JVM 运维、直接服务调用、统一认证、统一事务 | 单体代码量增加 |
决策: 所有电商功能直接构建在 cfc-backend,使用 shop/ 子包隔离,表使用 shop_ 前缀。
┌──────────────────────────────────────────────────────────────┐
│ cfc-frontend (uni-app) │
│ pages/shop/* → /api/product/*, /api/cart/* 等 CFC 原生 API │
└──────────────────────┬───────────────────────────────────────┘
│ JWT + POST Mapping
┌──────────────────────▼───────────────────────────────────────┐
│ cfc-backend (9082) │
├──────────────────────────────────────────────────────────────┤
│ controller/ │
│ ├── product/ ← 现有: Product/ProductOrder │
│ ├── cart/ ← 新增: 购物车 │
│ ├── shop/ ← 新增: 类目/售后/折扣 │
│ ├── admin/ ← 新增: 销售体系/折扣管理 │
│ └── payment/ ← 增强: PaymentService (真实微信支付) │
├──────────────────────────────────────────────────────────────┤
│ service/ + entity/ + mapper/ ← 按模块组织 │
└──────────────────────┬───────────────────────────────────────┘
│ 单数据源
┌──────────────────────▼───────────────────────────────────────┐
│ MySQL 8.0 (zxyj) │
│ 表: products, product_orders, cart_items, shop_categories, │
│ shop_discount_rules, distribution_systems, │
│ distribution_relations, after_sales_requests ... │
└──────────────────────────────────────────────────────────────┘
cfc-backend/src/main/java/com/etotem/cfc/
├── controller/
│ ├── product/ProductController.java ← 现有,增强
│ ├── product/ProductOrderController.java ← 现有,增强
│ ├── cart/CartController.java ← 新增:购物车
│ ├── payment/PaymentController.java ← 新增:支付
│ ├── shop/
│ │ ├── ProductCategoryController.java ← 新增:商品类目(小程序)
│ │ ├── AfterSalesController.java ← 新增:售后
│ │ └── RegionController.java ← 现有地址区域接口
│ └── admin/
│ ├── AdminCategoryController.java ← 新增:类目管理
│ ├── AdminDistributionController.java ← 新增:销售体系管理
│ └── AdminDiscountController.java ← 新增:折扣管理
├── entity/
│ ├── Product.java ← 增强(categoryId, distributionSystemId, images)
│ ├── ProductOrder.java ← 增强(discountAmount, couponId, cancelAt, items)
│ ├── CartItem.java ← 新增
│ ├── ProductCategory.java ← 新增
│ ├── DiscountRule.java ← 新增
│ ├── DistributionSystem.java ← 新增
│ ├── DistributionRelation.java ← 新增
│ └── AfterSalesRequest.java ← 新增
├── service/
│ ├── ProductService.java ← 现有,增强
│ ├── ProductOrderService.java ← 现有,增强
│ ├── CartService.java ← 新增
│ ├── PaymentService.java ← 重写(真实微信支付)
│ ├── ProductCategoryService.java ← 新增
│ ├── DiscountService.java ← 新增
│ ├── DistributionService.java ← 新增
│ └── AfterSalesService.java ← 新增
└── mapper/ ← 每个实体对应 Mapper
现状: PaymentService 目前为桩代码,返回 mock 数据。PackageOrder 使用,ProductOrder 下单后直接调 pay() 改状态。
改造目标:
@Service
public class PaymentService {
// 微信支付预下单 - 统一下单API
public Map<String, Object> createWechatPrepay(String orderNo, String description, Integer totalFee);
// 处理微信支付回调通知
public String handleWechatNotify(String requestBody, String signatureHeader);
// 处理支付宝回调
public boolean handleAlipayNotify(Map<String, String> params);
// 统一支付结果查询
public PaymentStatus queryPaymentStatus(String orderNo);
// 退款
public boolean refund(String orderNo, Integer amount, String reason);
}
配置:
payment:
wechat:
app-id: wx5ba8038ef16fb245
mch-id: ${WX_MCH_ID}
api-v3-key: ${WX_API_V3_KEY}
private-key-path: ${WX_PRIVATE_KEY_PATH}
notify-url: https://cfc.etotem.com.cn/api/payment/wechat/notify
cert-path: ${WX_CERT_PATH}
数据模型: MySQL 持久化(cart_items 表)
@TableName("cart_items")
public class CartItem {
Long id;
Long userId;
Long productId;
Integer quantity;
Boolean selected; // 是否选中
Date createdAt;
Date updatedAt;
}
API:
| 端点 | 说明 |
|---|---|
POST /api/cart/list |
我的购物车(返回商品实时信息 + 价格同步) |
POST /api/cart/add |
加入购物车(已有则增加数量) |
POST /api/cart/update |
修改数量 (productId + quantity) |
POST /api/cart/remove |
移除商品(支持批量) |
POST /api/cart/toggle |
切换选中状态 |
校验:
on_shelf当前 ProductOrder 增强:
@TableName("product_orders")
public class ProductOrder {
// 现有字段保留
Long id; String orderNo; Long productId; String productName;
String productType; Long buyerId; Long familyId;
Integer quantity; Integer unitPrice; Integer totalAmount;
String status; String paymentMethod; String remark;
Date paidAt; Date createdAt; Date updatedAt;
// 新增字段
String coverImage; // 商品封面(快照)
Integer discountAmount; // 优惠金额(分)
Long couponId; // 使用的优惠券/折扣ID
Date cancelAt; // 自动取消时间(createdAt+30min)
String transactionId; // 支付平台交易号
String addressSnapshot; // 收货地址快照(JSON)
String logisticsNo; // 物流单号
String logisticsCompany; // 物流公司
}
前端改造: 订单列表按状态 tab(全部/待支付/已完成/已取消),待支付订单显示支付倒计时和「去支付」按钮。
@TableName("after_sales_requests")
public class AfterSalesRequest {
Long id;
Long orderId;
String orderNo;
Long userId;
String type; // REFUND(仅退款) / RETURN_REFUND(退货退款)
String reason;
String description;
String images; // 凭证图片(JSON数组)
Integer refundAmount; // 退款金额(分)
String status; // pending(待审核)/approved(已通过)/rejected(驳回)/completed(已完成)
String rejectReason;
String handledBy; // 处理人ID
Date handledAt;
Date createdAt;
}
流程: 买家提交 → 管理员审核 → 线下退款 → 标记完成。无自动退款。
API:
| 端点 | 端 | 说明 |
|---|---|---|
POST /api/shop/after-sales/create |
小程序 | 提交售后申请 |
POST /api/shop/after-sales/list |
小程序 | 我的售后记录 |
POST /api/shop/after-sales/detail |
小程序 | 售后详情 |
POST /api/admin/shop/after-sales/list |
Web | 售后列表(管理端) |
POST /api/admin/shop/after-sales/review |
Web | 审核售后申请 |
@TableName("shop_categories")
public class ProductCategory {
Long id;
String name;
Long parentId; // 0=根节点
Integer level; // 0/1/2/3
Integer sort;
String image;
Boolean enabled;
String dimensionCodes; // "body,mind,heart" 多维度关联
String productTypes; // "PHYSICAL,COURSE,ASSESSMENT,VIRTUAL"
Date createdAt;
Date updatedAt;
}
Product 增加字段:
Long categoryId — 所属类目Long distributionSystemId — 销售体系归属维度继承:
类目(维度=身,智) →
子类目(继承维度=身,智, 可追加指定) →
商品(继承类目维度)
API:
| 端点 | 端 | 说明 |
|---|---|---|
POST /api/admin/shop/category/create |
Web | 创建类目 |
POST /api/admin/shop/category/update |
Web | 更新类目 |
POST /api/admin/shop/category/delete |
Web | 删除类目 |
POST /api/admin/shop/category/tree |
Web | 管理端树形 |
POST /api/shop/category/tree |
小程序 | 商城端类目树 |
POST /api/shop/category/products |
小程序 | 类目下商品列表 |
Product.images 增强:
coverImage 作为主图(封面)images 存储 JSON 数组 ["url1","url2","url3"]前端展示:
@TableName("distribution_systems")
public class DistributionSystem {
Long id;
String name;
String description;
Long ownerId; // 创建者
Integer profitRate; // 平台利润率(千分比),仅管理员可修改
Boolean enabled;
Date createdAt;
Date updatedAt;
}
@TableName("distribution_relations")
public class DistributionRelation {
Long id;
Long systemId;
Long userId;
Long parentId; // 上级(null=根)
Integer depth;
Date createdAt;
}
业务规则:
profitRate 管理员在 Web 端设置,合作商不可修改product.distributionSystemId)API(Web 管理端):
| 端点 | 说明 |
|---|---|
POST /api/admin/distribution/system/create |
创建销售体系 |
POST /api/admin/distribution/system/update |
更新(含 profitRate 设置) |
POST /api/admin/distribution/system/list |
体系列表 |
POST /api/admin/distribution/system/toggle |
启用/禁用 |
POST /api/admin/distribution/relation/list |
查看某体系的关系树 |
POST /api/admin/distribution/relation/add |
手动添加关系 |
POST /api/admin/distribution/relation/remove |
移除关系 |
@TableName("shop_discount_rules")
public class DiscountRule {
Long id;
String name;
String type; // PERCENT(打折) / FIXED(减额) / THRESHOLD(满减)
Integer value; // PERCENT: 打折值(如10=9折); FIXED/THRESHOLD: 金额(分)
Integer thresholdAmount; // 满减门槛(分), THRESHOLD时使用
Long categoryId; // 适用类目(null=全部)
Long distributionSystemId;// 适用体系(null=全部)
String productIds; // 适用商品(逗号分隔, null=全部)
Date startTime;
Date endTime;
Integer maxUses; // 最大使用次数(0=不限)
Integer usedCount;
Boolean enabled;
Date createdAt;
Date updatedAt;
}
API(Web 管理端):
| 端点 | 说明 |
|---|---|
POST /api/admin/shop/discount/create |
创建折扣规则 |
POST /api/admin/shop/discount/update |
更新 |
POST /api/admin/shop/discount/list |
规则列表 |
POST /api/admin/shop/discount/toggle |
启用/禁用 |
结算页集成: 下单时 DiscountService.calculateBestDiscount() 自动计算可享最优折扣,返回优惠信息。
所有 config.danshop(...) → config.baseUrl(...) / CFC 原生 API:
| 文件 | 当前 | 改造后 |
|---|---|---|
pages/shop/cart/cart.vue |
danshop/cart/list → danshop/cart/remove |
/api/cart/list → /api/cart/remove |
pages/shop/checkout/checkout.vue |
danshop/address/list → danshop/order/create |
/api/user/address/list → /api/product/order/create |
pages/shop/payment/payment.vue |
danshop/payment/precreate → danshop/order/cancel |
/api/product/order/pay → /api/product/order/cancel |
pages/shop/address/address.vue |
danshop/address/list/delete/setDefault |
/api/user/address/* (已有 CFC API) |
pages/shop/address-edit/address-edit.vue |
danshop/address/get/save + danshop/region/* |
/api/user/address/* + /api/region/* |
pages/shop/logistics/logistics.vue |
danshop/logistics/query |
/api/shop/logistics/query |
pages/shop/order-list/order-list.vue |
可能 mock | /api/product/order/list |
pages/shop/order-detail/order-detail.vue |
可能 mock | /api/product/order/detail |
pages/shop/detail/detail.vue |
— | 增加「加入购物车」按钮 |
| 阶段 | 模块 | 后端 | 前端 | Web | 依赖 |
|---|---|---|---|---|---|
| 1 | 购物车 CartItem + CartService + CartController | ✅ | ✅ | — | 无 |
| 2 | PaymentService 重构(真实微信支付) | ✅ | — | — | 无 |
| 3 | 结算 + 待支付(ProductOrder 增强) | ✅ | ✅ | — | 阶段1,2 |
| 4 | 售后(人工审核) | ✅ | ✅ | ✅ | 阶段3 |
| 5 | 商品类目(多维度+多种类) | ✅ | ✅ | ✅ | 无 |
| 6 | 商品相册(多图支持) | ✅ | — | ✅ | 阶段5 |
| 7 | 多销售体系 | ✅ | — | ✅ | 无 |
| 8 | 折扣管理 | ✅ | — | ✅ | 阶段5 |
| 表名 | 操作 | 说明 |
|---|---|---|
products |
增强 | 加 category_id, distribution_system_id, images JSON 格式 |
product_orders |
增强 | 加 discount_amount, coupon_id, cancel_at, transaction_id, 地址快照等 |
cart_items |
新建 | 购物车 |
shop_categories |
新建 | 商品类目(树形) |
shop_discount_rules |
新建 | 折扣规则 |
distribution_systems |
新建 | 销售体系 |
distribution_relations |
新建 | 销售关系 |
after_sales_requests |
新建 | 售后申请 |
user_address |
已有 | CFC 现有地址表(复用) |
@PostMapping,遵循 CFC 项目规范@TableName + @TableId(type = IdType.AUTO)Result<T> 包装@RequestAttribute("userId") 获取当前用户