From 2f8f7dccf9cbc82c5664532317a492b251515d2f Mon Sep 17 00:00:00 2001 From: mzl Date: Mon, 3 Nov 2025 18:07:56 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=A4=87=E8=B4=A7=E5=8D=95?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/StockOrdersController.php | 11 ++-- app/admin/controller/UserController.php | 5 ++ app/admin/service/UserService.php | 2 + app/common/model/StockOrdersFiles.php | 2 +- app/common/service/StockOrdersService.php | 56 +++++++++++++++++-- .../approval/service/ApprovalFlowService.php | 10 +++- app/crm/controller/StockOrdersController.php | 42 ++++++++------ 7 files changed, 98 insertions(+), 30 deletions(-) diff --git a/app/admin/controller/StockOrdersController.php b/app/admin/controller/StockOrdersController.php index 39806a5..47e694a 100644 --- a/app/admin/controller/StockOrdersController.php +++ b/app/admin/controller/StockOrdersController.php @@ -81,19 +81,22 @@ class StockOrdersController extends BaseController if (!isset($groupedFiles[$file['file_code']])) { $groupedFiles[$file['file_code']] = []; } - $groupedFiles[$file['file_code']][] = $file['file_url']; + $groupedFiles[$file['file_code']][] = [ + 'url' => $file['file_url'], + 'original_name' => $file['original_name'] + ]; } // 映射到对应字段 foreach ($fileTypes as $field => $fileCode) { if (isset($groupedFiles[$fileCode])) { - // 原始URL数组 + // 文件信息数组,包含url和original_name $data[$field] = $groupedFiles[$fileCode]; // 完整URL数组 $fullUrls = []; - foreach ($groupedFiles[$fileCode] as $url) { - $fullUrls[] = (new \app\common\service\OssService)->generatePrivateUrl($url); + foreach ($groupedFiles[$fileCode] as $fileInfo) { + $fullUrls[] = (new \app\common\service\OssService)->generatePrivateUrl($fileInfo['url']); } $data[$field . '_url'] = $fullUrls; } diff --git a/app/admin/controller/UserController.php b/app/admin/controller/UserController.php index 8c24c6c..e9ef8d4 100644 --- a/app/admin/controller/UserController.php +++ b/app/admin/controller/UserController.php @@ -118,6 +118,11 @@ class UserController extends BaseController $data['system_ids'][] = $system['id']; } } + if ($data['reportToInfo']) { + $data['report_to_name'] = $data['reportToInfo']['id'] == $data['id'] ? '/' : $data['reportToInfo']['name']; + } else { + $data['report_to_name'] = '-'; + } return $data; } diff --git a/app/admin/service/UserService.php b/app/admin/service/UserService.php index 7f2fadd..9d850a5 100644 --- a/app/admin/service/UserService.php +++ b/app/admin/service/UserService.php @@ -100,6 +100,8 @@ class UserService $config['with']['roles'][] = 'name'; $config['with']['systems'][] = 'id'; $config['with']['systems'][] = 'name'; + $config['with']['reportToInfo'][] = 'id'; + $config['with']['reportToInfo'][] = 'name'; break; case 'show': $config['where']['id'] = $p['id']; diff --git a/app/common/model/StockOrdersFiles.php b/app/common/model/StockOrdersFiles.php index 98daa3f..3b78e5c 100644 --- a/app/common/model/StockOrdersFiles.php +++ b/app/common/model/StockOrdersFiles.php @@ -40,7 +40,7 @@ class StockOrdersFiles extends Model /** * 允许自动填充模型字段 */ - protected $fillable = ['id', 'order_id', 'file_name', 'file_code', 'file_url', 'created_at', 'updated_at']; + protected $fillable = ['id', 'order_id', 'file_name', 'file_code', 'file_url', 'original_name', 'created_at', 'updated_at']; /** * 不允许自动填充模型字段 diff --git a/app/common/service/StockOrdersService.php b/app/common/service/StockOrdersService.php index 76d2ab5..d4187a1 100644 --- a/app/common/service/StockOrdersService.php +++ b/app/common/service/StockOrdersService.php @@ -161,7 +161,8 @@ class StockOrdersService { // 启动审批 $appro = new \app\common\utils\approval\service\ApprovalFlowService(); - $appro->start('stock_orders', 'stock_orders', $item->id, [], $item->salesperson_id); + $formData = $this->checkNewOrUsedVehicles($item->id); + $appro->start('stock_orders', 'stock_orders', $item->id, $formData, $item->salesperson_id); // 异步生成pdf文件 \Webman\RedisQueue\Redis::send('stock-order-pdf', ['id'=>$item->id]); } @@ -295,7 +296,8 @@ class StockOrdersService public function approvalNullify($item) { $appro = new \app\common\utils\approval\service\ApprovalFlowService(); - $appro->startNullify('stock_orders_nullify', 'stock_orders', $item->id, [], $item->salesperson_id); + $formData = $this->checkNewOrUsedVehicles($item->id); + $appro->startNullify('stock_orders_nullify', 'stock_orders', $item->id, $formData, $item->salesperson_id); } /** @@ -479,14 +481,19 @@ class StockOrdersService // 检查数据中是否存在该字段且为数组 if (!empty($data[$field]) && is_array($data[$field])) { // 处理该字段下的每个文件 - foreach ($data[$field] as $fileUrl) { + foreach ($data[$field] as $fileInfo) { $fileData = [ 'order_id' => $order->id, 'file_code' => $fileCode, - 'file_url' => $fileUrl, + 'file_url' => $fileInfo['url'] ?? '', 'file_name' => StockOrdersFiles::FILE_CODE[$fileCode], + 'original_name' => $fileInfo['original_name'] ?? StockOrdersFiles::FILE_CODE[$fileCode], ]; - StockOrdersFiles::create($fileData); + + // 只有当file_url不为空时才创建记录 + if (!empty($fileData['file_url'])) { + StockOrdersFiles::create($fileData); + } } } } @@ -905,6 +912,7 @@ class StockOrdersService 'id' => $file->id, 'file_url' => $file->file_url, 'file_full_url' => $this->getFileUrl($file->file_url), + 'original_name' => $file->original_name, ]; } @@ -978,4 +986,42 @@ class StockOrdersService } return (new \app\common\service\OssService)->generatePrivateUrl($fileUrl); } + + /** + * 检查备货单中的车辆是新车还是二手车 + * @param int $stockOrderId 备货单ID + * @return array 返回包含has_new和has_used的数组 + */ + public function checkNewOrUsedVehicles(int $stockOrderId): array + { + // 获取备货单关联的所有车辆项 + $vehicles = StockOrderItems::where('order_id', $stockOrderId)->get(); + + $hasNew = false; + $hasUsed = false; + $submitNote = ''; + + foreach ($vehicles as $vehicle) { + // 判断是否为二手车(mileage > 0) + if ($vehicle->mileage > 0) { + $hasUsed = true; + $submitNote = '本单只有二手车'; + } else { + $hasNew = true; + $submitNote = '本单只有新车'; + } + + // 如果两种类型都已经存在,可以提前退出循环 + if ($hasNew && $hasUsed) { + $submitNote = '本单包含新车和二手车'; + break; + } + } + + return [ + 'has_new' => $hasNew ? 1 : 0, + 'has_used' => $hasUsed ? 1 : 0, + 'submit_note' => $submitNote + ]; + } } \ No newline at end of file diff --git a/app/common/utils/approval/service/ApprovalFlowService.php b/app/common/utils/approval/service/ApprovalFlowService.php index 6eae8d8..a26b79a 100644 --- a/app/common/utils/approval/service/ApprovalFlowService.php +++ b/app/common/utils/approval/service/ApprovalFlowService.php @@ -68,7 +68,7 @@ class ApprovalFlowService } $this->sendNotification($approverIds, $instance, 'pending', false, $extra); - $this->notifyCCs($firstStep, $instance, 'pending'); + // $this->notifyCCs($firstStep, $instance, 'pending'); $this->pushTodoChanged($approverIds); @@ -193,6 +193,12 @@ class ApprovalFlowService 'updated_at' => $now, ]); $this->onFlowFinalized($instance, $finalStatus); + + // 新增:在流程最终完成时才发本步骤的抄送 + if (!empty($step['cc'])) { + $this->notifyCCs($step, $instance, $notifyAction); + } + $this->sendNotification([$instance->initiator_id], $instance, $notifyAction, false); $this->pushTodoChanged([$approverId]); return ['status' => 'completed', 'msg' => ($finalStatus === 'voided' ? '已作废' : '同意')]; @@ -215,7 +221,7 @@ class ApprovalFlowService $this->insertApprovalRecord($instance, $nextIndex, $uid); } $this->sendNotification($nextApprovers, $instance, 'pending', false); - $this->notifyCCs($nextStep, $instance, 'pending'); + // $this->notifyCCs($nextStep, $instance, 'pending'); $this->pushTodoChanged(array_merge([$approverId], $nextApprovers)); return ['status' => 'next_step', 'msg' => '进行下一步:'.$nextStep['name'] ?? ('Step '.$nextIndex)]; }); diff --git a/app/crm/controller/StockOrdersController.php b/app/crm/controller/StockOrdersController.php index 3716c69..3f6c6e4 100644 --- a/app/crm/controller/StockOrdersController.php +++ b/app/crm/controller/StockOrdersController.php @@ -61,43 +61,49 @@ class StockOrdersController extends BaseController if (isset($data['pick_up_date']) && $data['pick_up_date'] > 0) $data['pick_up_date'] = date('Y-m-d', $data['pick_up_date']); if (isset($data['collect_all_date']) && $data['collect_all_date'] > 0) $data['collect_all_date'] = date('Y-m-d', $data['collect_all_date']); - // 处理文件附件 + // 处理文件附件:只允许 _url 字段调用 OSS 生成私有链接 $fileTypes = [ 'contract' => \app\common\model\StockOrdersFiles::CONTRACT, 'transaction_slip' => \app\common\model\StockOrdersFiles::TRANSACTION_SLIP, 'pi_doc' => \app\common\model\StockOrdersFiles::PI_DOC ]; - + // 初始化文件字段 foreach (array_keys($fileTypes) as $field) { - $data[$field] = []; - $data[$field . '_url'] = []; + $data[$field] = []; // 存储原始文件信息(不包含签名链接) + $data[$field . '_url'] = []; // 存储通过OSS生成的私有链接 } - - // 按file_code分组文件 + + // 按 file_code 分组文件 if (!empty($data['files'])) { $groupedFiles = []; foreach ($data['files'] as $file) { - if (!isset($groupedFiles[$file['file_code']])) { - $groupedFiles[$file['file_code']] = []; + $code = $file['file_code']; + if (!isset($groupedFiles[$code])) { + $groupedFiles[$code] = []; } - $groupedFiles[$file['file_code']][] = $file['file_url']; + $groupedFiles[$code][] = [ + 'url' => $file['file_url'], // 原始路径 + 'original_name' => $file['original_name'] // 原始文件名 + ]; } - - // 映射到对应字段 + + // 映射到对应字段,并仅对 _url 调用 OSS 服务 foreach ($fileTypes as $field => $fileCode) { if (isset($groupedFiles[$fileCode])) { - // 原始URL数组 + // 主字段存储基本信息(无签名链接) $data[$field] = $groupedFiles[$fileCode]; - - // 完整URL数组 - $fullUrls = []; - foreach ($groupedFiles[$fileCode] as $url) { - $fullUrls[] = (new \app\common\service\OssService)->generatePrivateUrl($url); + + // 只有 *_url 字段才生成带签名的完整 URL + $signedUrls = []; + foreach ($groupedFiles[$fileCode] as $fileInfo) { + $signedUrls[] = (new \app\common\service\OssService)->generatePrivateUrl($fileInfo['url']); } - $data[$field . '_url'] = $fullUrls; + $data[$field . '_url'] = $signedUrls; } } + + // 清理临时数据 unset($data['files']); }