0, 'msg' => '获取合同列表失败', 'data' => [] ]; try { $page = $where['page'] ?? 1; $limit = $where['limit'] ?? 10; $personnel_id = $where['personnel_id'] ?? 0; if (empty($personnel_id)) { $res['msg'] = '员工ID不能为空'; return $res; } // 查询合同签订记录,关联合同表 $contractSignModel = new ContractSign(); $list = $contractSignModel->alias('cs') ->join('school_contract c', 'cs.contract_id = c.id') ->where('cs.personnel_id', $personnel_id) ->where('cs.deleted_at', 0) ->where('c.deleted_at', 0) ->field([ 'cs.id', 'cs.contract_id', 'cs.personnel_id', 'cs.sign_file', 'cs.status', 'cs.created_at', 'cs.sign_time', 'c.contract_name', 'c.contract_template', 'c.contract_status', 'c.contract_type', 'c.remarks' ]) ->order('cs.created_at', 'desc') ->paginate([ 'list_rows' => $limit, 'page' => $page ]) ->toArray(); $res = [ 'code' => 1, 'msg' => '获取成功', 'data' => $list ]; } catch (\Exception $e) { $res['msg'] = '获取合同列表异常:' . $e->getMessage(); } return $res; } /** * 获取合同详情 * @param array $where * @return array */ public function getContractDetail(array $where) { $res = [ 'code' => 0, 'msg' => '获取合同详情失败', 'data' => [] ]; try { $id = $where['id'] ?? 0; if (empty($id)) { $res['msg'] = '参数错误'; return $res; } // 查询合同签订记录,关联合同表 $contractSign = ContractSign::alias('cs') ->join('school_contract c', 'cs.contract_id = c.id') ->where('cs.id', $id) ->where('cs.deleted_at', 0) ->where('c.deleted_at', 0) ->field([ 'cs.id', 'cs.contract_id', 'cs.personnel_id', 'cs.sign_file', 'cs.status', 'cs.created_at', 'cs.sign_time', 'cs.updated_at', 'c.contract_name', 'c.contract_template', 'c.contract_status', 'c.contract_type', 'c.remarks' ]) ->find(); if (empty($contractSign)) { $res['msg'] = '合同不存在或无权限访问'; return $res; } $contractData = $contractSign->toArray(); $res = [ 'code' => 1, 'msg' => '获取成功', 'data' => $contractData ]; } catch (\Exception $e) { $res['msg'] = '获取合同详情异常:' . $e->getMessage(); } return $res; } /** * 签订合同 * @param array $data * @return array */ public function signContract(array $data) { $res = [ 'code' => 0, 'msg' => '签订合同失败', 'data' => [] ]; try { $contract_id = $data['contract_id'] ?? 0; $personnel_id = $data['personnel_id'] ?? 0; $sign_file = $data['sign_file'] ?? ''; if (empty($contract_id) || empty($personnel_id) || empty($sign_file)) { $res['msg'] = '参数错误'; return $res; } // 开启事务 Db::startTrans(); // 查询合同签订记录 $contractSign = ContractSign::where('contract_id', $contract_id) ->where('personnel_id', $personnel_id) ->where('deleted_at', 0) ->find(); if (empty($contractSign)) { Db::rollback(); $res['msg'] = '合同签订记录不存在'; return $res; } // 检查合同状态 if ($contractSign['status'] != 1) { Db::rollback(); $res['msg'] = '合同状态不允许签订'; return $res; } // 检查是否已经签订 if (!empty($contractSign['sign_file'])) { Db::rollback(); $res['msg'] = '合同已经签订,无需重复签订'; return $res; } // 生成签署后的合同文档 $generatedFile = null; if ($sign_file) { $generatedFile = $this->generateStaffSignedContract($contract_id, $personnel_id, $sign_file); } // 更新签订信息 $updateData = [ 'sign_file' => $generatedFile ?: $sign_file, 'sign_time' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s') ]; if ($generatedFile) { $updateData['signature_image'] = $sign_file; } $updateResult = ContractSign::where('id', $contractSign['id'])->update($updateData); if (!$updateResult) { Db::rollback(); $res['msg'] = '更新签订信息失败'; return $res; } // 提交事务 Db::commit(); $res = [ 'code' => 1, 'msg' => '签订成功', 'data' => [ 'contract_id' => $contract_id, 'sign_time' => $updateData['sign_time'], 'generated_file' => $generatedFile ] ]; } catch (\Exception $e) { Db::rollback(); $res['msg'] = '签订合同异常:' . $e->getMessage(); } return $res; } /** * 获取合同签订状态 * @param array $where * @return array */ public function getSignStatus(array $where) { $res = [ 'code' => 0, 'msg' => '获取签订状态失败', 'data' => [] ]; try { $contract_id = $where['contract_id'] ?? 0; $personnel_id = $where['personnel_id'] ?? 0; if (empty($contract_id) || empty($personnel_id)) { $res['msg'] = '参数错误'; return $res; } $contractSign = ContractSign::where('contract_id', $contract_id) ->where('personnel_id', $personnel_id) ->where('deleted_at', 0) ->field('id,sign_file,status,sign_time') ->find(); if (empty($contractSign)) { $res['msg'] = '合同签订记录不存在'; return $res; } $signData = $contractSign->toArray(); // 判断签订状态 $signData['is_signed'] = !empty($signData['sign_file']); $signData['can_sign'] = $signData['status'] == 1 && empty($signData['sign_file']); $res = [ 'code' => 1, 'msg' => '获取成功', 'data' => $signData ]; } catch (\Exception $e) { $res['msg'] = '获取签订状态异常:' . $e->getMessage(); } return $res; } /** * 下载合同文件 * @param array $where * @return array */ public function downloadContract(array $where) { $res = [ 'code' => 0, 'msg' => '下载合同失败', 'data' => [] ]; try { $contract_id = $where['contract_id'] ?? 0; $personnel_id = $where['personnel_id'] ?? 0; if (empty($contract_id) || empty($personnel_id)) { $res['msg'] = '参数错误'; return $res; } // 查询合同信息 $contractSign = ContractSign::alias('cs') ->join('school_contract c', 'cs.contract_id = c.id') ->where('cs.contract_id', $contract_id) ->where('cs.personnel_id', $personnel_id) ->where('cs.deleted_at', 0) ->where('c.deleted_at', 0) ->field([ 'cs.sign_file', 'c.contract_template', 'c.contract_name' ]) ->find(); if (empty($contractSign)) { $res['msg'] = '合同不存在或无权限访问'; return $res; } $contractData = $contractSign->toArray(); // 返回下载信息 $downloadData = [ 'contract_name' => $contractData['contract_name'], 'sign_file' => $contractData['sign_file'], 'contract_template' => $contractData['contract_template'], 'download_url' => !empty($contractData['sign_file']) ? $contractData['sign_file'] : $contractData['contract_template'] ]; $res = [ 'code' => 1, 'msg' => '获取下载信息成功', 'data' => $downloadData ]; } catch (\Exception $e) { $res['msg'] = '获取下载信息异常:' . $e->getMessage(); } return $res; } /** * 生成员工签署后的合同文档 * @param int $contractId * @param int $personnelId * @param string $signatureImage * @return string|null */ private function generateStaffSignedContract($contractId, $personnelId, $signatureImage) { try { // 获取合同模板信息 $contract = Contract::find($contractId); if (!$contract || !$contract['contract_template']) { return null; } // 构建模板路径 $templatePath = public_path() . '/upload/' . $contract['contract_template']; if (!file_exists($templatePath)) { return null; } // 生成输出文件名和路径 $outputFileName = 'staff_signed_contract_' . $personnelId . '_' . $contractId . '_' . date('YmdHis') . '.docx'; $outputRelPath = 'contracts/staff_signed/' . date('Y/m/') . $outputFileName; $outputFullPath = public_path() . '/upload/' . $outputRelPath; // 确保目录存在 $outputDir = dirname($outputFullPath); if (!is_dir($outputDir)) { mkdir($outputDir, 0755, true); } // 获取员工信息并准备填充数据 $fillData = $this->prepareStaffFillData($contractId, $personnelId); // 使用PhpWord处理模板 $templateProcessor = new TemplateProcessor($templatePath); // 填充文本数据 foreach ($fillData as $placeholder => $value) { $templateProcessor->setValue($placeholder, $value); } // 处理签名图片 if ($signatureImage) { // 处理签名图片 $signImagePath = $this->processStaffSignatureImage($signatureImage); // 使用ContractSign服务插入签名 $contractSignService = new ContractSignService(); $contractSignService->setSign($templatePath, $outputFullPath, $signImagePath, '员工签名'); // 清理临时文件 if (file_exists($signImagePath)) { unlink($signImagePath); } } else { // 没有签名时直接保存 $templateProcessor->saveAs($outputFullPath); } return $outputRelPath; } catch (\Exception $e) { return null; } } /** * 准备员工填充数据 * @param int $contractId * @param int $personnelId * @return array */ private function prepareStaffFillData($contractId, $personnelId) { $fillData = []; try { // 获取员工信息 $personnel = Db::table('school_personnel')->where('id', $personnelId)->find(); if ($personnel) { $fillData['员工姓名'] = $personnel['name'] ?? ''; $fillData['员工编号'] = $personnel['employee_number'] ?? ''; $fillData['员工电话'] = $personnel['phone'] ?? ''; $fillData['员工邮箱'] = $personnel['email'] ?? ''; $fillData['入职时间'] = $personnel['join_time'] ?? ''; } // 添加系统信息 $fillData['签署日期'] = date('Y-m-d'); $fillData['签署时间'] = date('Y-m-d H:i:s'); $fillData['合同编号'] = $contractId . date('Ymd') . $personnelId; } catch (\Exception $e) { // 记录错误日志但不中断流程 } return $fillData; } /** * 处理员工签名图片 * @param string $signatureImage * @return string */ private function processStaffSignatureImage($signatureImage) { $tempImagePath = public_path() . '/upload/temp_staff_sign_' . date('YmdHis') . '_' . mt_rand(1000, 9999) . '.png'; if (strpos($signatureImage, 'data:image') === 0) { // Base64图片 $imageData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $signatureImage)); if ($imageData !== false) { file_put_contents($tempImagePath, $imageData); } } elseif (filter_var($signatureImage, FILTER_VALIDATE_URL)) { // URL图片 $imageContent = file_get_contents($signatureImage); if ($imageContent !== false) { file_put_contents($tempImagePath, $imageContent); } } else { // 本地路径 $localPath = public_path() . '/upload/' . ltrim($signatureImage, '/'); if (file_exists($localPath)) { copy($localPath, $tempImagePath); } } return $tempImagePath; } }