华鲜生项目 — 现成系统源代码改动清单

基于 美国项目-BULK FOOD系统源代码(ThinkPHP 6 + uni-app + Vue.js)源码深度分析
分析日期:2026-08-14


系统现状总结

💡 TIP

经过对原始代码的全量扫描,发现系统已经内置了大量核心能力,实际需要的改动量远小于从零开发。以下是已有能力清单:

模块 已有能力 状态
支付系统 微信支付 V2/V3、支付宝、通联支付、Stripe ✅ 已有驱动
WMS 仓储 智能分仓 allocateOrder、出库单生成、温控分类、库存管理 ✅ 已有完整模块
司机配送端APP 独立 Driver 应用、接单/在途/签收状态机、GPS 上报、拍照签收 ✅ 已有独立应用
Google Maps 配送距离计算 calculateDistance、路线导航链接生成 ✅ 已集成
快递物流 轨迹查询、电子面单打印、快递员上门寄件 ✅ 已有驱动
订单系统 创建/拆单/发货/退款/核销/自动收货、4种发货模式 ✅ 完整闭环
客服系统 独立客服应用、实时聊天、客服话术、工单转接 ✅ 已有独立应用
📘 IMPORTANT

核心改动集中在两个方向:① PIX 支付驱动新增② 第三方同城配送平台 API 对接。微信海外支付仅需配置调整,无需新增代码。


一、PIX 支付对接(巴西本地支付)

优先级:🔴 P0 — 上线必备
PIX 是巴西央行推出的即时支付系统,覆盖率超 95%,是华鲜生在巴西运营的第一支付方式

1.1 技术选型建议

网关服务商 优势 推荐度
MercadoPago 巴西最大支付平台,PIX/信用卡/Boleto 全覆盖,SDK 成熟 ⭐⭐⭐⭐⭐
Ebanx 拉美跨境支付专家,支持中国企业主体 ⭐⭐⭐⭐
PagSeguro 巴西本土老牌,生态完善 ⭐⭐⭐
💡 TIP

推荐 MercadoPago,其提供完整的 PIX 即时支付 API(生成 BR Code + Copia e Cola),且有 Webhook 自动回调机制,与 CRMEB 的 Manager-Driver 模式完美兼容。


1.2 后端 — 新增 PIX 支付驱动(crmeb 核心层)

[NEW] crmeb/services/pay/storage/PixPay.php

PIX 支付驱动,实现 PayInterface 接口,与微信/支付宝/Stripe 驱动平级。

需实现的接口方法:
├── create()          → 调用 MercadoPago API 创建 PIX 收款请求
│                       返回:PIX QR Code (Base64 图片)、BR Code 字符串、
│                       Copia e Cola 文本、过期时间
├── handleNotify()    → 接收 MercadoPago Webhook(IPN)回调
│                       验证签名 → 解析支付状态 → 触发 NotifyListener 事件
├── refund()          → 调用 MercadoPago 退款 API(PIX 原路退回)
├── queryRefund()     → 查询退款状态
└── merchantPay()     → 商家 PIX 转账(用于佣金提现到供应商/配送员 PIX 账户)

关键实现细节:

  • PIX 收款请求有效期设为 30 分钟(生鲜订单时效性要求)
  • Webhook 签名验证使用 MercadoPago 提供的 x-signature header 与 HMAC-SHA256
  • 支付成功后,通过 Event::until('NotifyListener', [$data, 'pix']) 派发给业务层

[NEW] crmeb/services/pay/extend/mercadopago/MercadoPagoClient.php

MercadoPago API HTTP 客户端封装(类似已有的 allinpay/Client.php

封装方法:
├── createPixPayment($amount, $description, $externalRef, $expiration)
├── getPaymentStatus($paymentId)
├── refundPayment($paymentId, $amount)
├── validateWebhookSignature($headers, $body)
└── createPixTransfer($pixKey, $amount, $description)

[MODIFY] crmeb/services/pay/Pay.php

在支付管理器中注册 PIX 驱动

 protected function getSpace(): string
 {
     return '\\crmeb\\services\\pay\\storage\\';
 }

+ // 在驱动名映射中增加 PIX
+ // 确保 driver('pix') 能正确实例化 PixPay 类

改动量:约 3-5 行


[MODIFY] crmeb/services/pay/BasePay.php

在基类中添加 PIX 渠道的终端类型判断逻辑

+ case 'pix':
+     // PIX 不区分终端,统一返回 QR Code
+     break;

改动量:约 5-8 行


1.3 后端 — 业务层适配(app 层)

[MODIFY] app/services/pay/PayServices.php

在统一支付服务中添加 PIX 支付常量与分支

 const WEIXIN_PAY = 'weixin';
 const ALIAPY_PAY = 'alipay';
 const ALLIN_PAY  = 'allinpay';
 const STRIPE     = 'stripe';
+ const PIX_PAY    = 'pix';

 // 在 pay() 方法中增加 PIX 分支
+ case self::PIX_PAY:
+     $payInfo = app()->make(\crmeb\services\pay\Pay::class)
+         ->driver('pix')
+         ->create($orderId, $totalFee, $attach, $body, $detail);
+     // 返回 QR Code 和 Copia e Cola 给前端
+     break;

改动量:约 15-20 行


[MODIFY] app/services/pay/OrderPayServices.php

在订单支付前置处理中添加 PIX 渠道的参数装配

+ case PayServices::PIX_PAY:
+     $payInfo['pix_qr_code']    = $result['qr_code'];
+     $payInfo['pix_qr_code_base64'] = $result['qr_code_base64'];
+     $payInfo['pix_copia_cola'] = $result['copia_cola'];
+     $payInfo['pix_expiration'] = $result['expiration'];
+     break;

改动量:约 10-15 行


[MODIFY] app/services/pay/PayNotifyServices.php

在支付回调分发中增加 PIX 回调处理逻辑

+ case 'pix':
+     // 从 MercadoPago Webhook 数据中提取商户订单号
+     $orderSn = $data['external_reference'];
+     $this->paySuccess($orderSn);
+     break;

改动量:约 8-12 行


[NEW] app/api/controller/v1/pay/PixNotifyController.php

PIX 支付 Webhook 回调入口控制器

功能:
├── notify()    → 接收 MercadoPago IPN 通知
│                 验证签名 → 调用 PayNotifyServices 处理
└── 路由注册    → POST /api/pay/notify/pix

1.4 路由注册

[MODIFY] app/api/route/v1.php

新增 PIX 回调路由(无需授权中间件)

+ // PIX 支付异步回调(MercadoPago Webhook)
+ Route::post('pay/notify/pix', 'v1.pay.PixNotifyController/notify')
+     ->option(['real_name' => 'PIX支付异步回调']);

改动量:约 3 行


1.5 配置文件

[MODIFY] config/pay.php

在支付方式与驱动列表中注册 PIX

 'payType' => [
     'weixin' => '微信支付',
     'yue' => '余额支付',
     'offline' => '线下支付',
+    'pix' => 'PIX即时支付',
 ],

 'stores' => [
     'wechat_pay' => [],
     'ali_pay' => [],
     'yue' => [],
+    'pix' => [
+        'access_token' => '',    // MercadoPago Access Token
+        'public_key' => '',      // MercadoPago Public Key
+        'webhook_secret' => '',  // Webhook 签名密钥
+    ],
 ]

改动量:约 10 行


1.6 前端改动(用户端 H5 / 小程序)

⚠️ WARNING

前端代码当前为编译后的产物public/static/public/statics/mp_view/),修改需要获取 uni-app 原始源码工程后重新编译。如果没有源码,则需要在编译后的 JS 中定位并修改(难度较高但可行)。

[MODIFY] 收银台/支付选择页面

改动内容:
├── 增加「PIX 即时支付」选项按钮(带 PIX 图标)
├── 选择 PIX 后,调用统一下单接口传入 payType='pix'
├── 支付接口返回后,展示:
│   ├── PIX QR Code 二维码图片(供扫码支付)
│   ├── "Copiar Código" 一键复制按钮(复制 Copia e Cola 代码)
│   └── 倒计时器(30分钟过期提醒)
└── 前端轮询订单状态(每 3 秒一次),支付成功后跳转成功页

[MODIFY] 订单详情页 — 支付方式显示

增加 PIX 支付方式的图标与文字标识

1.7 管理后台改动

[MODIFY] 后台 — 系统设置 / 支付配置页面

改动内容:
├── 新增「PIX 支付配置」表单分组
│   ├── MercadoPago Access Token(输入框)
│   ├── MercadoPago Public Key(输入框)
│   ├── Webhook Secret(输入框)
│   └── Webhook URL 展示(只读,供商户复制到 MercadoPago 后台配置)
└── 新增「PIX 开关」(是否启用 PIX 支付)

二、微信支付海外版适配

优先级:🟡 P1 — 重要但非紧急
使用海外企业主体申请的微信支付商户号,接入方式与国内微信支付略有差异。

💡 TIP

系统已内置完整的微信支付 V3 驱动crmeb/services/pay/storage/V3WechatPay.php),且已支持服务商模式(ISV)参数(sp_appid, sp_mchid, sub_mchid)。海外微信支付的核心差异仅在于货币单位API 域名,无需新增驱动。

2.1 后端改动

[MODIFY] crmeb/services/pay/storage/V3WechatPay.php

 // 1. API 域名适配:海外商户需使用 hk.api.weixin.qq.com
+ private function getApiHost(): string
+ {
+     $isOverseas = sys_config('wechat_pay_overseas', 0);
+     return $isOverseas ? 'https://apihk.mch.weixin.qq.com' : 'https://api.mch.weixin.qq.com';
+ }

 // 2. 货币代码:海外商户使用 BRL(巴西雷亚尔)
+ // 在 create() 方法的请求体中:
+ 'amount' => [
+     'total' => intval(bcmul($totalFee, 100)),
-     'currency' => 'CNY',
+     'currency' => sys_config('wechat_pay_currency', 'CNY'),
+ ],

改动量:约 15-20 行


[MODIFY] crmeb/services/easywechat/v3pay/PayClient.php

调整 V3 支付请求的基础 URL 为可配置

- const BASE_URI = 'https://api.mch.weixin.qq.com';
+ protected $baseUri;
+
+ public function __construct($config)
+ {
+     $this->baseUri = $config['overseas'] ? 'https://apihk.mch.weixin.qq.com' : 'https://api.mch.weixin.qq.com';
+ }

改动量:约 5-8 行


2.2 配置改动

[MODIFY] 后台 — 微信支付配置页面

新增配置项:
├── 「是否海外商户」开关(wechat_pay_overseas: 0/1)
├── 「结算货币」下拉选择(wechat_pay_currency: CNY/BRL/USD/...)
└── 「API 域名模式」(自动根据海外开关切换,无需手动填写)
📝 NOTE

海外微信支付的小程序 AppID 和商户号与国内格式完全相同,现有后台的 AppID / MchID / APIv3 密钥 / 证书上传功能无需任何改动,直接填入海外商户信息即可。


三、第三方同城配送平台对接(Lalamove / Loggi / UBER)

优先级:🔴 P0 — 上线必备
实现后台一键询价、一键呼叫骑手、轨迹回传、自动变更订单状态。

3.1 技术架构设计

📘 IMPORTANT

采用与现有支付/物流相同的 Manager-Driver 模式,新增「同城配送」服务管理器,使 Lalamove 和 Loggi 可作为可插拔驱动热切换。

crmeb/services/citydelivery/              ← 新增目录
├── BaseCityDelivery.php                  ← 抽象基类
├── CityDelivery.php                      ← 驱动管理器 (extends BaseManager)
├── CityDeliveryInterface.php             ← 统一接口规范
└── storage/
    ├── Lalamove.php                       ← Lalamove 驱动实现
    └── Loggi.php                          ← Loggi 驱动实现(可后续扩展)

3.2 后端 — 新增同城配送服务( 核心层)

[NEW] crmeb/services/citydelivery/CityDeliveryInterface.php

统一接口规范,所有同城配送驱动必须实现

interface CityDeliveryInterface
{
    /**
     * 询价 — 获取运费报价
     * @param array $origin      发货地 ['lat' => '', 'lng' => '', 'address' => '']
     * @param array $destination 收货地 ['lat' => '', 'lng' => '', 'address' => '']
     * @param array $options     附加参数 ['weight' => 0, 'vehicle' => 'MOTORCYCLE']
     * @return array ['price' => 15.00, 'currency' => 'BRL', 'estimated_time' => '35min', 'vehicle_type' => 'MOTORCYCLE']
     */
    public function getQuotation(array $origin, array $destination, array $options = []): array;

    /**
     * 下单呼叫 — 创建配送订单
     * @param string $quotationId 询价返回的报价 ID
     * @param array  $sender      发件人信息
     * @param array  $recipient   收件人信息
     * @param array  $items       物品描述
     * @return array ['order_id' => '', 'tracking_url' => '', 'driver_info' => []]
     */
    public function createOrder(string $quotationId, array $sender, array $recipient, array $items = []): array;

    /**
     * 取消配送订单
     */
    public function cancelOrder(string $orderId): bool;

    /**
     * 获取配送订单详情(含骑手信息与实时位置)
     */
    public function getOrderDetail(string $orderId): array;

    /**
     * 获取支持的车辆类型列表
     */
    public function getVehicleTypes(): array;

    /**
     * 验证 Webhook 回调签名
     */
    public function validateWebhook(array $headers, string $body): array;
}

[NEW] crmeb/services/citydelivery/BaseCityDelivery.php

抽象基类,封装公共逻辑(继承 BaseStorage

封装内容:
├── initialize()     → 从 sys_config 读取 API Key / Secret
├── getOrigin()      → 获取仓库/发货点经纬度(从 WMS 仓库配置中读取)
├── formatAddress()  → 地址格式标准化(巴西地址格式:Rua/Av + Número + Bairro + CEP)
└── logDeliveryRequest() → 记录每次 API 调用的请求与响应日志

[NEW] crmeb/services/citydelivery/CityDelivery.php

驱动管理器(继承 BaseManager),支持 driver('lalamove') / driver('loggi') 动态切换

class CityDelivery extends BaseManager
{
    protected $namespace = '\\crmeb\\services\\citydelivery\\storage\\';

    protected function getSpace(): string
    {
        return $this->namespace;
    }

    // 默认驱动从后台配置读取
    protected function getDefaultDriver(): string
    {
        return sys_config('city_delivery_driver', 'lalamove');
    }
}

[NEW] crmeb/services/citydelivery/storage/Lalamove.php

Lalamove API 驱动实现(implements CityDeliveryInterface

核心实现:
├── getQuotation()
│   ├── POST https://rest.lalamove.com/v3/quotations
│   ├── Header: Authorization (HMAC-SHA256 签名)
│   ├── Body: { serviceType, language, stops[], item{} }
│   └── 返回: priceBreakdown, expiresAt, quotationId
│
├── createOrder()
│   ├── POST https://rest.lalamove.com/v3/orders
│   ├── Body: { quotationId, sender{}, recipients[], metadata{} }
│   │   metadata.externalOrderId = 华鲜生内部订单号(用于回调关联)
│   └── 返回: orderId, shareLink(客户追踪链接)
│
├── cancelOrder()
│   ├── DELETE https://rest.lalamove.com/v3/orders/{orderId}
│   └── 仅在骑手接单前可取消
│
├── getOrderDetail()
│   ├── GET https://rest.lalamove.com/v3/orders/{orderId}
│   └── 返回: status, driverInfo{name, phone, plateNumber}, shareLink
│
├── getVehicleTypes()
│   └── 巴西支持: MOTORCYCLE (摩托车), CAR (轿车), VAN (面包车), TRUCK (货车)
│
├── validateWebhook()
│   ├── 验证 X-Lalamove-Signature header
│   └── 解析状态: ASSIGNING_DRIVER → DRIVER_FOUND → PICKED_UP → COMPLETED
│
└── _generateSignature() (私有方法)
    ├── 构造签名字符串: {timestamp}\r\n{method}\r\n{path}\r\n\r\n{body}
    └── HMAC-SHA256 加密,格式: hmac {apiKey}:{timestamp}:{signature}
📝 NOTE

Lalamove 巴西 API 的 Base URL 为 https://rest.lalamove.com(正式环境),测试沙箱为 https://rest.sandbox.lalamove.com。市场代码使用 BR_SP(巴西圣保罗)。


[NEW] crmeb/services/citydelivery/storage/Loggi.php

Loggi 配送 API 驱动实现(后续扩展,初期可为空壳)

Loggi 使用 GraphQL API,接口风格与 Lalamove REST 不同:
├── getQuotation() → mutation { createOrder(input: ...) }
├── createOrder()  → 同上(Loggi 的询价和下单合并在一个 mutation 中)
├── cancelOrder()  → mutation { cancelOrder(pk: ...) }
└── getOrderDetail() → query { orderByPk(pk: ...) }

3.3 后端 — 业务层集成(app 层)

[NEW] app/services/wms/CityDeliveryServices.php

同城配送业务服务类 — 连接 WMS 出库单与第三方配送平台

核心方法:
├── getQuotation($wastageId)
│   ├── 从出库单(Wastage)中读取收货地址经纬度
│   ├── 从仓库配置中读取发货地址经纬度
│   ├── 根据出库单温控属性选择车辆类型:
│   │   ├── delivery_temp=0 (常温) + 重量<15kg → MOTORCYCLE
│   │   ├── delivery_temp=1 (冷藏) → VAN(需要保温箱空间)
│   │   └── 重量>30kg 或 B端大单 → TRUCK
│   └── 调用 CityDelivery::driver()->getQuotation()
│
├── createDeliveryOrder($wastageId, $quotationId)
│   ├── 调用 CityDelivery::driver()->createOrder()
│   ├── 将返回的第三方订单号、骑手追踪链接存入出库单
│   ├── 更新出库单状态:30 (待取货/已派单)
│   └── 更新商城订单状态为「已发货」+ 物流信息
│
├── handleWebhook($data)
│   ├── DRIVER_FOUND   → 更新骑手姓名、电话、车牌号到出库单
│   ├── PICKED_UP      → 出库单状态改为 40 (配送中)
│   ├── COMPLETED      → 出库单状态改为 60 (已签收)
│   │                    → 商城订单状态改为「已收货」
│   └── REJECTED/EXPIRED → 标记配送异常,通知客服重新派单
│
├── cancelDelivery($wastageId)
│   ├── 调用 CityDelivery::driver()->cancelOrder()
│   └── 出库单状态回退为 20 (待出库/已拣货)
│
└── getDeliveryTracking($wastageId)
    └── 返回第三方追踪链接 (shareLink) 给前端展示

[MODIFY] app/services/wms/WmsWastageServices.php

在现有出库/配送流转服务中集成第三方配送选项

 // 现有的 delivery() 方法(选择配送方式)中新增分支:
+ case 'city_delivery':
+     // 第三方同城配送
+     $cityDeliveryService = app()->make(CityDeliveryServices::class);
+     $result = $cityDeliveryService->createDeliveryOrder($wastageId, $data['quotation_id']);
+     break;

 // 现有状态机中新增「第三方配送」相关状态标识
+ // delivery_type 字段新增值:3 = 第三方同城配送(区别于 1=快递, 2=自建司机配送)

改动量:约 20-30 行


[MODIFY] app/services/order/StoreOrderDeliveryServices.php

在订单发货服务中打通第三方同城配送渠道

 // 现有发货模式:1=快递发货, 2=配送员送货, 3=虚拟发货, 4=WMS仓储派单
+ // 新增 type=5:第三方同城配送(Lalamove/Loggi)
+ case 5:
+     // 通过 CityDeliveryServices 呼叫第三方骑手
+     $deliveryInfo = $cityDeliveryService->createDeliveryOrder(...);
+     // 将追踪链接写入订单的物流信息
+     $this->update($orderId, [
+         'delivery_type' => 'city_delivery',
+         'delivery_id' => $deliveryInfo['order_id'],
+         'delivery_tracking_url' => $deliveryInfo['tracking_url'],
+     ]);
+     break;

改动量:约 25-35 行


3.4 路由注册

[MODIFY] app/adminapi/route/wms.php

在 WMS 路由组中新增同城配送相关接口

+ // 第三方同城配送
+ Route::get('delivery/quotation/:wastage_id', 'v1.wms.Wastage/getQuotation')
+     ->option(['real_name' => '获取第三方配送报价']);
+ Route::post('delivery/create', 'v1.wms.Wastage/createCityDelivery')
+     ->option(['real_name' => '呼叫第三方骑手']);
+ Route::post('delivery/cancel/:wastage_id', 'v1.wms.Wastage/cancelCityDelivery')
+     ->option(['real_name' => '取消第三方配送']);
+ Route::get('delivery/tracking/:wastage_id', 'v1.wms.Wastage/getDeliveryTracking')
+     ->option(['real_name' => '获取配送追踪']);
+ Route::get('delivery/vehicle_types', 'v1.wms.Wastage/getVehicleTypes')
+     ->option(['real_name' => '获取支持车辆类型']);

改动量:约 12 行


[MODIFY] app/api/route/v1.php

新增第三方配送 Webhook 回调路由(无需授权)

+ // 第三方同城配送回调
+ Route::post('delivery/notify/lalamove', 'v1.pay.CityDeliveryNotifyController/lalamoveNotify')
+     ->option(['real_name' => 'Lalamove配送状态回调']);
+ Route::post('delivery/notify/loggi', 'v1.pay.CityDeliveryNotifyController/loggiNotify')
+     ->option(['real_name' => 'Loggi配送状态回调']);

改动量:约 6 行


3.5 后台控制器

[MODIFY] app/adminapi/controller/v1/wms/Wastage.php

在现有出库控制器中新增同城配送操作方法

+ /**
+  * 获取第三方配送报价
+  */
+ public function getQuotation($wastage_id)
+ {
+     $data = $this->services->getCityDeliveryQuotation($wastage_id);
+     return app('json')->success($data);
+ }

+ /**
+  * 呼叫第三方骑手
+  */
+ public function createCityDelivery()
+ {
+     $data = $this->request->postMore([
+         ['wastage_id', 0],
+         ['quotation_id', ''],
+         ['vehicle_type', 'MOTORCYCLE'],
+     ]);
+     $result = $this->services->createCityDeliveryOrder($data);
+     return app('json')->success('已成功呼叫骑手', $result);
+ }

+ /**
+  * 取消第三方配送
+  */
+ public function cancelCityDelivery($wastage_id) { ... }

+ /**
+  * 获取配送追踪链接
+  */
+ public function getDeliveryTracking($wastage_id) { ... }

改动量:约 50-60 行


[NEW] app/api/controller/v1/pay/CityDeliveryNotifyController.php

第三方配送平台 Webhook 回调入口

方法:
├── lalamoveNotify()  → 接收 Lalamove 状态推送
│                       验签 → 调用 CityDeliveryServices::handleWebhook()
└── loggiNotify()     → 接收 Loggi 状态推送

3.6 数据库改动

[MODIFY] WMS 出库单表 (eb_wms_document 或对应出库单表)

新增字段以存储第三方配送信息

ALTER TABLE `eb_wms_document` ADD COLUMN `city_delivery_type` TINYINT(1) DEFAULT 0 COMMENT '同城配送类型: 0=无, 1=Lalamove, 2=Loggi' AFTER `delivery_temp`;
ALTER TABLE `eb_wms_document` ADD COLUMN `city_delivery_order_id` VARCHAR(100) DEFAULT '' COMMENT '第三方配送订单号' AFTER `city_delivery_type`;
ALTER TABLE `eb_wms_document` ADD COLUMN `city_delivery_tracking_url` VARCHAR(500) DEFAULT '' COMMENT '配送追踪链接' AFTER `city_delivery_order_id`;
ALTER TABLE `eb_wms_document` ADD COLUMN `city_delivery_driver_name` VARCHAR(50) DEFAULT '' COMMENT '骑手姓名' AFTER `city_delivery_tracking_url`;
ALTER TABLE `eb_wms_document` ADD COLUMN `city_delivery_driver_phone` VARCHAR(20) DEFAULT '' COMMENT '骑手电话' AFTER `city_delivery_driver_name`;
ALTER TABLE `eb_wms_document` ADD COLUMN `city_delivery_driver_plate` VARCHAR(20) DEFAULT '' COMMENT '骑手车牌号' AFTER `city_delivery_driver_phone`;
ALTER TABLE `eb_wms_document` ADD COLUMN `city_delivery_price` DECIMAL(8,2) DEFAULT 0.00 COMMENT '第三方配送费用(BRL)' AFTER `city_delivery_driver_plate`;
ALTER TABLE `eb_wms_document` ADD COLUMN `city_delivery_status` VARCHAR(30) DEFAULT '' COMMENT '第三方配送状态' AFTER `city_delivery_price`;

[MODIFY] 订单主表 (eb_store_order)

新增字段以存储客户可见的追踪链接

ALTER TABLE `eb_store_order` ADD COLUMN `delivery_tracking_url` VARCHAR(500) DEFAULT '' COMMENT '配送追踪链接(第三方)' AFTER `delivery_id`;

[MODIFY] WMS 出库单模型 app/model/wms/WmsDocument.php

新增字段的模型属性声明

+ // 新增字段填充
+ protected $append = ['city_delivery_type', 'city_delivery_order_id', 'city_delivery_tracking_url', ...];

改动量:约 10 行


[MODIFY] WMS 出库单 DAO app/dao/wms/WmsDocumentDao.php

搜索条件中增加按配送类型筛选

+ // 支持按 city_delivery_type 筛选出库单
+ if (isset($where['city_delivery_type']) && $where['city_delivery_type'] !== '') {
+     $query->where('city_delivery_type', $where['city_delivery_type']);
+ }

改动量:约 5-8 行


3.7 配置文件

[NEW] config/citydelivery.php

同城配送服务配置

return [
    // 默认驱动
    'default' => 'lalamove',

    // 驱动配置
    'stores' => [
        'lalamove' => [
            'api_key' => '',       // Lalamove API Key
            'api_secret' => '',    // Lalamove API Secret
            'market' => 'BR_SP',   // 巴西圣保罗市场代码
            'base_url' => 'https://rest.lalamove.com',  // 正式环境
            // 'base_url' => 'https://rest.sandbox.lalamove.com', // 测试环境
        ],
        'loggi' => [
            'api_key' => '',
            'company_id' => '',
            'base_url' => 'https://staging.loggi.com/graphql',
        ],
    ],

    // 仓库发货点配置(可从 WMS 仓库表动态读取)
    'warehouse_origin' => [
        'lat' => '',       // 仓库纬度
        'lng' => '',       // 仓库经度
        'address' => '',   // 仓库详细地址
        'contact_name' => '华鲜生仓库',
        'contact_phone' => '',
    ],
];

3.8 前端改动

[MODIFY] 管理后台 — 出库单/发货弹窗

改动内容:
├── 发货方式新增选项卡:「第三方同城配送」
├── 选择后展示:
│   ├── 车辆类型选择(摩托车 / 面包车 / 货车)
│   ├── 「获取报价」按钮 → 调用询价 API
│   ├── 报价展示卡片:
│   │   ├── 配送费:R$ 15.00
│   │   ├── 预计送达:35 分钟
│   │   └── 距离:8.2 km
│   └── 「确认呼叫骑手」按钮 → 调用下单 API
├── 派单成功后展示:
│   ├── 骑手姓名、电话、车牌号
│   ├── 实时追踪链接(可点击新窗口打开)
│   └── 「取消配送」按钮(骑手接单前可取消)
└── 出库单列表新增「配送类型」筛选列(自建 / Lalamove / Loggi)

[MODIFY] 管理后台 — 系统设置

新增「同城配送配置」页面:
├── 配送平台选择(Lalamove / Loggi)
├── API Key / Secret 输入框
├── 市场代码设置(默认 BR_SP)
├── Webhook URL 展示(供配置到 Lalamove 后台)
├── 仓库发货地址配置(地址 / 经纬度 / 联系人 / 电话)
└── 配送费承担策略(平台承担 / 用户支付 / 按比例分担)

[MODIFY] 用户端(H5 / 小程序)— 订单详情页

改动内容:
├── 物流信息区域新增「查看骑手位置」按钮
│   → 点击后在 WebView 中打开第三方追踪链接 (shareLink)
├── 显示骑手信息卡片:
│   ├── 骑手姓名
│   ├── 骑手电话(一键拨号)
│   └── 车牌号
└── 配送状态时间轴:
    ├── 🟢 商家已发货
    ├── 🟡 骑手已接单 (Pedro, 摩托车 ABC-1234)
    ├── 🔵 骑手已取货
    └── ✅ 已送达

四、本地化与基础适配改动

优先级:🟡 P1 — 上线前必须完成

4.1 时区与货币

[MODIFY] .env

 [APP]
- DEFAULT_TIMEZONE = Asia/Shanghai
+ DEFAULT_TIMEZONE = America/Sao_Paulo

[MODIFY] 系统配置 / 后台设置

├── 默认货币符号:R$(巴西雷亚尔)
├── 货币格式:巴西使用 1.234,56(点分隔千位,逗号分隔小数)
├── 默认语言:pt-BR(葡萄牙语-巴西)/ zh-CN(中文,后台保留中文)
└── 地址格式:CEP + Rua/Avenida + Número + Complemento + Bairro + Cidade + Estado

4.2 地址管理改动

[MODIFY] app/services/user/UserAddressServices.php

 // 现有中国省市区三级地址体系需要适配巴西行政区划
+ // 巴西地址结构:Estado(州) → Cidade(城市) → Bairro(街区) → Rua/Logradouro(街道)
+ // CEP(邮编,格式:XXXXX-XXX)
+ // CPF(个人纳税号,格式:XXX.XXX.XXX-XX,部分配送平台要求)

[MODIFY] app/services/shipping/SystemCityServices.php

 // 替换中国省市区数据为巴西 Estado/Cidade/Bairro 数据
+ // 或改用 Google Maps Geocoding API 实现地址自动补全

4.3 短信服务替换

📘 IMPORTANT

现有系统依赖中国短信服务商(一号通、阿里云、腾讯云、创蓝)。在巴西需要替换为本地 SMS 服务或使用 WhatsApp Business API 推送通知。

[NEW] crmeb/services/sms/storage/Twilio.php(或 WhatsApp)

使用 Twilio 发送巴西本地短信 / WhatsApp 消息:
├── sendSms($phone, $content)     → 发送葡语短信验证码
├── sendWhatsApp($phone, $content) → 通过 WhatsApp Business API 发送订单通知
└── 替代场景:注册验证码、支付成功通知、发货通知、配送到达通知

五、WMS 流程优化(最小改动)

优先级:🟢 P2 — 优化项
现有 WMS 模块已非常完善,仅需微调以适配华鲜生的实际操作流程。

5.1 预分装管理与条码打印

[MODIFY] app/adminapi/controller/v1/wms/Storage.php(入库控制器)

+ // 入库完成后,自动触发条码标签打印任务
+ // 调用已有的小票打印机服务(飞鹅云/易联云)打印 SKU 条码标签
+ public function printBarcodeLabel($storageId)
+ {
+     // 读取入库单中的商品列表
+     // 生成条码内容(商品编码 + 重量 + 入库日期)
+     // 通过 Printer 服务发送到标签打印机
+ }

5.2 拣货波次优化

[MODIFY] app/services/wms/WmsWastageServices.php

+ // 新增波次拣货方法:将多个待拣货出库单合并为一个拣货批次
+ public function createPickingWave(array $wastageIds)
+ {
+     // 按库位对商品进行聚合排序
+     // 生成最优拣货路线
+     // 返回拣货清单(按库位顺序)
+ }

六、完整改动文件汇总表

新增文件(10 个)

# 文件路径 用途 优先级
1 crmeb/services/pay/storage/PixPay.php PIX 支付驱动 P0
2 crmeb/services/pay/extend/mercadopago/MercadoPagoClient.php MercadoPago API 客户端 P0
3 app/api/controller/v1/pay/PixNotifyController.php PIX 回调控制器 P0
4 crmeb/services/citydelivery/CityDeliveryInterface.php 同城配送统一接口 P0
5 crmeb/services/citydelivery/BaseCityDelivery.php 同城配送基类 P0
6 crmeb/services/citydelivery/CityDelivery.php 同城配送管理器 P0
7 crmeb/services/citydelivery/storage/Lalamove.php Lalamove 驱动 P0
8 crmeb/services/citydelivery/storage/Loggi.php Loggi 驱动(预留) P2
9 app/services/wms/CityDeliveryServices.php 同城配送业务服务 P0
10 app/api/controller/v1/pay/CityDeliveryNotifyController.php 配送回调控制器 P0

修改文件(18 个)

# 文件路径 改动内容 改动量
1 crmeb/services/pay/Pay.php 注册 PIX 驱动 ~5 行
2 crmeb/services/pay/BasePay.php PIX 终端判断 ~8 行
3 app/services/pay/PayServices.php PIX 支付常量与分支 ~20 行
4 app/services/pay/OrderPayServices.php PIX 参数装配 ~15 行
5 app/services/pay/PayNotifyServices.php PIX 回调处理 ~12 行
6 crmeb/services/pay/storage/V3WechatPay.php 海外 API 域名+货币 ~20 行
7 crmeb/services/easywechat/v3pay/PayClient.php 可配置 Base URL ~8 行
8 config/pay.php PIX 配置注册 ~10 行
9 app/api/route/v1.php PIX + 配送回调路由 ~10 行
10 app/adminapi/route/wms.php 同城配送路由 ~12 行
11 app/services/wms/WmsWastageServices.php 集成第三方配送 + 波次拣货 ~50 行
12 app/services/order/StoreOrderDeliveryServices.php 新增发货模式 type=5 ~35 行
13 app/adminapi/controller/v1/wms/Wastage.php 同城配送控制器方法 ~60 行
14 app/model/wms/WmsDocument.php 新字段声明 ~10 行
15 app/dao/wms/WmsDocumentDao.php 新筛选条件 ~8 行
16 .env 时区改为巴西 ~1 行
17 app/services/user/UserAddressServices.php 巴西地址格式适配 ~30 行
18 app/services/shipping/SystemCityServices.php 巴西行政区划数据 ~20 行

新增配置文件(1 个)

# 文件路径 用途
1 config/citydelivery.php 同城配送平台配置

数据库变更(2 张表)

表名 变更 新增字段数
eb_wms_document 新增第三方配送信息字段 8 个字段
eb_store_order 新增配送追踪链接字段 1 个字段

前端改动(需 uni-app 源码)

终端 改动页面 内容
用户端 H5/小程序 收银台 新增 PIX 支付选项 + QR Code 展示
用户端 H5/小程序 订单详情 新增骑手追踪 + 配送状态时间轴
管理后台 出库单/发货弹窗 第三方配送询价+呼叫+追踪面板
管理后台 系统设置 PIX 配置 + 同城配送配置页
管理后台 订单列表 支付方式增加 PIX 图标显示

七、开发顺序与里程碑建议

gantt
    title 华鲜生代码开发里程碑
    dateFormat  YYYY-MM-DD
    axisFormat  %m/%d

    section 第一阶段 (核心支付)
    PIX 支付驱动开发           :a1, 2026-08-20, 5d
    PIX 前端收银台适配          :a2, after a1, 3d
    微信海外支付配置适配         :a3, after a1, 2d
    支付联调与测试              :a4, after a2, 3d

    section 第二阶段 (同城配送)
    Lalamove API 驱动开发       :b1, after a4, 5d
    WMS 出库-配送流程打通       :b2, after b1, 4d
    后台配送操作界面开发         :b3, after b2, 4d
    Webhook 回调与状态同步       :b4, after b3, 3d
    用户端追踪页面开发           :b5, after b4, 2d

    section 第三阶段 (本地化)
    时区/货币/地址本地化         :c1, after a4, 4d
    巴西短信/WhatsApp 通知      :c2, after c1, 3d

    section 第四阶段 (优化)
    波次拣货优化                :d1, after b5, 3d
    条码标签打印对接             :d2, after d1, 2d
    全流程联调测试              :d3, after d2, 5d
📘 IMPORTANT

总计代码改动估算:新增约 1,500-2,000 行 PHP 代码 + 前端页面适配。整体开发周期约 7-8 周(1名全职 PHP 开发 + 1名前端开发)。