审计内容取证单生成
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
31
src/main/java/com/gxwebsoft/ai/dto/AuditEvidenceRequest.java
Normal file
31
src/main/java/com/gxwebsoft/ai/dto/AuditEvidenceRequest.java
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user