You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
7.7 KiB
244 lines
7.7 KiB
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | Niucloud-admin 企业快速开发的多应用管理平台
|
|
// +----------------------------------------------------------------------
|
|
// | 官方网址:https://www.niucloud.com
|
|
// +----------------------------------------------------------------------
|
|
// | niucloud团队 版权所有 开源版本可自由商用
|
|
// +----------------------------------------------------------------------
|
|
// | Author: Niucloud Team
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace app\job\contract;
|
|
|
|
use core\base\BaseJob;
|
|
use app\model\document\DocumentGenerateLog;
|
|
use app\model\contract\Contract;
|
|
use app\model\document\DocumentDataSourceConfig;
|
|
use app\service\admin\document\DocumentTemplateService;
|
|
use think\facade\Log;
|
|
|
|
/**
|
|
* 文档生成队列任务
|
|
* Class DocumentGenerateJob
|
|
* @package app\job\contract
|
|
*/
|
|
class DocumentGenerateJob extends BaseJob
|
|
{
|
|
/**
|
|
* 执行文档生成任务
|
|
* @param array $data 任务数据
|
|
* @return bool
|
|
*/
|
|
public function doJob(array $data): bool
|
|
{
|
|
$logId = $data['log_id'] ?? 0;
|
|
if (!$logId) {
|
|
Log::error('DocumentGenerateJob: log_id is required');
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
// 获取生成记录
|
|
$log = (new DocumentGenerateLog())->find($logId);
|
|
if (!$log) {
|
|
Log::error('DocumentGenerateJob: Generate log not found', ['log_id' => $logId]);
|
|
return false;
|
|
}
|
|
|
|
// 更新状态为处理中
|
|
$log->save(['status' => 'processing']);
|
|
|
|
// 执行文档生成
|
|
$result = $this->generateDocument($log);
|
|
|
|
if ($result['success']) {
|
|
// 生成成功
|
|
$log->save([
|
|
'status' => 'completed',
|
|
'generated_file' => $result['file_path'],
|
|
'completed_at' => time(),
|
|
'error_msg' => null
|
|
]);
|
|
|
|
Log::info('DocumentGenerateJob: Document generated successfully', [
|
|
'log_id' => $logId,
|
|
'file_path' => $result['file_path']
|
|
]);
|
|
} else {
|
|
// 生成失败
|
|
$log->save([
|
|
'status' => 'failed',
|
|
'error_msg' => $result['error'],
|
|
'completed_at' => time()
|
|
]);
|
|
|
|
Log::error('DocumentGenerateJob: Document generation failed', [
|
|
'log_id' => $logId,
|
|
'error' => $result['error']
|
|
]);
|
|
}
|
|
|
|
return $result['success'];
|
|
|
|
} catch (\Exception $e) {
|
|
// 异常处理
|
|
if (isset($log)) {
|
|
$log->save([
|
|
'status' => 'failed',
|
|
'error_msg' => $e->getMessage(),
|
|
'completed_at' => time()
|
|
]);
|
|
}
|
|
|
|
Log::error('DocumentGenerateJob: Exception occurred', [
|
|
'log_id' => $logId,
|
|
'error' => $e->getMessage(),
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 生成文档
|
|
* @param DocumentGenerateLog $log 生成记录
|
|
* @return array
|
|
*/
|
|
private function generateDocument(DocumentGenerateLog $log): array
|
|
{
|
|
try {
|
|
// 获取合同模板信息
|
|
$contract = (new Contract())->find($log['template_id']);
|
|
if (!$contract) {
|
|
return ['success' => false, 'error' => '合同模板不存在'];
|
|
}
|
|
|
|
if (empty($contract['file_path'])) {
|
|
return ['success' => false, 'error' => '合同模板文件不存在'];
|
|
}
|
|
|
|
// 解析填充数据
|
|
$fillData = json_decode($log['fill_data'], true);
|
|
if (!$fillData) {
|
|
return ['success' => false, 'error' => '填充数据格式错误'];
|
|
}
|
|
|
|
// 获取数据源配置
|
|
$dataSourceConfigs = (new DocumentDataSourceConfig())
|
|
->where('contract_id', $log['template_id'])
|
|
->select()
|
|
->toArray();
|
|
|
|
// 构建占位符替换数据
|
|
$replacements = $this->buildReplacements($dataSourceConfigs, $fillData);
|
|
|
|
// 使用DocumentTemplateService生成文档
|
|
$service = new DocumentTemplateService();
|
|
$result = $service->generateDocument([
|
|
'template_path' => $contract['file_path'],
|
|
'replacements' => $replacements,
|
|
'output_name' => $this->generateFileName($contract, $log)
|
|
]);
|
|
|
|
if ($result['success']) {
|
|
return [
|
|
'success' => true,
|
|
'file_path' => $result['file_path']
|
|
];
|
|
} else {
|
|
return [
|
|
'success' => false,
|
|
'error' => $result['error'] ?? '文档生成失败'
|
|
];
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
return [
|
|
'success' => false,
|
|
'error' => '文档生成异常:' . $e->getMessage()
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 构建占位符替换数据
|
|
* @param array $dataSourceConfigs 数据源配置
|
|
* @param array $fillData 填充数据
|
|
* @return array
|
|
*/
|
|
private function buildReplacements(array $dataSourceConfigs, array $fillData): array
|
|
{
|
|
$replacements = [];
|
|
|
|
foreach ($dataSourceConfigs as $config) {
|
|
$placeholder = $config['field_alias'] ?? $config['placeholder'] ?? '';
|
|
$fieldName = $config['field_name'] ?? '';
|
|
|
|
if (empty($placeholder)) {
|
|
continue;
|
|
}
|
|
|
|
// 从填充数据中获取值
|
|
$value = $fillData[$fieldName] ?? $config['default_value'] ?? '';
|
|
|
|
// 格式化值
|
|
$value = $this->formatValue($value, $config['field_type'] ?? 'string');
|
|
|
|
// 添加到替换数组
|
|
$replacements['{{' . $placeholder . '}}'] = $value;
|
|
}
|
|
|
|
return $replacements;
|
|
}
|
|
|
|
/**
|
|
* 格式化值
|
|
* @param mixed $value 原始值
|
|
* @param string $type 字段类型
|
|
* @return string
|
|
*/
|
|
private function formatValue($value, string $type): string
|
|
{
|
|
switch ($type) {
|
|
case 'datetime':
|
|
if (is_numeric($value)) {
|
|
return date('Y-m-d H:i:s', $value);
|
|
} elseif (strtotime($value)) {
|
|
return date('Y-m-d H:i:s', strtotime($value));
|
|
}
|
|
break;
|
|
case 'date':
|
|
if (is_numeric($value)) {
|
|
return date('Y-m-d', $value);
|
|
} elseif (strtotime($value)) {
|
|
return date('Y-m-d', strtotime($value));
|
|
}
|
|
break;
|
|
case 'decimal':
|
|
return number_format((float)$value, 2);
|
|
case 'integer':
|
|
return (string)(int)$value;
|
|
default:
|
|
return (string)$value;
|
|
}
|
|
|
|
return (string)$value;
|
|
}
|
|
|
|
/**
|
|
* 生成文件名
|
|
* @param Contract $contract 合同模板
|
|
* @param DocumentGenerateLog $log 生成记录
|
|
* @return string
|
|
*/
|
|
private function generateFileName(Contract $contract, DocumentGenerateLog $log): string
|
|
{
|
|
$timestamp = date('YmdHis');
|
|
$contractName = preg_replace('/[^\w\-_\.]/', '_', $contract['name']);
|
|
$userId = $log['user_id'];
|
|
|
|
return "{$contractName}_{$userId}_{$timestamp}.docx";
|
|
}
|
|
}
|
|
|