Commit b3385304 by 杨树贤

报错兼容以及多流程判断

parent 87a3d0f4
...@@ -213,8 +213,11 @@ class SupplierApiController extends Controller ...@@ -213,8 +213,11 @@ class SupplierApiController extends Controller
$this->response(0, '操作成功'); $this->response(0, '操作成功');
} }
$service = new SupplierService(); $service = new SupplierService();
$supplierId = $service->saveSupplier($channel); try {
//dd(123); $supplierId = $service->saveSupplier($channel);
} catch (\Exception $e) {
$this->response(-1, $e->getMessage());
}
if (!$supplierId) { if (!$supplierId) {
$this->response(-1, '操作失败'); $this->response(-1, '操作失败');
} }
...@@ -235,7 +238,11 @@ class SupplierApiController extends Controller ...@@ -235,7 +238,11 @@ class SupplierApiController extends Controller
$channelMap = array_merge($this->channelMap, config('field.AttachmentFields')); $channelMap = array_merge($this->channelMap, config('field.AttachmentFields'));
$channel = $request->only($channelMap); $channel = $request->only($channelMap);
$service = new SupplierService(); $service = new SupplierService();
$result = $service->saveSupplier($channel); try {
$result = $service->saveSupplier($channel);
} catch (\Exception $e) {
$this->response(-1, $e->getMessage());
}
if (!$result) { if (!$result) {
$this->response(-1, '修改失败'); $this->response(-1, '修改失败');
} }
......
...@@ -157,6 +157,12 @@ class SupplierAuditService ...@@ -157,6 +157,12 @@ class SupplierAuditService
*/ */
public function addApprove($supplierId, $triggerReason) public function addApprove($supplierId, $triggerReason)
{ {
$canIgnoreAudit = (new SupplierAuditService())->checkCanIgnoreSupplierAudit($supplierId);
if ($canIgnoreAudit) {
return true;
}
$supplierInfo = SupplierChannelModel::where('supplier_id', $supplierId)->first(); $supplierInfo = SupplierChannelModel::where('supplier_id', $supplierId)->first();
if (!$supplierInfo) { if (!$supplierInfo) {
throw new \Exception("供应商不存在"); throw new \Exception("供应商不存在");
......
...@@ -87,10 +87,10 @@ class SupplierService ...@@ -87,10 +87,10 @@ class SupplierService
$isDirectApply = request()->get('direct_apply'); $isDirectApply = request()->get('direct_apply');
//走事务 //走事务
$supplierId = DB::connection('web')->transaction(function () use ($channel, $model, $oldSupplier, &$needAudit) { $supplierId = DB::connection('web')->transaction(function () use ($channel, $model, $oldSupplier, &$needAudit, $isDirectApply) {
//是否直接申请审核,如果是直接申请审核,那就变成待审核 //是否直接申请审核,如果是直接申请审核,那就变成待审核
$isDirectApply = request()->get('direct_apply'); // $isDirectApply 已经从外部传入
$tagService = new SupplierTagService(); $tagService = new SupplierTagService();
//获取附加税数据 //获取附加税数据
...@@ -235,18 +235,13 @@ class SupplierService ...@@ -235,18 +235,13 @@ class SupplierService
$supplierAddressService = new SupplierAddressService(); $supplierAddressService = new SupplierAddressService();
$supplierAddressService->saveShippingAddress($supplierId, $shippingAddress); $supplierAddressService->saveShippingAddress($supplierId, $shippingAddress);
// 如果是直接申请审核,触发审核中心流程 // 如果是直接申请审核,触发审核中心流程(在事务内,失败会回滚)
if ($isDirectApply) { if ($isDirectApply) {
try { $auditService = new SupplierAuditService();
$auditService = new SupplierAuditService(); $triggerReason = $channel['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_TEMPORARY
$triggerReason = $channel['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_TEMPORARY ? request()->input('apply_audit_reason', '新增临时供应商并申请审核')
? request()->input('apply_audit_reason', '新增临时供应商并申请审核') : '新增供应商并申请审核';
: '新增供应商并申请审核'; $auditService->addApprove($supplierId, $triggerReason);
$auditService->addApprove($supplierId, $triggerReason);
} catch (\Exception $e) {
// 如果审核中心调用失败,记录日志但不影响主流程
\Illuminate\Support\Facades\Log::error('新增供应商触发审核中心失败: ' . $e->getMessage());
}
} }
} else { } else {
/**这里的是更新供应商的操作**/ /**这里的是更新供应商的操作**/
...@@ -320,6 +315,21 @@ class SupplierService ...@@ -320,6 +315,21 @@ class SupplierService
$channel['customer_tags'], $channel['customer_tags'],
$oldCustomerTags $oldCustomerTags
); );
// 如果更新后需要审核,并且是申请审核,触发审核中心流程(在事务内,失败会回滚)
if ($needAudit || $isDirectApply) {
$auditService = new SupplierAuditService();
$triggerReason = $channel['supplier_type'] == SupplierChannelModel::SUPPLIER_TYPE_TEMPORARY
? request()->input('apply_audit_reason', '修改供应商并申请审核')
: '修改供应商并申请审核';
$auditService->addApprove($supplierId, $triggerReason);
// 更新状态为审核中
$model->where('supplier_id', $supplierId)->update([
'status' => SupplierChannelModel::STATUS_IN_REVIEW,
'apply_audit_reason' => $triggerReason,
'update_time' => time()
]);
}
} }
//新增供应商的话,还要去初始化有效期 //新增供应商的话,还要去初始化有效期
...@@ -419,9 +429,11 @@ class SupplierService ...@@ -419,9 +429,11 @@ class SupplierService
//这里有个申请审核的判断逻辑 //这里有个申请审核的判断逻辑
//如果是申请审核,并且原来的状态不是已通过,无论什么情况,都要变成审核中,如果是已通过,那么就要走下面的判断是否要忽略审核流程 //如果是申请审核,并且原来的状态不是已通过,无论什么情况,都要变成审核中,如果是已通过,那么就要走下面的判断是否要忽略审核流程
//注意: 如果是更新供应商并且 $isDirectApply = true, 已经在事务内处理了审核中心调用,这里不需要再处理
if ($isAudit && array_get($oldSupplier, 'status') == SupplierChannelModel::STATUS_PASSED && !$needAudit && !empty($channel['supplier_id'])) { if ($isAudit && array_get($oldSupplier, 'status') == SupplierChannelModel::STATUS_PASSED && !$needAudit && !empty($channel['supplier_id'])) {
//什么都不需要操作 //什么都不需要操作
} else if ($isAudit && $newSupplier['is_entity'] != 0) { } else if ($isAudit && $newSupplier['is_entity'] != 0 && !($isDirectApply && !empty($channel['supplier_id']))) {
// 排除更新供应商并直接申请审核的情况(已在事务内处理)
$auditData[] = [ $auditData[] = [
'supplier_id' => $supplierId, 'supplier_id' => $supplierId,
//供应商类型为临时供应商,才会去存申请理由 //供应商类型为临时供应商,才会去存申请理由
...@@ -782,28 +794,27 @@ class SupplierService ...@@ -782,28 +794,27 @@ class SupplierService
//批量申请审核供应商 //批量申请审核供应商
public function batchApplyInReviewSupplier($auditData = []) public function batchApplyInReviewSupplier($auditData = [])
{ {
$model = new SupplierChannelModel(); return DB::connection('web')->transaction(function () use ($auditData) {
foreach ($auditData as $data) { $model = new SupplierChannelModel();
$result = $model->where('supplier_id', $data['supplier_id'])->update([ $auditService = new SupplierAuditService();
'update_time' => time(),
'apply_audit_reason' => $data['apply_audit_reason'],
'status' => SupplierChannelModel::STATUS_IN_REVIEW
]);
if (!$result) {
return $result;
}
// 触发审核中心流程 foreach ($auditData as $data) {
try { $result = $model->where('supplier_id', $data['supplier_id'])->update([
$auditService = new SupplierAuditService(); 'update_time' => time(),
'apply_audit_reason' => $data['apply_audit_reason'],
'status' => SupplierChannelModel::STATUS_IN_REVIEW
]);
if (!$result) {
throw new \Exception('更新供应商状态失败');
}
// 触发审核中心流程(在事务内,失败会回滚)
$triggerReason = array_get($data, 'apply_audit_reason', '申请审核'); $triggerReason = array_get($data, 'apply_audit_reason', '申请审核');
$auditService->addApprove($data['supplier_id'], $triggerReason); $auditService->addApprove($data['supplier_id'], $triggerReason);
} catch (\Exception $e) {
// 如果审核中心调用失败,记录日志但不影响主流程
\Illuminate\Support\Facades\Log::error('添加审核中心审批失败: ' . $e->getMessage());
} }
}
return true; return true;
});
} }
//判断是否自动转正,并且还要修改为待提审状态给相关人员进行补充资料 //判断是否自动转正,并且还要修改为待提审状态给相关人员进行补充资料
......
...@@ -54,14 +54,31 @@ ...@@ -54,14 +54,31 @@
修改了两个方法: 修改了两个方法:
#### `saveSupplier()` 方法: #### `saveSupplier()` 方法:
**新增供应商并直接申请审核**(第238-244行)
- 在新增供应商并直接申请审核时(`$isDirectApply = true` - 在新增供应商并直接申请审核时(`$isDirectApply = true`
- 保存供应商后立即调用 `SupplierAuditService::addApprove()` 创建审核中心单据 - **在事务内**调用 `SupplierAuditService::addApprove()` 创建审核中心单据
- 使用 try-catch 包裹,失败不影响主流程 - **如果审核中心调用失败,会抛出异常并回滚整个事务**
- 保证数据一致性:要么供应商和审核单据都创建成功,要么都失败
**更新供应商并直接申请审核**(第319-331行)
- 在更新供应商并直接申请审核时(`$isDirectApply = true``$needAudit = true`
- **在事务内**先更新供应商信息,然后调用 `SupplierAuditService::addApprove()` 创建审核中心单据
- **在事务内**更新供应商状态为 `STATUS_IN_REVIEW`
- **如果审核中心调用失败,会抛出异常并回滚整个事务**
- 保证数据一致性:要么供应商修改、状态更新、审核单据都成功,要么都回滚
**避免重复创建审核单据**(第435行)
- 事务外的 `$isAudit` 逻辑排除了更新供应商并直接申请审核的情况
- 条件:`!($isDirectApply && !empty($channel['supplier_id']))`
- 确保不会重复调用审核中心
#### `batchApplyInReviewSupplier()` 方法: #### `batchApplyInReviewSupplier()` 方法:
- **使用 `DB::transaction()` 包裹整个操作**
- 在更新供应商状态为审核中后 - 在更新供应商状态为审核中后
- 调用 `SupplierAuditService::addApprove()` 创建审核中心单据 - **在事务内**调用 `SupplierAuditService::addApprove()` 创建审核中心单据
- 使用 try-catch 包裹,失败不影响主流程 - **如果审核中心调用失败,会抛出异常并回滚整个事务**
- 保证数据一致性:要么状态更新和审核单据都成功,要么都失败
## 核心流程 ## 核心流程
...@@ -158,11 +175,64 @@ AuditCenterService::TYPE_SUPPLIER_AUDIT = 'supplier_audit'; ...@@ -158,11 +175,64 @@ AuditCenterService::TYPE_SUPPLIER_AUDIT = 'supplier_audit';
AuditCenterService::SYSTEM_ID = 1; AuditCenterService::SYSTEM_ID = 1;
``` ```
## 数据一致性保证
### 事务处理机制
#### 1. **新增供应商直接申请审核**
```
开始事务 (saveSupplier 第90行)
保存供应商基本信息
保存联系人、附件、银行信息
保存地址信息
调用审核中心创建单据 (第238-244行)
成功 → 提交事务 ✅
失败 → 抛出异常 → 回滚事务 → 所有供应商数据不保存 ✅
```
#### 2. **更新供应商并直接申请审核**
```
开始事务 (saveSupplier 第90行)
更新供应商基本信息
更新地址、附加费、标签等
调用审核中心创建单据 (第319-331行)
更新状态为 STATUS_IN_REVIEW
成功 → 提交事务 ✅
失败 → 抛出异常 → 回滚事务 → 供应商修改全部回滚 ✅
```
**关键点**
- 供应商的所有修改(基本信息、地址、标签等)都在事务内
- 审核中心调用也在事务内
- 如果审核中心失败,**所有修改都会回滚**,供应商恢复到修改前的状态
#### 3. **批量申请审核**(非直接申请)
```
开始事务 (batchApplyInReviewSupplier 第780行)
更新供应商状态为 STATUS_IN_REVIEW
调用审核中心创建单据
成功 → 提交事务 ✅
失败 → 抛出异常 → 回滚事务 → 状态不更新 ✅
```
#### 4. **异常处理链**
- `AuditCenterService::addAudit()` - 审核中心API调用失败时抛出异常
- `SupplierAuditService::addApprove()` - 供应商不存在或流程配置错误时抛出异常
- `DB::transaction()` - 捕获异常并自动回滚事务
- 前端会收到错误提示,用户可以重试
## 兼容性说明 ## 兼容性说明
1. **向后兼容**:保留了旧的审核流程 `auditSupplierOld()`,如果没有审核中心单据,会自动使用旧流程 1. **向后兼容**:保留了旧的审核流程 `auditSupplierOld()`,如果没有审核中心单据,会自动使用旧流程
2. **异常处理**:审核中心调用失败不会影响主流程,会记录日志 2. **数据迁移**:现有的供应商审核数据不受影响,新的审核会自动使用审核中心
3. **数据迁移**:现有的供应商审核数据不受影响,新的审核会自动使用审核中心
## 测试要点 ## 测试要点
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment