2026-06-24-cfc-ecommerce-extension-design.md 17 KB

CFC 电商原生扩展设计方案

版本: v1.0 日期: 2026-06-24 优先级: P0+P1

1. 决策背景

原计划将 DanShop(dan/danshop/)作为独立 Spring Boot 模块部署在 9081 端口,与 cfc-backend(9082)通过 Feign 跨服务通信。经评估:

方案 优势 劣势
独立模块 (DanShop) 代码隔离、独立部署 双 JVM 运维、Feign 网络开销、共享 DB 仍耦合、重复认证逻辑
CFC 原生扩展 单 JVM 运维、直接服务调用、统一认证、统一事务 单体代码量增加

决策: 所有电商功能直接构建在 cfc-backend,使用 shop/ 子包隔离,表使用 shop_ 前缀。


2. 架构概览

┌──────────────────────────────────────────────────────────────┐
│                     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 ...        │
└──────────────────────────────────────────────────────────────┘

2.1 模块位置

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

3. 模块设计

3.1 [P0] 支付统一(PaymentService 重构)

现状: 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}

3.2 [P0] 购物车

数据模型: 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
  • list 时检查库存和价格同步
  • 下架/删除商品标记失效(仍显示但不允许勾选结算)

3.3 [P0] 结算 + 待支付

当前 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(全部/待支付/已完成/已取消),待支付订单显示支付倒计时和「去支付」按钮。

3.4 [P0] 售后(人工客服版)

@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 审核售后申请

3.5 [P1] 商品类目(多维度 + 多种类)

@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 小程序 类目下商品列表

3.6 [P1] 商品相册

Product.images 增强:

  • coverImage 作为主图(封面)
  • images 存储 JSON 数组 ["url1","url2","url3"]
  • 管理端商品编辑支持多图上传/排序/删除

前端展示:

  • 详情页轮播图(coverImage + images)
  • 列表页使用 coverImage

3.7 [P1] 多销售体系

@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
  • 下单时通过用户 → 销售关系链查找上级,按体系规则返利
  • 平台只记录外部销售关系(external),不计算外部利润

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 移除关系

3.8 [P1] 折扣管理

@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() 自动计算可享最优折扣,返回优惠信息。


4. 前端改造(小程序 cfc-frontend)

4.1 API 切换

所有 config.danshop(...)config.baseUrl(...) / CFC 原生 API:

文件 当前 改造后
pages/shop/cart/cart.vue danshop/cart/listdanshop/cart/remove /api/cart/list/api/cart/remove
pages/shop/checkout/checkout.vue danshop/address/listdanshop/order/create /api/user/address/list/api/product/order/create
pages/shop/payment/payment.vue danshop/payment/precreatedanshop/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 增加「加入购物车」按钮

4.2 新增/增强功能

  • detail.vue:增加「加入购物车」按钮、数量选择
  • order-list.vue:按状态 tab 分组(全部/待付款/已付款/已完成/已取消),待付款显示倒计时和「去支付」
  • cart.vue:商品失效标记、直接从 CFC API 获取
  • checkout.vue:优惠信息展示(后续对接折扣系统)

5. 实施顺序

阶段 模块 后端 前端 Web 依赖
1 购物车 CartItem + CartService + CartController
2 PaymentService 重构(真实微信支付)
3 结算 + 待支付(ProductOrder 增强) 阶段1,2
4 售后(人工审核) 阶段3
5 商品类目(多维度+多种类)
6 商品相册(多图支持) 阶段5
7 多销售体系
8 折扣管理 阶段5

6. 数据库表变更总览

表名 操作 说明
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 现有地址表(复用)

7. 关键约定

  • 所有新接口使用 @PostMapping,遵循 CFC 项目规范
  • 新实体使用 @TableName + @TableId(type = IdType.AUTO)
  • 统一返回 Result<T> 包装
  • JWT 认证:@RequestAttribute("userId") 获取当前用户
  • 金额统一使用 分(Integer) 存储
  • 状态字段使用字符串(可读性)
  • 新 Controller/Service 名避免与其他包 Bean Name 冲突