leftJoin('school_contract c', 'cs.contract_id = c.id') ->where($where) ->field(' cs.id as sign_id, cs.contract_id, cs.status, cs.sign_time, cs.created_at, c.contract_name, c.contract_type, c.remarks, c.contract_template ') ->order('cs.created_at desc'); $total = $query->count(); $list = $query->page($page, $limit)->select()->toArray(); // 处理每个合同的详细信息 foreach ($list as &$contract) { // 状态文本映射 $contract['status_text'] = $this->getStatusText($contract['status']); // 获取合同相关的课程信息 $courseInfo = $this->getContractCourseInfo($contract['contract_id'], $studentId); $contract = array_merge($contract, $courseInfo); // 格式化日期 $contract['sign_date'] = $contract['sign_time'] ? date('Y-m-d', strtotime($contract['sign_time'])) : null; $contract['create_date'] = date('Y-m-d', strtotime($contract['created_at'])); // 文件路径处理 $contract['contract_file_url'] = $contract['contract_template'] ? get_image_url($contract['contract_template']) : ''; // 计算课时使用进度 if ($contract['total_hours'] > 0) { $contract['progress_percent'] = round(($contract['used_hours'] / $contract['total_hours']) * 100, 1); } else { $contract['progress_percent'] = 0; } // 判断是否可以续约(生效状态且课时即将用完) $contract['can_renew'] = $contract['status'] == 3 && $contract['remaining_hours'] <= 5; } // 统计数据 $stats = $this->getContractStats($studentId); return [ 'list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit, 'has_more' => $total > $page * $limit, 'stats' => $stats ]; } /** * 获取合同详情 * @param int $contractId * @param int $studentId * @return array */ public function getContractDetail($contractId, $studentId) { // 查询合同签署记录 $contractSign = Db::table('school_contract_sign cs') ->leftJoin('school_contract c', 'cs.contract_id = c.id') ->where([ ['cs.contract_id', '=', $contractId], ['cs.student_id', '=', $studentId], ['cs.deleted_at', '=', 0] ]) ->field(' cs.id as sign_id, cs.contract_id, cs.status, cs.sign_time, cs.created_at, cs.fill_data, c.contract_name, c.contract_type, c.remarks, c.contract_template, c.contract_content, c.placeholders ') ->find(); if (!$contractSign) { throw new CommonException('合同不存在或无权限访问'); } // 获取课程信息 $courseInfo = $this->getContractCourseInfo($contractId, $studentId); $contractSign = array_merge($contractSign, $courseInfo); // 状态文本 $contractSign['status_text'] = $this->getStatusText($contractSign['status']); // 格式化日期 $contractSign['sign_date'] = $contractSign['sign_time'] ? date('Y-m-d H:i:s', strtotime($contractSign['sign_time'])) : null; $contractSign['create_date'] = date('Y-m-d H:i:s', strtotime($contractSign['created_at'])); // 文件路径 $contractSign['contract_file_url'] = $contractSign['contract_template'] ? get_image_url($contractSign['contract_template']) : ''; // 解析填写的数据 $contractSign['form_data'] = []; if ($contractSign['fill_data']) { $contractSign['form_data'] = json_decode($contractSign['fill_data'], true) ?: []; } // 合同条款(如果有内容的话) $contractSign['terms'] = $contractSign['contract_content'] ?: $contractSign['remarks']; // 对于已签署成功的合同(status=3),进行占位符替换 if ($contractSign['status'] == 3 && !empty($contractSign['terms'])) { $contractSign['terms'] = $this->replacePlaceholdersInTerms( $contractSign['terms'], $contractId, $contractSign['sign_id'], $studentId ); } return $contractSign; } /** * 获取合同签署表单配置 * @param int $contractId * @param int $studentId * @return array */ public function getSignForm($contractId, $studentId) { // 验证合同是否存在且用户有权限 $contractSign = Db::table('school_contract_sign') ->where([ ['contract_id', '=', $contractId], ['student_id', '=', $studentId], ['deleted_at', '=', 0] ]) ->find(); if (!$contractSign) { throw new CommonException('合同不存在或无权限访问'); } // 检查合同状态 if ($contractSign['status'] != 1) { throw new CommonException('当前合同状态不允许签署'); } // 获取合同基本信息 $contract = Db::table('school_contract') ->where('id', $contractId) ->field('id, contract_name, contract_type, contract_template, contract_content, placeholders') ->find(); if (!$contract) { throw new CommonException('合同模板不存在'); } // 获取所有字段配置 $formFields = Db::table('school_document_data_source_config') ->where('contract_id', $contractId) ->field('id, placeholder, field_type, data_type, is_required, default_value, table_name, field_name, system_function, sign_party') ->order('id ASC') ->select() ->toArray(); // 格式化表单字段 $fields = []; foreach ($formFields as $field) { // 根据数据类型预填充默认值 $defaultValue = ''; switch ($field['data_type']) { case 'database': $defaultValue = $this->getDataFromDatabase($field['table_name'], $field['field_name'], $studentId); break; case 'system': $defaultValue = $this->getSystemValue($field['system_function']); break; case 'user_input': default: $defaultValue = $field['default_value'] ?: ''; break; } $fields[] = [ 'id' => $field['id'], 'name' => $field['placeholder'], // 使用placeholder作为字段名称 'placeholder' => $field['placeholder'], 'field_type' => $field['field_type'], 'data_type' => $field['data_type'], 'is_required' => (bool)$field['is_required'], 'default_value' => $defaultValue, 'sign_party' => $field['sign_party'] ]; } return [ 'contract_id' => $contractId, 'contract_name' => $contract['contract_name'], 'contract_type' => $contract['contract_type'], 'contract_content' => $contract['contract_content'] ?: '', 'form_fields' => $fields, 'contract_template_url' => $contract['contract_template'] ? get_image_url($contract['contract_template']) : '' ]; } /** * 提交合同签署 * @param array $data * @return bool */ public function signContract($data) { $contractId = $data['contract_id']; $studentId = $data['student_id']; $formData = $data['form_data']; $signatureImage = $data['signature_image'] ?? ''; // 验证合同签署记录 $contractSign = Db::table('school_contract_sign') ->where([ ['contract_id', '=', $contractId], ['student_id', '=', $studentId], ['deleted_at', '=', 0] ]) ->find(); if (!$contractSign) { throw new CommonException('合同不存在或无权限访问'); } if ($contractSign['status'] != 1) { throw new CommonException('当前合同状态不允许签署'); } // 从form_data中提取签名图片路径 $extractedSignatures = $this->extractSignatureImages($formData); // 上传并处理签名图片 $processedSignatures = $this->uploadSignatureImages($extractedSignatures); // 更新form_data中的签名路径为服务器路径 $formData = $this->updateFormDataWithUploadedPaths($formData, $processedSignatures); // 验证必填字段 $this->validateFormData($contractId, $formData); // 开始事务 Db::startTrans(); try { // 生成签署后的合同文档 $generatedFile = null; $mainSignature = $processedSignatures['{{学员签名}}'] ?? $signatureImage; if ($mainSignature || !empty($processedSignatures)) { $generatedFile = $this->generateSignedContract($contractId, $studentId, $formData, $mainSignature); } // 更新合同签署状态 $updateData = [ 'status' => 3, // 直接设为已生效 'sign_time' => date('Y-m-d H:i:s'), 'fill_data' => json_encode($formData, JSON_UNESCAPED_UNICODE), 'updated_at' => date('Y-m-d H:i:s') ]; if ($mainSignature) { $updateData['signature_image'] = $mainSignature; } if ($generatedFile) { $updateData['sign_file'] = $generatedFile; } $result = Db::table('school_contract_sign') ->where('id', $contractSign['id']) ->update($updateData); if ($result === false) { throw new CommonException('合同签署失败'); } Db::commit(); return [ 'sign_id' => $contractSign['id'], 'generated_file' => $generatedFile, 'sign_time' => $updateData['sign_time'], 'status' => 3, 'processed_signatures' => $processedSignatures ]; } catch (\Exception $e) { Db::rollback(); throw new CommonException('合同签署失败:' . $e->getMessage()); } } /** * 下载合同文件 * @param int $contractId * @param int $studentId * @return array */ public function downloadContract($contractId, $studentId) { // 验证权限 $contractSign = Db::table('school_contract_sign') ->where([ ['contract_id', '=', $contractId], ['student_id', '=', $studentId], ['deleted_at', '=', 0] ]) ->find(); if (!$contractSign) { throw new CommonException('合同不存在或无权限访问'); } // 获取合同基本信息 $contract = Db::table('school_contract') ->where('id', $contractId) ->find(); if (!$contract) { throw new CommonException('合同不存在'); } // 优先返回已签署的文档 if ($contractSign['sign_file'] && $contractSign['status'] >= 2) { // 检查已签署文档是否存在 $signedFilePath = public_path() . '/upload/' . $contractSign['sign_file']; if (file_exists($signedFilePath)) { return [ 'file_url' => get_image_url($contractSign['sign_file']), 'file_name' => $contract['contract_name'] . '_已签署.docx', 'contract_name' => $contract['contract_name'], 'file_type' => 'signed', // 标识为已签署文档 'status' => $contractSign['status'], 'sign_time' => $contractSign['sign_time'] ]; } } // 如果没有已签署文档或文件不存在,返回原始模板 if (!$contract['contract_template']) { throw new CommonException('合同文件不存在'); } return [ 'file_url' => get_image_url($contract['contract_template']), 'file_name' => $contract['contract_name'] . '_模板.docx', 'contract_name' => $contract['contract_name'], 'file_type' => 'template', // 标识为模板文档 'status' => $contractSign['status'] ]; } /** * 获取合同相关的课程信息 * @param int $contractId * @param int $studentId * @return array */ private function getContractCourseInfo($contractId, $studentId) { // 通过订单表获取课程信息 $orderInfo = Db::table('school_order_table ot') ->leftJoin('school_course c', 'ot.course_id = c.id') ->where([ // 这里需要根据实际业务逻辑调整关联条件 ['ot.student_id', '=', $studentId] ]) ->field(' c.course_name, c.course_type, ot.order_amount as total_amount ') ->find(); // 从课程表获取课时信息 $courseStats = Db::table('school_student_courses') ->where('student_id', $studentId) ->field(' SUM(total_hours + gift_hours) as total_hours, SUM(use_total_hours + use_gift_hours) as used_hours, SUM(total_hours + gift_hours - use_total_hours - use_gift_hours) as remaining_hours ') ->find(); return [ 'course_type' => $orderInfo['course_name'] ?? '未知课程', 'total_amount' => $orderInfo['total_amount'] ?? '0.00', 'total_hours' => (int)($courseStats['total_hours'] ?? 0), 'used_hours' => (int)($courseStats['used_hours'] ?? 0), 'remaining_hours' => (int)($courseStats['remaining_hours'] ?? 0) ]; } /** * 获取合同统计数据 * @param int $studentId * @return array */ private function getContractStats($studentId) { // 统计各状态合同数量 $statusCounts = Db::table('school_contract_sign') ->where([ ['student_id', '=', $studentId], ['deleted_at', '=', 0] ]) ->field('status, COUNT(*) as count') ->group('status') ->select() ->toArray(); $stats = [ 'total_contracts' => 0, 'active_contracts' => 0, // 已生效 'pending_contracts' => 0, // 未签署 'signed_contracts' => 0, // 已签署 'expired_contracts' => 0, // 已失效 ]; foreach ($statusCounts as $item) { $stats['total_contracts'] += $item['count']; switch ($item['status']) { case 1: $stats['pending_contracts'] = $item['count']; break; case 2: $stats['signed_contracts'] = $item['count']; break; case 3: $stats['active_contracts'] = $item['count']; break; case 4: $stats['expired_contracts'] = $item['count']; break; } } // 获取剩余总课时 $courseStats = Db::table('school_student_courses') ->where('student_id', $studentId) ->field('SUM(total_hours + gift_hours - use_total_hours - use_gift_hours) as remaining_hours') ->find(); $stats['remaining_hours'] = (int)($courseStats['remaining_hours'] ?? 0); return $stats; } /** * 获取状态文本 * @param int $status * @return string */ private function getStatusText($status) { $statusMap = [ 1 => '未签署', 2 => '已签署', 3 => '已生效', 4 => '已失效' ]; return $statusMap[$status] ?? '未知状态'; } /** * 获取学员基本信息 * @param int $studentId * @return array */ public function getStudentInfo($studentId) { $student = Db::table('school_student') ->where('id', $studentId) ->field('id, name, gender, age, headimg') ->find(); if (!$student) { throw new CommonException('学员不存在'); } return [ 'id' => $student['id'], 'name' => $student['name'], 'gender' => $student['gender'], 'age' => $student['age'], 'avatar' => $student['headimg'] ? get_image_url($student['headimg']) : '' ]; } /** * 生成签署后的合同文档 * @param int $contractId * @param int $studentId * @param array $formData * @param string $signatureImage * @return string * @throws CommonException */ private function generateSignedContract($contractId, $studentId, $formData, $signatureImage) { try { // 获取合同模板信息 $contract = Db::table('school_contract') ->where('id', $contractId) ->find(); if (!$contract || !$contract['contract_template']) { throw new CommonException('合同模板不存在'); } // 构建模板路径 $templatePath = public_path() . '/upload/' . $contract['contract_template']; if (!file_exists($templatePath)) { throw new CommonException('合同模板文件不存在'); } // 生成输出文件名和路径 $outputFileName = 'signed_contract_' . $studentId . '_' . $contractId . '_' . date('YmdHis') . '.docx'; $outputRelPath = 'contracts/signed/' . date('Y/m/') . $outputFileName; $outputFullPath = public_path() . '/upload/' . $outputRelPath; // 确保目录存在 $outputDir = dirname($outputFullPath); if (!is_dir($outputDir)) { mkdir($outputDir, 0755, true); } // 获取数据源配置并准备填充数据 $fillData = $this->prepareFillData($contractId, $studentId, $formData); // 使用PhpWord处理模板 $templateProcessor = new TemplateProcessor($templatePath); // 填充文本数据 foreach ($fillData as $placeholder => $value) { $templateProcessor->setValue($placeholder, $value); } // 处理签名图片 if ($signatureImage && $this->hasSignaturePlaceholder($templateProcessor)) { // 处理签名图片 - 支持base64和URL $signImagePath = $this->processSignatureImage($signatureImage); // 使用ContractSign服务插入签名 $contractSignService = new ContractSign(); $contractSignService->setSign($templatePath, $outputFullPath, $signImagePath, '学员签名'); // 清理临时文件 if (file_exists($signImagePath)) { unlink($signImagePath); } } else { // 没有签名时直接保存 $templateProcessor->saveAs($outputFullPath); } return $outputRelPath; } catch (\Exception $e) { throw new CommonException('生成签署合同失败:' . $e->getMessage()); } } /** * 检查模板是否包含签名占位符 * @param TemplateProcessor $templateProcessor * @return bool */ private function hasSignaturePlaceholder($templateProcessor) { // 这里可以检查模板是否包含签名占位符 // 简化处理,假设所有模板都支持签名 return true; } /** * 处理签名图片 * @param string $signatureImage * @return string * @throws CommonException */ private function processSignatureImage($signatureImage) { $tempImagePath = public_path() . '/upload/temp_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) { throw new CommonException('签名图片格式错误'); } file_put_contents($tempImagePath, $imageData); } elseif (filter_var($signatureImage, FILTER_VALIDATE_URL)) { // URL图片 $imageContent = file_get_contents($signatureImage); if ($imageContent === false) { throw new CommonException('无法下载签名图片'); } file_put_contents($tempImagePath, $imageContent); } else { // 本地路径 $localPath = public_path() . '/upload/' . ltrim($signatureImage, '/'); if (!file_exists($localPath)) { throw new CommonException('签名图片文件不存在'); } copy($localPath, $tempImagePath); } return $tempImagePath; } /** * 准备填充数据 * @param int $contractId * @param int $studentId * @param array $formData * @return array */ private function prepareFillData($contractId, $studentId, $formData) { $fillData = []; // 获取数据源配置 $configs = Db::table('school_document_data_source_config') ->where('contract_id', $contractId) ->select() ->toArray(); foreach ($configs as $config) { $placeholder = str_replace(['{{', '}}'], '', $config['placeholder']); $value = ''; switch ($config['data_type']) { case 'database': $value = $this->getDataFromDatabase($config['table_name'], $config['field_name'], $studentId); break; case 'system': $value = $this->getSystemValue($config['system_function']); break; case 'user_input': default: $value = $formData[$placeholder] ?? $config['default_value'] ?? ''; break; } $fillData[$placeholder] = $value; } return $fillData; } /** * 从数据库获取数据 * @param string $tableName * @param string $fieldName * @param int $studentId * @return string */ private function getDataFromDatabase($tableName, $fieldName, $studentId) { try { if ($tableName === 'school_student') { $data = Db::table($tableName)->where('id', $studentId)->value($fieldName); } else { // 其他表可能需要更复杂的关联查询 $data = Db::table($tableName)->where('student_id', $studentId)->value($fieldName); } return $data ?: ''; } catch (\Exception $e) { return ''; } } /** * 获取系统值 * @param string $systemFunction * @return string */ private function getSystemValue($systemFunction) { switch ($systemFunction) { case 'current_date': return date('Y-m-d'); case 'current_time': return date('H:i:s'); case 'current_datetime': return date('Y-m-d H:i:s'); case 'current_year': return date('Y'); case 'current_month': return date('m'); case 'current_day': return date('d'); case 'random_number': return mt_rand(100000, 999999); case 'contract_generate_time': return date('Y-m-d H:i:s'); default: return ''; } } /** * 验证表单数据 * @param int $contractId * @param array $formData * @throws CommonException */ private function validateFormData($contractId, $formData) { // 获取必填字段配置 $requiredFields = Db::table('school_document_data_source_config') ->where([ ['contract_id', '=', $contractId], ['data_type', '=', 'manual'], ['is_required', '=', 1] ]) ->column('placeholder'); // 检查必填字段 foreach ($requiredFields as $field) { $fieldName = str_replace(['{{', '}}'], '', $field); if (!isset($formData[$fieldName]) || trim($formData[$fieldName]) === '') { throw new CommonException($fieldName . ' 为必填项'); } } } /** * 从表单数据中提取签名图片路径 * @param array $formData * @return array */ private function extractSignatureImages($formData) { $signatures = []; // 常见的签名字段模式 $signaturePatterns = ['签名', '乙方', '甲方', '学员签名']; foreach ($formData as $key => $value) { // 检查是否为图片URL(临时路径或正式路径) if (is_string($value) && ( strpos($value, 'http://tmp/') === 0 || strpos($value, 'https://tmp/') === 0 || preg_match('/\.(png|jpg|jpeg|gif)$/i', $value) )) { // 检查是否包含签名相关关键词 foreach ($signaturePatterns as $pattern) { if (strpos($key, $pattern) !== false) { $signatures[$key] = $value; break; } } } } return $signatures; } /** * 上传签名图片到服务器 * @param array $signatures * @return array */ private function uploadSignatureImages($signatures) { $processed = []; foreach ($signatures as $key => $imagePath) { try { // 如果是临时路径,需要下载并保存 if (strpos($imagePath, 'http://tmp/') === 0 || strpos($imagePath, 'https://tmp/') === 0) { // 微信小程序临时文件路径,需要通过API下载 // 这里简化处理,直接生成一个占位图片路径 $filename = 'signature_' . date('YmdHis') . '_' . mt_rand(1000, 9999) . '.png'; $relativePath = 'signatures/' . date('Y/m/') . $filename; $fullPath = public_path() . '/upload/' . $relativePath; // 确保目录存在 $dir = dirname($fullPath); if (!is_dir($dir)) { mkdir($dir, 0755, true); } // 尝试下载临时文件(实际环境中需要通过微信API) // 这里模拟处理,生成一个占位文件 $placeholderContent = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='); file_put_contents($fullPath, $placeholderContent); $processed[$key] = $relativePath; } else { // 已经是正式路径,直接使用 $processed[$key] = $imagePath; } } catch (\Exception $e) { // 签名图片处理失败,记录日志但不中断流程 error_log('签名图片上传失败: ' . $e->getMessage()); $processed[$key] = $imagePath; // 保持原路径 } } return $processed; } /** * 更新表单数据中的签名路径 * @param array $formData * @param array $processedSignatures * @return array */ private function updateFormDataWithUploadedPaths($formData, $processedSignatures) { foreach ($processedSignatures as $key => $newPath) { if (isset($formData[$key])) { $formData[$key] = $newPath; } } return $formData; } /** * 在合同条款中替换占位符 * 使用 school_document_data_source_config 表中的 default_value 数据进行替换 * * @param string $terms 合同条款内容 * @param int $contractId 合同模板ID * @param int $contractSignId 合同签署记录ID * @param int $studentId 学员ID * @return string 替换后的合同条款 */ private function replacePlaceholdersInTerms($terms, $contractId, $contractSignId, $studentId) { try { if (empty($terms)) { return $terms; } // 获取该合同的所有占位符配置 $configs = Db::table('school_document_data_source_config') ->where('contract_id', $contractId) ->where(function($query) use ($contractSignId) { $query->where('contract_sign_id', $contractSignId) ->whereOr('contract_sign_id', 'IS', null); }) ->field('placeholder, data_type, default_value, table_name, field_name, system_function') ->select() ->toArray(); if (empty($configs)) { return $terms; } // 获取学员信息(用于数据库类型查询) $student = Db::table('school_student') ->where('id', $studentId) ->find(); // 遍历配置,逐个替换占位符 foreach ($configs as $config) { $placeholder = $config['placeholder']; $value = ''; // 优先使用 default_value if (!empty($config['default_value'])) { $value = $config['default_value']; } else { // 根据数据类型获取值 switch ($config['data_type']) { case 'database': $value = $this->getDatabaseFieldValueFromConfig($config, $student ?: []); break; case 'system': $value = $this->getSystemFunctionValueFromConfig($config); break; case 'user_input': default: $value = $config['default_value'] ?: ''; break; } } // 替换占位符(支持 {{placeholder}} 和 {placeholder} 格式) $patterns = [ '{{' . $placeholder . '}}', '{' . $placeholder . '}' ]; foreach ($patterns as $pattern) { $terms = str_replace($pattern, $value, $terms); } } return $terms; } catch (\Exception $e) { // 出现错误时返回原内容,记录日志 \think\facade\Log::error('合同条款占位符替换失败', [ 'contract_id' => $contractId, 'contract_sign_id' => $contractSignId, 'student_id' => $studentId, 'error' => $e->getMessage() ]); return $terms; } } /** * 从配置中获取数据库字段值 * @param array $config 字段配置 * @param array $student 学员信息 * @return string */ private function getDatabaseFieldValueFromConfig($config, $student) { try { $tableName = $config['table_name'] ?? ''; $fieldName = $config['field_name'] ?? ''; if (empty($tableName) || empty($fieldName)) { return ''; } $value = ''; switch ($tableName) { case 'school_student': case 'students': // 学员表:直接从学员信息获取 $value = $student[$fieldName] ?? ''; break; case 'school_customer_resources': // 用户表:通过学员的user_id关联查询 if (!empty($student['user_id'])) { $value = Db::table('school_customer_resources') ->where('id', $student['user_id']) ->value($fieldName) ?: ''; } break; case 'school_order_table': // 订单表:查询该学员最新的订单信息 $value = Db::table('school_order_table') ->where('student_id', $student['id']) ->order('created_at', 'desc') ->value($fieldName) ?: ''; break; case 'school_personnel': // 员工表:这里可能需要根据业务逻辑确定关联的员工 $value = ''; break; default: \think\facade\Log::warning('不支持的数据库表', [ 'table_name' => $tableName, 'field_name' => $fieldName ]); break; } // 格式化字段值 $value = $this->formatFieldValue($fieldName, $value); return (string)$value; } catch (\Exception $e) { \think\facade\Log::error('从配置获取数据库字段值失败', [ 'config' => $config, 'student_id' => $student['id'] ?? 0, 'error' => $e->getMessage() ]); return ''; } } /** * 从配置中获取系统函数值 * @param array $config 字段配置 * @return string */ private function getSystemFunctionValueFromConfig($config) { try { $systemFunction = $config['system_function'] ?? ''; if (empty($systemFunction)) { return ''; } $value = ''; switch ($systemFunction) { case 'current_date': $value = date('Y-m-d'); break; case 'current_time': $value = date('H:i:s'); break; case 'current_datetime': $value = date('Y-m-d H:i:s'); break; case 'current_year': $value = date('Y'); break; case 'current_month': $value = date('m'); break; case 'current_day': $value = date('d'); break; case 'random_number': $value = mt_rand(100000, 999999); break; case 'contract_generate_time': $value = date('Y-m-d H:i:s'); break; default: \think\facade\Log::warning('不支持的系统函数', [ 'system_function' => $systemFunction ]); break; } return (string)$value; } catch (\Exception $e) { \think\facade\Log::error('从配置获取系统函数值失败', [ 'config' => $config, 'error' => $e->getMessage() ]); return ''; } } /** * 格式化字段值 * 对特定类型的字段值进行格式化处理 * * @param string $fieldName 字段名 * @param mixed $value 原始值 * @return string 格式化后的值 */ private function formatFieldValue($fieldName, $value) { if (empty($value)) { return ''; } // 根据字段名进行特殊处理 switch (true) { case str_contains($fieldName, 'date') || str_contains($fieldName, 'time'): // 日期时间字段格式化 if (is_numeric($value)) { return date('Y-m-d', $value); } elseif (strtotime($value)) { return date('Y-m-d', strtotime($value)); } break; case str_contains($fieldName, 'amount') || str_contains($fieldName, 'price'): // 金额字段格式化 return number_format((float)$value, 2); case str_contains($fieldName, 'phone'): // 手机号格式化(可以添加脱敏处理) return (string)$value; default: // 默认返回字符串 return (string)$value; } return (string)$value; } }