审计内容取证单生成

This commit is contained in:
2026-01-16 17:44:26 +08:00
parent 378d37f590
commit ae1e150d1c
4 changed files with 299 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
package com.gxwebsoft.ai.controller;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.ai.dto.AuditEvidenceRequest;
import com.gxwebsoft.ai.service.AuditEvidenceService;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 审计取证单控制器
*/
@Slf4j
@Tag(name = "审计取证单")
@RestController
@RequestMapping("/api/ai/auditEvidence")
public class AuditEvidenceController extends BaseController {
@Autowired
private AuditEvidenceService auditEvidenceService;
/**
* 生成审计取证单
*/
@Operation(summary = "生成审计取证单")
@PostMapping("/generate")
public ApiResult<?> generateAuditEvidence(@RequestBody AuditEvidenceRequest request) {
try {
final User loginUser = getLoginUser();
request.setUserName(loginUser.getUsername());
log.info("接收到审计取证单生成请求 - 用户: {}, 项目: {}", request.getUserName(), request.getProjectName());
JSONObject result = auditEvidenceService.generateAuditEvidence(request);
if (Boolean.TRUE.equals(result.getBoolean("success"))) {
return success(result);
} else {
return fail(result.getString("error") != null ? result.getString("error") : "生成审计取证单失败");
}
} catch (Exception e) {
log.error("生成审计取证单异常", e);
return fail("生成审计取证单异常: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,31 @@
package com.gxwebsoft.ai.dto;
import lombok.Data;
@Data
public class AuditEvidenceRequest {
// 基础信息
private String caseIndex; // 案引号
private String projectName; // 项目名称
private String auditedTarget; // 被审计单位或个人
private String auditMatter; // 审计事项
private String summaryTitle; // 标题
private String auditRecord; // 审计记录
private String auditFinding; // 审计发现
private String evidenceBasis; // 定性依据
private String handling; // 处理
private String suggestion; // 建议
private String attachment; // 附件
private String auditors; // 审计人员
private String compileDate; // 编制日期
private String providerOpinion; // 证据提供单位意见
private String providerDate; // 证据提供日期
private String attachmentPages; // 附件页数
private String feedbackDeadline; // 反馈期限
// 历史内容(用于工作流生成)
private String history;
// 用户信息
private String userName;
}

View File

@@ -0,0 +1,11 @@
package com.gxwebsoft.ai.service;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.ai.dto.AuditEvidenceRequest;
public interface AuditEvidenceService {
/**
* 生成审计取证单
*/
JSONObject generateAuditEvidence(AuditEvidenceRequest request);
}

View File

@@ -0,0 +1,204 @@
package com.gxwebsoft.ai.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.ai.dto.AuditEvidenceRequest;
import com.gxwebsoft.ai.service.AuditEvidenceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import java.util.Date;
@Slf4j
@Service
public class AuditEvidenceServiceImpl implements AuditEvidenceService {
// Dify工作流配置
private static final String DIFY_WORKFLOW_URL = "http://1.14.159.185:8180/v1/workflows/run";
private static final String DIFY_WORKFLOW_TOKEN = "Bearer app-DEhvF537rQfy6MvH9KeBKUVj";
@Override
public JSONObject generateAuditEvidence(AuditEvidenceRequest request) {
log.info("开始生成审计取证单 - 用户: {}, 项目: {}", request.getUserName(), request.getProjectName());
long startTime = System.currentTimeMillis();
try {
// 1. 构建完整上下文
String knowledgeContext = buildCompleteContext(request);
// 2. 构建工作流请求
JSONObject requestBody = buildWorkflowRequest(knowledgeContext, request.getUserName());
// 3. 调用Dify工作流
JSONObject result = callWorkflow(requestBody, "审计取证单");
// 4. 添加处理时间等信息
result.put("success", true);
result.put("processing_time", (System.currentTimeMillis() - startTime) + "ms");
result.put("generated_time", new Date().toString());
log.info("审计取证单生成成功 - 处理时间: {}ms", (System.currentTimeMillis() - startTime));
return result;
} catch (Exception e) {
log.error("生成审计取证单失败", e);
return buildErrorResponse("生成审计取证单失败: " + e.getMessage());
}
}
/**
* 构建完整上下文
*/
private String buildCompleteContext(AuditEvidenceRequest request) {
StringBuilder context = new StringBuilder();
// 1. 审计取证单生成要求
context.append("## 审计取证单生成要求\n");
context.append("请基于以下信息生成一份完整的审计取证单。审计取证单是审计工作中的重要文书,用于记录审计发现的问题、事实依据、处理建议等。\n\n");
// 2. 输出格式要求
context.append("## 输出格式要求\n");
context.append("请严格按照以下JSON格式输出不要包含任何额外文本\n");
context.append("{\n");
context.append(" \"caseIndex\": \"案件编号,如审计-[2024]-001\",\n");
context.append(" \"projectName\": \"具体项目名称\",\n");
context.append(" \"auditedTarget\": \"被审计单位或个人\",\n");
context.append(" \"auditMatter\": \"审计事项描述\",\n");
context.append(" \"summaryTitle\": \"核心问题标题\",\n");
context.append(" \"auditRecord\": \"客观的审计核查事实记录,包括时间、地点、主体、行为、数据等\",\n");
context.append(" \"auditFinding\": \"审计发现的具体问题、性质及影响\",\n");
context.append(" \"evidenceBasis\": \"定性依据,引用法规、制度或合同条款\",\n");
context.append(" \"handling\": \"拟采取的处理措施\",\n");
context.append(" \"suggestion\": \"改进或整改建议\",\n");
context.append(" \"attachment\": \"列示随附的证明材料只出现材料中文名称不要出现FileId不要出现网站链接\",\n");
context.append(" \"auditors\": \"审计人员姓名\",\n");
context.append(" \"compileDate\": \"编制日期格式YYYY-MM-DD\",\n");
context.append(" \"providerOpinion\": \"证据提供单位或个人意见\",\n");
context.append(" \"providerDate\": \"证据提供日期格式YYYY-MM-DD\",\n");
context.append(" \"attachmentPages\": \"附件页数2\",\n");
context.append(" \"feedbackDeadline\": \"反馈期限5个工作日内\"\n");
context.append("}\n");
// 3. 字段内容要求
context.append("## 字段内容具体要求\n");
context.append("1. **审计记录**:客观记录审计核查的具体事实,包括时间、地点、主体、行为、数据等,避免主观评价。\n");
context.append("2. **审计发现**:基于审计记录提出具体问题性质,先事实后定性,避免夸大。\n");
context.append("3. **定性依据**必须引用具体的法规、制度或合同条款格式如根据《XX法》第XX条规定...\n");
context.append("4. **处理措施**:针对发现的问题提出具体的处理措施,要有可操作性。\n");
context.append("5. **建议**:针对问题根源提出改进或整改建议,要具体可行。\n");
context.append("6. **日期**所有日期必须使用YYYY-MM-DD格式。\n\n");
// 4. 用户提供的基础信息
if (StrUtil.isNotBlank(request.getProjectName()) ||
StrUtil.isNotBlank(request.getAuditedTarget()) ||
StrUtil.isNotBlank(request.getAuditMatter())) {
context.append("## 用户提供的基础信息\n");
if (StrUtil.isNotBlank(request.getProjectName())) {
context.append("- 项目名称:").append(request.getProjectName()).append("\n");
}
if (StrUtil.isNotBlank(request.getAuditedTarget())) {
context.append("- 被审计单位/个人:").append(request.getAuditedTarget()).append("\n");
}
if (StrUtil.isNotBlank(request.getAuditMatter())) {
context.append("- 审计事项:").append(request.getAuditMatter()).append("\n");
}
if (StrUtil.isNotBlank(request.getSummaryTitle())) {
context.append("- 标题:").append(request.getSummaryTitle()).append("\n");
}
context.append("\n");
}
// 5. 历史内容(如果存在)
if (StrUtil.isNotBlank(request.getHistory())) {
context.append("## 历史内容参考\n");
context.append("以下是与本次审计相关的历史内容,请参考但不完全照搬:\n");
context.append(request.getHistory()).append("\n\n");
}
// 6. 额外要求
context.append("## 额外要求\n");
context.append("1. 内容必须真实、准确、完整,符合审计文书规范\n");
context.append("2. 语言表述要严谨、客观、规范\n");
context.append("3. 各字段内容要相互衔接,逻辑清晰\n");
context.append("4. 如果某些信息不明确,请根据审计常规进行合理补充\n");
log.debug("构建的上下文长度: {}", context.length());
return context.toString();
}
/**
* 构建工作流请求
*/
private JSONObject buildWorkflowRequest(String knowledge, String userName) {
JSONObject requestBody = new JSONObject();
JSONObject inputs = new JSONObject();
inputs.put("knowledge", knowledge);
requestBody.put("inputs", inputs);
requestBody.put("response_mode", "blocking");
requestBody.put("user", userName);
requestBody.put("timeout", 300); // 5分钟超时
return requestBody;
}
/**
* 调用工作流
*/
private JSONObject callWorkflow(JSONObject requestBody, String workflowName) {
try {
log.info("调用{}工作流,请求体长度: {}", workflowName, requestBody.toString().length());
String result = HttpUtil.createPost(DIFY_WORKFLOW_URL)
.header("Authorization", DIFY_WORKFLOW_TOKEN)
.header("Content-Type", "application/json")
.body(requestBody.toString())
.timeout(5 * 60 * 1000) // 5分钟
.execute()
.body();
log.info("{}工作流返回结果长度: {}", workflowName, result.length());
JSONObject jsonResponse = JSONObject.parseObject(result);
// 提取输出文本
String outputText = jsonResponse.getJSONObject("data")
.getJSONObject("outputs")
.getString("result");
if (StrUtil.isBlank(outputText)) {
log.warn("{}工作流返回结果为空", workflowName);
return new JSONObject();
}
// 解析为JSON对象
JSONObject auditEvidence = JSONObject.parseObject(outputText);
log.info("成功解析{}工作流返回数据", workflowName);
return auditEvidence;
} catch (Exception e) {
log.error("调用{}工作流失败", workflowName, e);
throw new RuntimeException("调用" + workflowName + "工作流失败: " + e.getMessage(), e);
}
}
/**
* 构建错误响应
*/
private JSONObject buildErrorResponse(String errorMessage) {
JSONObject result = new JSONObject();
result.put("success", false);
result.put("error", errorMessage);
result.put("timestamp", System.currentTimeMillis());
return result;
}
}