Appearance
系统概述
承信租 V4 基于 基础版 4.0 二开,在保留完整商城功能的基础上,增加了租赁下单能力。核心涉及:
- 商品租赁属性设置(租金、租期、买断价、续租等)
- 租赁下单审核流程(实名→人脸→创建→审核→签约→发货)
- 租赁订单全生命周期管理(代扣、逾期、归还、买断、续租、完结)
核心架构
用户端(Uniapp) 后台(Admin)
│ │
▼ ▼
POST /api/order/confirm GET /adminapi/order/lease_list
POST /api/order/computed/:key POST /adminapi/order/lease_audit/:id
POST /api/order/create/:key POST /adminapi/order/generate_installment/:id
POST /api/order/pay POST /adminapi/order/withhold_pay/:id
│ POST /adminapi/order/buyout_order/:id
▼ POST /adminapi/order/return_goods/:id
Controller → Service → DAO POST /adminapi/order/complete_order/:id
│ POST /adminapi/order/relet_order
▼
MySQL + Redis下单前准备
1 商品配置要求
| 配置项 | 说明 | 影响 |
|---|---|---|
| 租赁属性 | is_lease=1 标记租赁商品 | 决定走租赁下单流程 |
| 租金/租期 | first_rent(首期租金)、lease_days(租期天数)、rent_num(期数) | 分期账单计算基础 |
| 买断价 | buyout_money(买断总价)、buyout_final_money(到期买断尾款) | 买断流程使用 |
| 续租开关 | is_relet | 是否允许续租 |
| 买断开关 | is_buyout | 是否允许买断 |
| 芝麻评估额 | zhima_assist_amount、zhima_assessment_amount | 芝麻免押额度 |
| 合同模板 | contract_type | 合同签署使用 |
| 运费模板 | 默认模板(id=1)必须配置 | 否则无法下单 |
2 用户前置条件
| 条件 | 必须/可选 | 说明 |
|---|---|---|
| 实名认证 | 必须 | eb_user 表中 real_name 和 card_id 不能为空 |
| 人脸识别 | 必须(下单前) | face_auth_status=2 才能创建订单 |
| 支付宝账号 | 视渠道 | 芝麻免押/租赁宝需要支付宝小程序环境 |
| 京东账号 | 视渠道 | 京东渠道需要京东小程序环境 |
下单完整流程(四步架构)
┌─────────────────────────────────────────────────────────────────┐
│ 下单四步架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ① 订单确认 (confirm) │
│ POST /api/order/confirm │
│ → 获取确认页数据 + Redis缓存 │
│ → 返回: orderKey, 商品列表, 地址, 配送方式等 │
│ │
│ ② 计算金额 (computedOrder) │
│ POST /api/order/computed/:key │
│ → 用户每次变更选项时调用(切换地址/优惠券/积分等) │
│ → 返回: 各项金额明细 │
│ │
│ ③ 创建订单 (create) │
│ POST /api/order/create/:key │
│ → 校验(实名/人脸/地址/库存/支付方式) │
│ → 写入DB(store_order + store_order_lease) │
│ → 锁定库存 + 删除缓存 │
│ │
│ ④ 支付 (pay) │
│ POST /api/order/pay │
│ → 支付宝/微信/余额/线下 │
│ │
└─────────────────────────────────────────────────────────────────┘1 步骤①:订单确认 (confirm)
入口: app/controller/api/v1/order/StoreOrder.php:246 → StoreOrderServices::getOrderConfirmData()
关键参数:
cartId— 购物车ID(租赁不使用购物车,直接传商品ID)addressId— 收货地址IDshipping_type— 配送方式storeId— 门店ID
处理逻辑:
- 校验默认运费模板(id=1)是否存在
- 获取购物车/商品信息 →
StoreCartServices::getUserProductCartListV1() - 处理商品有效性(库存、配送范围、规格)
- 缓存确认数据到 Redis:
user_order_{uid}{orderKey}(TTL=600秒) - 返回确认页所需数据
常见错误:
| 错误信息 | 原因 |
|---|---|
| "默认模板未配置,无法下单" | 运费模板缺失 |
| "请提交购买的商品" | cartId 为空 |
| "获取购物车信息失败" | 购物车无数据或已失效 |
2 步骤②:计算订单金额 (computedOrder)
入口: StoreOrder::computedOrder():283 → StoreOrderComputedServices::computedOrder():108
关键参数:
addressId/receiveAddress— 收货地址shipping_type— 配送方式lease_type— 1=租赁, 2=商城lease_start_time/lease_end_time— 自定义租期store_id— 门店IDis_store_delivery_type— 门店配送类型
金额计算链:
基础价格
├── 租赁(lease_type=1): first_rent + addServicePrice + cardAmount
└── 商城(lease_type=2): totalPrice
│
├── 邮费 computedPayPostage()
│ ├── shipping_type=1: 顺丰API计算
│ ├── shipping_type=2: 自提免运费
│ ├── shipping_type=3: 门店配送费
│ ├── shipping_type=4: 收银免运费
│ └── shipping_type=5: 同城闪送费(达达/顺丰同城)
│
├── 优惠券抵扣 couponPrice(租赁不使用)
├── 首单优惠 firstOrderPrice
├── 积分抵扣 useIntegral()
├── 长租折扣 discount_price
└── 至尊会员0元判断 is_super常见错误:
| 错误信息 | 原因 |
|---|---|
| "订单已过期,请刷新当前页面" | Redis缓存KEY过期(600秒) |
| "参数错误" | key 为空 |
| 金额不正确 | 计算逻辑变化或配置改动 |
3 步骤③:创建订单 (create)
入口: StoreOrder::create():436 → StoreOrderCreateServices::createOrder():133
关键参数:
addressId— 收货地址payType— 支付方式(alipay/weixin/yue/offline)shipping_type— 配送方式lease_type— 1=租赁, 2=商城check_type— 核验方式(1=芝麻免押, 2=租赁宝, 3=租赁行业交易)lease_start_time/lease_end_time— 租期is_super— 至尊会员标识
校验流程:
分布式锁 (api_order_create_{uid}_{key}, TTL=10秒)
│
├── 1. 检查订单重复 (order_id|unique=key)
├── 2. 获取Redis缓存数据
├── 3. 校验地址 (shipping_type=1/5 需要addressId)
├── 4. 校验砍价/拼团/支付方式
├── 5. 校验库存
└── 6. 租赁校验:
├── 实名认证 (real_name + card_id 不为空)
├── 人脸认证 (face_auth_status=2)
└── 至尊会员校验 (is_super=1时)创建事务:
事务开始
│
├── 1. computedOrder() 二次计价
├── 2. 组装 orderInfo
├── 3. dao->save() → 写入 eb_store_order
├── 4. 使用优惠券 (如有)
├── 5. 租赁: addOrderLease() → 写入 eb_store_order_lease
├── 6. 扣积分 deductIntegral()
├── 7. 扣库存 decGoodsStock()
├── 8. 保存商品快照 → eb_store_order_cart_info
└── 9. 预约处理 (product_type=6)
│
事务结束
│
├── 删除缓存 CacheService::delete("user_order_{uid}{key}")
└── 派发自动审核任务 (60秒后)eb_store_order_lease 关键字段填充:
| 字段 | 来源 | 说明 |
|---|---|---|
oid | order['id'] | 关联订单ID |
order_id | 生成 | 'zl'前缀的租赁订单号 |
audit_status | 固定=0 | 初始待审核 |
check_type | 参数传入 | 1/2/3 |
deposit | priceGroup | 押金金额 |
first_rent | priceGroup | 首期租金 |
buyout_money | priceGroup | 买断总价 |
buyout_final_money | priceGroup | 到期买断尾款 |
day_price | priceGroup | 日租金 |
lease_days | priceGroup | 租期天数 |
lease_num | priceGroup | 总期数 |
lease_plan | priceGroup | 租赁计划 |
is_buyout | 商品属性 | 是否可买断 |
is_relet | 商品属性 | 是否可续租 |
freeze_status | is_super=1时=1 | 至尊会员直接免押 |
risk_permit | check_type=3时=1 | 行业交易纯代扣 |
常见错误:
| 错误信息 | 原因 |
|---|---|
| "请求太过频繁,请稍后再试" | 分布式锁冲突 |
| "订单已创建,请点击查看完成支付" | 重复下单 |
| "租赁下单前需实名认证" | 未实名 |
| "库存不足" | 库存扣减失败 |
| "暂不支持该支付方式" | payType不在允许列表 |
4 步骤④:支付 (pay)
入口: StoreOrder::pay():738
支付方式:
| pay_type | 说明 | 服务 |
|---|---|---|
alipay | 支付宝 | PayServices::ALIAPY_PAY |
weixin | 微信 | PayServices::WEIXIN_PAY |
yue | 余额 | PayServices::YUE_PAY |
offline | 线下 | PayServices::OFFLINE_PAY |
特殊处理:
pay_price ≤ 0→ 触发0元支付zeroYuanPayment()- 租赁订单首期支付 →
leasePay()方法 - 押金支付 →
depositPay()方法 - 买断支付 →
buyoutPay()方法
租赁核验方式 (check_type)
┌─────────────────────────────────────────────────────────────────┐
│ 三种核验方式对比 │
├──────────┬──────────────┬──────────────┬────────────────────────┤
│ │ 芝麻免押(1) │ 租赁宝(2) │ 租赁行业交易(3) │
├──────────┼──────────────┼──────────────┼────────────────────────┤
│ 协议 │ 芝麻信用 │ 蚂蚁链 │ 支付宝租赁行业交易 │
│ 冻结机制 │ 预授权冻结 │ 代扣签约 │ 纯代扣 │
│ 合同 │ E签宝/爱签 │ 蚂蚁链智能合同│ E签宝/爱签 │
│ 代扣 │ 芝麻代扣 │ 租赁宝代扣 │ 行业交易代扣 │
│ API服务 │ CreditZhima │ AtoOpenApi │ CommerceRent │
│ 适用场景 │ 支付宝小程序 │ 支付宝小程序 │ 支付宝小程序(新) │
│ 状态 │ 逐渐废弃 │ 已完全废弃 │ 当前主推 │
└──────────┴──────────────┴──────────────┴────────────────────────┘1 芝麻免押 (check_type=1)
流程:
创建订单 → 唤起芝麻免押受理台 → 免押成功(freeze_status=1)
→ 立刻扣首期+运费+增值服务费
→ 审核通过 → 用户签署合同 → 发货关键字段: freeze_status (0=未冻结, 1=已冻结, 2=已完结, 3=已解约)
2 租赁宝 (check_type=2) — 已废弃
流程:
创建订单 → 跳转订单详情 → 等待审核
→ 审核通过 → 修改合同类型为租赁宝
→ 商品同步查询/商品同步/订单进件
→ 生成合同(后置签署) → 用户签署合同
→ 用户签署代扣协议 → 扣款3 租赁行业交易 (check_type=3) — 当前主推
流程:
创建订单 → 唤起芝麻免押(可选) → 审核通过
→ 合同签署 → 代扣支付
→ 到期自动代扣(每天7:00-22:00)特殊逻辑:
risk_permit=1(纯代扣模式)- 支持部分代扣
- 每期每天仅能扣成功一次
- 买断通过
CommerceRentServices::create()创建新订单
合同签署方式 (contract_sign)
| 方式 | 值 | 人脸时机 | 签署流程 |
|---|---|---|---|
| E签宝 | 1 | 下单后 | 创建合同文件 → 三方签署(用户→平台→企业) → 验签上传OSS |
| 爱签 | 2 | 下单前 | 本地模板上传 → 创建待签署文件 → 添加签署方 → 静默签署 |
1 E签宝流程 (contract_sign=1)
下单后 → 创建E签宝个人用户 → 人脸识别(依赖人脸)
→ 审核通过 → 生成合同(createFileFromTemplate)
→ 三方签署: 用户→平台→企业
→ 验签并上传OSS2 爱签流程 (contract_sign=2)
首次下单 → 实名认证(姓名+身份证号)
→ 二要素比对(获取serialNo)
→ 异步队列创建爱签个人用户(返回sealNo)
→ 人脸识别(活体认证+核身结果,缓存一天)
→ 创建订单(从缓存获取人脸数据)
→ 审核完成 → 静默签署(本地模板上传,订单号作为模板编号)
→ 签署完成(异步通知)配送方式 (shipping_type)
| 值 | 名称 | 说明 | 地址要求 |
|---|---|---|---|
| 1 | 平台/门店快递 | 顺丰API计算运费 | 需要完整地址 |
| 2 | 门店自提 | 免运费,生成核销码 | 需要姓名+电话 |
| 3 | 门店配送 | 门店自行配送 | 需要姓名+电话 |
| 4 | 门店收银 | 线下收银台 | 需要姓名+电话 |
| 5 | 同城闪送 | 达达/顺丰同城 | 需要完整地址 |
订单状态机
1 平台后台状态 Tab
┌─────────────────────────────────────────────────────────────────┐
│ 订单状态流转图 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 用户下单 │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ 待审核(0)│ ←── audit_status=0 │
│ └────┬─────┘ │
│ │ │
│ ├──审核通过──┐ │
│ │ ▼ │
│ │ ┌──────────┐ check_type=1/3 │
│ │ │待免押(100)│ ← freeze_status=0 │
│ │ └────┬─────┘ │
│ │ │免押成功 │
│ │ ▼ │
│ │ ┌──────────┐ contract_status=-1 │
│ │ │待签约(101)│ │
│ │ └────┬─────┘ │
│ │ │生成合同 │
│ │ ▼ │
│ │ ┌──────────┐ contract_status=0/1 │
│ │ │签约中(102)│ │
│ │ └────┬─────┘ │
│ │ │签署完成 │
│ │ ▼ │
│ │ ┌──────────┐ paid=0 │
│ │ │待支付(103)│ ← 首期代扣失败 │
│ │ └────┬─────┘ │
│ │ │支付成功 │
│ │ ▼ │
│ │ ┌──────────┐ status=1 │
│ │ │未发货(1) │ │
│ │ └────┬─────┘ │
│ │ │发货 │
│ │ ▼ │
│ │ ┌──────────┐ status=1/5 │
│ │ │待收货(2) │ │
│ │ └────┬─────┘ │
│ │ │收货/核销 │
│ │ ▼ │
│ │ ┌──────────┐ status=3 │
│ │ │租赁中(3) │ │
│ │ └────┬─────┘ │
│ │ │ │
│ │ ┌─────┼─────┬─────────┐ │
│ │ ▼ ▼ ▼ ▼ │
│ │ 今天(31) 明天(32) 逾期(34) 司法(35) │
│ │ │ │ │ │ │
│ │ └─────┴─────┴─────────┘ │
│ │ │ │
│ │ ┌─────┼─────┬─────────┐ │
│ │ ▼ ▼ ▼ ▼ │
│ │ 买断中(36) 待归还(37) 待接收(38) │
│ │ │ │ │ │
│ │ │ │ 确认归还 │
│ │ │ ▼ │ │
│ │ │ ┌────────┐ │ │
│ │ │ │交易完成│◄──┘ │
│ │ │ │ (4) │ │
│ │ │ └────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌────────┐ │
│ │ │已买断 │ │
│ │ │ (41) │ │
│ │ └────────┘ │
│ │ │
│ └──审核驳回──┐ │
│ ▼ │
│ ┌──────────┐ │
│ │已取消(-4) │ │
│ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘2 状态值速查表
| status | 后台显示 | 用户端显示 | 关键条件 |
|---|---|---|---|
| 0 | 待审核 | 待审核 | paid∈(0,1), status=0, audit_status∈(0,2) |
| 98 | 待绑定 | 待绑定 | 代客下单,待用户绑定 |
| 99 | 待认证 | 待认证 | 代客下单,待用户人脸 |
| 100 | 待免押 | 待免押 | check_type∈(1,3), freeze_status=0, audit_status=1 |
| 101 | 待签约 | 待签约 | paid=1, audit_status=1, 合同未签署 |
| 102 | 签约中 | 签约中 | contract_status∈(-1,0,1,4) |
| 103 | 待支付 | 待付款 | paid=0, status=0 (免押但未支付) |
| 1 | 未发货 | 待发货 | paid=1, status=1, audit_status=1 |
| 2 | 待收货 | 待收货 | paid=1, status∈(1,5) |
| 5 | 待核销 | — | shipping_type=2 (门店自提) |
| 6 | 已核销 | — | shipping_type=2, status=2 |
| 3 | 租赁中 | 租用中 | status=3 |
| 31 | 今天到期 | — | 到期时间=今天 |
| 32 | 明天到期 | — | 到期时间=明天 |
| 34 | 逾期中 | — | 已逾期未归还 |
| 35 | 司法中 | — | 进入司法程序 |
| 36 | 买断中 | 待买断 | 正在买断流程 |
| 37 | 待归还 | 待归还 | 租期到期,等待归还 |
| 38 | 待接收 | 待接收 | 归还发货,待门店接收 |
| 4 | 交易完成 | 交易完成 | 订单已完成 |
| 41 | 已买断 | — | 买断完成 |
| -4 | 已取消 | — | is_del=1 |
租赁订单生命周期
1 完整生命周期流程图
┌─────────────────────────────────────────────────────────────────┐
│ 租赁订单完整生命周期 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ ① 下单 │───▶│ ② 实名 │───▶│ ③ 人脸 │───▶│ ④ 创建 │ │
│ │ 确认页 │ │ 认证 │ │ 认证 │ │ 订单 │ │
│ └─────────┘ └─────────┘ └─────────┘ └────┬────┘ │
│ │ │
│ ┌──────────┴──────────┐│
│ │ ││
│ ▼ ▼│
│ ┌──────────┐ ┌──────────┐│
│ │⑤ 芝麻免押│ │⑤ 等待审核││
│ │(check=1/3)│ │(check=2) ││
│ └────┬─────┘ └────┬─────┘│
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐│
│ │⑥ 后台审核│◄─────────│⑥ 后台审核││
│ │ │ │ ││
│ └────┬─────┘ └────┬─────┘│
│ │ │ │
│ ┌─────────┴─────────┐ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │⑦ 生成分期│ │ 审核驳回 │ │
│ │ 账单 │ │ → 取消 │ │
│ └────┬─────┘ └──────────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │⑧ 合同签署│ │
│ │(e签宝/爱签)│ │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │⑨ 首期支付│ │
│ │(代扣/主动)│ │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │⑩ 发货 │ │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │⑪ 收货 │ │
│ │ 租赁开始 │ │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ ⑫ 租赁中 │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ 每月循环: 到期 → 自动代扣 → 成功/失败 │ │ │
│ │ │ 代扣时间: 7:00-22:00 (行业交易限制) │ │ │
│ │ │ 每期每天仅能扣成功一次 │ │ │
│ │ │ 失败 → 第二天标注逾期 │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ └────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │⑬ 归还 │ │⑬ 买断 │ │⑬ 续租 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 确认归还 │ │ 支付尾款 │ │ 新分期/ │ │
│ │ 回退库存 │ │ 订单完结 │ │ 新合同 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ▼ ▼ │ │
│ ┌──────────┐ ┌──────────┐ │ │
│ │⑭ 订单完结│ │⑭ 订单完结│ │ │
│ │ 解冻押金 │ │ 解冻押金 │ │ │
│ └──────────┘ └──────────┘ │ │
│ │ │
│ └──▶ 返回⑫ 租赁中 │
│ │
└─────────────────────────────────────────────────────────────────┘2 各环节详解
1 订单审核 (leaseAudit)
触发: 后台管理员操作 入口: POST /adminapi/order/lease_audit/:id
审核通过校验:
- 免押状态检查 (check_type=3 时 freeze_status=1)
- 人脸认证状态 (face_auth_status=2)
- 合同模板数据存在
- 分期账单已生成
- 预计发货时间 ≥ 当前时间
审核通过副作用:
- 触发合同静默签署 (爱签/e签宝)
- 超级会员订单标记为已支付
- 触发首期代扣检查 (
OrderWithholdJob::checkWithhold) - 发送订阅消息
审核驳回:
- 自动取消订单
- 恢复库存/优惠券
- 若已免押 → 解除芝麻冻结
2 分期账单生成 (generateInstallment)
触发: 后台管理员操作(或审核通过后自动生成) 入口: POST /adminapi/order/generate_installment/:id
计算逻辑:
每期租金 = (总租金 - 首期租金) / (期数 - 1)
差额加到首期
首期截止时间 = 当前时间 + 5分钟
后续期数 = 每月一期 或 自定义每期天数关键字段:
| 字段 | 说明 |
|---|---|
num | 第几期 |
amount | 应付金额 |
pay_amount | 实付金额 |
status | 0=未付, 1=部分付, 2=已付 |
dead_line | 截止时间 |
relet_times | 续租次数 |
3 合同生成与签署
生成合同: POST /adminapi/order/generate_contract/:id
| check_type | 合同方式 | 流程 |
|---|---|---|
| 1 (芝麻免押) | E签宝/爱签 | 创建合同文件 → 三方签署 |
| 2 (租赁宝) | 蚂蚁链 | 商品同步 → 订单进件 → 后置签署 |
| 3 (行业交易) | E签宝/爱签 | 同芝麻免押流程 |
开始签署: POST /adminapi/order/start_sign_contract/:id
- 获取用户签署信息
- e签宝: 获取签署链接 (
getSignUrl) - 更新合同状态:
contract_status: 0 → 1
合同状态:
| contract_status | 含义 |
|---|---|
| -1 | 未生成 |
| 0 | 待签署 |
| 1 | 签署中 |
| 2 | 已完成 |
| 3 | 已取消 |
| 4 | 已撤回 |
4 代扣支付 (withholdPay)
触发: 后台管理员操作 或 系统自动代扣 入口: POST /adminapi/order/withhold_pay/:id
代扣方式:
| check_type | 代扣服务 | 说明 |
|---|---|---|
| 1 | CreditZhimaServices::tradePay | 芝麻代扣 |
| 2 | AtoOpenApiServices::retryWithholdPlan | 租赁宝代扣 |
| 3 | CommerceRentServices::pay | 行业交易代扣 |
代扣规则:
- 首期不可代扣 (
withhold_plan=2时从第二期开始) - 行业交易限制: 7:00-22:00
- 每期每天仅能扣成功一次
- 仅 check_type=3 支持部分代扣
- 有减免时需一次性支付
自动代扣计划:
- 租赁宝: 每天三次
- 芝麻免押: 看计划任务
- 行业交易: 限制7:00-22:00
5 买断 (buyoutOrder)
触发: 用户主动买断 或 后台代扣买断 入口: POST /adminapi/order/buyout_order/:id
买断条件:
is_buyout=true- 订单未完结
- 免押码订单需完成所有分期
买断金额计算:
买断金额 = 剩余冻结金额 + 买断价差额状态转换:
lease_status: 1/2/3/5/6 → 8 (已买断)
order status: → 6 (完结)6 归还 (returnGoods + confirmReturn)
用户发起归还: POST /adminapi/order/return_goods/:id
归还条件:
lease_status=5(待归还)- 不存在未完成账期
- 订单未完结
归还方式:
| delivery_type | 方式 | 说明 |
|---|---|---|
| 1 | 快递 | 需填写快递单号 |
| 2 | 到店 | 线下归还 |
| 3 | 其他 | 其他方式 |
状态转换:
lease_status: 5 → 6 (待归还 → 待接收)确认归还: POST /adminapi/order/confirm_return/:id
确认条件:
lease_status=6(待接收)- 无未完成的赔付单
确认后处理:
- 回退库存
lease_status: 6 → 7(已归还)- 订单完结 (
status=6) - 行业交易: 调用
CommerceRentServices::receive - 解冻剩余预授权
7 完结订单 (completeOrder)
触发: 后台管理员操作 入口: POST /adminapi/order/complete_order/:id
完结条件:
- 订单状态非6 (未完结)
- 订单状态 ≥2 (已发货)
- 无未完成的赔付单
完结处理:
- 检查是否有买断支付记录
- 更新订单状态为6 (完结)
- 调用
endOrder:- 检查违约设置
lease_status → 4(已完成)- 解冻剩余预授权
- 行业交易: 同步未支付分期 + 调用
CommerceRentServices::finish - 租赁宝: 取消代扣计划 + 关闭订单 + 解约
- 发送
END_OF_LEASE事件
8 续租 (reletOrder)
触发: 后台管理员操作 入口: POST /adminapi/order/relet_order
续租条件:
is_relet=true- 订单已收货 (
status≥2) - 订单未完结 (
status≠6) lease_status为 1/2/5/6- 已完成所有分期 (
lease_num_paid ≥ lease_num) - 续租租金 ≤ 剩余预授权金额
check_type为 1 或 3
续租类型:
| 类型 | 条件 | 处理方式 |
|---|---|---|
| 短租续租 | 租期≤90天 | 在原订单追加租期 |
| 长租续租 | 租期>90天 | 生成新续租子订单 |
续租计算:
普通续租: 每日租金 × 续租天数
自定义租期: 斜率公式计算
续租期数: ≤30天=1期, >30天=round(天数/30)期续租流程:
- 创建续租分期数据
- 爱签: 静默签署续租合同
- e签宝: 开启人脸认证 → 返回认证链接
- 长租: 创建新订单 → 复制商品信息 → 计算新租金 → 生成新分期
押金系统
1 押金类型
| type | 名称 | 说明 |
|---|---|---|
| 1 | 普通押金 | 用户直接支付的押金 |
| 2 | 资金授权 | 支付宝 alifreeze 预授权冻结 |
| 3 | 逾期罚金/违约金 | 违约产生的罚款 |
2 押金生命周期
创建押金订单 (status=0)
│
├── 支付成功 (status=1)
│ └── 退款 (status=2部分退/3全退)
│
└── 取消 (status=-1)3 押金与分期的关系
- 押金(type=1)累计到
store_order_lease.deposit字段 - 违约金(type=3)通过
lease_id关联到具体分期 - 资金授权(type=2)通过
StoreAlifreezeOrderServices管理
4 押金退款
退款条件: less_money(剩余可退金额)> 0
退款流程:
- 校验退款金额 ≤
less_money - 生成退款请求号 (TK前缀)
- 调用支付宝
precreateTradeRefundAPI - 更新
less_money和status - 创建退款记录
- 触发资金流动记录
租赁形式
1 租完即送(逐渐废弃)
完成所有分期账单 → 订单自动完结2 租完归还
完成所有分期账单 → 进入[待归还]状态
├── 后台/小程序操作归还(物流信息) → 确认归还 → 完结
├── 买断 → 支付买断金额 → 完结
└── 续租 → 生成续租子订单 → 新免押/签约 → 支付成功第一期时完结原订单3 到期买断
完成所有分期账单 → 进入[待买断]状态
└── 买断 → 支付金额 → 订单完结货损赔付
保存货损: POST /adminapi/order/save_order_damage/:id
货损字段:
| 字段 | 说明 |
|---|---|
amount | 赔付金额 |
delivery_voucher | 发货凭证(图片/视频) |
take_voucher | 收货凭证 |
repair_cost_img | 维修费用凭证 |
货损与订单完结:
- 有未完成的赔付单时,无法操作归还确认和订单完结
- 行业交易: 货损会创建售后单并绑定后续支付
代客下单
1 流程
后台创建订单 (status=98, 待绑定)
│
▼
用户绑定订单 (status=99, 待认证)
│
▼
用户人脸识别 (face_auth_status=2)
│
▼
进入正常下单流程2 代客下单特殊操作
- 后台可修改: 商品规格、租赁相关价格、生成分期账单
- 用户需完成: 绑定订单、人脸识别
数据库核心表
1 表关系图
eb_store_order (订单主表)
├── eb_store_order_lease (租赁扩展) [1:1]
│ ├── audit_status: 审核状态
│ ├── freeze_status: 冻结/免押状态
│ ├── contract_status: 合同状态
│ ├── check_type: 核验方式
│ └── contract_detail: 合同详情(JSON)
│
├── eb_store_order_installment (分期账单) [1:N]
│ ├── num: 期数
│ ├── amount: 应付金额
│ ├── pay_amount: 实付金额
│ └── status: 支付状态
│
├── eb_store_order_deposit (押金订单) [1:N]
│ ├── type: 押金类型
│ ├── money: 金额
│ ├── less_money: 剩余可退
│ └── lease_id: 关联分期(违约金时)
│
├── eb_store_order_connect (客情沟通) [1:N]
├── eb_store_order_damage (货损赔付) [1:N]
├── eb_store_order_notarial (公证信息) [1:1]
├── eb_store_order_status (状态变更日志) [1:N]
└── eb_store_order_cart_info (商品快照) [1:N]2 核心表字段
eb_store_order (订单主表)
| 字段 | 类型 | 说明 |
|---|---|---|
id | int | 主键 |
order_id | varchar | 订单编号(md5) |
unique | varchar | 唯一键(=缓存orderKey) |
uid | int | 用户ID |
is_lease | tinyint | 1=租赁, 0=商城 |
status | tinyint | 订单状态 |
paid | tinyint | 0=未付, 1=已付 |
pid | int | 父订单ID(拆分订单用) |
pay_type | varchar | 支付方式 |
total_price | decimal | 总价 |
pay_price | decimal | 实付价 |
store_id | int | 门店ID |
supplier_id | int | 供应商ID |
shipping_type | tinyint | 配送方式 |
type | tinyint | 订单类型 |
product_type | tinyint | 商品类型 |
is_system_del | tinyint | 系统删除标记 |
eb_store_order_lease (租赁扩展)
| 字段 | 类型 | 说明 |
|---|---|---|
oid | int | 关联订单ID |
order_id | varchar | 租赁订单号(zl前缀) |
audit_status | tinyint | 0待审, 1通过, -1驳回 |
freeze_status | tinyint | 0未冻结, 1已冻结, 2已完结, 3已解约 |
contract_status | tinyint | -1未生成, 0待签, 1签中, 2完成, 3取消, 4撤回 |
check_type | tinyint | 1芝麻免押, 2租赁宝, 3行业交易 |
contract_sign | tinyint | 1=e签宝, 2=爱签 |
deposit | decimal | 押金金额 |
first_rent | decimal | 首期租金 |
buyout_money | decimal | 买断总价 |
buyout_final_money | decimal | 到期买断尾款 |
day_price | decimal | 日租金 |
lease_days | int | 租期天数 |
lease_num | int | 总期数 |
lease_num_paid | int | 已付期数 |
lease_plan | text | 租赁计划 |
is_buyout | tinyint | 是否可买断 |
is_relet | tinyint | 是否可续租 |
start_time | int | 租期开始时间 |
end_time | int | 租期结束时间 |
serial_number | varchar | 设备序列号 |
face_auth_status | tinyint | 人脸认证状态 |
risk_permit | tinyint | 风控许可 |
withhold_plan | tinyint | 代扣计划 |
contract_detail | text | 合同详情(JSON) |
mdm_status | text | MDM状态(JSON) |
eb_store_order_installment (分期账单)
| 字段 | 类型 | 说明 |
|---|---|---|
oid | int | 关联订单ID |
num | int | 第几期 |
amount | decimal | 应付金额 |
pay_amount | decimal | 实付金额 |
status | tinyint | 0未付, 1部分付, 2已付 |
dead_line | int | 截止时间戳 |
relet_times | int | 续租次数 |
常见问题排查指南
1 下单阶段问题
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 页面打不开/数据缺失 | 运费模板未配置 | 检查 eb_system_config 中 shipping 配置 |
| "租赁下单前需实名认证" | 用户未实名 | 查 eb_user 表 real_name/card_id |
| "请求太过频繁" | 分布式锁冲突 | 等待10秒或检查 LockService |
| "订单已创建" | 重复下单 | 查 eb_store_order 表 unique 字段 |
| "库存不足" | 库存扣减失败 | 检查 Redis 缓存库存 + DB 实际库存 |
| 金额不对 | 计算逻辑问题 | 检查 computedOrder 计算链 |
| 下单后没有生成分期 | 未触发生成 | 手动调用 generate_installment |
2 审核阶段问题
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 审核失败 | 状态不合法 | 检查 audit_status 是否为0 |
| 审核后没有自动代扣 | 首期代扣未触发 | 检查 OrderWithholdJob 队列 |
| 合同生成失败 | 序列号缺失 | 检查 serial_number 字段 |
| 签署失败 | 合同服务异常 | 检查 e签宝/爱签 配置 |
3 代扣阶段问题
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 代扣失败 | 余额不足/限额 | 查 payrecord 表结果 |
| 代扣时间不对 | 非工作时间 | 行业交易限制 7:00-22:00 |
| 部分代扣失败 | 非行业交易 | 仅 check_type=3 支持 |
| 逾期标注错误 | 代扣未触发 | 检查 OrderWithholdJob 队列 |
4 归还/买断/完结问题
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 归还失败 | 参数缺失 | 检查 delivery_type/delivery_id |
| 确认归还失败 | 有未完成赔付 | 检查 store_order_damage 表 |
| 买断失败 | 租期未到期 | 检查 lease_status |
| 完结失败 | 有未完成赔付 | 检查 store_order_damage 表 |
| 续租失败 | 已有未完成续租 | 检查续租分期状态 |
5 列表/统计问题
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 列表为空 | pid 过滤 | 检查 pid 条件: 带 store_id 时 pid=0 |
| Tab 数字不对 | COUNT 缓存 | Redis 缓存 30 秒过期 |
| 搜索不生效 | whereExists 条件 | 检查 DAO.search() L419 租赁分支 |
| 订单重复显示 | pid 条件处理 | 子订单与父订单同时展示 |
快速排查 SQL
sql
-- 查某用户最近的租赁订单
SELECT o.id, o.order_id, o.uid, o.status, o.paid, o.total_price,
l.audit_status, l.contract_status, l.check_type, l.freeze_status
FROM eb_store_order o
LEFT JOIN eb_store_order_lease l ON l.oid = o.id
WHERE o.is_lease = 1 AND o.uid = ? AND o.is_system_del = 0
ORDER BY o.id DESC LIMIT 10;
-- 查订单的分期账单
SELECT id, num, amount, pay_amount, status, dead_line, relet_times
FROM eb_store_order_installment WHERE oid = ? ORDER BY num;
-- 查订单的押金记录
SELECT id, type, money, less_money, status, lease_id
FROM eb_store_order_deposit WHERE oid = ?;
-- 查订单状态变更日志
SELECT * FROM eb_store_order_status WHERE oid = ? ORDER BY change_time DESC;
-- 查订单的客情沟通记录
SELECT * FROM eb_store_order_connect WHERE oid = ? AND is_del = 0 ORDER BY id DESC;
-- 查用户实名状态
SELECT uid, real_name, card_id, status FROM eb_user WHERE uid = ?;
-- 查某管理员分配了哪些订单
SELECT oid FROM eb_system_admin_order WHERE admin_id = ?;
-- 查货损赔付单
SELECT * FROM eb_store_order_damage WHERE oid = ?;关键代码文件索引
后端
| 层级 | 文件 | 核心方法 |
|---|---|---|
| 路由 | route/api.php:588-590 | confirm / computed/:key / create/:key |
| 路由 | route/admin.php:2002-2132 | 40+ 条 /adminapi/order/ 路由 |
| 控制器-API | app/controller/api/v1/order/StoreOrder.php | confirm():246, computedOrder():283, create():436, pay():738 |
| 控制器-Admin | app/controller/admin/v1/order/StoreOrder.php:44 | use Order, Notarial, Lease |
| Trait-Order | app/common/controller/Order.php | leaseList():1716, leaseChart():1649, leaseStatistics():1682 |
| Trait-Lease | app/common/controller/Lease.php | leaseAudit():31, cancelOrder():64, generateInstallment():196, withholdPay():493, buyoutOrder():735, returnGoods():782, completeOrder():758, reletOrder():1228 |
| 服务层 | app/services/order/StoreOrderServices.php | getOrderConfirmData():2011, cacheOrderInfo():2270 |
| 创建服务 | app/services/order/StoreOrderCreateServices.php | createOrder():133, decGoodsStock():652 |
| 计算服务 | app/services/order/StoreOrderComputedServices.php | computedOrder():108, getOrderPriceGroup():946 |
| 租赁服务 | app/services/order/StoreOrderLeaseServices.php | addOrderLease():65 |
| 分期服务 | app/services/order/StoreOrderInstallmentServices.php | createAverageData, createReletData |
| 押金服务 | app/services/order/StoreOrderDepositServices.php | createDepositOrder():50, refundDepositOrder():99 |
| 芝麻服务 | app/services/alipay/CreditZhimaServices.php | tradePay, buyoutPay, cancelFreezeOrder |
| 行业交易 | app/services/alipay/CommerceRentServices.php | create, pay, receive, finish |
| 租赁宝 | app/services/alipay/AtoOpenApiServices.php | synProduct, orderEntry, submitBehindSignFlow |
| E签宝 | app/services/user/EsignServices.php | fileUploadUrl, personSign, platformSign |
| 爱签 | app/services/user/AsignServices.php | addPersonalUser, authPersonFace, asignFlow |
| 合同服务 | app/services/other/SystemContractServices.php | asignFlow, asignReletFlow |
前端
| 层级 | 文件 | 说明 |
|---|---|---|
| API封装 | view/uniapp/api/order.js | orderConfirm():252, postOrderComputed():325, orderCreate():296 |
| 确认页 | view/uniapp/pages/goods/order_confirm/index.vue | getConfirm→computedPrice→SubOrder→payment |
| 后台API | view/admin/src/api/leaseOrder.js | 60+ 个接口函数 |
| 后台主页面 | view/admin/src/pages/order/leaseOrderList/orderlistDetails.vue | 编排器 |
| 后台表格 | view/admin/src/pages/order/leaseOrderList/components/tableList.vue | 核心表格, 2000+ 行 |
| 后台逻辑 | view/admin/src/pages/order/leaseOrderList/components/orderMix.js | 共享 mixin, 1300+ 行 |