Compare commits
3 Commits
council/Fr
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
5314d0caff | |
|
|
3340016969 | |
|
|
39230958a0 |
|
|
@ -1,7 +1,7 @@
|
||||||
<!-- gitnexus:start -->
|
<!-- gitnexus:start -->
|
||||||
# GitNexus — Code Intelligence
|
# GitNexus — Code Intelligence
|
||||||
|
|
||||||
This project is indexed by GitNexus as **vr-shopxo-plugin** (26423 symbols, 57331 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
|
This project is indexed by GitNexus as **vr-shopxo-plugin** (26564 symbols, 57490 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
|
||||||
|
|
||||||
> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.
|
> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<!-- gitnexus:start -->
|
<!-- gitnexus:start -->
|
||||||
# GitNexus — Code Intelligence
|
# GitNexus — Code Intelligence
|
||||||
|
|
||||||
This project is indexed by GitNexus as **vr-shopxo-plugin** (26423 symbols, 57331 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
|
This project is indexed by GitNexus as **vr-shopxo-plugin** (26564 symbols, 57490 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
|
||||||
|
|
||||||
> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.
|
> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,165 @@
|
||||||
|
# 核销自动确认收货 — 设计与验证
|
||||||
|
|
||||||
|
> 文档类型:功能归档 | 日期:2026-06-12 | 关联 ticket:TicketService 核销流程
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
核销流程中,需要将确认收货步骤自动化:核销成功后自动触发确认收货。此前该功能作为 TODO 存在于代码中,本轮完成实现并验证。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 原始需求
|
||||||
|
|
||||||
|
1. 核销后**自动确认收货**
|
||||||
|
2. 仅**待收货**状态(status=3)才触发确认收货
|
||||||
|
3. 如果已经是**确认收货**状态(status=4),幂等返回成功,不报错
|
||||||
|
4. 如果确认收货失败,**回滚核销操作**(整个操作在事务内)
|
||||||
|
5. **并发安全**:使用悲观锁防并发
|
||||||
|
6. 短码核销(`verifyByShortCode`)复用同一逻辑
|
||||||
|
7. 已确认收货但未核销的情况,核销流程正常走通(autoConfirmOrder 返回 code=0 兜底)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 技术方案
|
||||||
|
|
||||||
|
### 核心流程图
|
||||||
|
|
||||||
|
```
|
||||||
|
verifyTicket / verifyTicketById
|
||||||
|
│
|
||||||
|
├─ 悲观锁查票(SELECT ... lock(true))
|
||||||
|
├─ 核销票(标记 status=1)
|
||||||
|
├─ autoConfirmOrder()
|
||||||
|
│ ├─ 悲观锁查订单(SELECT ... lock(true))
|
||||||
|
│ ├─ status==4 → return code=0(幂等)
|
||||||
|
│ ├─ status!=3 → return code=0(跳过)
|
||||||
|
│ └─ status==3 → 调用订单API确认收货
|
||||||
|
├─ 如 autoConfirmOrder 失败 → throw \Exception → 事务回滚
|
||||||
|
└─ commit
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关键设计决策
|
||||||
|
|
||||||
|
| 决策 | 理由 |
|
||||||
|
|------|------|
|
||||||
|
| 不记录核销人与电话号码(`staffId`, `staffMobile`) | 设计文档未提及,避免过度实现 |
|
||||||
|
| `autoConfirmOrder` 不做 `null` 直接返回 | 缺乏需求约束,静默丢弃会产生不可追踪的数据不一致 |
|
||||||
|
| 使用 `if/elseif` 而非守卫语句 | 符合仓库现有风格 |
|
||||||
|
| 悲观锁 | 防止并发场景下同一订单被重复确认收货 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 改动清单
|
||||||
|
|
||||||
|
### [MODIFY] `shopxo/app/plugins/vr_ticket/service/TicketService.php`
|
||||||
|
|
||||||
|
| 位置 | 改动 |
|
||||||
|
|------|------|
|
||||||
|
| `verifyTicket`(L314附近) | 核销后调用 `autoConfirmOrder`,失败则抛异常回滚 |
|
||||||
|
| `verifyTicketById`(L474附近) | 同上,在事务末尾调用 `autoConfirmOrder` |
|
||||||
|
| `autoConfirmOrder`(L614-L657) | **新增方法**:悲观锁查单 → 状态判断 → 幂等/跳过/确认收货 |
|
||||||
|
|
||||||
|
#### `verifyTicket` 事务内调用
|
||||||
|
|
||||||
|
```php
|
||||||
|
// 在 verifyTicket 事务内,核销完成后
|
||||||
|
$auto_confirm_ret = $this->autoConfirmOrder($order_id);
|
||||||
|
if ($auto_confirm_ret['code'] != 0) {
|
||||||
|
throw new \Exception($auto_confirm_ret['msg']);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `autoConfirmOrder` 方法签名
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* 核销后自动确认收货
|
||||||
|
* - 使用悲观锁防并发
|
||||||
|
* - status==4:幂等返回成功
|
||||||
|
* - status!=3:跳过
|
||||||
|
* @return array ['code'=>0/1, 'msg'=>...]
|
||||||
|
*/
|
||||||
|
private function autoConfirmOrder($order_id): array
|
||||||
|
```
|
||||||
|
|
||||||
|
### GitNexus 变更报告
|
||||||
|
|
||||||
|
| 指标 | 值 |
|
||||||
|
|------|-----|
|
||||||
|
| 变更符号数 | 4(autoConfirmOrder 新增 + verifyTicket/verifyTicketById/verifyByShortCode 受影响) |
|
||||||
|
| 变更文件数 | 1(TicketService.php) |
|
||||||
|
| 受影响执行流程 | 0 |
|
||||||
|
| 风险级别 | **LOW** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 测试策略
|
||||||
|
|
||||||
|
### 单元测试(验证码核销 + 待收货订单)
|
||||||
|
|
||||||
|
**请求:**
|
||||||
|
```
|
||||||
|
POST /api.php?s=plugins/index&pluginsname=vr_ticket&pluginscontrol=verifier&pluginsaction=verify
|
||||||
|
code=<验证码> status=<状态>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 用例1:待收货订单核销(核心路径)
|
||||||
|
|
||||||
|
| 步骤 | 预期 |
|
||||||
|
|------|------|
|
||||||
|
| 1. 手机端下单票品 | 订单 status=3(待发货/待收货) |
|
||||||
|
| 2. 使用核销码核销 | 票 status=1,订单 status=4 |
|
||||||
|
| 3. 检查订单详情 | 确认收货时间已记录 |
|
||||||
|
|
||||||
|
#### 用例2:已确认收货订单核销(幂等)
|
||||||
|
|
||||||
|
| 步骤 | 预期 |
|
||||||
|
|------|------|
|
||||||
|
| 1. 使用已确认收货订单的核销码核销 | 票正常核销,不报错 |
|
||||||
|
|
||||||
|
#### 用例3:手动确认收货后再核销
|
||||||
|
|
||||||
|
| 步骤 | 预期 |
|
||||||
|
|------|------|
|
||||||
|
| 1. 手动确认收货(status 3→4) | 成功 |
|
||||||
|
| 2. 使用核销码核销 | 票正常核销,`autoConfirmOrder` 幂等返回 |
|
||||||
|
|
||||||
|
#### 用例4:并发核销
|
||||||
|
|
||||||
|
| 步骤 | 预期 |
|
||||||
|
|------|------|
|
||||||
|
| 1. 两个核销请求几乎同时到达 | 只有一个成功,另一个因悲观锁或票状态被拒绝 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验证结果
|
||||||
|
|
||||||
|
| # | 需求 | 实现位置 | 状态 |
|
||||||
|
|---|------|----------|------|
|
||||||
|
| 1 | 核销后自动确认收货 | `verifyTicket` L314 + `verifyTicketById` L474 调用 `autoConfirmOrder` | ✅ |
|
||||||
|
| 2 | 仅待收货才处理 | `autoConfirmOrder` L635: `if ($order['status'] != 3)` → 跳过 | ✅ |
|
||||||
|
| 3 | 已确认收货幂等 | `autoConfirmOrder` L629: `if ($order['status'] == 4)` → 返回 success | ✅ |
|
||||||
|
| 4 | 确认失败回滚核销 | `$confirm_ret['code'] != 0` → `throw \Exception`,事务回滚 | ✅ |
|
||||||
|
| 5 | 悲观锁防并发 | 订单查询 `->lock(true)` (L620),票查询 `->lock(true)` (L257, L417) | ✅ |
|
||||||
|
| 6 | 短码核销继承 | `verifyByShortCode` → 委托 `verifyTicketById` | ✅ |
|
||||||
|
| 7 | 已收货+未核销正常走 | `autoConfirmOrder` 返回 `code=0`,核销不受影响 | ✅ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 未实现项(明确排除)
|
||||||
|
|
||||||
|
| 项 | 原因 |
|
||||||
|
|----|------|
|
||||||
|
| 核销时记录核销人(staffId) | 需求文档未提及 |
|
||||||
|
| 核销时记录电话号码(staffMobile) | 需求文档未提及 |
|
||||||
|
| `autoConfirmOrder` 对 `$order == null` 的静默处理 | 没有需求约束,不做猜测性实现 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 未来增强建议
|
||||||
|
|
||||||
|
1. **核销记录表**:如需追溯核销人,可扩展 `vr_ticket_verification` 表增加 `staff_id`/`staff_mobile` 字段
|
||||||
|
2. **异步确认收货**:如确认收货 API 耗时较长,可考虑队列化处理以提高核销吞吐
|
||||||
|
3. **核销回调钩子**:在 `verifyTicket` 完成后增加后置钩子(如发送核销通知),使扩展点更清晰
|
||||||
|
|
@ -280,11 +280,15 @@ class Goods
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 缓存检查
|
// 缓存检查(注意:旧缓存不含 goods 字段,需要补充)
|
||||||
$cacheKey = 'vr_tree_v4_' . $goodsId . '_' . md5(implode(',', $groupBy));
|
$cacheKey = 'vr_tree_v4_' . $goodsId . '_' . md5(implode(',', $groupBy));
|
||||||
$cached = \think\facade\Cache::get($cacheKey);
|
$cached = \think\facade\Cache::get($cacheKey);
|
||||||
if ($cached !== null) {
|
if ($cached !== null) {
|
||||||
$cached['meta']['cache_hit'] = true;
|
$cached['meta']['cache_hit'] = true;
|
||||||
|
// 旧缓存不含 goods,补充构建
|
||||||
|
if (!isset($cached['goods'])) {
|
||||||
|
$cached['goods'] = self::buildGoodsField($goodsId);
|
||||||
|
}
|
||||||
return self::success($cached);
|
return self::success($cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,6 +301,7 @@ class Goods
|
||||||
'goods_id' => $goodsId,
|
'goods_id' => $goodsId,
|
||||||
'group_by' => $groupBy,
|
'group_by' => $groupBy,
|
||||||
'tree' => [],
|
'tree' => [],
|
||||||
|
'goods' => self::buildGoodsField($goodsId),
|
||||||
'seat_templates' => new \stdClass(),
|
'seat_templates' => new \stdClass(),
|
||||||
'meta' => [
|
'meta' => [
|
||||||
'seat_count' => 0,
|
'seat_count' => 0,
|
||||||
|
|
@ -320,6 +325,7 @@ class Goods
|
||||||
'goods_id' => $goodsId,
|
'goods_id' => $goodsId,
|
||||||
'group_by' => $groupBy,
|
'group_by' => $groupBy,
|
||||||
'tree' => $treeData['tree'],
|
'tree' => $treeData['tree'],
|
||||||
|
'goods' => self::buildGoodsField($goodsId),
|
||||||
'seat_templates' => $seatTemplates,
|
'seat_templates' => $seatTemplates,
|
||||||
'session_meta' => $sessionMeta,
|
'session_meta' => $sessionMeta,
|
||||||
'peer_goods' => QueryManager::getPeerGoods($goodsId),
|
'peer_goods' => QueryManager::getPeerGoods($goodsId),
|
||||||
|
|
@ -340,6 +346,47 @@ class Goods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建 goods 字段(包含手机详情 content_app)
|
||||||
|
*
|
||||||
|
* 复用 GoodsService::GoodsList,传入 is_content_app=1 以包含手机端详情数据。
|
||||||
|
* 这使得 uniapp 可以仅调用 tree API 一次就获取完整数据,无需二次请求 goods/detail。
|
||||||
|
*
|
||||||
|
* @param int $goodsId
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private static function buildGoodsField(int $goodsId): array
|
||||||
|
{
|
||||||
|
$isUseMobileDetail = intval(\MyC('common_app_is_use_mobile_detail', 0, true));
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'where' => [
|
||||||
|
['id', '=', $goodsId],
|
||||||
|
['is_delete_time', '=', 0],
|
||||||
|
],
|
||||||
|
'is_content_app' => $isUseMobileDetail,
|
||||||
|
'is_spec' => 1,
|
||||||
|
'is_params' => 1,
|
||||||
|
'is_favor' => 1,
|
||||||
|
'm' => 0,
|
||||||
|
'n' => 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
$ret = GoodsService::GoodsList($params);
|
||||||
|
$goods = $ret['data'][0] ?? null;
|
||||||
|
|
||||||
|
if (empty($goods)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手机端详情模式下移除 PC 富文本,减少响应体积
|
||||||
|
if ($isUseMobileDetail == 1) {
|
||||||
|
unset($goods['content_web']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $goods;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化商品列表数据
|
* 格式化商品列表数据
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class AdminGoodsIndex
|
||||||
|
|
||||||
// 触发chosen组件更新(如果已初始化)
|
// 触发chosen组件更新(如果已初始化)
|
||||||
if ($.fn.chosen && select.classList.contains('chosen-init-success')) {
|
if ($.fn.chosen && select.classList.contains('chosen-init-success')) {
|
||||||
select.trigger('chosen:updated');
|
$(select).trigger('chosen:updated');
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -364,11 +364,19 @@ class AdminGoodsSave
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 备份原始的 produce_region 选项 HTML
|
||||||
|
let originalRegionOptionsHtml = '';
|
||||||
|
|
||||||
// ── 动态替换 produce_region 下拉选项为 level=2 城市 ──
|
// ── 动态替换 produce_region 下拉选项为 level=2 城市 ──
|
||||||
const replaceCityOptions = () => {
|
const replaceCityOptions = () => {
|
||||||
const select = document.querySelector('select[name="produce_region"]');
|
const select = document.querySelector('select[name="produce_region"]');
|
||||||
if (!select) return;
|
if (!select) return;
|
||||||
|
|
||||||
|
// 备份原始选项 HTML(仅在第一次被替换前备份)
|
||||||
|
if (!originalRegionOptionsHtml) {
|
||||||
|
originalRegionOptionsHtml = select.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
// 优先使用 PHP 传递的保存值(城市 ID),这是最可靠的数据源
|
// 优先使用 PHP 传递的保存值(城市 ID),这是最可靠的数据源
|
||||||
const savedValue = AppData.savedProduceRegion || 0;
|
const savedValue = AppData.savedProduceRegion || 0;
|
||||||
|
|
||||||
|
|
@ -391,7 +399,18 @@ class AdminGoodsSave
|
||||||
|
|
||||||
// 触发chosen组件更新(如果使用了chosen插件)
|
// 触发chosen组件更新(如果使用了chosen插件)
|
||||||
if ($.fn.chosen) {
|
if ($.fn.chosen) {
|
||||||
select.trigger('chosen:updated');
|
$(select).trigger('chosen:updated');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const restoreCityOptions = () => {
|
||||||
|
const select = document.querySelector('select[name="produce_region"]');
|
||||||
|
if (!select || !originalRegionOptionsHtml) return;
|
||||||
|
|
||||||
|
select.innerHTML = originalRegionOptionsHtml;
|
||||||
|
|
||||||
|
if ($.fn.chosen) {
|
||||||
|
$(select).trigger('chosen:updated');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -400,6 +419,9 @@ class AdminGoodsSave
|
||||||
if (val) {
|
if (val) {
|
||||||
// 票务商品模式:替换城市下拉选项
|
// 票务商品模式:替换城市下拉选项
|
||||||
replaceCityOptions();
|
replaceCityOptions();
|
||||||
|
} else {
|
||||||
|
// 恢复原始选项
|
||||||
|
restoreCityOptions();
|
||||||
}
|
}
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ namespace app\plugins\vr_ticket\service;
|
||||||
|
|
||||||
require_once __DIR__ . '/BaseService.php';
|
require_once __DIR__ . '/BaseService.php';
|
||||||
|
|
||||||
|
use app\service\OrderService;
|
||||||
|
|
||||||
class TicketService extends BaseService
|
class TicketService extends BaseService
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -308,6 +310,17 @@ class TicketService extends BaseService
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// P1 核销成功后自动确认收货(失败则回滚整个核销事务)
|
||||||
|
$confirm_ret = self::autoConfirmOrder($ticket['order_id'], $verifier_id);
|
||||||
|
if ($confirm_ret['code'] != 0) {
|
||||||
|
BaseService::log('verifyTicket: auto_confirm_failed', [
|
||||||
|
'ticket_id' => $ticket['id'],
|
||||||
|
'order_id' => $ticket['order_id'],
|
||||||
|
'error' => $confirm_ret['msg'],
|
||||||
|
], 'error');
|
||||||
|
throw new \Exception('确认收货失败:' . $confirm_ret['msg']);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'code' => 0,
|
'code' => 0,
|
||||||
'msg' => '核销成功',
|
'msg' => '核销成功',
|
||||||
|
|
@ -457,6 +470,17 @@ class TicketService extends BaseService
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// P1 核销成功后自动确认收货(失败则回滚整个核销事务)
|
||||||
|
$confirm_ret = self::autoConfirmOrder($ticket['order_id'], $verifier_id);
|
||||||
|
if ($confirm_ret['code'] != 0) {
|
||||||
|
BaseService::log('verifyTicketById: auto_confirm_failed', [
|
||||||
|
'ticket_id' => $ticket_id,
|
||||||
|
'order_id' => $ticket['order_id'],
|
||||||
|
'error' => $confirm_ret['msg'],
|
||||||
|
], 'error');
|
||||||
|
throw new \Exception('确认收货失败:' . $confirm_ret['msg']);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'code' => 0,
|
'code' => 0,
|
||||||
'msg' => '核销成功',
|
'msg' => '核销成功',
|
||||||
|
|
@ -575,4 +599,60 @@ class TicketService extends BaseService
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 核销成功后自动确认收货
|
||||||
|
*
|
||||||
|
* 仅针对订单状态=3(待收货)的票务订单
|
||||||
|
* 幂等:已是 status=4 则直接返回
|
||||||
|
* 调用商城统一 OrderCollectHandle 完成积分赠送、销量增加、消息推送等
|
||||||
|
*
|
||||||
|
* @param int $order_id 订单ID
|
||||||
|
* @param int $verifier_id 核销员ID(作为 creator 记录)
|
||||||
|
* @return array [code, msg]
|
||||||
|
*/
|
||||||
|
private static function autoConfirmOrder($order_id, $verifier_id = 0)
|
||||||
|
{
|
||||||
|
// 完整查询订单(OrderCollectHandle 需要 id,status,pay_status,user_id,order_model)
|
||||||
|
$order = \think\facade\Db::name('Order')
|
||||||
|
->where('id', $order_id)
|
||||||
|
->field('id,status,pay_status,user_id,order_model')
|
||||||
|
->lock(true)
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if (empty($order)) {
|
||||||
|
BaseService::log('autoConfirmOrder: order_not_found', ['order_id' => $order_id], 'warning');
|
||||||
|
return ['code' => -1, 'msg' => '订单不存在'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 幂等保护:已经是已完成状态
|
||||||
|
if ($order['status'] == 4) {
|
||||||
|
BaseService::log('autoConfirmOrder: already_completed', ['order_id' => $order_id], 'info');
|
||||||
|
return ['code' => 0, 'msg' => '已完成'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅自动确认待收货状态(status=3)的订单
|
||||||
|
if ($order['status'] != 3) {
|
||||||
|
BaseService::log('autoConfirmOrder: wrong_status', [
|
||||||
|
'order_id' => $order_id,
|
||||||
|
'status' => $order['status'],
|
||||||
|
], 'warning');
|
||||||
|
return ['code' => -2, 'msg' => '订单状态非待收货'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用商城统一收货处理
|
||||||
|
$params = [
|
||||||
|
'creator' => $verifier_id,
|
||||||
|
'creator_name' => '票务核销自动确认',
|
||||||
|
];
|
||||||
|
$ret = OrderService::OrderCollectHandle($order, $params);
|
||||||
|
|
||||||
|
BaseService::log('autoConfirmOrder: done', [
|
||||||
|
'order_id' => $order_id,
|
||||||
|
'result' => $ret['code'] == 0 ? 'success' : 'failed',
|
||||||
|
'msg' => $ret['msg'] ?? '',
|
||||||
|
], $ret['code'] == 0 ? 'info' : 'warning');
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue