新增企业信息、知识库、审计报告生成功能
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package com.gxwebsoft.ai.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "aliyun.knowledge-base")
|
||||
public class KnowledgeBaseConfig {
|
||||
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
private String workspaceId;
|
||||
|
||||
}
|
||||
12
src/main/java/com/gxwebsoft/ai/config/TemplateConfig.java
Normal file
12
src/main/java/com/gxwebsoft/ai/config/TemplateConfig.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.gxwebsoft.ai.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "ai.template")
|
||||
public class TemplateConfig {
|
||||
private String wordTemplatePath;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.gxwebsoft.ai.constants;
|
||||
|
||||
public class KnowledgeBaseConstants {
|
||||
|
||||
public static final String[] KEY_WORDS = {
|
||||
"",
|
||||
"审计依据 法律法规 审计业务约定书 经济责任审计管理办法 中共中央办公厅 国务院办公厅 党政主要领导干部审计规定 国家法规 公司管理制度 年度工作目标 党政主要领导干部经济责任审计规定",
|
||||
"审计目标 经济责任审计目标 资产负债损益真实性 合法性 效益性 经济指标完成情况 重大决策执行 遵守财经法规 国有资产保值增值 经济责任评价 任职期间履职评价 责任界定 业绩评价",
|
||||
"审计对象 审计范围 被审计领导干部 [职务] [姓名] 任职期间 [开始日期]至[结束日期] 职务任期 重大问题追溯 重要事项延伸 审计时限 下属子公司 代管企业",
|
||||
"被审计单位基本情况 单位概况 组织机构 人员结构 财务会计政策 合并口径财务数据 资产总额 负债总额 营业收入 利润 内部控制制度 子公司 代管企业 职能部门设置 合并财务报表",
|
||||
"审计内容 审计重点 贯彻执行经济方针 重大决策执行 发展战略 年度目标完成 法人治理结构 内部控制 财务真实性 风险管控 党风廉政建设 以往审计整改 三重一大经济决策 资产管理 采购管理 债权债务",
|
||||
"审计风险 证据不充分 评价不客观 内部控制失效 法律法规变化 风险应对策略 审计证据充分性 评价客观性 内部控制审查 法规政策跟踪 重要性水平",
|
||||
"审计方法 穿行测试 趋势分析 比率分析 访谈法 数据分析 分析性程序 检查 监盘 观察 询问 函证 计算 重新执行",
|
||||
"审计步骤 时间安排 准备阶段 实施阶段 报告阶段 归档阶段 审计人员安排 资料收集 实质性程序 审计报告编写 交换意见 审计归档 进点会 进度表",
|
||||
"审计组织实施 审计组人员分工 职责分配 审计工作计划 前期调研 审前培训 实地审计 质量控制 内部培训 沟通协调 分级复核 集体讨论 重大事项汇报 里程碑事件清单 审计工作组 项目负责人 主审"
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package com.gxwebsoft.ai.controller;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.poi.openxml4j.util.ZipSecureFile;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
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;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.gxwebsoft.ai.config.TemplateConfig;
|
||||
import com.gxwebsoft.ai.dto.AuditReportRequest;
|
||||
import com.gxwebsoft.ai.dto.KnowledgeBaseRequest;
|
||||
import com.gxwebsoft.ai.enums.AuditReportEnum;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import com.gxwebsoft.common.system.entity.User;
|
||||
|
||||
import cn.afterturn.easypoi.word.WordExportUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
/**
|
||||
* 审计报告控制器
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
@Tag(name = "审计报告")
|
||||
@RestController
|
||||
@RequestMapping("/api/ai/auditReport")
|
||||
public class AuditReportController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private TemplateConfig templateConfig;
|
||||
|
||||
@Autowired
|
||||
private KnowledgeBaseController knowledgeBaseController;
|
||||
|
||||
private String invok(String query, String knowledge, String history, String suggestion, String userName) {
|
||||
// 构建请求体
|
||||
JSONObject requestBody = new JSONObject();
|
||||
JSONObject inputs = new JSONObject();
|
||||
inputs.put("query", query);
|
||||
inputs.put("knowledge", knowledge);
|
||||
inputs.put("history", history);
|
||||
inputs.put("suggestion", suggestion);
|
||||
|
||||
requestBody.put("inputs", inputs);
|
||||
requestBody.put("response_mode", "blocking");
|
||||
requestBody.put("user", userName);
|
||||
|
||||
// 发送 POST 请求
|
||||
String result = HttpUtil.createPost("http://1.14.159.185:8180/v1/workflows/run")
|
||||
.header("Authorization", "Bearer app-d7Ok9FECVZG2Ybw9wpg7tGu9")
|
||||
.header("Content-Type", "application/json")
|
||||
.body(requestBody.toString())
|
||||
.timeout(600000)
|
||||
.execute()
|
||||
.body();
|
||||
// 解析返回的JSON字符串
|
||||
JSONObject jsonResponse = JSONObject.parseObject(result);
|
||||
// 获取data字段
|
||||
JSONObject data = jsonResponse.getJSONObject("data");
|
||||
// 获取outputs字段
|
||||
JSONObject outputs = data.getJSONObject("outputs");
|
||||
// 获取outputs中的result字符串
|
||||
String resultStr = outputs.getString("result");
|
||||
return resultStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成审计报告-单一模块
|
||||
*/
|
||||
@Operation(summary = "生成审计报告-单一模块")
|
||||
@PostMapping("/generate")
|
||||
public ApiResult<?> generateAuditReport(@RequestBody AuditReportRequest req) {
|
||||
final User loginUser = getLoginUser();
|
||||
|
||||
KnowledgeBaseRequest knowledgeBaseRequest = new KnowledgeBaseRequest();
|
||||
knowledgeBaseRequest.setKbId(req.getKbId());
|
||||
knowledgeBaseRequest.setFormCommit((req.getFormCommit() > 10) ? req.getFormCommit() / 10 : req.getFormCommit());
|
||||
String knowledge = knowledgeBaseController.query(knowledgeBaseRequest).getData().toString();
|
||||
|
||||
String query = AuditReportEnum.getByCode(req.getFormCommit()).getDesc();
|
||||
String ret = this.invok(query, knowledge, req.getHistory(), req.getSuggestion(), loginUser.getUsername());
|
||||
|
||||
return success(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成并下载审计报告
|
||||
*/
|
||||
@Operation(summary = "生成并下载审计报告")
|
||||
@PostMapping("/download")
|
||||
public void downloadAuditReport(@RequestBody AuditReportRequest req, HttpServletResponse response) {
|
||||
// 保存原始的安全阈值
|
||||
double originalMinInflateRatio = ZipSecureFile.getMinInflateRatio();
|
||||
|
||||
try {
|
||||
// 降低Zip bomb检测的阈值,解决模板文件的安全检测问题
|
||||
ZipSecureFile.setMinInflateRatio(0.001);
|
||||
|
||||
// 准备模板数据
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(AuditReportEnum.AUDIT_TITLE.getCode().toString(), req.getFrom0());
|
||||
map.put(AuditReportEnum.AUDIT_BASIS.getCode().toString(), req.getFrom1());
|
||||
map.put(AuditReportEnum.AUDIT_OBJECTIVE.getCode().toString(), req.getFrom2());
|
||||
map.put(AuditReportEnum.AUDIT_SCOPE.getCode().toString(), req.getFrom3());
|
||||
map.put(AuditReportEnum.UNIT_OVERVIEW.getCode().toString(), req.getFrom41());
|
||||
map.put(AuditReportEnum.ORG_AND_PERSONNEL.getCode().toString(), req.getFrom42());
|
||||
map.put(AuditReportEnum.AUDIT_CONTENT_METHODS.getCode().toString(), req.getFrom5());
|
||||
|
||||
// 使用Easypoi的Word模板功能
|
||||
XWPFDocument document = WordExportUtil.exportWord07(templateConfig.getWordTemplatePath(), map);
|
||||
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=audit_report.docx");
|
||||
|
||||
// 输出到响应流
|
||||
OutputStream out = response.getOutputStream();
|
||||
document.write(out);
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("生成审计报告失败", e);
|
||||
} finally {
|
||||
// 恢复原始的安全阈值
|
||||
ZipSecureFile.setMinInflateRatio(originalMinInflateRatio);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.gxwebsoft.ai.controller;
|
||||
|
||||
import com.aliyun.bailian20231229.Client;
|
||||
import com.aliyun.bailian20231229.models.RetrieveResponse;
|
||||
import com.aliyun.bailian20231229.models.RetrieveResponseBody.RetrieveResponseBodyDataNodes;
|
||||
import com.gxwebsoft.ai.config.KnowledgeBaseConfig;
|
||||
import com.gxwebsoft.ai.constants.KnowledgeBaseConstants;
|
||||
import com.gxwebsoft.ai.factory.KnowledgeBaseClientFactory;
|
||||
import com.gxwebsoft.ai.util.KnowledgeBaseRetrieve;
|
||||
import com.gxwebsoft.ai.dto.KnowledgeBaseRequest;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Tag(name = "知识库")
|
||||
@RestController
|
||||
@RequestMapping("/api/ai/knowledgeBase")
|
||||
public class KnowledgeBaseController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private KnowledgeBaseConfig config;
|
||||
|
||||
@Autowired
|
||||
private KnowledgeBaseClientFactory clientFactory;
|
||||
|
||||
@Operation(summary = "查询知识库")
|
||||
@GetMapping("/query")
|
||||
public ApiResult<?> query(KnowledgeBaseRequest req) {
|
||||
Set<String> ret = new LinkedHashSet<>();
|
||||
String workspaceId = config.getWorkspaceId();
|
||||
List<String> keyWords = Arrays.asList(KnowledgeBaseConstants.KEY_WORDS);
|
||||
String indexId = req.getKbId();
|
||||
String query = StrUtil.isEmpty(req.getQuery()) ? keyWords.get(req.getFormCommit()) : req.getQuery();
|
||||
Integer topK = req.getTopK() == null ? 10 : req.getTopK();
|
||||
|
||||
try {
|
||||
Client client = clientFactory.createClient();
|
||||
RetrieveResponse resp = KnowledgeBaseRetrieve.retrieveIndex(client, workspaceId, indexId, query);
|
||||
for (RetrieveResponseBodyDataNodes node : resp.getBody().getData().getNodes()) {
|
||||
ret.add(node.getText());
|
||||
if (ret.size() >= topK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
return success(ret);
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/gxwebsoft/ai/dto/AuditReportRequest.java
Normal file
42
src/main/java/com/gxwebsoft/ai/dto/AuditReportRequest.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.gxwebsoft.ai.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AuditReportRequest{
|
||||
|
||||
@Schema(description = "审计标题")
|
||||
private String from0;
|
||||
|
||||
@Schema(description = "审计依据")
|
||||
private String from1;
|
||||
|
||||
@Schema(description = "审计目标")
|
||||
private String from2;
|
||||
|
||||
@Schema(description = "审计对象和范围")
|
||||
private String from3;
|
||||
|
||||
@Schema(description = "被审计单位基本情况-单位概况")
|
||||
private String from41;
|
||||
|
||||
@Schema(description = "被审计单位基本情况-机构和人员相关情况")
|
||||
private String from42;
|
||||
|
||||
@Schema(description = "审计内容和重点及审计方法")
|
||||
private String from5;
|
||||
|
||||
@Schema(description = "知识库ID")
|
||||
private String kbId;
|
||||
|
||||
@Schema(description = "生成模块:AuditReportEnum.code")
|
||||
private Integer formCommit;
|
||||
|
||||
@Schema(description = "历史内容")
|
||||
private String history;
|
||||
|
||||
@Schema(description = "修改建议")
|
||||
private String suggestion;
|
||||
|
||||
}
|
||||
20
src/main/java/com/gxwebsoft/ai/dto/KnowledgeBaseRequest.java
Normal file
20
src/main/java/com/gxwebsoft/ai/dto/KnowledgeBaseRequest.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package com.gxwebsoft.ai.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class KnowledgeBaseRequest {
|
||||
|
||||
@Schema(description = "知识库ID")
|
||||
private String kbId;
|
||||
|
||||
@Schema(description = "召回内容")
|
||||
private String query;
|
||||
|
||||
@Schema(description = "召回模块(1~9)")
|
||||
private Integer formCommit;
|
||||
|
||||
@Schema(description = "返回TOP切片数量")
|
||||
private Integer topK;
|
||||
}
|
||||
45
src/main/java/com/gxwebsoft/ai/enums/AuditReportEnum.java
Normal file
45
src/main/java/com/gxwebsoft/ai/enums/AuditReportEnum.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package com.gxwebsoft.ai.enums;
|
||||
|
||||
public enum AuditReportEnum {
|
||||
|
||||
AUDIT_TITLE(0, "审计标题"),
|
||||
AUDIT_BASIS(1, "审计依据"),
|
||||
AUDIT_OBJECTIVE(2, "审计目标"),
|
||||
AUDIT_SCOPE(3, "审计对象和范围"),
|
||||
UNIT_OVERVIEW(41, "被审计单位基本情况-单位概况"),
|
||||
ORG_AND_PERSONNEL(42, "被审计单位基本情况-机构和人员相关情况"),
|
||||
AUDIT_CONTENT_METHODS(5, "审计内容和重点及审计方法");
|
||||
|
||||
private final Integer code;
|
||||
private final String desc;
|
||||
|
||||
AuditReportEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public static AuditReportEnum getByCode(Integer code) {
|
||||
for (AuditReportEnum value : values()) {
|
||||
if (value.code.equals(code)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据代码获取描述信息
|
||||
*/
|
||||
public static String getDescByCode(Integer code) {
|
||||
AuditReportEnum enumValue = getByCode(code);
|
||||
return enumValue != null ? enumValue.getDesc() : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.gxwebsoft.ai.factory;
|
||||
|
||||
import com.aliyun.bailian20231229.Client;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import com.gxwebsoft.ai.config.KnowledgeBaseConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class KnowledgeBaseClientFactory {
|
||||
|
||||
@Autowired
|
||||
private KnowledgeBaseConfig config;
|
||||
|
||||
public Client createClient() throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config authConfig = new com.aliyun.teaopenapi.models.Config()
|
||||
.setAccessKeyId(config.getAccessKeyId())
|
||||
.setAccessKeySecret(config.getAccessKeySecret());
|
||||
// 下方接入地址以公有云的公网接入地址为例,可按需更换接入地址。
|
||||
authConfig.endpoint = "bailian.cn-beijing.aliyuncs.com";
|
||||
return new com.aliyun.bailian20231229.Client(authConfig);
|
||||
}
|
||||
}
|
||||
384
src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseCreate.java
Normal file
384
src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseCreate.java
Normal file
@@ -0,0 +1,384 @@
|
||||
package com.gxwebsoft.ai.util;
|
||||
|
||||
import com.aliyun.bailian20231229.models.*;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 创建知识库
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
public class KnowledgeBaseCreate {
|
||||
|
||||
String ALIBABA_CLOUD_ACCESS_KEY_ID = "LTAI5tD5YRKuxWz6Eg7qrM4P";
|
||||
String ALIBABA_CLOUD_ACCESS_KEY_SECRET = "bO8TBDXflOwbtSKimPpG8XrJnyzgTk";
|
||||
String WORKSPACE_ID = "llm-4pf5auwewoz34zqu";
|
||||
|
||||
/**
|
||||
* 检查并提示设置必要的环境变量。
|
||||
*
|
||||
* @return true 如果所有必需的环境变量都已设置,否则 false
|
||||
*/
|
||||
public static boolean checkEnvironmentVariables() {
|
||||
Map<String, String> requiredVars = new HashMap<>();
|
||||
requiredVars.put("ALIBABA_CLOUD_ACCESS_KEY_ID", "阿里云访问密钥ID");
|
||||
requiredVars.put("ALIBABA_CLOUD_ACCESS_KEY_SECRET", "阿里云访问密钥密码");
|
||||
requiredVars.put("WORKSPACE_ID", "阿里云百炼业务空间ID");
|
||||
|
||||
List<String> missingVars = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : requiredVars.entrySet()) {
|
||||
String value = System.getenv(entry.getKey());
|
||||
if (value == null || value.isEmpty()) {
|
||||
missingVars.add(entry.getKey());
|
||||
System.out.println("错误:请设置 " + entry.getKey() + " 环境变量 (" + entry.getValue() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
return missingVars.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算文档的MD5值。
|
||||
*
|
||||
* @param filePath 文档本地路径
|
||||
* @return 文档的MD5值
|
||||
* @throws Exception 如果计算过程中发生错误
|
||||
*/
|
||||
public static String calculateMD5(String filePath) throws Exception {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
try (FileInputStream fis = new FileInputStream(filePath)) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = fis.read(buffer)) != -1) {
|
||||
md.update(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : md.digest()) {
|
||||
sb.append(String.format("%02x", b & 0xff));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文档大小(以字节为单位)。
|
||||
*
|
||||
* @param filePath 文档本地路径
|
||||
* @return 文档大小(以字节为单位)
|
||||
*/
|
||||
public static String getFileSize(String filePath) {
|
||||
File file = new File(filePath);
|
||||
long fileSize = file.length();
|
||||
return String.valueOf(fileSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化客户端(Client)。
|
||||
*
|
||||
* @return 配置好的客户端对象
|
||||
*/
|
||||
public static com.aliyun.bailian20231229.Client createClient() throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
|
||||
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
|
||||
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
|
||||
// 下方接入地址以公有云的公网接入地址为例,可按需更换接入地址。
|
||||
config.endpoint = "bailian.cn-beijing.aliyuncs.com";
|
||||
return new com.aliyun.bailian20231229.Client(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请文档上传租约。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param categoryId 类目ID
|
||||
* @param fileName 文档名称
|
||||
* @param fileMd5 文档的MD5值
|
||||
* @param fileSize 文档大小(以字节为单位)
|
||||
* @param workspaceId 业务空间ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static ApplyFileUploadLeaseResponse applyLease(com.aliyun.bailian20231229.Client client, String categoryId,
|
||||
String fileName, String fileMd5, String fileSize, String workspaceId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.ApplyFileUploadLeaseRequest applyFileUploadLeaseRequest = new com.aliyun.bailian20231229.models.ApplyFileUploadLeaseRequest();
|
||||
applyFileUploadLeaseRequest.setFileName(fileName);
|
||||
applyFileUploadLeaseRequest.setMd5(fileMd5);
|
||||
applyFileUploadLeaseRequest.setSizeInBytes(fileSize);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
ApplyFileUploadLeaseResponse applyFileUploadLeaseResponse = null;
|
||||
applyFileUploadLeaseResponse = client.applyFileUploadLeaseWithOptions(categoryId, workspaceId,
|
||||
applyFileUploadLeaseRequest, headers, runtime);
|
||||
return applyFileUploadLeaseResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文档到临时存储。
|
||||
*
|
||||
* @param preSignedUrl 上传租约中的 URL
|
||||
* @param headers 上传请求的头部
|
||||
* @param filePath 文档本地路径
|
||||
* @throws Exception 如果上传过程中发生错误
|
||||
*/
|
||||
public static void uploadFile(String preSignedUrl, Map<String, String> headers, String filePath) throws Exception {
|
||||
File file = new File(filePath);
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
throw new IllegalArgumentException("文件不存在或不是普通文件: " + filePath);
|
||||
}
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
URL url = new URL(preSignedUrl);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("PUT");
|
||||
conn.setDoOutput(true);
|
||||
|
||||
// 设置上传请求头
|
||||
conn.setRequestProperty("X-bailian-extra", headers.get("X-bailian-extra"));
|
||||
conn.setRequestProperty("Content-Type", headers.get("Content-Type"));
|
||||
|
||||
// 分块读取并上传文档
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = fis.read(buffer)) != -1) {
|
||||
conn.getOutputStream().write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
int responseCode = conn.getResponseCode();
|
||||
if (responseCode != 200) {
|
||||
throw new RuntimeException("上传失败: " + responseCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文档添加到类目中。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param leaseId 租约ID
|
||||
* @param parser 用于文档的解析器
|
||||
* @param categoryId 类目ID
|
||||
* @param workspaceId 业务空间ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static AddFileResponse addFile(com.aliyun.bailian20231229.Client client, String leaseId, String parser,
|
||||
String categoryId, String workspaceId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.AddFileRequest addFileRequest = new com.aliyun.bailian20231229.models.AddFileRequest();
|
||||
addFileRequest.setLeaseId(leaseId);
|
||||
addFileRequest.setParser(parser);
|
||||
addFileRequest.setCategoryId(categoryId);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.addFileWithOptions(workspaceId, addFileRequest, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询文档的基本信息。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param fileId 文档ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static DescribeFileResponse describeFile(com.aliyun.bailian20231229.Client client, String workspaceId,
|
||||
String fileId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.describeFileWithOptions(workspaceId, fileId, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在阿里云百炼服务中创建知识库(初始化)。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param fileId 文档ID
|
||||
* @param name 知识库名称
|
||||
* @param structureType 知识库的数据类型
|
||||
* @param sourceType 应用数据的数据类型,支持类目类型和文档类型
|
||||
* @param sinkType 知识库的向量存储类型
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static CreateIndexResponse createIndex(com.aliyun.bailian20231229.Client client, String workspaceId,
|
||||
String fileId, String name, String structureType, String sourceType, String sinkType) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.CreateIndexRequest createIndexRequest = new com.aliyun.bailian20231229.models.CreateIndexRequest();
|
||||
createIndexRequest.setStructureType(structureType);
|
||||
createIndexRequest.setName(name);
|
||||
createIndexRequest.setSourceType(sourceType);
|
||||
createIndexRequest.setSinkType(sinkType);
|
||||
createIndexRequest.setDocumentIds(Collections.singletonList(fileId));
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.createIndexWithOptions(workspaceId, createIndexRequest, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向阿里云百炼服务提交索引任务。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param indexId 知识库ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static SubmitIndexJobResponse submitIndex(com.aliyun.bailian20231229.Client client, String workspaceId,
|
||||
String indexId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.SubmitIndexJobRequest submitIndexJobRequest = new com.aliyun.bailian20231229.models.SubmitIndexJobRequest();
|
||||
submitIndexJobRequest.setIndexId(indexId);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.submitIndexJobWithOptions(workspaceId, submitIndexJobRequest, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询索引任务状态。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param jobId 任务ID
|
||||
* @param indexId 知识库ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static GetIndexJobStatusResponse getIndexJobStatus(com.aliyun.bailian20231229.Client client,
|
||||
String workspaceId, String jobId, String indexId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.GetIndexJobStatusRequest getIndexJobStatusRequest = new com.aliyun.bailian20231229.models.GetIndexJobStatusRequest();
|
||||
getIndexJobStatusRequest.setIndexId(indexId);
|
||||
getIndexJobStatusRequest.setJobId(jobId);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
GetIndexJobStatusResponse getIndexJobStatusResponse = null;
|
||||
getIndexJobStatusResponse = client.getIndexJobStatusWithOptions(workspaceId, getIndexJobStatusRequest, headers,
|
||||
runtime);
|
||||
return getIndexJobStatusResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用阿里云百炼服务创建知识库。
|
||||
*
|
||||
* @param filePath 文档本地路径
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param name 知识库名称
|
||||
* @return 如果成功,返回知识库ID;否则返回 null
|
||||
*/
|
||||
public static String createKnowledgeBase(String filePath, String workspaceId, String name) {
|
||||
// 设置默认值
|
||||
String categoryId = "default";
|
||||
String parser = "DASHSCOPE_DOCMIND";
|
||||
String sourceType = "DATA_CENTER_FILE";
|
||||
String structureType = "unstructured";
|
||||
String sinkType = "DEFAULT";
|
||||
try {
|
||||
// 步骤1:初始化客户端(Client)
|
||||
System.out.println("步骤1:初始化Client");
|
||||
com.aliyun.bailian20231229.Client client = createClient();
|
||||
|
||||
// 步骤2:准备文档信息
|
||||
System.out.println("步骤2:准备文档信息");
|
||||
String fileName = new File(filePath).getName();
|
||||
String fileMd5 = calculateMD5(filePath);
|
||||
String fileSize = getFileSize(filePath);
|
||||
|
||||
// 步骤3:申请上传租约
|
||||
System.out.println("步骤3:向阿里云百炼申请上传租约");
|
||||
ApplyFileUploadLeaseResponse leaseResponse = applyLease(client, categoryId, fileName, fileMd5, fileSize,
|
||||
workspaceId);
|
||||
String leaseId = leaseResponse.getBody().getData().getFileUploadLeaseId();
|
||||
String uploadUrl = leaseResponse.getBody().getData().getParam().getUrl();
|
||||
Object uploadHeaders = leaseResponse.getBody().getData().getParam().getHeaders();
|
||||
|
||||
// 步骤4:上传文档
|
||||
System.out.println("步骤4:上传文档到阿里云百炼");
|
||||
// 请自行安装jackson-databind
|
||||
// 将上一步的uploadHeaders转换为Map(Key-Value形式)
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
Map<String, String> uploadHeadersMap = (Map<String, String>) mapper
|
||||
.readValue(mapper.writeValueAsString(uploadHeaders), Map.class);
|
||||
uploadFile(uploadUrl, uploadHeadersMap, filePath);
|
||||
|
||||
// 步骤5:将文档添加到服务器
|
||||
System.out.println("步骤5:将文档添加到阿里云百炼服务器");
|
||||
AddFileResponse addResponse = addFile(client, leaseId, parser, categoryId, workspaceId);
|
||||
String fileId = addResponse.getBody().getData().getFileId();
|
||||
|
||||
// 步骤6:检查文档状态
|
||||
System.out.println("步骤6:检查阿里云百炼中的文档状态");
|
||||
while (true) {
|
||||
DescribeFileResponse describeResponse = describeFile(client, workspaceId, fileId);
|
||||
String status = describeResponse.getBody().getData().getStatus();
|
||||
System.out.println("当前文档状态:" + status);
|
||||
|
||||
if (status.equals("INIT")) {
|
||||
System.out.println("文档待解析,请稍候...");
|
||||
} else if (status.equals("PARSING")) {
|
||||
System.out.println("文档解析中,请稍候...");
|
||||
} else if (status.equals("PARSE_SUCCESS")) {
|
||||
System.out.println("文档解析完成!");
|
||||
break;
|
||||
} else {
|
||||
System.out.println("未知的文档状态:" + status + ",请联系技术支持。");
|
||||
return null;
|
||||
}
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
}
|
||||
|
||||
// 步骤7:初始化知识库
|
||||
System.out.println("步骤7:在阿里云百炼中创建知识库");
|
||||
CreateIndexResponse indexResponse = createIndex(client, workspaceId, fileId, name, structureType,
|
||||
sourceType, sinkType);
|
||||
String indexId = indexResponse.getBody().getData().getId();
|
||||
|
||||
// 步骤8:提交索引任务
|
||||
System.out.println("步骤8:向阿里云百炼提交索引任务");
|
||||
SubmitIndexJobResponse submitResponse = submitIndex(client, workspaceId, indexId);
|
||||
String jobId = submitResponse.getBody().getData().getId();
|
||||
|
||||
// 步骤9:获取索引任务状态
|
||||
System.out.println("步骤9:获取阿里云百炼索引任务状态");
|
||||
while (true) {
|
||||
GetIndexJobStatusResponse getStatusResponse = getIndexJobStatus(client, workspaceId, jobId, indexId);
|
||||
String status = getStatusResponse.getBody().getData().getStatus();
|
||||
System.out.println("当前索引任务状态:" + status);
|
||||
|
||||
if (status.equals("COMPLETED")) {
|
||||
break;
|
||||
}
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
}
|
||||
|
||||
System.out.println("阿里云百炼知识库创建成功!");
|
||||
return indexId;
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主函数。
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
if (!checkEnvironmentVariables()) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.print("请输入您需要上传文档的实际本地路径(以Linux为例:/xxx/xxx/阿里云百炼系列手机产品介绍.docx):");
|
||||
String filePath = scanner.nextLine();
|
||||
|
||||
System.out.print("请为您的知识库输入一个名称:");
|
||||
String kbName = scanner.nextLine();
|
||||
|
||||
String workspaceId = System.getenv("WORKSPACE_ID");
|
||||
String result = createKnowledgeBase(filePath, workspaceId, kbName);
|
||||
if (result != null) {
|
||||
System.out.println("知识库ID: " + result);
|
||||
}
|
||||
}
|
||||
}
|
||||
145
src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseManage.java
Normal file
145
src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseManage.java
Normal file
@@ -0,0 +1,145 @@
|
||||
package com.gxwebsoft.ai.util;
|
||||
|
||||
import com.aliyun.bailian20231229.models.DeleteIndexResponse;
|
||||
import com.aliyun.bailian20231229.models.ListIndicesResponse;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 管理知识库
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
public class KnowledgeBaseManage {
|
||||
|
||||
String ALIBABA_CLOUD_ACCESS_KEY_ID = "LTAI5tD5YRKuxWz6Eg7qrM4P";
|
||||
String ALIBABA_CLOUD_ACCESS_KEY_SECRET = "bO8TBDXflOwbtSKimPpG8XrJnyzgTk";
|
||||
String WORKSPACE_ID = "llm-4pf5auwewoz34zqu";
|
||||
|
||||
/**
|
||||
* 检查并提示设置必要的环境变量。
|
||||
*
|
||||
* @return true 如果所有必需的环境变量都已设置,否则 false
|
||||
*/
|
||||
public static boolean checkEnvironmentVariables() {
|
||||
Map<String, String> requiredVars = new HashMap<>();
|
||||
requiredVars.put("ALIBABA_CLOUD_ACCESS_KEY_ID", "阿里云访问密钥ID");
|
||||
requiredVars.put("ALIBABA_CLOUD_ACCESS_KEY_SECRET", "阿里云访问密钥密码");
|
||||
requiredVars.put("WORKSPACE_ID", "阿里云百炼业务空间ID");
|
||||
|
||||
List<String> missingVars = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : requiredVars.entrySet()) {
|
||||
String value = System.getenv(entry.getKey());
|
||||
if (value == null || value.isEmpty()) {
|
||||
missingVars.add(entry.getKey());
|
||||
System.out.println("错误:请设置 " + entry.getKey() + " 环境变量 (" + entry.getValue() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
return missingVars.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并配置客户端(Client)
|
||||
*
|
||||
* @return 配置好的客户端(Client)
|
||||
*/
|
||||
public static com.aliyun.bailian20231229.Client createClient() throws Exception {
|
||||
com.aliyun.credentials.Client credential = new com.aliyun.credentials.Client();
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
|
||||
.setCredential(credential);
|
||||
// 下方接入地址以公有云的公网接入地址为例,可按需更换接入地址。
|
||||
config.endpoint = "bailian.cn-beijing.aliyuncs.com";
|
||||
return new com.aliyun.bailian20231229.Client(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定业务空间下一个或多个知识库的详细信息
|
||||
*
|
||||
* @param client 客户端(Client)
|
||||
* @param workspaceId 业务空间ID
|
||||
* @return 阿里云百炼服务的响应
|
||||
*/
|
||||
public static ListIndicesResponse listIndices(com.aliyun.bailian20231229.Client client, String workspaceId)
|
||||
throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.ListIndicesRequest listIndicesRequest = new com.aliyun.bailian20231229.models.ListIndicesRequest();
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.listIndicesWithOptions(workspaceId, listIndicesRequest, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 永久性删除指定的知识库
|
||||
*
|
||||
* @param client 客户端(Client)
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param indexId 知识库ID
|
||||
* @return 阿里云百炼服务的响应
|
||||
*/
|
||||
public static DeleteIndexResponse deleteIndex(com.aliyun.bailian20231229.Client client, String workspaceId,
|
||||
String indexId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.DeleteIndexRequest deleteIndexRequest = new com.aliyun.bailian20231229.models.DeleteIndexRequest();
|
||||
deleteIndexRequest.setIndexId(indexId);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.deleteIndexWithOptions(workspaceId, deleteIndexRequest, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主函数
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
if (!checkEnvironmentVariables()) {
|
||||
System.out.println("环境变量校验未通过。");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
System.out.print("请选择要执行的操作:\n1. 查看知识库\n2. 删除知识库\n请输入选项(1或2):");
|
||||
String startOption = scanner.nextLine();
|
||||
com.aliyun.bailian20231229.Client client = createClient();
|
||||
if (startOption.equals("1")) {
|
||||
// 查看知识库
|
||||
System.out.println("\n执行查看知识库");
|
||||
String workspaceId = System.getenv("WORKSPACE_ID");
|
||||
ListIndicesResponse response = listIndices(client, workspaceId);
|
||||
// 请自行安装jackson-databind。将响应转换为 JSON 字符串
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String result = mapper.writeValueAsString(response.getBody().getData());
|
||||
System.out.println(result);
|
||||
} else if (startOption.equals("2")) {
|
||||
System.out.println("\n执行删除知识库");
|
||||
String workspaceId = System.getenv("WORKSPACE_ID");
|
||||
System.out.print("请输入知识库ID:"); // 即 CreateIndex 接口返回的 Data.Id,您也可以在阿里云百炼控制台的知识库页面获取。
|
||||
String indexId = scanner.nextLine();
|
||||
// 删除前二次确认
|
||||
boolean confirm = false;
|
||||
while (!confirm) {
|
||||
System.out.print("您确定要永久性删除该知识库 " + indexId + " 吗?(y/n): ");
|
||||
String input = scanner.nextLine().trim().toLowerCase();
|
||||
if (input.equals("y")) {
|
||||
confirm = true;
|
||||
} else if (input.equals("n")) {
|
||||
System.out.println("已取消删除操作。");
|
||||
return;
|
||||
} else {
|
||||
System.out.println("无效输入,请输入 y 或 n。");
|
||||
}
|
||||
}
|
||||
DeleteIndexResponse resp = deleteIndex(client, workspaceId, indexId);
|
||||
if (resp.getBody().getStatus().equals("200")) {
|
||||
System.out.println("知识库" + indexId + "删除成功!");
|
||||
} else {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
System.out.println("发生错误:" + mapper.writeValueAsString(resp.getBody()));
|
||||
}
|
||||
} else {
|
||||
System.out.println("无效的选项,程序退出。");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("发生错误:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
110
src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseRetrieve.java
Normal file
110
src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseRetrieve.java
Normal file
@@ -0,0 +1,110 @@
|
||||
package com.gxwebsoft.ai.util;
|
||||
|
||||
import com.aliyun.bailian20231229.models.RetrieveRequest;
|
||||
import com.aliyun.bailian20231229.models.RetrieveResponse;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 检索知识库
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
public class KnowledgeBaseRetrieve {
|
||||
|
||||
static String ALIBABA_CLOUD_ACCESS_KEY_ID = "LTAI5tD5YRKuxWz6Eg7qrM4P";
|
||||
static String ALIBABA_CLOUD_ACCESS_KEY_SECRET = "bO8TBDXflOwbtSKimPpG8XrJnyzgTk";
|
||||
static String WORKSPACE_ID = "llm-4pf5auwewoz34zqu";
|
||||
|
||||
|
||||
/**
|
||||
* 检查并提示设置必要的环境变量。
|
||||
*
|
||||
* @return true 如果所有必需的环境变量都已设置,否则 false
|
||||
*/
|
||||
public static boolean checkEnvironmentVariables() {
|
||||
Map<String, String> requiredVars = new HashMap<>();
|
||||
requiredVars.put("ALIBABA_CLOUD_ACCESS_KEY_ID", "阿里云访问密钥ID");
|
||||
requiredVars.put("ALIBABA_CLOUD_ACCESS_KEY_SECRET", "阿里云访问密钥密码");
|
||||
requiredVars.put("WORKSPACE_ID", "阿里云百炼业务空间ID");
|
||||
|
||||
List<String> missingVars = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : requiredVars.entrySet()) {
|
||||
String value = System.getenv(entry.getKey());
|
||||
if (value == null || value.isEmpty()) {
|
||||
missingVars.add(entry.getKey());
|
||||
System.out.println("错误:请设置 " + entry.getKey() + " 环境变量 (" + entry.getValue() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
return missingVars.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化客户端(Client)。
|
||||
*
|
||||
* @return 配置好的客户端对象
|
||||
*/
|
||||
public static com.aliyun.bailian20231229.Client createClient() throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
|
||||
.setAccessKeyId(ALIBABA_CLOUD_ACCESS_KEY_ID)
|
||||
.setAccessKeySecret(ALIBABA_CLOUD_ACCESS_KEY_SECRET);
|
||||
// 下方接入地址以公有云的公网接入地址为例,可按需更换接入地址。
|
||||
config.endpoint = "bailian.cn-beijing.aliyuncs.com";
|
||||
return new com.aliyun.bailian20231229.Client(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在指定的知识库中检索信息。
|
||||
*
|
||||
* @param client 客户端对象(bailian20231229Client)
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param indexId 知识库ID
|
||||
* @param query 检索查询语句
|
||||
* @return 阿里云百炼服务的响应
|
||||
*/
|
||||
public static RetrieveResponse retrieveIndex(com.aliyun.bailian20231229.Client client, String workspaceId,
|
||||
String indexId, String query) throws Exception {
|
||||
RetrieveRequest retrieveRequest = new RetrieveRequest();
|
||||
retrieveRequest.setIndexId(indexId);
|
||||
retrieveRequest.setQuery(query);
|
||||
retrieveRequest.setDenseSimilarityTopK(null);
|
||||
RuntimeOptions runtime = new RuntimeOptions();
|
||||
return client.retrieveWithOptions(workspaceId, retrieveRequest, null, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用阿里云百炼服务检索知识库。
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// if (!checkEnvironmentVariables()) {
|
||||
// System.out.println("环境变量校验未通过。");
|
||||
// return;
|
||||
// }
|
||||
|
||||
try {
|
||||
// 步骤1:初始化客户端(Client)
|
||||
System.out.println("步骤1:创建Client");
|
||||
com.aliyun.bailian20231229.Client client = createClient();
|
||||
|
||||
// 步骤2:检索知识库
|
||||
System.out.println("步骤2:检索知识库");
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
System.out.print("请输入知识库ID:"); // 即 CreateIndex 接口返回的 Data.Id,您也可以在阿里云百炼控制台的知识库页面获取。
|
||||
String indexId = scanner.nextLine();
|
||||
System.out.print("请输入检索query:");
|
||||
String query = scanner.nextLine();
|
||||
String workspaceId = WORKSPACE_ID;
|
||||
RetrieveResponse resp = retrieveIndex(client, workspaceId, indexId, query);
|
||||
|
||||
// 请自行安装jackson-databind。将响应体responsebody转换为 JSON 字符串
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String result = mapper.writeValueAsString(resp.getBody());
|
||||
System.out.println(result);
|
||||
} catch (Exception e) {
|
||||
System.out.println("发生错误:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
384
src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseUpdate.java
Normal file
384
src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseUpdate.java
Normal file
@@ -0,0 +1,384 @@
|
||||
package com.gxwebsoft.ai.util;
|
||||
|
||||
import com.aliyun.bailian20231229.models.*;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 更新知识库
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
public class KnowledgeBaseUpdate {
|
||||
|
||||
String ALIBABA_CLOUD_ACCESS_KEY_ID = "LTAI5tD5YRKuxWz6Eg7qrM4P";
|
||||
String ALIBABA_CLOUD_ACCESS_KEY_SECRET = "bO8TBDXflOwbtSKimPpG8XrJnyzgTk";
|
||||
String WORKSPACE_ID = "llm-4pf5auwewoz34zqu";
|
||||
|
||||
/**
|
||||
* 检查并提示设置必要的环境变量。
|
||||
*
|
||||
* @return true 如果所有必需的环境变量都已设置,否则 false
|
||||
*/
|
||||
public static boolean checkEnvironmentVariables() {
|
||||
Map<String, String> requiredVars = new HashMap<>();
|
||||
requiredVars.put("ALIBABA_CLOUD_ACCESS_KEY_ID", "阿里云访问密钥ID");
|
||||
requiredVars.put("ALIBABA_CLOUD_ACCESS_KEY_SECRET", "阿里云访问密钥密码");
|
||||
requiredVars.put("WORKSPACE_ID", "阿里云百炼业务空间ID");
|
||||
|
||||
List<String> missingVars = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : requiredVars.entrySet()) {
|
||||
String value = System.getenv(entry.getKey());
|
||||
if (value == null || value.isEmpty()) {
|
||||
missingVars.add(entry.getKey());
|
||||
System.out.println("错误:请设置 " + entry.getKey() + " 环境变量 (" + entry.getValue() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
return missingVars.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并配置客户端(Client)
|
||||
*
|
||||
* @return 配置好的客户端(Client)
|
||||
*/
|
||||
public static com.aliyun.bailian20231229.Client createClient() throws Exception {
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
|
||||
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
|
||||
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
|
||||
// 下方接入地址以公有云的公网接入地址为例,可按需更换接入地址。
|
||||
config.endpoint = "bailian.cn-beijing.aliyuncs.com";
|
||||
return new com.aliyun.bailian20231229.Client(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算文档的MD5值
|
||||
*
|
||||
* @param filePath 文档本地路径
|
||||
* @return 文档的MD5值
|
||||
*/
|
||||
public static String calculateMD5(String filePath) throws Exception {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
try (FileInputStream fis = new FileInputStream(filePath)) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = fis.read(buffer)) != -1) {
|
||||
md.update(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : md.digest()) {
|
||||
sb.append(String.format("%02x", b & 0xff));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文档大小(以字节为单位)
|
||||
*
|
||||
* @param filePath 文档本地路径
|
||||
* @return 文档大小(以字节为单位)
|
||||
*/
|
||||
public static String getFileSize(String filePath) {
|
||||
File file = new File(filePath);
|
||||
long fileSize = file.length();
|
||||
return String.valueOf(fileSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请文档上传租约。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param categoryId 类目ID
|
||||
* @param fileName 文档名称
|
||||
* @param fileMd5 文档的MD5值
|
||||
* @param fileSize 文档大小(以字节为单位)
|
||||
* @param workspaceId 业务空间ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static ApplyFileUploadLeaseResponse applyLease(com.aliyun.bailian20231229.Client client, String categoryId,
|
||||
String fileName, String fileMd5, String fileSize, String workspaceId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.ApplyFileUploadLeaseRequest applyFileUploadLeaseRequest = new com.aliyun.bailian20231229.models.ApplyFileUploadLeaseRequest();
|
||||
applyFileUploadLeaseRequest.setFileName(fileName);
|
||||
applyFileUploadLeaseRequest.setMd5(fileMd5);
|
||||
applyFileUploadLeaseRequest.setSizeInBytes(fileSize);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
ApplyFileUploadLeaseResponse applyFileUploadLeaseResponse = null;
|
||||
applyFileUploadLeaseResponse = client.applyFileUploadLeaseWithOptions(categoryId, workspaceId,
|
||||
applyFileUploadLeaseRequest, headers, runtime);
|
||||
return applyFileUploadLeaseResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文档到临时存储。
|
||||
*
|
||||
* @param preSignedUrl 上传租约中的 URL
|
||||
* @param headers 上传请求的头部
|
||||
* @param filePath 文档本地路径
|
||||
* @throws Exception 如果上传过程中发生错误
|
||||
*/
|
||||
public static void uploadFile(String preSignedUrl, Map<String, String> headers, String filePath) throws Exception {
|
||||
File file = new File(filePath);
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
throw new IllegalArgumentException("文件不存在或不是普通文件: " + filePath);
|
||||
}
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
URL url = new URL(preSignedUrl);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("PUT");
|
||||
conn.setDoOutput(true);
|
||||
|
||||
// 设置上传请求头
|
||||
conn.setRequestProperty("X-bailian-extra", headers.get("X-bailian-extra"));
|
||||
conn.setRequestProperty("Content-Type", headers.get("Content-Type"));
|
||||
|
||||
// 分块读取并上传文档
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = fis.read(buffer)) != -1) {
|
||||
conn.getOutputStream().write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
int responseCode = conn.getResponseCode();
|
||||
if (responseCode != 200) {
|
||||
throw new RuntimeException("上传失败: " + responseCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文档添加到类目中。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param leaseId 租约ID
|
||||
* @param parser 用于文档的解析器
|
||||
* @param categoryId 类目ID
|
||||
* @param workspaceId 业务空间ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static AddFileResponse addFile(com.aliyun.bailian20231229.Client client, String leaseId, String parser,
|
||||
String categoryId, String workspaceId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.AddFileRequest addFileRequest = new com.aliyun.bailian20231229.models.AddFileRequest();
|
||||
addFileRequest.setLeaseId(leaseId);
|
||||
addFileRequest.setParser(parser);
|
||||
addFileRequest.setCategoryId(categoryId);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.addFileWithOptions(workspaceId, addFileRequest, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询文档的基本信息。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param fileId 文档ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static DescribeFileResponse describeFile(com.aliyun.bailian20231229.Client client, String workspaceId,
|
||||
String fileId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.describeFileWithOptions(workspaceId, fileId, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向一个非结构化知识库追加导入已解析的文档
|
||||
*
|
||||
* @param client 客户端(Client)
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param indexId 知识库ID
|
||||
* @param fileId 文档ID
|
||||
* @param sourceType 数据类型
|
||||
* @return 阿里云百炼服务的响应
|
||||
*/
|
||||
public static SubmitIndexAddDocumentsJobResponse submitIndexAddDocumentsJob(
|
||||
com.aliyun.bailian20231229.Client client, String workspaceId, String indexId, String fileId,
|
||||
String sourceType) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
SubmitIndexAddDocumentsJobRequest submitIndexAddDocumentsJobRequest = new SubmitIndexAddDocumentsJobRequest();
|
||||
submitIndexAddDocumentsJobRequest.setIndexId(indexId);
|
||||
submitIndexAddDocumentsJobRequest.setDocumentIds(Collections.singletonList(fileId));
|
||||
submitIndexAddDocumentsJobRequest.setSourceType(sourceType);
|
||||
RuntimeOptions runtime = new RuntimeOptions();
|
||||
return client.submitIndexAddDocumentsJobWithOptions(workspaceId, submitIndexAddDocumentsJobRequest, headers,
|
||||
runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询索引任务状态。
|
||||
*
|
||||
* @param client 客户端对象
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param jobId 任务ID
|
||||
* @param indexId 知识库ID
|
||||
* @return 阿里云百炼服务的响应对象
|
||||
*/
|
||||
public static GetIndexJobStatusResponse getIndexJobStatus(com.aliyun.bailian20231229.Client client,
|
||||
String workspaceId, String jobId, String indexId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
com.aliyun.bailian20231229.models.GetIndexJobStatusRequest getIndexJobStatusRequest = new com.aliyun.bailian20231229.models.GetIndexJobStatusRequest();
|
||||
getIndexJobStatusRequest.setIndexId(indexId);
|
||||
getIndexJobStatusRequest.setJobId(jobId);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
GetIndexJobStatusResponse getIndexJobStatusResponse = null;
|
||||
getIndexJobStatusResponse = client.getIndexJobStatusWithOptions(workspaceId, getIndexJobStatusRequest, headers,
|
||||
runtime);
|
||||
return getIndexJobStatusResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从指定的非结构化知识库中永久删除一个或多个文档
|
||||
*
|
||||
* @param client 客户端(Client)
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param indexId 知识库ID
|
||||
* @param fileId 文档ID
|
||||
* @return 阿里云百炼服务的响应
|
||||
*/
|
||||
public static DeleteIndexDocumentResponse deleteIndexDocument(com.aliyun.bailian20231229.Client client,
|
||||
String workspaceId, String indexId, String fileId) throws Exception {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
DeleteIndexDocumentRequest deleteIndexDocumentRequest = new DeleteIndexDocumentRequest();
|
||||
deleteIndexDocumentRequest.setIndexId(indexId);
|
||||
deleteIndexDocumentRequest.setDocumentIds(Collections.singletonList(fileId));
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
return client.deleteIndexDocumentWithOptions(workspaceId, deleteIndexDocumentRequest, headers, runtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用阿里云百炼服务更新知识库
|
||||
*
|
||||
* @param filePath 文档(更新后的)的实际本地路径
|
||||
* @param workspaceId 业务空间ID
|
||||
* @param indexId 需要更新的知识库ID
|
||||
* @param oldFileId 需要更新的文档的FileID
|
||||
* @return 如果成功,返回知识库ID;否则返回 null
|
||||
*/
|
||||
public static String updateKnowledgeBase(String filePath, String workspaceId, String indexId, String oldFileId) {
|
||||
// 设置默认值
|
||||
String categoryId = "default";
|
||||
String parser = "DASHSCOPE_DOCMIND";
|
||||
String sourceType = "DATA_CENTER_FILE";
|
||||
try {
|
||||
// 步骤1:初始化客户端(Client)
|
||||
System.out.println("步骤1:创建Client");
|
||||
com.aliyun.bailian20231229.Client client = createClient();
|
||||
|
||||
// 步骤2:准备文档信息(更新后的文档)
|
||||
System.out.println("步骤2:准备文档信息");
|
||||
String fileName = Paths.get(filePath).getFileName().toString();
|
||||
String fileMd5 = calculateMD5(filePath);
|
||||
String fileSize = getFileSize(filePath);
|
||||
|
||||
// 步骤3:申请上传租约
|
||||
System.out.println("步骤3:向阿里云百炼申请上传租约");
|
||||
ApplyFileUploadLeaseResponse leaseResponse = applyLease(client, categoryId, fileName, fileMd5, fileSize,
|
||||
workspaceId);
|
||||
String leaseId = leaseResponse.getBody().getData().getFileUploadLeaseId();
|
||||
String uploadUrl = leaseResponse.getBody().getData().getParam().getUrl();
|
||||
Object uploadHeaders = leaseResponse.getBody().getData().getParam().getHeaders();
|
||||
|
||||
// 步骤4:上传文档到临时存储
|
||||
System.out.println("步骤4:上传文档到临时存储");
|
||||
// 请自行安装jackson-databind
|
||||
// 将上一步的uploadHeaders转换为Map(Key-Value形式)
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
Map<String, String> uploadHeadersMap = (Map<String, String>) mapper
|
||||
.readValue(mapper.writeValueAsString(uploadHeaders), Map.class);
|
||||
uploadFile(uploadUrl, uploadHeadersMap, filePath);
|
||||
|
||||
// 步骤5:添加文档到类目中
|
||||
System.out.println("步骤5:添加文档到类目中");
|
||||
AddFileResponse addResponse = addFile(client, leaseId, parser, categoryId, workspaceId);
|
||||
String fileId = addResponse.getBody().getData().getFileId();
|
||||
|
||||
// 步骤6:检查更新后的文档状态
|
||||
System.out.println("步骤6:检查阿里云百炼中的文档状态");
|
||||
while (true) {
|
||||
DescribeFileResponse describeResponse = describeFile(client, workspaceId, fileId);
|
||||
String status = describeResponse.getBody().getData().getStatus();
|
||||
System.out.println("当前文档状态:" + status);
|
||||
if ("INIT".equals(status)) {
|
||||
System.out.println("文档待解析,请稍候...");
|
||||
} else if ("PARSING".equals(status)) {
|
||||
System.out.println("文档解析中,请稍候...");
|
||||
} else if ("PARSE_SUCCESS".equals(status)) {
|
||||
System.out.println("文档解析完成!");
|
||||
break;
|
||||
} else {
|
||||
System.out.println("未知的文档状态:" + status + ",请联系技术支持。");
|
||||
return null;
|
||||
}
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
|
||||
// 步骤7:提交追加文档任务
|
||||
System.out.println("步骤7:提交追加文档任务");
|
||||
SubmitIndexAddDocumentsJobResponse indexAddResponse = submitIndexAddDocumentsJob(client, workspaceId,
|
||||
indexId, fileId, sourceType);
|
||||
String jobId = indexAddResponse.getBody().getData().getId();
|
||||
|
||||
// 步骤8:等待追加任务完成
|
||||
System.out.println("步骤8:等待追加任务完成");
|
||||
while (true) {
|
||||
GetIndexJobStatusResponse jobStatusResponse = getIndexJobStatus(client, workspaceId, jobId, indexId);
|
||||
String status = jobStatusResponse.getBody().getData().getStatus();
|
||||
System.out.println("当前索引任务状态:" + status);
|
||||
if ("COMPLETED".equals(status)) {
|
||||
break;
|
||||
}
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
|
||||
// 步骤9:删除旧文档
|
||||
System.out.println("步骤9:删除旧文档");
|
||||
deleteIndexDocument(client, workspaceId, indexId, oldFileId);
|
||||
|
||||
System.out.println("阿里云百炼知识库更新成功!");
|
||||
return indexId;
|
||||
} catch (Exception e) {
|
||||
System.out.println("发生错误:" + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主函数。
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
if (!checkEnvironmentVariables()) {
|
||||
System.out.println("环境变量校验未通过。");
|
||||
return;
|
||||
}
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
System.out.print("请输入您需要上传文档(更新后的)的实际本地路径(以Linux为例:/xxx/xxx/阿里云百炼系列手机产品介绍.docx):");
|
||||
String filePath = scanner.nextLine();
|
||||
|
||||
System.out.print("请输入需要更新的知识库ID:"); // 即 CreateIndex 接口返回的 Data.Id,您也可以在阿里云百炼控制台的知识库页面获取。
|
||||
String indexId = scanner.nextLine(); // 即 AddFile 接口返回的 FileId。您也可以在阿里云百炼控制台的应用数据页面,单击文件名称旁的 ID 图标获取。
|
||||
|
||||
System.out.print("请输入需要更新的文档的 FileID:");
|
||||
String oldFileId = scanner.nextLine();
|
||||
|
||||
String workspaceId = System.getenv("WORKSPACE_ID");
|
||||
String result = updateKnowledgeBase(filePath, workspaceId, indexId, oldFileId);
|
||||
if (result != null) {
|
||||
System.out.println("知识库更新成功,返回知识库ID: " + result);
|
||||
} else {
|
||||
System.out.println("知识库更新失败。");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.gxwebsoft.enterprise.controller;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.gxwebsoft.common.core.web.BaseController;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||||
import com.gxwebsoft.common.system.entity.User;
|
||||
import com.gxwebsoft.enterprise.entity.Enterprise;
|
||||
import com.gxwebsoft.enterprise.service.EnterpriseService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
@Tag(name = "企业信息管理")
|
||||
@RestController
|
||||
@RequestMapping("/api/enterprise/enterprise")
|
||||
public class EnterpriseController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private EnterpriseService enterpriseService;
|
||||
|
||||
// @PreAuthorize("hasAuthority('enterprise:enterprise:list')")
|
||||
@Operation(summary = "分页查询企业信息")
|
||||
@GetMapping("/page")
|
||||
public ApiResult<PageResult<Enterprise>> page(Enterprise enterprise) {
|
||||
LambdaQueryWrapper<Enterprise> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.like(StrUtil.isNotBlank(enterprise.getName()), Enterprise::getName, enterprise.getName());
|
||||
wrapper.like(StrUtil.isNotBlank(enterprise.getCreditCode()), Enterprise::getCreditCode, enterprise.getCreditCode());
|
||||
wrapper.orderByAsc(Enterprise::getName);
|
||||
|
||||
final Page<Enterprise> page = new Page<>(enterprise.getPage(), enterprise.getLimit());
|
||||
final IPage<Enterprise> p = enterpriseService.page(page, wrapper);
|
||||
|
||||
return success(new PageResult<Enterprise>(p.getRecords(), p.getTotal()));
|
||||
}
|
||||
|
||||
// @PreAuthorize("hasAuthority('enterprise:enterprise:list')")
|
||||
@Operation(summary = "查询全部企业信息")
|
||||
@GetMapping("/list")
|
||||
public ApiResult<List<Enterprise>> list(Enterprise enterprise) {
|
||||
LambdaQueryWrapper<Enterprise> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.like(StrUtil.isNotBlank(enterprise.getName()), Enterprise::getName, enterprise.getName());
|
||||
wrapper.like(StrUtil.isNotBlank(enterprise.getCreditCode()), Enterprise::getCreditCode, enterprise.getCreditCode());
|
||||
return success(enterpriseService.list(wrapper));
|
||||
}
|
||||
|
||||
// @PreAuthorize("hasAuthority('enterprise:enterprise:list')")
|
||||
@Operation(summary = "根据id查询企业信息")
|
||||
@GetMapping("/{id}")
|
||||
public ApiResult<Enterprise> get(@PathVariable("id") Integer id) {
|
||||
return success(enterpriseService.getById(id));
|
||||
}
|
||||
|
||||
// @PreAuthorize("hasAuthority('enterprise:enterprise:list')")
|
||||
@Operation(summary = "根据CreditCode查询企业信息")
|
||||
@GetMapping("/creditCode/{creditCode}")
|
||||
public ApiResult<Enterprise> getByCreditCode(@PathVariable("creditCode") String creditCode) {
|
||||
Enterprise enterprise = enterpriseService.getOne(new LambdaQueryWrapper<Enterprise>().eq(Enterprise::getCreditCode, creditCode));
|
||||
return success(enterprise);
|
||||
}
|
||||
|
||||
// @PreAuthorize("hasAuthority('enterprise:enterprise:save')")
|
||||
@OperationLog
|
||||
@Operation(summary = "添加企业信息")
|
||||
@PostMapping()
|
||||
public ApiResult<?> save(@RequestBody Enterprise enterprise) {
|
||||
// 记录当前登录用户id
|
||||
User loginUser = getLoginUser();
|
||||
if (loginUser != null) {
|
||||
enterprise.setUserId(loginUser.getUserId());
|
||||
final Enterprise one = enterpriseService.getOne(new LambdaQueryWrapper<Enterprise>().eq(Enterprise::getCreditCode, enterprise.getCreditCode()));
|
||||
if (!ObjectUtil.isEmpty(one)) {
|
||||
return fail("企业统一信用代码已存在");
|
||||
}
|
||||
if (enterpriseService.save(enterprise)) {
|
||||
//TODO 查询知识库(kb_name=enterprise.getCreditCode)
|
||||
|
||||
//TODO 新建知识库
|
||||
String kbId = "pggi9mpair";
|
||||
|
||||
//绑定知识库
|
||||
enterprise.setKbId(kbId);
|
||||
enterpriseService.updateById(enterprise);
|
||||
return success("添加成功");
|
||||
}
|
||||
}
|
||||
return fail("添加失败");
|
||||
}
|
||||
|
||||
// @PreAuthorize("hasAuthority('enterprise:enterprise:update')")
|
||||
@OperationLog
|
||||
@Operation(summary = "修改企业信息")
|
||||
@PutMapping()
|
||||
public ApiResult<?> update(@RequestBody Enterprise enterprise) {
|
||||
if(StrUtil.isEmpty(enterprise.getKbId())) {
|
||||
//TODO 查询知识库
|
||||
|
||||
//TODO 新建知识库
|
||||
String kbId = "pggi9mpair";
|
||||
|
||||
//绑定知识库
|
||||
enterprise.setKbId(kbId);
|
||||
}
|
||||
if (enterpriseService.updateById(enterprise)) {
|
||||
return success("修改成功");
|
||||
}
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
// @PreAuthorize("hasAuthority('enterprise:enterprise:remove')")
|
||||
@OperationLog
|
||||
@Operation(summary = "删除企业信息")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResult<?> remove(@PathVariable("id") Integer id) {
|
||||
if (enterpriseService.removeById(id)) {
|
||||
return success("删除成功");
|
||||
}
|
||||
return fail("删除失败");
|
||||
}
|
||||
|
||||
// @PreAuthorize("hasAuthority('enterprise:enterprise:remove')")
|
||||
@OperationLog
|
||||
@Operation(summary = "批量删除企业信息")
|
||||
@DeleteMapping("/batch")
|
||||
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
|
||||
if (enterpriseService.removeByIds(ids)) {
|
||||
return success("删除成功");
|
||||
}
|
||||
return fail("删除失败");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.gxwebsoft.enterprise.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.gxwebsoft.common.core.web.BaseParam;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 企业信息
|
||||
* @author GIIT-YC
|
||||
*/
|
||||
@Data
|
||||
@TableName("enterprise")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(name = "Enterprise对象", description = "企业信息表")
|
||||
public class Enterprise extends BaseParam implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "ID")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
@Schema(description = "企业名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "统一代码")
|
||||
private String creditCode;
|
||||
|
||||
@Schema(description = "企业性质(国企、行政事业单位、民间非营利组织)")
|
||||
private String enterpriseType;
|
||||
|
||||
@Schema(description = "所属行业(使用插件)")
|
||||
private String industry;
|
||||
|
||||
@Schema(description = "知识库ID")
|
||||
private String kbId;
|
||||
|
||||
@Schema(description = "客户ID")
|
||||
private Integer userId;
|
||||
|
||||
@Schema(description = "租户ID")
|
||||
private Integer tenantId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "修改时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "状态, 0正常, 1冻结")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否删除, 0否, 1是")
|
||||
@TableLogic
|
||||
private Integer deleted;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.gxwebsoft.enterprise.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.gxwebsoft.enterprise.entity.Enterprise;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
public interface EnterpriseMapper extends BaseMapper<Enterprise> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.gxwebsoft.enterprise.mapper.EnterpriseMapper">
|
||||
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.gxwebsoft.enterprise.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.gxwebsoft.enterprise.entity.Enterprise;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
public interface EnterpriseService extends IService<Enterprise> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.gxwebsoft.enterprise.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.enterprise.entity.Enterprise;
|
||||
import com.gxwebsoft.enterprise.mapper.EnterpriseMapper;
|
||||
import com.gxwebsoft.enterprise.service.EnterpriseService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author GIIT-YC
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterprise> implements EnterpriseService {
|
||||
|
||||
}
|
||||
@@ -63,3 +63,16 @@ certificate:
|
||||
private-key-file: "apiclient_key.pem"
|
||||
apiclient-cert-file: "apiclient_cert.pem"
|
||||
wechatpay-cert-file: "wechatpay_cert.pem"
|
||||
|
||||
aliyun:
|
||||
knowledge-base:
|
||||
access-key-id: LTAI5tD5YRKuxWz6Eg7qrM4P
|
||||
access-key-secret: bO8TBDXflOwbtSKimPpG8XrJnyzgTk
|
||||
workspace-id: llm-4pf5auwewoz34zqu
|
||||
|
||||
ai:
|
||||
template:
|
||||
# Word 模板路径
|
||||
word-template-path: classpath:templates/audit_report_template.docx
|
||||
# 或者使用绝对路径
|
||||
# word-template-path: D:\\公司经济责任审计方案模板.docx
|
||||
@@ -69,3 +69,16 @@ payment:
|
||||
key-prefix: "Payment:1"
|
||||
# 缓存过期时间(小时)
|
||||
expire-hours: 24
|
||||
|
||||
aliyun:
|
||||
knowledge-base:
|
||||
access-key-id: LTAI5tD5YRKuxWz6Eg7qrM4P
|
||||
access-key-secret: bO8TBDXflOwbtSKimPpG8XrJnyzgTk
|
||||
workspace-id: llm-4pf5auwewoz34zqu
|
||||
|
||||
ai:
|
||||
template:
|
||||
# Word 模板路径
|
||||
word-template-path: classpath:templates/audit_report_template.docx
|
||||
# 或者使用绝对路径
|
||||
# word-template-path: D:\\公司经济责任审计方案模板.docx
|
||||
BIN
src/main/resources/templates/audit_report_template.docx
Normal file
BIN
src/main/resources/templates/audit_report_template.docx
Normal file
Binary file not shown.
Reference in New Issue
Block a user