智慧教务系统
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.
 
 
 
 
 
 

287 lines
8.2 KiB

<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\admin\document;
use app\model\document\DocumentGenerateLog;
use app\model\contract\Contract;
use app\job\contract\DocumentGenerateJob;
use core\base\BaseAdminService;
use think\facade\Queue;
use think\facade\Db;
/**
* 文档生成服务类
* Class DocumentGenerateService
* @package app\service\admin\document
*/
class DocumentGenerateService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new DocumentGenerateLog();
}
/**
* 获取生成记录分页列表
* @param array $where
* @return array
*/
public function getPage(array $where = []): array
{
$field = 'id, user_type, template_id, user_id, generated_file, status, error_msg, created_at, completed_at';
$order = 'created_at desc';
$search_model = $this->model
->withSearch(['template_id', 'user_id', 'user_type', 'status'], $where)
->field($field)
->order($order);
$list = $this->pageQuery($search_model, $where);
// 关联合同信息
if (!empty($list['data'])) {
$template_ids = array_unique(array_column($list['data'], 'template_id'));
$contracts = (new Contract())->whereIn('id', $template_ids)->column('name', 'id');
foreach ($list['data'] as &$item) {
$item['template_name'] = $contracts[$item['template_id']] ?? '';
$item['user_type_text'] = $item['user_type'] == 1 ? '内部员工' : '外部会员';
$item['status_text'] = $this->getStatusText($item['status']);
}
}
return $list;
}
/**
* 获取生成记录信息
* @param int $id
* @return array
*/
public function getInfo(int $id): array
{
$field = 'id, user_type, template_id, user_id, fill_data, generated_file, status, error_msg, created_at, completed_at';
$info = $this->model->field($field)->where([['id', '=', $id]])->findOrEmpty()->toArray();
if (empty($info)) {
throw new \Exception('DATA_NOT_EXIST');
}
// 获取合同信息
if (!empty($info['template_id'])) {
$contract = (new Contract())->where('id', $info['template_id'])->field('id, name')->findOrEmpty();
$info['template_name'] = $contract['name'] ?? '';
}
// 解析填充数据
$info['fill_data'] = json_decode($info['fill_data'], true) ?: [];
$info['user_type_text'] = $info['user_type'] == 1 ? '内部员工' : '外部会员';
$info['status_text'] = $this->getStatusText($info['status']);
return $info;
}
/**
* 生成文档
* @param array $data
* @return array
*/
public function generate(array $data): array
{
// 验证模板是否存在
$contract = (new Contract())->find($data['template_id']);
if (!$contract) {
throw new \Exception('合同模板不存在');
}
// 创建生成记录
$logData = [
'user_type' => $data['user_type'],
'template_id' => $data['template_id'],
'user_id' => $data['user_id'],
'fill_data' => json_encode($data['fill_data']),
'status' => 'pending',
'created_at' => time()
];
$log = $this->model->create($logData);
if (!$log) {
throw new \Exception('创建生成记录失败');
}
// 推送到队列
Queue::push(DocumentGenerateJob::class, ['log_id' => $log->id]);
return [
'log_id' => $log->id,
'status' => 'pending'
];
}
/**
* 重新生成文档
* @param int $id
* @return array
*/
public function regenerate(int $id): array
{
$log = $this->model->find($id);
if (!$log) {
throw new \Exception('生成记录不存在');
}
// 重置状态
$log->save([
'status' => 'pending',
'error_msg' => null,
'completed_at' => 0
]);
// 重新推送到队列
Queue::push(DocumentGenerateJob::class, ['log_id' => $id]);
return [
'log_id' => $id,
'status' => 'pending'
];
}
/**
* 下载生成的文档
* @param int $id
* @return array
*/
public function download(int $id): array
{
$log = $this->model->find($id);
if (!$log) {
return ['success' => false, 'error' => '生成记录不存在'];
}
if ($log['status'] !== 'completed') {
return ['success' => false, 'error' => '文档尚未生成完成'];
}
if (empty($log['generated_file']) || !file_exists($log['generated_file'])) {
return ['success' => false, 'error' => '文件不存在'];
}
return [
'success' => true,
'file_path' => $log['generated_file'],
'file_name' => basename($log['generated_file'])
];
}
/**
* 删除生成记录
* @param int $id
* @return bool
*/
public function del(int $id): bool
{
$info = $this->model->findOrEmpty($id);
if ($info->isEmpty()) {
throw new \Exception('DATA_NOT_EXIST');
}
// 删除生成的文件
if (!empty($info['generated_file']) && file_exists($info['generated_file'])) {
unlink($info['generated_file']);
}
$res = $info->delete();
if (!$res) {
throw new \Exception('DELETE_FAIL');
}
return true;
}
/**
* 批量删除生成记录
* @param array $ids
* @return bool
*/
public function batchDel(array $ids): bool
{
if (empty($ids)) {
throw new \Exception('请选择要删除的记录');
}
Db::startTrans();
try {
foreach ($ids as $id) {
$this->del($id);
}
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
throw $e;
}
}
/**
* 获取生成统计信息
* @param int $templateId
* @return array
*/
public function getStats(int $templateId = 0): array
{
$where = [];
if ($templateId) {
$where[] = ['template_id', '=', $templateId];
}
$stats = [
'total' => $this->model->where($where)->count(),
'pending' => $this->model->where($where)->where('status', 'pending')->count(),
'processing' => $this->model->where($where)->where('status', 'processing')->count(),
'completed' => $this->model->where($where)->where('status', 'completed')->count(),
'failed' => $this->model->where($where)->where('status', 'failed')->count(),
];
return $stats;
}
/**
* 预览文档数据
* @param int $templateId
* @param array $fillData
* @return array
*/
public function preview(int $templateId, array $fillData): array
{
// 获取数据源配置
$dataSourceService = new DocumentDataSourceService();
return $dataSourceService->preview($templateId, $fillData);
}
/**
* 获取状态文本
* @param string $status
* @return string
*/
private function getStatusText(string $status): string
{
$statusMap = [
'pending' => '等待处理',
'processing' => '处理中',
'completed' => '已完成',
'failed' => '失败'
];
return $statusMap[$status] ?? '未知状态';
}
}