DukeDuke
主页
文档转换
关于我们
主页
文档转换
关于我们
  • 代办项目

    • 风险评估文档
    • 开发计划文档
    • 项目需求文档
    • 概要设计文档
    • 详细设计文档
    • 数据库设计文档

车驾管服务系统详细设计说明书

1. 详细设计概述

1.1 文档说明

本文档是车驾管服务系统的详细设计说明书,基于需求文档和概要设计文档编写,详细描述系统的功能模块设计、类设计、接口设计、数据库设计、业务流程设计等,为系统开发提供详细的技术指导。

1.2 设计目标

  • 功能完整性:详细描述所有功能模块的实现细节
  • 逻辑严谨性:业务流程设计逻辑严谨,考虑各种边界情况
  • 技术可行性:设计方案技术可行,符合实际开发需求
  • 可维护性:代码结构清晰,易于维护和扩展

1.3 设计原则

  • 单一职责原则:每个类、每个方法只负责一个功能
  • 开闭原则:对扩展开放,对修改关闭
  • 依赖倒置原则:依赖抽象而不是具体实现
  • 接口隔离原则:使用多个专门的接口,而不是使用单一的总接口
  • 里氏替换原则:子类可以替换父类
  • 最小知识原则:一个对象应当对其他对象有尽可能少的了解

1.4 设计约束

  • 技术约束:基于Spring Boot、MySQL、Redis等技术栈
  • 性能约束:接口响应时间 ≤ 1秒,支持500+并发用户
  • 安全约束:数据加密、接口签名、权限控制
  • 兼容性约束:支持主流浏览器和移动端

2. 订单管理模块详细设计

2.1 模块概述

订单管理模块是系统的核心模块,负责订单的全生命周期管理,包括订单创建、状态流转、支付、分配、进度跟踪、材料管理等。

2.2 类设计

2.2.1 订单实体类 (Order)

/**
 * 订单实体类
 */
public class Order {
    /**
     * 订单ID
     */
    private Long orderId;
    
    /**
     * 订单号(唯一)
     */
    private String orderNo;
    
    /**
     * 客户ID
     */
    private Long customerId;
    
    /**
     * 车辆ID
     */
    private Long vehicleId;
    
    /**
     * 服务类型ID
     */
    private Long serviceId;
    
    /**
     * 订单类型(DRIVER-代驾订单, SELF-自驾订单)
     */
    private String orderType;
    
    /**
     * 订单来源(CUSTOMER-客户直接下单, CHANNEL-渠道API下单, ADMIN-管理员手动创建)
     */
    private String orderSource;
    
    /**
     * 渠道ID(渠道来源订单必填)
     */
    private Long channelId;
    
    /**
     * 订单状态(PENDING_PAYMENT-待支付, PAID-已支付, PENDING_ASSIGN-待分配, 
     * PROCESSING-办理中, PENDING_CONFIRM-待确认, COMPLETED-已完成, 
     * CANCELLED-已取消, REFUNDED-已退款)
     */
    private String status;
    
    /**
     * 订单金额
     */
    private BigDecimal amount;
    
    /**
     * 实际支付金额
     */
    private BigDecimal paidAmount;
    
    /**
     * 服务地址
     */
    private String serviceAddress;
    
    /**
     * 服务时间
     */
    private LocalDateTime serviceTime;
    
    /**
     * 代驾人员ID
     */
    private Long driverId;
    
    /**
     * 接待员ID
     */
    private Long receptionistId;
    
    /**
     * 检测站ID
     */
    private Long stationId;
    
    /**
     * 订单备注
     */
    private String remark;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    
    // getter/setter方法
}

2.2.2 订单服务类 (OrderService)

/**
 * 订单服务接口
 */
public interface OrderService {
    /**
     * 创建订单(客户下单)
     * @param orderCreateDTO 订单创建DTO
     * @return 订单信息
     */
    OrderVO createOrder(OrderCreateDTO orderCreateDTO);
    
    /**
     * 创建订单(渠道API下单)
     * @param channelOrderCreateDTO 渠道订单创建DTO
     * @return 订单信息
     */
    OrderVO createOrderFromChannel(ChannelOrderCreateDTO channelOrderCreateDTO);
    
    /**
     * 手动创建订单
     * @param adminOrderCreateDTO 管理员订单创建DTO
     * @return 订单信息
     */
    OrderVO createOrderByAdmin(AdminOrderCreateDTO adminOrderCreateDTO);
    
    /**
     * 查询订单列表
     * @param queryDTO 查询条件
     * @return 订单列表
     */
    PageResult<OrderVO> queryOrderList(OrderQueryDTO queryDTO);
    
    /**
     * 查询订单详情
     * @param orderId 订单ID
     * @return 订单详情
     */
    OrderDetailVO getOrderDetail(Long orderId);
    
    /**
     * 更新订单状态
     * @param orderId 订单ID
     * @param newStatus 新状态
     * @param operatorId 操作人ID
     * @param reason 变更原因
     */
    void updateOrderStatus(Long orderId, String newStatus, Long operatorId, String reason);
    
    /**
     * 取消订单
     * @param orderId 订单ID
     * @param reason 取消原因
     */
    void cancelOrder(Long orderId, String reason);
    
    /**
     * 分配订单
     * @param orderId 订单ID
     * @param assignDTO 分配信息
     */
    void assignOrder(Long orderId, OrderAssignDTO assignDTO);
}

2.2.3 订单状态机 (OrderStateMachine)

/**
 * 订单状态机
 * 管理订单状态的流转规则
 */
public class OrderStateMachine {
    
    /**
     * 订单状态流转规则
     */
    private static final Map<String, Set<String>> STATUS_TRANSITION_MAP = new HashMap<>();
    
    static {
        // 待支付可以流转到:已支付、已取消
        STATUS_TRANSITION_MAP.put("PENDING_PAYMENT", 
            Set.of("PAID", "CANCELLED"));
        
        // 已支付可以流转到:待分配、已退款、已取消
        STATUS_TRANSITION_MAP.put("PAID", 
            Set.of("PENDING_ASSIGN", "REFUNDED", "CANCELLED"));
        
        // 待分配可以流转到:办理中、已取消
        STATUS_TRANSITION_MAP.put("PENDING_ASSIGN", 
            Set.of("PROCESSING", "CANCELLED"));
        
        // 办理中可以流转到:待确认、已取消
        STATUS_TRANSITION_MAP.put("PROCESSING", 
            Set.of("PENDING_CONFIRM", "CANCELLED"));
        
        // 待确认可以流转到:已完成、已取消
        STATUS_TRANSITION_MAP.put("PENDING_CONFIRM", 
            Set.of("COMPLETED", "CANCELLED"));
        
        // 已完成、已取消、已退款为终态,不能再流转
    }
    
    /**
     * 验证状态流转是否合法
     * @param currentStatus 当前状态
     * @param newStatus 新状态
     * @return 是否合法
     */
    public boolean canTransition(String currentStatus, String newStatus) {
        Set<String> allowedStatuses = STATUS_TRANSITION_MAP.get(currentStatus);
        if (allowedStatuses == null) {
            return false;
        }
        return allowedStatuses.contains(newStatus);
    }
    
    /**
     * 获取可流转的状态列表
     * @param currentStatus 当前状态
     * @return 可流转的状态列表
     */
    public Set<String> getAllowedStatuses(String currentStatus) {
        return STATUS_TRANSITION_MAP.getOrDefault(currentStatus, Collections.emptySet());
    }
}

2.3 业务流程设计

2.3.1 订单创建流程(客户下单)

流程说明:

  1. 客户在客户端选择服务类型、车辆、填写订单信息
  2. 系统验证订单数据(客户信息、车辆信息、服务类型可用性)
  3. 系统计算订单金额(根据服务类型、价格规则、优惠活动)
  4. 创建订单,状态为"待支付"
  5. 返回订单信息给客户端

详细步骤:

1. 接收订单创建请求
   ├─ 验证客户登录状态
   ├─ 验证订单数据完整性
   │   ├─ 客户信息验证(客户是否存在、状态是否正常)
   │   ├─ 车辆信息验证(车辆是否存在、是否属于该客户)
   │   ├─ 服务类型验证(服务类型是否存在、是否启用)
   │   └─ 订单信息验证(服务地址、服务时间等)
   │
2. 计算订单金额
   ├─ 获取服务基础价格
   ├─ 根据价格规则计算价格(按车型、按地区等)
   ├─ 应用优惠活动(优惠券、积分等)
   └─ 计算最终金额
   
3. 创建订单
   ├─ 生成订单号(唯一)
   ├─ 设置订单基本信息
   ├─ 设置订单状态为"待支付"
   ├─ 保存订单到数据库
   ├─ 记录订单创建日志
   └─ 发送订单创建通知(可选)
   
4. 返回订单信息
   └─ 返回订单号、订单金额、支付信息等

异常处理:

  • 客户信息不存在:返回错误信息"客户信息不存在"
  • 车辆信息不存在:返回错误信息"车辆信息不存在"
  • 服务类型不可用:返回错误信息"服务类型不可用"
  • 价格计算失败:记录错误日志,返回错误信息"价格计算失败,请稍后重试"
  • 订单创建失败:记录错误日志,返回错误信息"订单创建失败,请稍后重试"

2.3.2 订单创建流程(渠道API下单)

流程说明:

  1. 渠道调用订单创建API
  2. 系统验证API签名和权限
  3. 系统验证订单数据
  4. 创建订单,状态根据渠道是否已支付设置为"待支付"或"已支付"
  5. 返回订单号给渠道

详细步骤:

1. 接收API请求
   ├─ 验证API签名(HMAC-SHA256)
   ├─ 验证API Key和Secret
   ├─ 验证IP白名单
   ├─ 验证限流(检查调用频率)
   └─ 记录API调用日志
   
2. 验证订单数据
   ├─ 必填字段验证
   │   ├─ 客户信息(姓名、手机号、身份证号)
   │   ├─ 车辆信息(车牌号、品牌、型号)
   │   ├─ 服务信息(服务类型、服务地址)
   │   └─ 订单信息(订单类型、订单金额)
   ├─ 数据格式验证
   │   ├─ 手机号格式验证
   │   ├─ 身份证号格式验证
   │   ├─ 车牌号格式验证
   │   └─ 金额格式验证
   └─ 业务规则验证
       ├─ 服务类型可用性验证
       ├─ 价格计算准确性验证
       └─ 车辆信息有效性验证
       
3. 创建订单
   ├─ 生成订单号
   ├─ 设置订单来源为"渠道API下单"
   ├─ 关联渠道信息
   ├─ 根据渠道是否已支付设置订单状态
   │   ├─ 渠道已支付 → 状态为"已支付"
   │   └─ 渠道未支付 → 状态为"待支付"
   ├─ 保存订单到数据库
   ├─ 记录订单创建日志
   └─ 如果状态为"已支付",触发订单分配流程
   
4. 返回订单信息
   └─ 返回订单号、订单状态等

异常处理:

  • API签名验证失败:返回401错误"签名验证失败"
  • API Key无效:返回401错误"API Key无效"
  • IP不在白名单:返回403错误"IP不在白名单"
  • 限流触发:返回429错误"请求频率超限"
  • 数据验证失败:返回400错误,包含具体错误信息
  • 订单创建失败:返回500错误"订单创建失败",记录错误日志

2.3.3 订单状态流转流程

流程说明: 订单状态流转必须遵循状态机规则,不允许跨状态流转。每次状态变更都需要记录变更日志。

状态流转规则:

待支付 (PENDING_PAYMENT)
  ├─ 支付成功 → 已支付 (PAID)
  └─ 客户取消 → 已取消 (CANCELLED)

已支付 (PAID)
  ├─ 分配完成 → 待分配 (PENDING_ASSIGN)
  ├─ 申请退款 → 已退款 (REFUNDED)
  └─ 管理员取消 → 已取消 (CANCELLED)

待分配 (PENDING_ASSIGN)
  ├─ 材料审核通过 → 办理中 (PROCESSING)
  └─ 订单取消 → 已取消 (CANCELLED)

办理中 (PROCESSING)
  ├─ 业务办理完成 → 待确认 (PENDING_CONFIRM)
  └─ 订单取消 → 已取消 (CANCELLED)

待确认 (PENDING_CONFIRM)
  ├─ 客户确认 → 已完成 (COMPLETED)
  └─ 订单取消 → 已取消 (CANCELLED)

已完成 (COMPLETED) - 终态
已取消 (CANCELLED) - 终态
已退款 (REFUNDED) - 终态

状态流转实现:

/**
 * 更新订单状态
 */
public void updateOrderStatus(Long orderId, String newStatus, Long operatorId, String reason) {
    // 1. 查询订单当前状态
    Order order = orderMapper.selectById(orderId);
    if (order == null) {
        throw new BusinessException("订单不存在");
    }
    
    String currentStatus = order.getStatus();
    
    // 2. 验证状态流转是否合法
    if (!orderStateMachine.canTransition(currentStatus, newStatus)) {
        throw new BusinessException(
            String.format("订单状态不能从 %s 流转到 %s", currentStatus, newStatus));
    }
    
    // 3. 使用分布式锁,防止并发修改
    String lockKey = "order:status:lock:" + orderId;
    RLock lock = redissonClient.getLock(lockKey);
    try {
        if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
            // 4. 再次查询订单状态(双重检查)
            order = orderMapper.selectById(orderId);
            if (!currentStatus.equals(order.getStatus())) {
                throw new BusinessException("订单状态已被修改,请刷新后重试");
            }
            
            // 5. 更新订单状态
            order.setStatus(newStatus);
            order.setUpdateTime(LocalDateTime.now());
            orderMapper.updateById(order);
            
            // 6. 记录状态变更日志
            OrderStatusLog statusLog = new OrderStatusLog();
            statusLog.setOrderId(orderId);
            statusLog.setOldStatus(currentStatus);
            statusLog.setNewStatus(newStatus);
            statusLog.setOperatorId(operatorId);
            statusLog.setReason(reason);
            statusLog.setCreateTime(LocalDateTime.now());
            orderStatusLogMapper.insert(statusLog);
            
            // 7. 发送状态变更通知
            sendStatusChangeNotification(order, currentStatus, newStatus);
            
            // 8. 如果状态为"已支付",触发订单分配流程
            if ("PAID".equals(newStatus)) {
                triggerOrderAssign(order);
            }
            
            // 9. 如果状态为"已完成",触发后续流程
            if ("COMPLETED".equals(newStatus)) {
                triggerOrderComplete(order);
            }
        } else {
            throw new BusinessException("订单正在处理中,请稍后重试");
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new BusinessException("订单状态更新失败");
    } finally {
        if (lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
}

2.4 订单分配详细设计

2.4.1 分配规则引擎

/**
 * 订单分配规则引擎
 */
public class OrderAssignRuleEngine {
    
    /**
     * 代驾人员分配规则
     */
    public List<Driver> filterDrivers(Order order, List<Driver> allDrivers) {
        return allDrivers.stream()
            .filter(driver -> checkDriverStatus(driver))           // 状态检查
            .filter(driver -> checkDriverArea(driver, order))     // 区域检查
            .filter(driver -> checkDriverWorkload(driver))         // 负载检查
            .filter(driver -> checkDriverQualification(driver))    // 资质检查
            .filter(driver -> checkDriverRating(driver))           // 评价检查
            .collect(Collectors.toList());
    }
    
    /**
     * 代驾人员排序(优先级排序)
     */
    public List<Driver> sortDrivers(List<Driver> drivers, Order order) {
        return drivers.stream()
            .sorted(Comparator
                .comparing((Driver d) -> calculateDistance(d, order)).thenComparing(  // 距离最近
                Comparator.comparing(Driver::getCurrentOrderCount)).thenComparing(      // 负载最轻
                Comparator.comparing(Driver::getAverageRating).reversed()).thenComparing( // 评价最高
                Comparator.comparing(Driver::getAverageResponseTime)))                 // 响应最快
            .collect(Collectors.toList());
    }
    
    /**
     * 计算距离(使用高德地图API或数据库存储的距离信息)
     */
    private double calculateDistance(Driver driver, Order order) {
        // 实现距离计算逻辑
        // 可以使用高德地图API计算实际距离
        // 或使用数据库存储的距离信息
        return 0.0;
    }
}

2.4.2 自动分配流程

流程说明:

  1. 系统根据订单类型、服务地址等条件筛选可用的服务人员
  2. 按优先级排序,选择优先级最高的服务人员
  3. 分配订单,发送通知
  4. 如果分配失败,自动重新分配

详细步骤:

1. 触发订单分配
   ├─ 订单状态变为"已支付"
   └─ 调用分配服务
   
2. 根据订单类型选择分配策略
   ├─ 代驾订单
   │   ├─ 先分配代驾人员
   │   ├─ 再分配接待员
   │   └─ 最后分配检测站(如需要)
   └─ 自驾订单
       ├─ 先分配接待员
       └─ 再分配检测站(如需要)
       
3. 代驾人员分配
   ├─ 筛选符合条件的代驾人员
   │   ├─ 状态:在线、非忙碌、非休息
   │   ├─ 服务区域:包含订单服务地址
   │   ├─ 工作负载:当前订单数 < 最大并发数
   │   ├─ 资质:审核通过、证件有效
   │   └─ 评价:好评率 >= 80%
   ├─ 按优先级排序
   │   ├─ 第一优先级:距离最近
   │   ├─ 第二优先级:工作负载最轻
   │   ├─ 第三优先级:评价最高
   │   └─ 第四优先级:响应最快
   ├─ 选择优先级最高的代驾人员
   ├─ 分配订单(使用分布式锁)
   ├─ 发送短信通知(使用模板:DRIVER_ORDER_ASSIGN)
   └─ 设置超时时间(15分钟)
   
4. 代驾人员接单处理
   ├─ 代驾人员接受订单
   │   ├─ 更新订单状态为"待分配"(代驾已分配)
   │   └─ 更新代驾人员状态为"忙碌"
   ├─ 代驾人员拒绝订单
   │   └─ 重新分配(选择下一个优先级)
   └─ 超时未接单
       └─ 重新分配(选择下一个优先级)
       
5. 接待员分配
   ├─ 筛选符合条件的接待员
   │   ├─ 状态:启用、在线
   │   ├─ 服务区域:包含订单服务地址
   │   ├─ 工作负载:当前订单数 < 最大并发数
   │   └─ 服务类型:具备该服务类型办理能力
   ├─ 按优先级排序
   │   ├─ 第一优先级:工作负载最轻
   │   ├─ 第二优先级:距离最近
   │   └─ 第三优先级:历史完成率最高
   ├─ 选择优先级最高的接待员
   └─ 分配订单
   
6. 检测站分配(如需要)
   ├─ 筛选符合条件的检测站
   │   ├─ 状态:启用
   │   ├─ 服务范围:包含订单服务地址
   │   ├─ 服务类型:支持该服务类型
   │   └─ 营业时间:当前时间在营业时间内
   ├─ 按优先级排序
   │   ├─ 第一优先级:距离最近
   │   ├─ 第二优先级:评价最高
   │   └─ 第三优先级:当前订单量最少
   └─ 分配订单

异常处理:

  • 没有可用的代驾人员:记录日志,转为手动分配或等待代驾人员上线
  • 连续3次分配失败:记录异常,转为手动分配,通知管理员
  • 分配超时:自动重新分配,记录超时日志

2.5 数据库设计

2.5.1 订单表 (car_order)

CREATE TABLE `car_order` (
  `order_id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单ID',
  `order_no` varchar(32) NOT NULL COMMENT '订单号(唯一)',
  `customer_id` bigint NOT NULL COMMENT '客户ID',
  `vehicle_id` bigint NOT NULL COMMENT '车辆ID',
  `service_id` bigint NOT NULL COMMENT '服务类型ID',
  `order_type` varchar(20) NOT NULL COMMENT '订单类型(DRIVER-代驾订单, SELF-自驾订单)',
  `order_source` varchar(20) NOT NULL COMMENT '订单来源(CUSTOMER-客户直接下单, CHANNEL-渠道API下单, ADMIN-管理员手动创建)',
  `channel_id` bigint DEFAULT NULL COMMENT '渠道ID(渠道来源订单必填)',
  `status` varchar(20) NOT NULL DEFAULT 'PENDING_PAYMENT' COMMENT '订单状态',
  `amount` decimal(10,2) NOT NULL COMMENT '订单金额',
  `paid_amount` decimal(10,2) DEFAULT 0.00 COMMENT '实际支付金额',
  `service_address` varchar(200) NOT NULL COMMENT '服务地址',
  `service_time` datetime NOT NULL COMMENT '服务时间',
  `driver_id` bigint DEFAULT NULL COMMENT '代驾人员ID',
  `receptionist_id` bigint DEFAULT NULL COMMENT '接待员ID',
  `station_id` bigint DEFAULT NULL COMMENT '检测站ID',
  `remark` text COMMENT '订单备注',
  `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`order_id`),
  UNIQUE KEY `uk_order_no` (`order_no`),
  KEY `idx_customer_id` (`customer_id`),
  KEY `idx_vehicle_id` (`vehicle_id`),
  KEY `idx_service_id` (`service_id`),
  KEY `idx_channel_id` (`channel_id`),
  KEY `idx_status` (`status`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_service_time` (`service_time`),
  KEY `idx_driver_id` (`driver_id`),
  KEY `idx_receptionist_id` (`receptionist_id`),
  KEY `idx_station_id` (`station_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表';

2.5.2 订单状态流转日志表 (car_order_status_log)

CREATE TABLE `car_order_status_log` (
  `log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志ID',
  `order_id` bigint NOT NULL COMMENT '订单ID',
  `old_status` varchar(20) NOT NULL COMMENT '原状态',
  `new_status` varchar(20) NOT NULL COMMENT '新状态',
  `operator_id` bigint DEFAULT NULL COMMENT '操作人ID',
  `operator_type` varchar(20) DEFAULT NULL COMMENT '操作人类型(ADMIN-管理员, CUSTOMER-客户, SYSTEM-系统)',
  `reason` varchar(500) DEFAULT NULL COMMENT '变更原因',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`log_id`),
  KEY `idx_order_id` (`order_id`),
  KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单状态流转日志表';

2.5.3 订单材料表 (car_order_material)

CREATE TABLE `car_order_material` (
  `material_id` bigint NOT NULL AUTO_INCREMENT COMMENT '材料ID',
  `order_id` bigint NOT NULL COMMENT '订单ID',
  `material_type` varchar(50) NOT NULL COMMENT '材料类型(ID_CARD-身份证, DRIVING_LICENSE-行驶证, VEHICLE_PHOTO-车辆照片等)',
  `material_name` varchar(100) NOT NULL COMMENT '材料名称',
  `file_url` varchar(500) NOT NULL COMMENT '文件URL',
  `file_size` bigint DEFAULT NULL COMMENT '文件大小(字节)',
  `audit_status` varchar(20) DEFAULT 'PENDING' COMMENT '审核状态(PENDING-待审核, PASSED-通过, REJECTED-不通过)',
  `audit_comment` varchar(500) DEFAULT NULL COMMENT '审核意见',
  `auditor_id` bigint DEFAULT NULL COMMENT '审核人ID',
  `audit_time` datetime DEFAULT NULL COMMENT '审核时间',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`material_id`),
  KEY `idx_order_id` (`order_id`),
  KEY `idx_audit_status` (`audit_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单材料表';

2.6 接口设计

2.6.1 创建订单接口

接口地址:POST /api/v1/order/create

请求参数:

{
  "serviceId": 1,
  "vehicleId": 1,
  "orderType": "DRIVER",
  "serviceAddress": "重庆市渝北区xxx",
  "serviceTime": "2024-01-15 10:00:00",
  "remark": "备注信息"
}

响应参数:

{
  "code": 200,
  "message": "success",
  "data": {
    "orderId": 1,
    "orderNo": "ORD202401150001",
    "amount": 100.00,
    "status": "PENDING_PAYMENT",
    "createTime": "2024-01-15 09:00:00"
  },
  "timestamp": 1705280400000
}

错误码:

  • 400:请求参数错误
  • 401:未登录
  • 403:无权限
  • 500:服务器内部错误

2.6.2 查询订单列表接口

接口地址:GET /api/v1/order/list

请求参数:

  • pageNum:页码(默认1)
  • pageSize:每页数量(默认10)
  • orderNo:订单号(可选)
  • status:订单状态(可选)
  • orderType:订单类型(可选)
  • startTime:开始时间(可选)
  • endTime:结束时间(可选)

响应参数:

{
  "code": 200,
  "message": "success",
  "data": {
    "total": 100,
    "pageNum": 1,
    "pageSize": 10,
    "list": [
      {
        "orderId": 1,
        "orderNo": "ORD202401150001",
        "customerName": "张三",
        "serviceName": "车辆年检",
        "status": "PROCESSING",
        "amount": 100.00,
        "createTime": "2024-01-15 09:00:00"
      }
    ]
  },
  "timestamp": 1705280400000
}

3. 渠道管理模块详细设计

3.1 模块概述

渠道管理模块负责管理渠道信息、API对接、订单接收、订单统计及结算。渠道通过API接口向系统发送订单,系统接收订单后进行后续处理。

3.2 类设计

3.2.1 渠道实体类 (Channel)

/**
 * 渠道实体类
 */
public class Channel {
    /**
     * 渠道ID
     */
    private Long channelId;
    
    /**
     * 渠道编码(唯一)
     */
    private String channelCode;
    
    /**
     * 渠道名称
     */
    private String channelName;
    
    /**
     * 联系方式
     */
    private String contactPhone;
    
    /**
     * 地址
     */
    private String address;
    
    /**
     * 负责人
     */
    private String contactPerson;
    
    /**
     * 业务类型
     */
    private String businessType;
    
    /**
     * 渠道状态(ENABLED-启用, DISABLED-停用, PENDING-审核中, BANNED-已禁用)
     */
    private String status;
    
    /**
     * API Key
     */
    private String apiKey;
    
    /**
     * API Secret(加密存储)
     */
    private String apiSecret;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    
    // getter/setter方法
}

3.2.2 API签名验证服务 (ApiSignatureService)

/**
 * API签名验证服务
 */
@Service
public class ApiSignatureService {
    
    /**
     * 验证API签名
     * @param request 请求对象
     * @param apiKey API Key
     * @param apiSecret API Secret
     * @return 是否验证通过
     */
    public boolean verifySignature(HttpServletRequest request, String apiKey, String apiSecret) {
        // 1. 获取请求参数
        String timestamp = request.getHeader("X-Timestamp");
        String nonce = request.getHeader("X-Nonce");
        String signature = request.getHeader("X-Signature");
        
        // 2. 验证时间戳(防止重放攻击,时间差不超过5分钟)
        if (!isValidTimestamp(timestamp)) {
            return false;
        }
        
        // 3. 验证nonce(防止重复请求,使用Redis存储已使用的nonce)
        if (!isValidNonce(nonce)) {
            return false;
        }
        
        // 4. 构建签名字符串
        String signString = buildSignString(request, timestamp, nonce);
        
        // 5. 计算签名
        String calculatedSignature = calculateSignature(signString, apiSecret);
        
        // 6. 比较签名
        return signature != null && signature.equals(calculatedSignature);
    }
    
    /**
     * 构建签名字符串
     */
    private String buildSignString(HttpServletRequest request, String timestamp, String nonce) {
        // 获取请求方法、URI、参数等
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        String body = getRequestBody(request);
        
        // 按字典序排序参数
        Map<String, String> params = new TreeMap<>();
        params.put("timestamp", timestamp);
        params.put("nonce", nonce);
        if (queryString != null) {
            // 解析query参数
            String[] pairs = queryString.split("&");
            for (String pair : pairs) {
                String[] kv = pair.split("=");
                if (kv.length == 2) {
                    params.put(kv[0], kv[1]);
                }
            }
        }
        if (body != null && !body.isEmpty()) {
            // 解析body参数(JSON格式)
            // ...
        }
        
        // 构建签名字符串
        StringBuilder sb = new StringBuilder();
        sb.append(method).append("\n");
        sb.append(uri).append("\n");
        for (Map.Entry<String, String> entry : params.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        
        return sb.toString();
    }
    
    /**
     * 计算签名(HMAC-SHA256)
     */
    private String calculateSignature(String signString, String apiSecret) {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKeySpec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            mac.init(secretKeySpec);
            byte[] hash = mac.doFinal(signString.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(hash);
        } catch (Exception e) {
            throw new RuntimeException("签名计算失败", e);
        }
    }
    
    /**
     * 验证时间戳
     */
    private boolean isValidTimestamp(String timestamp) {
        try {
            long ts = Long.parseLong(timestamp);
            long currentTime = System.currentTimeMillis() / 1000;
            long diff = Math.abs(currentTime - ts);
            return diff <= 300; // 5分钟内有效
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 验证nonce
     */
    private boolean isValidNonce(String nonce) {
        // 使用Redis存储已使用的nonce,有效期5分钟
        String key = "api:nonce:" + nonce;
        Boolean exists = redisTemplate.hasKey(key);
        if (exists != null && exists) {
            return false; // nonce已使用
        }
        redisTemplate.opsForValue().set(key, "1", 5, TimeUnit.MINUTES);
        return true;
    }
}

3.2.3 API限流服务 (ApiRateLimitService)

/**
 * API限流服务(令牌桶算法)
 */
@Service
public class ApiRateLimitService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    /**
     * 检查是否限流
     * @param channelId 渠道ID
     * @param limit 限流阈值(每分钟请求数)
     * @return 是否允许请求
     */
    public boolean checkRateLimit(Long channelId, int limit) {
        String key = "api:ratelimit:" + channelId;
        
        // 获取当前令牌数
        String tokensStr = (String) redisTemplate.opsForValue().get(key);
        int tokens = tokensStr != null ? Integer.parseInt(tokensStr) : limit;
        
        if (tokens > 0) {
            // 有令牌,允许请求,令牌数减1
            redisTemplate.opsForValue().set(key, String.valueOf(tokens - 1), 60, TimeUnit.SECONDS);
            return true;
        } else {
            // 无令牌,拒绝请求
            return false;
        }
    }
    
    /**
     * 添加令牌(定时任务,每秒添加limit/60个令牌)
     */
    @Scheduled(fixedRate = 1000)
    public void addTokens() {
        // 获取所有渠道的限流配置
        List<Channel> channels = channelService.getAllChannels();
        for (Channel channel : channels) {
            if ("ENABLED".equals(channel.getStatus())) {
                String key = "api:ratelimit:" + channel.getChannelId();
                int limit = channel.getRateLimit(); // 每分钟限流数
                int addTokens = limit / 60; // 每秒添加的令牌数
                
                String tokensStr = (String) redisTemplate.opsForValue().get(key);
                int tokens = tokensStr != null ? Integer.parseInt(tokensStr) : limit;
                int newTokens = Math.min(tokens + addTokens, limit); // 不超过上限
                
                redisTemplate.opsForValue().set(key, String.valueOf(newTokens), 60, TimeUnit.SECONDS);
            }
        }
    }
}

3.3 业务流程设计

3.3.1 渠道API订单创建流程

详细步骤:

1. 接收API请求
   ├─ 从请求头获取API Key
   ├─ 根据API Key查询渠道信息
   ├─ 验证渠道状态(必须是启用状态)
   ├─ 验证API签名
   │   ├─ 获取时间戳、随机数、签名
   │   ├─ 验证时间戳有效性(5分钟内)
   │   ├─ 验证nonce唯一性(防止重放攻击)
   │   ├─ 构建签名字符串
   │   ├─ 计算签名(HMAC-SHA256)
   │   └─ 比较签名
   ├─ 验证IP白名单
   │   └─ 检查请求IP是否在渠道的IP白名单中
   └─ 验证限流
       └─ 检查渠道的API调用频率是否超限
       
2. 验证订单数据
   ├─ 必填字段验证
   │   ├─ 客户信息(姓名、手机号、身份证号)
   │   ├─ 车辆信息(车牌号、品牌、型号)
   │   ├─ 服务信息(服务类型、服务地址)
   │   └─ 订单信息(订单类型、订单金额)
   ├─ 数据格式验证
   │   ├─ 手机号格式:11位数字,1开头
   │   ├─ 身份证号格式:18位,最后一位可能是X
   │   ├─ 车牌号格式:符合中国车牌号规则
   │   └─ 金额格式:大于0的数值
   └─ 业务规则验证
       ├─ 服务类型是否存在且启用
       ├─ 价格计算是否准确(验证订单金额)
       └─ 车辆信息是否有效
       
3. 创建订单
   ├─ 生成订单号(格式:ORD + 年月日 + 6位序号)
   ├─ 设置订单来源为"渠道API下单"
   ├─ 关联渠道信息
   ├─ 根据渠道是否已支付设置订单状态
   │   ├─ 如果渠道已支付 → 状态为"已支付",触发订单分配
   │   └─ 如果渠道未支付 → 状态为"待支付"
   ├─ 保存订单到数据库
   ├─ 记录订单创建日志
   └─ 记录API调用日志
   
4. 返回订单信息
   └─ 返回订单号、订单状态、创建时间等

异常处理:

  • API Key不存在:返回401错误"API Key不存在"
  • 渠道状态异常:返回403错误"渠道状态异常"
  • 签名验证失败:返回401错误"签名验证失败"
  • IP不在白名单:返回403错误"IP不在白名单"
  • 限流触发:返回429错误"请求频率超限,请稍后重试"
  • 数据验证失败:返回400错误,包含具体错误信息
  • 订单创建失败:返回500错误"订单创建失败",记录错误日志

3.3.2 订单状态回调流程

流程说明: 系统订单状态变更时,自动回调渠道接口,通知渠道订单最新状态。

详细步骤:

1. 订单状态变更触发回调
   ├─ 订单状态变更时,检查订单是否来自渠道
   ├─ 如果是渠道订单,获取渠道的回调地址
   └─ 异步调用回调接口
   
2. 构建回调数据
   ├─ 订单号
   ├─ 订单状态
   ├─ 状态变更时间
   ├─ 状态变更原因
   └─ 签名(使用渠道的API Secret签名)
   
3. 发送回调请求
   ├─ HTTP POST请求
   ├─ 请求头:Content-Type: application/json
   ├─ 请求体:JSON格式的回调数据
   └─ 设置超时时间(5秒)
   
4. 处理回调结果
   ├─ 回调成功(HTTP 200)
   │   ├─ 记录回调成功日志
   │   └─ 更新回调状态为"成功"
   └─ 回调失败(非200或超时)
       ├─ 记录回调失败日志
       ├─ 更新回调状态为"失败"
       └─ 加入重试队列(最多重试3次,间隔递增)

重试机制:

  • 第1次重试:失败后立即重试
  • 第2次重试:失败后等待1分钟重试
  • 第3次重试:失败后等待5分钟重试
  • 3次都失败:记录异常日志,通知管理员

3.4 数据库设计

3.4.1 渠道表 (car_channel)

CREATE TABLE `car_channel` (
  `channel_id` bigint NOT NULL AUTO_INCREMENT COMMENT '渠道ID',
  `channel_code` varchar(20) NOT NULL COMMENT '渠道编码(唯一)',
  `channel_name` varchar(100) NOT NULL COMMENT '渠道名称',
  `contact_person` varchar(50) NOT NULL COMMENT '负责人',
  `contact_phone` varchar(11) NOT NULL COMMENT '联系电话',
  `contact_email` varchar(100) DEFAULT NULL COMMENT '联系邮箱',
  `address` varchar(200) DEFAULT NULL COMMENT '地址',
  `business_type` varchar(50) DEFAULT NULL COMMENT '业务类型',
  `api_key` varchar(64) NOT NULL COMMENT 'API Key',
  `api_secret` varchar(128) NOT NULL COMMENT 'API Secret(加密存储)',
  `rate_limit` int DEFAULT 100 COMMENT '限流阈值(每分钟请求数)',
  `callback_url` varchar(500) DEFAULT NULL COMMENT '回调地址',
  `ip_whitelist` text COMMENT 'IP白名单(JSON数组)',
  `status` varchar(20) NOT NULL DEFAULT 'PENDING' COMMENT '状态(ENABLED-启用, DISABLED-停用, PENDING-审核中, BANNED-已禁用)',
  `remark` text COMMENT '备注',
  `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`channel_id`),
  UNIQUE KEY `uk_channel_code` (`channel_code`),
  UNIQUE KEY `uk_api_key` (`api_key`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='渠道表';

3.4.2 API调用日志表 (car_api_call_log)

CREATE TABLE `car_api_call_log` (
  `log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志ID',
  `channel_id` bigint NOT NULL COMMENT '渠道ID',
  `api_path` varchar(200) NOT NULL COMMENT '接口路径',
  `request_method` varchar(10) NOT NULL COMMENT '请求方法',
  `request_params` text COMMENT '请求参数(JSON)',
  `response_code` int DEFAULT NULL COMMENT '响应码',
  `response_data` text COMMENT '响应数据(JSON)',
  `response_time` int DEFAULT NULL COMMENT '响应时间(毫秒)',
  `client_ip` varchar(50) DEFAULT NULL COMMENT '客户端IP',
  `user_agent` varchar(500) DEFAULT NULL COMMENT 'User Agent',
  `status` varchar(20) DEFAULT NULL COMMENT '调用状态(SUCCESS-成功, FAILED-失败)',
  `error_message` varchar(500) DEFAULT NULL COMMENT '错误信息',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`log_id`),
  KEY `idx_channel_id` (`channel_id`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='API调用日志表';

3.5 接口设计

3.5.1 渠道订单创建接口

接口地址:POST /api/v1/channel/order/create

认证方式:API Key + Secret签名

请求头:

  • X-API-Key: {apiKey}
  • X-Timestamp: {timestamp}
  • X-Nonce: {nonce}
  • X-Signature: {signature}
  • Content-Type: application/json

请求参数:

{
  "customerName": "张三",
  "customerPhone": "13800138000",
  "customerIdCard": "500123199001011234",
  "plateNumber": "渝A12345",
  "brand": "大众",
  "model": "朗逸",
  "serviceId": 1,
  "orderType": "DRIVER",
  "serviceAddress": "重庆市渝北区xxx",
  "serviceTime": "2024-01-15 10:00:00",
  "amount": 100.00,
  "paid": true
}

响应参数:

{
  "code": 200,
  "message": "success",
  "data": {
    "orderNo": "ORD202401150001",
    "orderId": 1,
    "status": "PAID",
    "createTime": "2024-01-15 09:00:00"
  },
  "timestamp": 1705280400000
}

错误码:

  • 400:请求参数错误
  • 401:签名验证失败
  • 403:IP不在白名单或渠道状态异常
  • 429:请求频率超限
  • 500:服务器内部错误

4. 支付管理模块详细设计

4.1 模块概述

支付管理模块负责订单支付、退款处理、支付记录管理等。支持微信支付、支付宝支付等多种支付方式。

4.2 类设计

4.2.1 支付服务类 (PaymentService)

/**
 * 支付服务接口
 */
public interface PaymentService {
    /**
     * 创建支付订单
     * @param orderId 订单ID
     * @param paymentType 支付方式(WECHAT-微信, ALIPAY-支付宝)
     * @return 支付信息(支付URL或支付参数)
     */
    PaymentVO createPayment(Long orderId, String paymentType);
    
    /**
     * 处理支付回调
     * @param paymentType 支付方式
     * @param callbackData 回调数据
     * @return 处理结果
     */
    PaymentCallbackResult handlePaymentCallback(String paymentType, Map<String, String> callbackData);
    
    /**
     * 查询支付状态
     * @param paymentNo 支付流水号
     * @return 支付状态
     */
    PaymentStatusVO queryPaymentStatus(String paymentNo);
    
    /**
     * 申请退款
     * @param orderId 订单ID
     * @param refundAmount 退款金额
     * @param reason 退款原因
     * @return 退款信息
     */
    RefundVO applyRefund(Long orderId, BigDecimal refundAmount, String reason);
    
    /**
     * 处理退款回调
     * @param paymentType 支付方式
     * @param callbackData 回调数据
     * @return 处理结果
     */
    RefundCallbackResult handleRefundCallback(String paymentType, Map<String, String> callbackData);
}

4.2.2 支付流程设计

支付流程:

1. 创建支付订单
   ├─ 验证订单状态(必须是"待支付")
   ├─ 验证订单金额
   ├─ 创建支付记录(状态:待支付)
   ├─ 调用第三方支付接口
   │   ├─ 微信支付:调用统一下单接口
   │   └─ 支付宝支付:调用统一收单接口
   ├─ 获取支付参数(支付URL或支付二维码)
   └─ 返回支付信息给客户端
   
2. 客户端完成支付
   ├─ 用户完成支付
   └─ 第三方支付平台回调系统
   
3. 处理支付回调
   ├─ 验证回调签名
   ├─ 验证订单金额
   ├─ 更新支付记录状态(已支付)
   ├─ 更新订单状态(已支付)
   ├─ 触发订单分配流程
   ├─ 发送支付成功通知
   └─ 返回成功响应给第三方平台

支付超时处理:

  • 订单创建后30分钟内未支付,自动取消订单
  • 订单创建后25分钟发送支付提醒
  • 使用定时任务检查超时订单

4.3 退款流程设计

退款流程:

1. 申请退款
   ├─ 客户申请退款或管理员发起退款
   ├─ 验证订单状态(必须是"已支付")
   ├─ 验证退款金额(不能超过支付金额)
   ├─ 创建退款记录(状态:待审核)
   └─ 通知管理员审核
   
2. 退款审核
   ├─ 管理员审核退款申请
   ├─ 审核通过
   │   ├─ 更新退款记录状态(已审核)
   │   └─ 调用第三方支付退款接口
   └─ 审核拒绝
       ├─ 更新退款记录状态(已拒绝)
       └─ 通知客户审核结果
       
3. 处理退款回调
   ├─ 第三方支付平台回调系统
   ├─ 验证回调签名
   ├─ 更新退款记录状态(退款成功/失败)
   ├─ 更新订单状态(已退款)
   ├─ 发送退款通知
   └─ 返回成功响应给第三方平台

5. 订单分配模块详细设计

5.1 分配算法详细设计

5.1.1 代驾人员分配算法

算法流程:

/**
 * 代驾人员分配算法
 */
public Driver assignDriver(Order order) {
    // 1. 筛选符合条件的代驾人员
    List<Driver> candidates = driverService.findAvailableDrivers(order);
    
    if (candidates.isEmpty()) {
        throw new BusinessException("没有可用的代驾人员");
    }
    
    // 2. 计算每个代驾人员的综合得分
    List<DriverScore> scores = new ArrayList<>();
    for (Driver driver : candidates) {
        double score = calculateDriverScore(driver, order);
        scores.add(new DriverScore(driver, score));
    }
    
    // 3. 按得分排序(得分越高优先级越高)
    scores.sort((a, b) -> Double.compare(b.getScore(), a.getScore()));
    
    // 4. 选择得分最高的代驾人员
    Driver selectedDriver = scores.get(0).getDriver();
    
    // 5. 分配订单
    assignOrderToDriver(order, selectedDriver);
    
    return selectedDriver;
}

/**
 * 计算代驾人员综合得分
 */
private double calculateDriverScore(Driver driver, Order order) {
    double score = 0.0;
    
    // 距离得分(距离越近得分越高,权重40%)
    double distance = calculateDistance(driver.getLocation(), order.getServiceAddress());
    double distanceScore = 100.0 / (1.0 + distance / 10.0); // 距离每增加10km,得分减半
    score += distanceScore * 0.4;
    
    // 负载得分(负载越轻得分越高,权重30%)
    int currentOrders = driver.getCurrentOrderCount();
    int maxOrders = driver.getMaxConcurrentOrders();
    double loadScore = 100.0 * (1.0 - (double)currentOrders / maxOrders);
    score += loadScore * 0.3;
    
    // 评价得分(评价越高得分越高,权重20%)
    double rating = driver.getAverageRating();
    double ratingScore = rating * 20.0; // 5星评价 = 100分
    score += ratingScore * 0.2;
    
    // 响应速度得分(响应越快得分越高,权重10%)
    long avgResponseTime = driver.getAverageResponseTime(); // 秒
    double responseScore = 100.0 / (1.0 + avgResponseTime / 60.0); // 响应时间每增加60秒,得分减半
    score += responseScore * 0.1;
    
    return score;
}

5.1.2 接待员分配算法

算法流程:

/**
 * 接待员分配算法
 */
public Receptionist assignReceptionist(Order order) {
    // 1. 筛选符合条件的接待员
    List<Receptionist> candidates = receptionistService.findAvailableReceptionists(order);
    
    if (candidates.isEmpty()) {
        throw new BusinessException("没有可用的接待员");
    }
    
    // 2. 计算每个接待员的综合得分
    List<ReceptionistScore> scores = new ArrayList<>();
    for (Receptionist receptionist : candidates) {
        double score = calculateReceptionistScore(receptionist, order);
        scores.add(new ReceptionistScore(receptionist, score));
    }
    
    // 3. 按得分排序
    scores.sort((a, b) -> Double.compare(b.getScore(), a.getScore()));
    
    // 4. 选择得分最高的接待员
    Receptionist selectedReceptionist = scores.get(0).getReceptionist();
    
    // 5. 分配订单
    assignOrderToReceptionist(order, selectedReceptionist);
    
    return selectedReceptionist;
}

/**
 * 计算接待员综合得分
 */
private double calculateReceptionistScore(Receptionist receptionist, Order order) {
    double score = 0.0;
    
    // 负载得分(权重50%)
    int currentOrders = receptionist.getCurrentOrderCount();
    int maxOrders = receptionist.getMaxConcurrentOrders();
    double loadScore = 100.0 * (1.0 - (double)currentOrders / maxOrders);
    score += loadScore * 0.5;
    
    // 距离得分(权重30%)
    double distance = calculateDistance(receptionist.getLocation(), order.getServiceAddress());
    double distanceScore = 100.0 / (1.0 + distance / 10.0);
    score += distanceScore * 0.3;
    
    // 完成率得分(权重20%)
    double completionRate = receptionist.getCompletionRate();
    double completionScore = completionRate * 100.0;
    score += completionScore * 0.2;
    
    return score;
}

5.2 分配失败处理

处理流程:

1. 代驾人员15分钟内未接受订单
   ├─ 系统检测到超时
   ├─ 释放当前分配
   ├─ 重新筛选代驾人员(排除已分配的)
   ├─ 重新分配订单
   └─ 记录重新分配日志
   
2. 代驾人员拒绝订单
   ├─ 接收拒绝请求
   ├─ 释放当前分配
   ├─ 重新筛选代驾人员(排除已拒绝的)
   ├─ 重新分配订单
   └─ 记录拒绝日志
   
3. 连续3次分配失败
   ├─ 记录异常日志
   ├─ 标记订单为"分配异常"
   ├─ 通知管理员
   └─ 转为手动分配或等待代驾人员上线

6. 数据模型详细设计

6.1 核心表结构设计

6.1.1 订单表详细设计

表名:car_order

字段说明:

字段名类型长度是否必填说明
order_idbigint-是订单ID,主键,自增
order_novarchar32是订单号,唯一,格式:ORD+年月日+6位序号
customer_idbigint-是客户ID,外键关联car_customer
vehicle_idbigint-是车辆ID,外键关联car_vehicle
service_idbigint-是服务类型ID,外键关联car_service
order_typevarchar20是订单类型:DRIVER-代驾订单,SELF-自驾订单
order_sourcevarchar20是订单来源:CUSTOMER-客户直接下单,CHANNEL-渠道API下单,ADMIN-管理员手动创建
channel_idbigint-否渠道ID,外键关联car_channel,渠道来源订单必填
statusvarchar20是订单状态:PENDING_PAYMENT-待支付,PAID-已支付,PENDING_ASSIGN-待分配,PROCESSING-办理中,PENDING_CONFIRM-待确认,COMPLETED-已完成,CANCELLED-已取消,REFUNDED-已退款
amountdecimal10,2是订单金额,大于0
paid_amountdecimal10,2否实际支付金额,默认0
service_addressvarchar200是服务地址
service_timedatetime-是服务时间
driver_idbigint-否代驾人员ID,外键关联car_driver
receptionist_idbigint-否接待员ID,外键关联car_receptionist
station_idbigint-否检测站ID,外键关联car_inspection_station
remarktext-否订单备注
create_byvarchar64否创建者
create_timedatetime-是创建时间
update_byvarchar64否更新者
update_timedatetime-是更新时间

索引设计:

  • 主键索引:order_id
  • 唯一索引:order_no
  • 普通索引:customer_id, vehicle_id, service_id, channel_id, status, create_time, service_time, driver_id, receptionist_id, station_id
  • 组合索引:(status, create_time) - 用于按状态和时间查询

6.1.2 支付记录表详细设计

表名:car_payment_record

字段说明:

字段名类型长度是否必填说明
payment_idbigint-是支付记录ID,主键,自增
payment_novarchar32是支付流水号,唯一
order_idbigint-是订单ID,外键关联car_order
payment_typevarchar20是支付方式:WECHAT-微信支付,ALIPAY-支付宝支付
payment_amountdecimal10,2是支付金额
payment_statusvarchar20是支付状态:PENDING-待支付,PAID-已支付,FAILED-支付失败,REFUNDED-已退款
third_party_order_novarchar64否第三方支付平台订单号
payment_timedatetime-否支付时间
create_timedatetime-是创建时间
update_timedatetime-是更新时间

7. 接口详细设计

7.1 内部接口设计

7.1.1 订单创建接口

接口地址:POST /api/v1/order/create

接口描述:客户创建订单

请求头:

  • Authorization: Bearer {token}
  • Content-Type: application/json

请求参数:

参数名类型是否必填说明
serviceIdLong是服务类型ID
vehicleIdLong是车辆ID
orderTypeString是订单类型:DRIVER-代驾订单,SELF-自驾订单
serviceAddressString是服务地址,长度1-200
serviceTimeString是服务时间,格式:yyyy-MM-dd HH:mm:ss
remarkString否备注,长度0-500

请求示例:

{
  "serviceId": 1,
  "vehicleId": 1,
  "orderType": "DRIVER",
  "serviceAddress": "重庆市渝北区xxx街道xxx号",
  "serviceTime": "2024-01-15 10:00:00",
  "remark": "请准时到达"
}

响应参数:

参数名类型说明
codeInteger响应码:200-成功,其他-失败
messageString响应消息
dataObject响应数据
data.orderIdLong订单ID
data.orderNoString订单号
data.amountBigDecimal订单金额
data.statusString订单状态
data.createTimeString创建时间

响应示例:

{
  "code": 200,
  "message": "success",
  "data": {
    "orderId": 1,
    "orderNo": "ORD202401150001",
    "amount": 100.00,
    "status": "PENDING_PAYMENT",
    "createTime": "2024-01-15 09:00:00"
  },
  "timestamp": 1705280400000
}

错误响应示例:

{
  "code": 400,
  "message": "服务类型不存在",
  "data": null,
  "timestamp": 1705280400000
}

业务规则:

  1. 客户必须登录
  2. 服务类型必须存在且启用
  3. 车辆必须属于当前客户
  4. 服务时间必须大于当前时间
  5. 订单金额必须大于0

异常处理:

  • 客户未登录:返回401错误
  • 服务类型不存在:返回400错误"服务类型不存在"
  • 车辆不存在:返回400错误"车辆不存在"
  • 服务时间无效:返回400错误"服务时间必须大于当前时间"
  • 价格计算失败:返回500错误"价格计算失败,请稍后重试"

7.2 外部接口设计(渠道API)

7.2.1 渠道订单创建接口

接口地址:POST /api/v1/channel/order/create

接口描述:渠道通过API创建订单

认证方式:API Key + Secret签名

请求头:

  • X-API-Key: {apiKey}
  • X-Timestamp: {timestamp} - Unix时间戳(秒)
  • X-Nonce: {nonce} - 随机字符串,32位
  • X-Signature: {signature} - HMAC-SHA256签名
  • Content-Type: application/json

签名算法:

  1. 构建签名字符串:
    • 请求方法(POST)
    • 请求URI(/api/v1/channel/order/create)
    • 请求参数(按字典序排序,key=value格式,用&连接)
    • 时间戳(timestamp)
    • 随机数(nonce)
  2. 使用HMAC-SHA256算法,以API Secret为密钥,对签名字符串进行签名
  3. 对签名结果进行Base64编码

请求参数:

参数名类型是否必填说明
customerNameString是客户姓名,长度1-50
customerPhoneString是客户手机号,11位数字
customerIdCardString否客户身份证号,18位
plateNumberString是车牌号
brandString是品牌
modelString是型号
serviceIdLong是服务类型ID
orderTypeString是订单类型:DRIVER-代驾订单,SELF-自驾订单
serviceAddressString是服务地址
serviceTimeString是服务时间,格式:yyyy-MM-dd HH:mm:ss
amountBigDecimal是订单金额,大于0
paidBoolean是是否已支付:true-已支付,false-未支付

请求示例:

{
  "customerName": "张三",
  "customerPhone": "13800138000",
  "customerIdCard": "500123199001011234",
  "plateNumber": "渝A12345",
  "brand": "大众",
  "model": "朗逸",
  "serviceId": 1,
  "orderType": "DRIVER",
  "serviceAddress": "重庆市渝北区xxx街道xxx号",
  "serviceTime": "2024-01-15 10:00:00",
  "amount": 100.00,
  "paid": true
}

响应参数:

参数名类型说明
codeInteger响应码:200-成功,其他-失败
messageString响应消息
dataObject响应数据
data.orderNoString订单号
data.orderIdLong订单ID
data.statusString订单状态
data.createTimeString创建时间

响应示例:

{
  "code": 200,
  "message": "success",
  "data": {
    "orderNo": "ORD202401150001",
    "orderId": 1,
    "status": "PAID",
    "createTime": "2024-01-15 09:00:00"
  },
  "timestamp": 1705280400000
}

错误码定义:

错误码说明
200成功
400请求参数错误
401签名验证失败或API Key无效
403IP不在白名单或渠道状态异常
429请求频率超限
500服务器内部错误

8. 异常处理详细设计

8.1 异常分类

8.1.1 业务异常 (BusinessException)

使用场景:

  • 业务规则验证失败
  • 数据状态不符合业务要求
  • 业务操作失败

异常示例:

  • 订单状态不能流转
  • 订单金额计算错误
  • 代驾人员不可用
  • 支付金额不匹配

处理方式:

  • 返回明确的错误信息给用户
  • 记录业务异常日志
  • 不进行重试

8.1.2 系统异常 (SystemException)

使用场景:

  • 系统内部错误
  • 数据库操作失败
  • 第三方服务调用失败

异常示例:

  • 数据库连接失败
  • Redis连接失败
  • 第三方支付接口调用失败

处理方式:

  • 记录系统异常日志
  • 返回通用错误信息给用户
  • 支持重试机制

8.1.3 参数异常 (ParameterException)

使用场景:

  • 请求参数格式错误
  • 必填参数缺失
  • 参数值不符合要求

异常示例:

  • 手机号格式错误
  • 订单金额为负数
  • 服务时间格式错误

处理方式:

  • 返回具体的参数错误信息
  • 不记录异常日志(参数错误是正常情况)

8.2 异常处理策略

8.2.1 统一异常处理

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    /**
     * 处理业务异常
     */
    @ExceptionHandler(BusinessException.class)
    public Result handleBusinessException(BusinessException e) {
        log.warn("业务异常:{}", e.getMessage());
        return Result.error(e.getCode(), e.getMessage());
    }
    
    /**
     * 处理参数异常
     */
    @ExceptionHandler(ParameterException.class)
    public Result handleParameterException(ParameterException e) {
        log.warn("参数异常:{}", e.getMessage());
        return Result.error(400, e.getMessage());
    }
    
    /**
     * 处理系统异常
     */
    @ExceptionHandler(SystemException.class)
    public Result handleSystemException(SystemException e) {
        log.error("系统异常:", e);
        return Result.error(500, "系统异常,请稍后重试");
    }
    
    /**
     * 处理其他异常
     */
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        log.error("未知异常:", e);
        return Result.error(500, "系统异常,请稍后重试");
    }
}

8.2.2 重试机制

使用场景:

  • 第三方服务调用失败
  • 网络超时
  • 临时性错误

重试策略:

  • 最大重试次数:3次
  • 重试间隔:递增(1秒、3秒、5秒)
  • 重试条件:网络超时、5xx错误
  • 不重试:4xx错误、业务异常

实现示例:

/**
 * 重试机制实现
 */
@Retryable(value = {SystemException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000, multiplier = 2))
public void callThirdPartyService() {
    // 调用第三方服务
}

9. 性能优化详细设计

9.1 数据库优化

9.1.1 查询优化

优化策略:

  1. 使用索引:

    • 为常用查询字段创建索引
    • 为组合查询创建组合索引
    • 定期分析慢查询,优化索引
  2. 分页查询:

    • 使用LIMIT分页,避免一次性查询大量数据
    • 使用游标分页(适用于大数据量)
  3. 避免全表扫描:

    • 使用索引字段查询
    • 避免在WHERE子句中使用函数
  4. 优化JOIN查询:

    • 使用合适的JOIN类型
    • 避免多表JOIN(超过3个表)

9.1.2 写入优化

优化策略:

  1. 批量插入:使用批量插入减少数据库交互
  2. 异步写入:非关键数据异步写入
  3. 分库分表:数据量大时进行分库分表

9.2 缓存优化

9.2.1 缓存策略

缓存数据类型:

  1. 热点数据:

    • 服务列表
    • 地区数据
    • 字典数据
    • 价格规则
  2. 用户数据:

    • 登录用户信息
    • 用户权限信息
  3. 订单数据:

    • 订单状态(短期缓存)
    • 订单分配规则
  4. 代驾人员数据:

    • 代驾人员状态
    • 代驾人员位置信息

缓存更新策略:

  • Cache Aside:先更新数据库,再删除缓存
  • Write Through:先更新缓存,再更新数据库
  • Write Back:先更新缓存,异步更新数据库

9.2.2 缓存穿透防护

问题:查询不存在的数据,每次都查询数据库

解决方案:

  1. 布隆过滤器:使用布隆过滤器判断数据是否存在
  2. 空值缓存:查询不存在的数据时,缓存空值(设置较短的过期时间)

9.3 异步处理

9.3.1 消息队列使用

使用场景:

  1. 订单分配:异步分配订单,提升响应速度
  2. 短信发送:异步发送短信,避免阻塞
  3. 订单状态回调:异步回调渠道,提升性能
  4. 统计计算:异步计算统计数据

消息队列选型:RabbitMQ

消息格式:

{
  "messageId": "msg_123456",
  "messageType": "ORDER_ASSIGN",
  "timestamp": 1705280400000,
  "data": {
    "orderId": 1,
    "orderNo": "ORD202401150001"
  }
}

10. 安全设计详细说明

10.1 数据加密

10.1.1 敏感数据加密

加密字段:

  • 身份证号
  • 银行卡号
  • API Secret

加密算法:AES-256

加密实现:

/**
 * 数据加密服务
 */
@Service
public class EncryptionService {
    
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    
    /**
     * 加密
     */
    public String encrypt(String data) {
        // 实现AES加密
    }
    
    /**
     * 解密
     */
    public String decrypt(String encryptedData) {
        // 实现AES解密
    }
}

10.2 接口安全

10.2.1 防重放攻击

实现方式:

  1. 时间戳验证:请求时间戳必须在5分钟内
  2. Nonce验证:使用Redis存储已使用的nonce,防止重复请求

10.2.2 防SQL注入

实现方式:

  1. 参数化查询:使用MyBatis的参数化查询
  2. 输入验证:对用户输入进行验证和过滤

11. 其他核心模块设计

11.1 结算管理模块

11.1.1 结算单生成流程

流程说明:

  1. 定时任务触发(按结算周期)
  2. 查询该周期内完成的订单
  3. 根据结算规则计算结算金额
  4. 生成结算单
  5. 通知财务人员审核

详细步骤:

1. 定时任务触发
   ├─ 每月1日0点触发(月结)
   ├─ 每周一0点触发(周结)
   └─ 每天0点触发(日结)
   
2. 查询结算订单
   ├─ 根据结算对象查询订单
   ├─ 筛选订单状态为"已完成"
   ├─ 筛选订单时间在结算周期内
   └─ 排除已结算的订单
   
3. 计算结算金额
   ├─ 根据结算规则计算
   │   ├─ 按订单结算:订单数 × 固定金额
   │   ├─ 按比例结算:订单金额 × 比例
   │   └─ 混合结算:基础金额 + 按比例
   ├─ 计算总金额
   └─ 生成结算明细
   
4. 生成结算单
   ├─ 创建结算单记录
   ├─ 关联结算订单
   ├─ 设置结算单状态为"待审核"
   └─ 通知财务人员

11.2 评价管理模块

11.2.1 评价审核流程

流程说明:

  1. 客户提交评价
  2. 系统自动审核(敏感词过滤)
  3. 管理员审核
  4. 审核通过后展示评价

详细步骤:

1. 客户提交评价
   ├─ 验证订单状态(必须是"已完成")
   ├─ 验证评价时间(订单完成后7天内)
   ├─ 保存评价记录(状态:待审核)
   └─ 触发自动审核
   
2. 系统自动审核
   ├─ 敏感词过滤
   ├─ 违规内容识别
   ├─ 如果通过 → 状态改为"待人工审核"
   └─ 如果不通过 → 状态改为"已拒绝",通知客户
   
3. 管理员审核
   ├─ 查看待审核评价
   ├─ 审核评价内容
   ├─ 审核通过 → 状态改为"已通过",展示评价
   └─ 审核拒绝 → 状态改为"已拒绝",通知客户

12. 附录

12.1 设计模式应用

  • 状态机模式:订单状态流转
  • 策略模式:支付方式、结算规则
  • 工厂模式:支付服务创建
  • 观察者模式:订单状态变更通知
  • 模板方法模式:订单分配算法

12.2 技术选型说明

  • Spring Boot:快速开发框架
  • MyBatis Plus:ORM框架,简化数据库操作
  • Redis:缓存和分布式锁
  • RabbitMQ:消息队列
  • Redisson:Redis客户端,支持分布式锁

13. 服务管理模块详细设计

13.1 模块概述

服务管理模块负责配置和管理可办理的服务类型、价格、流程及材料。系统支持多级服务分类、灵活的价格规则配置、服务流程定义等。

13.2 类设计

13.2.1 服务实体类 (Service)

/**
 * 服务实体类
 */
public class Service {
    /**
     * 服务ID
     */
    private Long serviceId;
    
    /**
     * 服务编码(唯一)
     */
    private String serviceCode;
    
    /**
     * 服务名称
     */
    private String serviceName;
    
    /**
     * 服务分类ID
     */
    private Long categoryId;
    
    /**
     * 服务描述
     */
    private String description;
    
    /**
     * 基础价格
     */
    private BigDecimal basePrice;
    
    /**
     * 价格规则类型(FIXED-固定价格, BY_VEHICLE-按车型, BY_REGION-按地区, MIXED-混合规则)
     */
    private String priceRuleType;
    
    /**
     * 价格规则配置(JSON格式)
     */
    private String priceRuleConfig;
    
    /**
     * 服务状态(ENABLED-启用, DISABLED-停用)
     */
    private String status;
    
    /**
     * 办理时长(小时)
     */
    private Integer processingHours;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    
    // getter/setter方法
}

13.2.2 价格计算服务 (PriceCalculationService)

/**
 * 价格计算服务
 */
@Service
public class PriceCalculationService {
    
    /**
     * 计算订单价格
     * @param serviceId 服务ID
     * @param vehicleId 车辆ID
     * @param regionId 地区ID
     * @return 订单价格
     */
    public BigDecimal calculatePrice(Long serviceId, Long vehicleId, Long regionId) {
        // 1. 获取服务信息
        Service service = serviceService.getById(serviceId);
        if (service == null || !"ENABLED".equals(service.getStatus())) {
            throw new BusinessException("服务不存在或已停用");
        }
        
        // 2. 获取基础价格
        BigDecimal basePrice = service.getBasePrice();
        
        // 3. 根据价格规则类型计算价格
        String priceRuleType = service.getPriceRuleType();
        BigDecimal finalPrice = basePrice;
        
        switch (priceRuleType) {
            case "FIXED":
                // 固定价格
                finalPrice = basePrice;
                break;
                
            case "BY_VEHICLE":
                // 按车型计算
                finalPrice = calculateByVehicle(basePrice, vehicleId, service.getPriceRuleConfig());
                break;
                
            case "BY_REGION":
                // 按地区计算
                finalPrice = calculateByRegion(basePrice, regionId, service.getPriceRuleConfig());
                break;
                
            case "MIXED":
                // 混合规则
                finalPrice = calculateByMixed(basePrice, vehicleId, regionId, service.getPriceRuleConfig());
                break;
        }
        
        // 4. 应用优惠活动
        finalPrice = applyDiscounts(finalPrice, serviceId);
        
        return finalPrice;
    }
    
    /**
     * 按车型计算价格
     */
    private BigDecimal calculateByVehicle(BigDecimal basePrice, Long vehicleId, String config) {
        // 解析配置:{"brand": "大众", "multiplier": 1.2}
        // 根据车辆品牌、型号等计算价格
        Vehicle vehicle = vehicleService.getById(vehicleId);
        // 实现价格计算逻辑
        return basePrice;
    }
    
    /**
     * 按地区计算价格
     */
    private BigDecimal calculateByRegion(BigDecimal basePrice, Long regionId, String config) {
        // 解析配置:{"regionId": 1, "multiplier": 1.1}
        // 根据地区计算价格
        return basePrice;
    }
    
    /**
     * 混合规则计算价格
     */
    private BigDecimal calculateByMixed(BigDecimal basePrice, Long vehicleId, Long regionId, String config) {
        // 综合车型和地区计算价格
        return basePrice;
    }
    
    /**
     * 应用优惠活动
     */
    private BigDecimal applyDiscounts(BigDecimal price, Long serviceId) {
        // 查询该服务的优惠活动
        // 应用优惠折扣
        return price;
    }
}

13.3 业务流程设计

13.3.1 服务价格计算流程

流程说明:

  1. 获取服务基础价格
  2. 根据价格规则类型计算价格
  3. 应用优惠活动
  4. 返回最终价格

详细步骤:

1. 获取服务信息
   ├─ 根据服务ID查询服务
   ├─ 验证服务是否存在
   └─ 验证服务是否启用
   
2. 获取基础价格
   └─ 从服务信息中获取基础价格
   
3. 根据价格规则计算
   ├─ 固定价格:直接使用基础价格
   ├─ 按车型:根据车辆品牌、型号等计算
   ├─ 按地区:根据服务地区计算
   └─ 混合规则:综合车型和地区计算
   
4. 应用优惠活动
   ├─ 查询该服务的优惠活动
   ├─ 检查优惠活动是否有效
   ├─ 应用优惠折扣
   └─ 计算最终价格
   
5. 返回价格
   └─ 返回计算后的价格(保留2位小数)

13.4 数据库设计

13.4.1 服务分类表 (car_service_category)

CREATE TABLE `car_service_category` (
  `category_id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类ID',
  `category_code` varchar(20) NOT NULL COMMENT '分类编码(唯一)',
  `category_name` varchar(100) NOT NULL COMMENT '分类名称',
  `parent_id` bigint DEFAULT 0 COMMENT '父分类ID,0表示顶级分类',
  `level` int DEFAULT 1 COMMENT '分类层级',
  `sort_order` int DEFAULT 0 COMMENT '排序顺序',
  `icon` varchar(200) DEFAULT NULL COMMENT '图标URL',
  `description` varchar(500) DEFAULT NULL COMMENT '分类描述',
  `status` varchar(20) NOT NULL DEFAULT 'ENABLED' COMMENT '状态(ENABLED-启用, DISABLED-停用)',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`category_id`),
  UNIQUE KEY `uk_category_code` (`category_code`),
  KEY `idx_parent_id` (`parent_id`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='服务分类表';

13.4.2 服务表 (car_service)

CREATE TABLE `car_service` (
  `service_id` bigint NOT NULL AUTO_INCREMENT COMMENT '服务ID',
  `service_code` varchar(20) NOT NULL COMMENT '服务编码(唯一)',
  `service_name` varchar(100) NOT NULL COMMENT '服务名称',
  `category_id` bigint NOT NULL COMMENT '服务分类ID',
  `description` text COMMENT '服务描述',
  `base_price` decimal(10,2) NOT NULL COMMENT '基础价格',
  `price_rule_type` varchar(20) NOT NULL DEFAULT 'FIXED' COMMENT '价格规则类型',
  `price_rule_config` text COMMENT '价格规则配置(JSON)',
  `processing_hours` int DEFAULT NULL COMMENT '办理时长(小时)',
  `status` varchar(20) NOT NULL DEFAULT 'ENABLED' COMMENT '状态(ENABLED-启用, DISABLED-停用)',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`service_id`),
  UNIQUE KEY `uk_service_code` (`service_code`),
  KEY `idx_category_id` (`category_id`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='服务表';

14. 客户管理模块详细设计

14.1 模块概述

客户管理模块负责客户信息管理、客户车辆关联、客户订单查询等功能。

14.2 类设计

14.2.1 客户实体类 (Customer)

/**
 * 客户实体类
 */
public class Customer {
    /**
     * 客户ID
     */
    private Long customerId;
    
    /**
     * 客户姓名
     */
    private String customerName;
    
    /**
     * 手机号(唯一)
     */
    private String phone;
    
    /**
     * 邮箱
     */
    private String email;
    
    /**
     * 身份证号(加密存储)
     */
    private String idCard;
    
    /**
     * 地址
     */
    private String address;
    
    /**
     * 性别
     */
    private String gender;
    
    /**
     * 生日
     */
    private LocalDate birthday;
    
    /**
     * 客户状态(ACTIVE-正常, DISABLED-禁用, BLACKLIST-黑名单)
     */
    private String status;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    
    // getter/setter方法
}

14.3 业务流程设计

14.3.1 客户注册流程

流程说明:

  1. 客户输入手机号和验证码
  2. 系统验证验证码
  3. 创建客户账号
  4. 返回注册结果

详细步骤:

1. 接收注册请求
   ├─ 验证手机号格式
   ├─ 验证手机号是否已注册
   └─ 验证验证码
   
2. 创建客户账号
   ├─ 生成客户ID
   ├─ 保存客户基本信息
   ├─ 设置默认状态为"正常"
   └─ 记录注册日志
   
3. 返回注册结果
   └─ 返回客户ID、注册时间等

15. 车辆管理模块详细设计

15.1 模块概述

车辆管理模块负责车辆信息管理、车辆证件管理、车辆办理记录等功能。

15.2 类设计

15.2.1 车辆实体类 (Vehicle)

/**
 * 车辆实体类
 */
public class Vehicle {
    /**
     * 车辆ID
     */
    private Long vehicleId;
    
    /**
     * 客户ID
     */
    private Long customerId;
    
    /**
     * 车牌号(唯一)
     */
    private String plateNumber;
    
    /**
     * 品牌
     */
    private String brand;
    
    /**
     * 型号
     */
    private String model;
    
    /**
     * 颜色
     */
    private String color;
    
    /**
     * VIN码(唯一)
     */
    private String vinCode;
    
    /**
     * 发动机号
     */
    private String engineNumber;
    
    /**
     * 车架号
     */
    private String frameNumber;
    
    /**
     * 车辆状态(ACTIVE-正常, DELETED-已删除)
     */
    private String status;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    
    // getter/setter方法
}

15.2.2 OCR识别服务 (OcrService)

/**
 * OCR识别服务
 */
@Service
public class OcrService {
    
    /**
     * 识别身份证信息
     * @param imageUrl 图片URL
     * @return 身份证信息
     */
    public IdCardInfo recognizeIdCard(String imageUrl) {
        // 调用第三方OCR服务(阿里云/腾讯云)
        // 解析识别结果
        // 返回身份证信息
    }
    
    /**
     * 识别行驶证信息
     * @param imageUrl 图片URL
     * @return 行驶证信息
     */
    public DrivingLicenseInfo recognizeDrivingLicense(String imageUrl) {
        // 调用第三方OCR服务
        // 解析识别结果
        // 返回行驶证信息
    }
}

15.3 业务流程设计

15.3.1 车辆添加流程(带OCR识别)

流程说明:

  1. 客户上传行驶证照片
  2. 系统调用OCR服务识别行驶证信息
  3. 客户确认或修改识别结果
  4. 保存车辆信息

详细步骤:

1. 上传行驶证照片
   ├─ 验证图片格式(JPG、PNG)
   ├─ 验证图片大小(不超过5MB)
   ├─ 上传图片到OSS
   └─ 返回图片URL
   
2. OCR识别
   ├─ 调用OCR服务识别行驶证
   ├─ 解析识别结果
   │   ├─ 车牌号
   │   ├─ 品牌型号
   │   ├─ 车辆识别代号(VIN码)
   │   ├─ 发动机号
   │   └─ 注册日期
   └─ 返回识别结果
   
3. 客户确认信息
   ├─ 展示识别结果
   ├─ 客户确认或修改
   └─ 验证信息完整性
   
4. 保存车辆信息
   ├─ 验证车牌号是否已存在
   ├─ 验证VIN码是否已存在
   ├─ 保存车辆信息
   ├─ 关联客户信息
   └─ 返回车辆ID

16. 代驾管理模块详细设计

16.1 模块概述

代驾管理模块负责代驾人员管理、代驾业务管理、代驾评价管理等功能。

16.2 类设计

16.2.1 代驾人员实体类 (Driver)

/**
 * 代驾人员实体类
 */
public class Driver {
    /**
     * 代驾人员ID
     */
    private Long driverId;
    
    /**
     * 姓名
     */
    private String name;
    
    /**
     * 手机号(唯一)
     */
    private String phone;
    
    /**
     * 身份证号(加密存储)
     */
    private String idCard;
    
    /**
     * 驾驶证号
     */
    private String drivingLicenseNo;
    
    /**
     * 驾驶证有效期
     */
    private LocalDate drivingLicenseExpiry;
    
    /**
     * 车辆信息(JSON格式)
     */
    private String vehicleInfo;
    
    /**
     * 服务区域(JSON数组,存储地区ID)
     */
    private String serviceAreas;
    
    /**
     * 工作状态(ONLINE-在线, OFFLINE-离线, BUSY-忙碌, REST-休息, PENDING-审核中, DISABLED-已禁用)
     */
    private String workStatus;
    
    /**
     * 审核状态(PENDING-待审核, PASSED-已通过, REJECTED-已拒绝)
     */
    private String auditStatus;
    
    /**
     * 当前订单数
     */
    private Integer currentOrderCount;
    
    /**
     * 最大并发订单数
     */
    private Integer maxConcurrentOrders;
    
    /**
     * 平均评分
     */
    private BigDecimal averageRating;
    
    /**
     * 好评率
     */
    private BigDecimal goodRatingRate;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    
    // getter/setter方法
}

16.2.2 代驾人员状态管理服务 (DriverStatusService)

/**
 * 代驾人员状态管理服务
 */
@Service
public class DriverStatusService {
    
    /**
     * 更新代驾人员工作状态
     * @param driverId 代驾人员ID
     * @param newStatus 新状态
     */
    public void updateWorkStatus(Long driverId, String newStatus) {
        // 1. 验证状态流转是否合法
        Driver driver = driverService.getById(driverId);
        String currentStatus = driver.getWorkStatus();
        
        if (!canTransitionStatus(currentStatus, newStatus)) {
            throw new BusinessException("状态不能从 " + currentStatus + " 流转到 " + newStatus);
        }
        
        // 2. 更新状态
        driver.setWorkStatus(newStatus);
        driverService.updateById(driver);
        
        // 3. 更新Redis缓存
        String key = "driver:status:" + driverId;
        redisTemplate.opsForValue().set(key, newStatus, 30, TimeUnit.MINUTES);
        
        // 4. 如果状态为"在线",加入可用代驾人员列表
        if ("ONLINE".equals(newStatus)) {
            addToAvailableDrivers(driverId);
        } else {
            removeFromAvailableDrivers(driverId);
        }
    }
    
    /**
     * 根据订单状态自动更新代驾人员状态
     */
    public void autoUpdateStatusByOrder(Long driverId, String orderStatus) {
        if ("PROCESSING".equals(orderStatus) || "PENDING_ASSIGN".equals(orderStatus)) {
            // 订单处理中,代驾人员状态为"忙碌"
            updateWorkStatus(driverId, "BUSY");
        } else if ("COMPLETED".equals(orderStatus) || "CANCELLED".equals(orderStatus)) {
            // 订单完成或取消,检查是否还有其他订单
            int currentOrders = driverService.getCurrentOrderCount(driverId);
            if (currentOrders == 0) {
                updateWorkStatus(driverId, "ONLINE");
            }
        }
    }
}

16.3 业务流程设计

16.3.1 代驾人员注册与审核流程

流程说明:

  1. 代驾人员注册账号
  2. 上传资质材料(身份证、驾驶证、行驶证、保险等)
  3. 系统审核资质
  4. 审核通过后可以接单

详细步骤:

1. 代驾人员注册
   ├─ 手机号注册
   ├─ 设置密码
   ├─ 填写基本信息
   └─ 创建账号(状态:待审核)
   
2. 上传资质材料
   ├─ 上传身份证(OCR识别)
   ├─ 上传驾驶证(OCR识别)
   ├─ 上传行驶证(OCR识别)
   ├─ 上传车辆照片
   └─ 上传保险凭证
   
3. 系统审核
   ├─ 管理员审核资质材料
   ├─ 验证身份证、驾驶证、行驶证真实性
   ├─ 验证证件有效期
   └─ 审核结果
       ├─ 审核通过 → 状态改为"已通过",可以接单
       └─ 审核不通过 → 状态改为"已拒绝",通知代驾人员补充材料

17. 权限管理模块详细设计

17.1 模块概述

权限管理模块基于RBAC模型,实现用户、角色、权限的管理,支持菜单权限、按钮权限、数据权限。

17.2 类设计

17.2.1 权限验证服务 (PermissionService)

/**
 * 权限验证服务
 */
@Service
public class PermissionService {
    
    /**
     * 验证用户是否有权限访问资源
     * @param userId 用户ID
     * @param resource 资源标识(如:order:create)
     * @return 是否有权限
     */
    public boolean hasPermission(Long userId, String resource) {
        // 1. 获取用户角色
        List<Role> roles = userRoleService.getRolesByUserId(userId);
        
        // 2. 获取角色权限
        Set<String> permissions = new HashSet<>();
        for (Role role : roles) {
            List<Permission> rolePermissions = rolePermissionService.getPermissionsByRoleId(role.getRoleId());
            for (Permission permission : rolePermissions) {
                permissions.add(permission.getPermissionCode());
            }
        }
        
        // 3. 检查权限
        return permissions.contains(resource);
    }
    
    /**
     * 验证用户是否有权限访问菜单
     * @param userId 用户ID
     * @param menuId 菜单ID
     * @return 是否有权限
     */
    public boolean hasMenuPermission(Long userId, Long menuId) {
        // 实现菜单权限验证逻辑
        return true;
    }
    
    /**
     * 获取用户的数据权限范围
     * @param userId 用户ID
     * @return 数据权限范围(部门ID列表等)
     */
    public List<Long> getDataPermissionScope(Long userId) {
        // 实现数据权限范围获取逻辑
        return Collections.emptyList();
    }
}

17.3 权限拦截器设计

/**
 * 权限拦截器
 */
@Component
public class PermissionInterceptor implements HandlerInterceptor {
    
    @Autowired
    private PermissionService permissionService;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 1. 获取请求路径和方法
        String path = request.getRequestURI();
        String method = request.getMethod();
        
        // 2. 构建资源标识(如:order:create)
        String resource = buildResource(path, method);
        
        // 3. 获取当前用户ID
        Long userId = getCurrentUserId(request);
        
        // 4. 验证权限
        if (!permissionService.hasPermission(userId, resource)) {
            // 返回403错误
            response.setStatus(403);
            return false;
        }
        
        return true;
    }
}

18. 通知管理模块详细设计

18.1 模块概述

通知管理模块负责系统通知和公告的管理,支持多种通知方式和推送渠道。

18.2 类设计

18.2.1 通知服务 (NotificationService)

/**
 * 通知服务
 */
@Service
public class NotificationService {
    
    /**
     * 发送通知
     * @param notification 通知对象
     */
    public void sendNotification(Notification notification) {
        // 1. 确定推送对象
        List<Long> targetUserIds = determineTargetUsers(notification);
        
        // 2. 根据推送方式发送通知
        List<String> pushMethods = notification.getPushMethods();
        for (String method : pushMethods) {
            switch (method) {
                case "STATION_MESSAGE":
                    // 站内信
                    sendStationMessage(notification, targetUserIds);
                    break;
                case "SMS":
                    // 短信
                    sendSms(notification, targetUserIds);
                    break;
                case "EMAIL":
                    // 邮件
                    sendEmail(notification, targetUserIds);
                    break;
                case "APP_PUSH":
                    // APP推送
                    sendAppPush(notification, targetUserIds);
                    break;
            }
        }
    }
    
    /**
     * 发送订单状态变更通知
     */
    public void sendOrderStatusChangeNotification(Order order, String oldStatus, String newStatus) {
        // 1. 构建通知内容
        Notification notification = new Notification();
        notification.setType("ORDER_STATUS_CHANGE");
        notification.setTitle("订单状态变更");
        notification.setContent(buildOrderStatusChangeContent(order, oldStatus, newStatus));
        
        // 2. 确定推送对象(客户、代驾人员、接待员等)
        List<Long> targetUserIds = new ArrayList<>();
        targetUserIds.add(order.getCustomerId());
        if (order.getDriverId() != null) {
            targetUserIds.add(order.getDriverId());
        }
        if (order.getReceptionistId() != null) {
            targetUserIds.add(order.getReceptionistId());
        }
        
        // 3. 发送通知
        notification.setTargetUserIds(targetUserIds);
        sendNotification(notification);
    }
}

19. 短信管理模块详细设计

19.1 模块概述

短信管理模块负责短信模板管理、短信发送、第三方审核等功能。

19.2 类设计

19.2.1 短信模板实体类 (SmsTemplate)

/**
 * 短信模板实体类
 */
public class SmsTemplate {
    /**
     * 模板ID
     */
    private Long templateId;
    
    /**
     * 模板编码(唯一)
     */
    private String templateCode;
    
    /**
     * 模板名称
     */
    private String templateName;
    
    /**
     * 模板内容
     */
    private String templateContent;
    
    /**
     * 模板类型
     */
    private String templateType;
    
    /**
     * 使用场景
     */
    private String usageScenario;
    
    /**
     * 模板状态(DRAFT-草稿, PENDING-待审核, APPROVED-已审核, REJECTED-已驳回, ENABLED-已启用, DISABLED-已停用)
     */
    private String status;
    
    /**
     * 第三方审核状态(PENDING-待审核, APPROVING-审核中, APPROVED-已通过, REJECTED-已驳回)
     */
    private String thirdPartyStatus;
    
    /**
     * 第三方模板ID(审核通过后返回)
     */
    private String thirdPartyTemplateId;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    
    // getter/setter方法
}

19.2.2 短信发送服务 (SmsService)

/**
 * 短信发送服务
 */
@Service
public class SmsService {
    
    /**
     * 发送短信
     * @param templateCode 模板编码
     * @param phone 手机号
     * @param params 模板参数
     */
    public void sendSms(String templateCode, String phone, Map<String, String> params) {
        // 1. 获取短信模板
        SmsTemplate template = smsTemplateService.getByCode(templateCode);
        if (template == null || !"ENABLED".equals(template.getStatus())) {
            throw new BusinessException("短信模板不存在或未启用");
        }
        
        // 2. 替换模板变量
        String content = replaceTemplateVariables(template.getTemplateContent(), params);
        
        // 3. 调用第三方短信服务
        SmsResult result = callThirdPartySmsService(phone, content, template.getThirdPartyTemplateId());
        
        // 4. 记录发送日志
        SmsSendLog log = new SmsSendLog();
        log.setTemplateCode(templateCode);
        log.setPhone(phone);
        log.setContent(content);
        log.setStatus(result.isSuccess() ? "SUCCESS" : "FAILED");
        log.setErrorMessage(result.getErrorMessage());
        log.setCreateTime(LocalDateTime.now());
        smsSendLogMapper.insert(log);
        
        // 5. 如果发送失败,加入重试队列
        if (!result.isSuccess()) {
            addToRetryQueue(templateCode, phone, params);
        }
    }
    
    /**
     * 替换模板变量
     */
    private String replaceTemplateVariables(String template, Map<String, String> params) {
        String result = template;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            result = result.replace("{" + entry.getKey() + "}", entry.getValue());
        }
        return result;
    }
}

19.3 业务流程设计

19.3.1 短信模板审核流程

流程说明:

  1. 管理员创建短信模板
  2. 提交第三方审核
  3. 第三方审核通过后,模板可以启用
  4. 启用后可以用于发送短信

详细步骤:

1. 创建短信模板
   ├─ 填写模板信息(名称、编码、内容等)
   ├─ 设置模板变量(如:{客户姓名}、{订单号})
   ├─ 保存模板(状态:草稿)
   └─ 预览模板效果
   
2. 提交第三方审核
   ├─ 调用第三方短信服务审核接口
   ├─ 提交模板内容
   ├─ 更新模板状态为"审核中"
   └─ 等待第三方审核结果
   
3. 处理审核结果
   ├─ 第三方回调审核结果
   ├─ 审核通过
   │   ├─ 更新模板状态为"已审核"
   │   ├─ 保存第三方模板ID
   │   └─ 可以启用模板
   └─ 审核不通过
       ├─ 更新模板状态为"已驳回"
       ├─ 记录驳回原因
       └─ 允许修改后重新提交
       
4. 启用模板
   ├─ 管理员启用模板
   ├─ 更新模板状态为"已启用"
   └─ 可以用于发送短信

20. 数据一致性设计

20.1 事务管理

20.1.1 订单创建事务

/**
 * 订单创建事务
 */
@Transactional(rollbackFor = Exception.class)
public OrderVO createOrder(OrderCreateDTO dto) {
    // 1. 创建订单
    Order order = new Order();
    // ... 设置订单信息
    orderMapper.insert(order);
    
    // 2. 创建订单状态日志
    OrderStatusLog statusLog = new OrderStatusLog();
    statusLog.setOrderId(order.getOrderId());
    statusLog.setOldStatus(null);
    statusLog.setNewStatus("PENDING_PAYMENT");
    orderStatusLogMapper.insert(statusLog);
    
    // 3. 如果创建失败,事务回滚
    return convertToVO(order);
}

20.1.2 支付回调事务

/**
 * 支付回调事务
 */
@Transactional(rollbackFor = Exception.class)
public void handlePaymentCallback(String paymentType, Map<String, String> callbackData) {
    // 1. 验证回调签名
    if (!verifyCallbackSignature(paymentType, callbackData)) {
        throw new BusinessException("回调签名验证失败");
    }
    
    // 2. 查询支付记录
    String paymentNo = callbackData.get("paymentNo");
    PaymentRecord payment = paymentRecordMapper.selectByPaymentNo(paymentNo);
    
    // 3. 幂等性检查(防止重复处理)
    if ("PAID".equals(payment.getPaymentStatus())) {
        return; // 已处理,直接返回
    }
    
    // 4. 更新支付记录状态
    payment.setPaymentStatus("PAID");
    payment.setPaymentTime(LocalDateTime.now());
    paymentRecordMapper.updateById(payment);
    
    // 5. 更新订单状态
    Order order = orderMapper.selectById(payment.getOrderId());
    orderStateMachine.updateOrderStatus(order.getOrderId(), "PAID", null, "支付成功");
    
    // 6. 如果任何一步失败,事务回滚
}

20.2 分布式锁设计

20.2.1 订单创建分布式锁

/**
 * 订单创建(使用分布式锁防止重复创建)
 */
public OrderVO createOrderWithLock(OrderCreateDTO dto) {
    // 使用客户ID+服务ID+时间戳作为锁的key
    String lockKey = "order:create:lock:" + dto.getCustomerId() + ":" + dto.getServiceId();
    RLock lock = redissonClient.getLock(lockKey);
    
    try {
        // 尝试获取锁,最多等待5秒,锁定10秒
        if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
            // 再次检查是否已创建订单(防止重复提交)
            Order existingOrder = checkExistingOrder(dto);
            if (existingOrder != null) {
                return convertToVO(existingOrder);
            }
            
            // 创建订单
            return createOrder(dto);
        } else {
            throw new BusinessException("订单正在创建中,请稍后重试");
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new BusinessException("订单创建失败");
    } finally {
        if (lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
}

21. 监控与日志设计

21.1 日志设计

21.1.1 日志级别

  • DEBUG:调试信息,开发环境使用
  • INFO:一般信息,记录重要操作
  • WARN:警告信息,记录异常但不影响系统运行
  • ERROR:错误信息,记录系统错误

21.1.2 日志格式

[时间] [级别] [线程] [类名] [方法名] - [消息] [异常堆栈]

示例:

2024-01-15 09:00:00.123 [INFO] [http-nio-8080-exec-1] [OrderService] [createOrder] - 创建订单成功,订单号:ORD202401150001
2024-01-15 09:00:01.456 [ERROR] [http-nio-8080-exec-2] [PaymentService] [handlePaymentCallback] - 支付回调处理失败:签名验证失败

21.2 监控指标

21.2.1 业务监控指标

  • 订单创建量(按小时、按天统计)
  • 订单完成率
  • 支付成功率
  • 订单分配成功率
  • 渠道API调用量
  • 渠道API成功率

21.2.2 系统监控指标

  • 接口响应时间
  • 接口调用次数
  • 接口错误率
  • 数据库连接数
  • Redis连接数
  • 系统资源使用率(CPU、内存、磁盘)

22. 测试设计

22.1 单元测试设计

22.1.1 订单服务单元测试

/**
 * 订单服务单元测试
 */
@SpringBootTest
class OrderServiceTest {
    
    @Autowired
    private OrderService orderService;
    
    @Test
    void testCreateOrder() {
        // 1. 准备测试数据
        OrderCreateDTO dto = new OrderCreateDTO();
        dto.setServiceId(1L);
        dto.setVehicleId(1L);
        dto.setOrderType("DRIVER");
        // ...
        
        // 2. 执行测试
        OrderVO result = orderService.createOrder(dto);
        
        // 3. 验证结果
        assertNotNull(result);
        assertEquals("PENDING_PAYMENT", result.getStatus());
        // ...
    }
    
    @Test
    void testCreateOrderWithInvalidService() {
        // 测试服务类型不存在的情况
        OrderCreateDTO dto = new OrderCreateDTO();
        dto.setServiceId(999L); // 不存在的服务ID
        
        assertThrows(BusinessException.class, () -> {
            orderService.createOrder(dto);
        });
    }
}

22.2 集成测试设计

22.2.1 订单创建集成测试

测试场景:

  1. 正常创建订单流程
  2. 订单创建后自动触发支付流程
  3. 支付成功后自动触发订单分配流程

测试步骤:

1. 创建测试客户和车辆
2. 调用订单创建接口
3. 验证订单创建成功
4. 调用支付接口
5. 验证支付成功
6. 验证订单状态变为"已支付"
7. 验证订单分配流程触发

23. 部署设计

23.1 部署架构

23.1.1 应用部署

  • 应用服务器:多实例部署,使用Nginx负载均衡
  • 数据库:主从复制,读写分离
  • Redis:主从+哨兵模式
  • 消息队列:RabbitMQ集群

23.1.2 配置文件管理

  • 开发环境配置:application-dev.yml
  • 测试环境配置:application-test.yml
  • 生产环境配置:application-prod.yml

配置内容:

  • 数据库连接配置
  • Redis连接配置
  • 第三方服务配置(支付、短信、OCR等)
  • 日志配置
  • 安全配置

23.2 数据迁移设计

23.2.1 数据库迁移

  • 使用Flyway或Liquibase管理数据库版本
  • 每次发布包含数据库迁移脚本
  • 迁移脚本必须可重复执行(幂等性)

24. 附录

24.1 设计模式总结

设计模式应用场景说明
状态机模式订单状态流转管理订单状态的合法流转
策略模式支付方式、结算规则不同支付方式和结算规则的可替换实现
工厂模式支付服务创建根据支付类型创建对应的支付服务
观察者模式订单状态变更通知订单状态变更时通知相关角色
模板方法模式订单分配算法定义分配算法的骨架,具体实现由子类完成
责任链模式权限验证多个权限验证器组成责任链
单例模式配置管理系统配置单例管理

24.2 技术难点与解决方案

24.2.1 订单状态一致性

难点:多系统、多角色操作订单,保证状态一致性

解决方案:

  • 使用状态机模式,严格控制状态流转
  • 使用分布式锁,防止并发修改
  • 使用事务,保证数据库操作原子性

24.2.2 订单分配性能

难点:大量订单需要快速分配,分配算法复杂

解决方案:

  • 使用Redis缓存代驾人员状态和位置信息
  • 使用消息队列异步分配
  • 优化分配算法,减少计算时间

24.2.3 渠道API高并发

难点:多个渠道同时调用API,需要保证性能和安全性

解决方案:

  • 使用限流控制,防止恶意调用
  • 使用签名验证,保证接口安全
  • 使用异步处理,提升响应速度

备注: 本详细设计说明书基于需求文档和概要设计文档编写,详细描述了系统的功能模块设计、类设计、接口设计、数据库设计、业务流程设计等,为系统开发提供详细的技术指导。后续可根据实际情况进行调整和优化。

最近更新:: 2026/1/20 13:02
Contributors: Duke
Prev
概要设计文档
Next
数据库设计文档