feat(ai): 初始化审计报告生成与知识库管理模块新增审计报告生成接口,支持通过AI模型生成审计内容并下载为Word文档。
新增知识库配置与查询接口,集成阿里云百炼平台实现文档检索功能。 新增相关DTO、枚举、常量及工具类,支持审计报告模块化生成与知识库管理。 新增模板配置与知识库客户端工厂,优化阿里云相关配置注入方式。
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -352,6 +352,13 @@
|
|||||||
<version>3.1.8</version>
|
<version>3.1.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.aliyun</groupId>
|
||||||
|
<artifactId>bailian20231229</artifactId>
|
||||||
|
<version>2.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.freewayso</groupId>
|
<groupId>com.freewayso</groupId>
|
||||||
<artifactId>image-combiner</artifactId>
|
<artifactId>image-combiner</artifactId>
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
Config authConfig = new 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);
|
||||||
|
RuntimeOptions runtime = new 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);
|
||||||
|
RuntimeOptions runtime = new 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<>();
|
||||||
|
RuntimeOptions runtime = new 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);
|
||||||
|
RuntimeOptions runtime = new 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));
|
||||||
|
RuntimeOptions runtime = new 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("知识库更新失败。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -178,9 +178,12 @@ public class CmsWebsiteController extends BaseController {
|
|||||||
@Operation(summary = "网站基本信息")
|
@Operation(summary = "网站基本信息")
|
||||||
@GetMapping("/getSiteInfo")
|
@GetMapping("/getSiteInfo")
|
||||||
public ApiResult<CmsWebsite> getSiteInfo() {
|
public ApiResult<CmsWebsite> getSiteInfo() {
|
||||||
|
log.info("开始获取网站基本信息...");
|
||||||
try {
|
try {
|
||||||
Integer tenantId = getTenantId();
|
Integer tenantId = getTenantId();
|
||||||
|
log.info("获取到租户ID: {}", tenantId);
|
||||||
if (ObjectUtil.isEmpty(tenantId)) {
|
if (ObjectUtil.isEmpty(tenantId)) {
|
||||||
|
log.warn("租户ID为空");
|
||||||
return fail("租户ID不能为空", null);
|
return fail("租户ID不能为空", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,13 +204,15 @@ public class CmsWebsiteController extends BaseController {
|
|||||||
// 获取站点信息
|
// 获取站点信息
|
||||||
CmsWebsite website = null;
|
CmsWebsite website = null;
|
||||||
try {
|
try {
|
||||||
|
log.info("开始查询租户{}的站点信息", tenantId);
|
||||||
website = cmsWebsiteService.getOne(new LambdaQueryWrapper<CmsWebsite>()
|
website = cmsWebsiteService.getOne(new LambdaQueryWrapper<CmsWebsite>()
|
||||||
.eq(CmsWebsite::getTenantId, tenantId)
|
.eq(CmsWebsite::getTenantId, tenantId)
|
||||||
.eq(CmsWebsite::getDeleted, 0)
|
.eq(CmsWebsite::getDeleted, 0)
|
||||||
.last("limit 1"));
|
.last("limit 1"));
|
||||||
|
log.info("查询站点信息完成, website: {}", website != null ? "存在" : "不存在");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("查询站点信息失败: {}", e.getMessage(), e);
|
log.error("查询站点信息失败: {}", e.getMessage(), e);
|
||||||
return fail("查询站点信息失败", null);
|
return fail("查询站点信息失败: " + e.getMessage(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建默认站点
|
// 创建默认站点
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public class CmsWebsiteParam extends BaseParam {
|
|||||||
|
|
||||||
@Schema(description = "服务到期时间")
|
@Schema(description = "服务到期时间")
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime expirationTime;
|
private String expirationTime;
|
||||||
|
|
||||||
@Schema(description = "模版ID")
|
@Schema(description = "模版ID")
|
||||||
@QueryField(type = QueryType.EQ)
|
@QueryField(type = QueryType.EQ)
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class SettingServiceImpl extends ServiceImpl<SettingMapper, Setting> impl
|
|||||||
public JSONObject getBySettingKeyIgnoreTenant(String key, Integer tenantId) {
|
public JSONObject getBySettingKeyIgnoreTenant(String key, Integer tenantId) {
|
||||||
System.out.println("跨租户查询设置 - key: " + key + ", tenantId: " + tenantId);
|
System.out.println("跨租户查询设置 - key: " + key + ", tenantId: " + tenantId);
|
||||||
final List<Setting> list = list(new LambdaQueryWrapper<Setting>().eq(Setting::getTenantId, tenantId));
|
final List<Setting> list = list(new LambdaQueryWrapper<Setting>().eq(Setting::getTenantId, tenantId));
|
||||||
System.out.println("list = " + list);
|
System.out.println("跨租户获取指定租户的设置配置 list = " + list);
|
||||||
|
|
||||||
// 使用跨租户查询,指定租户ID
|
// 使用跨租户查询,指定租户ID
|
||||||
Setting setting = this.getOne(new QueryWrapper<Setting>()
|
Setting setting = this.getOne(new QueryWrapper<Setting>()
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -46,6 +46,9 @@ public class HjmCar implements Serializable {
|
|||||||
@Schema(description = "车辆编号")
|
@Schema(description = "车辆编号")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
|
@Schema(description = "车辆车架号")
|
||||||
|
private String vinCode;
|
||||||
|
|
||||||
@Schema(description = "司机")
|
@Schema(description = "司机")
|
||||||
private Integer driverId;
|
private Integer driverId;
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,10 @@
|
|||||||
<if test="param.code != null">
|
<if test="param.code != null">
|
||||||
AND a.code LIKE CONCAT('%', #{param.code}, '%')
|
AND a.code LIKE CONCAT('%', #{param.code}, '%')
|
||||||
</if>
|
</if>
|
||||||
|
<if test="param.vinCode != null">
|
||||||
|
AND a.vin_code LIKE CONCAT('%', #{param.vinCode}, '%')
|
||||||
|
</if>
|
||||||
|
|
||||||
<if test="param.driver != null">
|
<if test="param.driver != null">
|
||||||
AND a.driver = #{param.driver}
|
AND a.driver = #{param.driver}
|
||||||
</if>
|
</if>
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ public class HjmCarParam extends BaseParam {
|
|||||||
@Schema(description = "车辆编号")
|
@Schema(description = "车辆编号")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
|
@Schema(description = "车辆车架号")
|
||||||
|
private String vinCode;
|
||||||
|
|
||||||
@Schema(description = "司机ID")
|
@Schema(description = "司机ID")
|
||||||
@QueryField(type = QueryType.EQ)
|
@QueryField(type = QueryType.EQ)
|
||||||
private Integer driverId;
|
private Integer driverId;
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ public class ShopWebsiteServiceImpl implements ShopWebsiteService {
|
|||||||
String shopInfo = redisUtil.get(cacheKey);
|
String shopInfo = redisUtil.get(cacheKey);
|
||||||
if (StrUtil.isNotBlank(shopInfo)) {
|
if (StrUtil.isNotBlank(shopInfo)) {
|
||||||
log.info("从缓存获取商城信息,租户ID: {}", tenantId);
|
log.info("从缓存获取商城信息,租户ID: {}", tenantId);
|
||||||
try {
|
// try {
|
||||||
return JSONUtil.parseObject(shopInfo, ShopVo.class);
|
// return JSONUtil.parseObject(shopInfo, ShopVo.class);
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
log.warn("商城缓存解析失败,从数据库重新获取: {}", e.getMessage());
|
// log.warn("商城缓存解析失败,从数据库重新获取: {}", e.getMessage());
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 直接调用 CMS 服务获取站点信息,然后使用商城专用缓存
|
// 直接调用 CMS 服务获取站点信息,然后使用商城专用缓存
|
||||||
@@ -59,9 +59,9 @@ public class ShopWebsiteServiceImpl implements ShopWebsiteService {
|
|||||||
throw new RuntimeException("请先创建商城");
|
throw new RuntimeException("请先创建商城");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存结果(商城信息缓存时间设置为12小时)
|
// 缓存结果(商城信息缓存时间设置为1小时)
|
||||||
try {
|
try {
|
||||||
redisUtil.set(cacheKey, shopVO, 12L, TimeUnit.HOURS);
|
redisUtil.set(cacheKey, shopVO, 1L, TimeUnit.HOURS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("缓存商城信息失败: {}", e.getMessage());
|
log.warn("缓存商城信息失败: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ server:
|
|||||||
# 多环境配置
|
# 多环境配置
|
||||||
spring:
|
spring:
|
||||||
profiles:
|
profiles:
|
||||||
active: test
|
active: dev
|
||||||
|
|
||||||
application:
|
application:
|
||||||
name: server
|
name: server
|
||||||
|
|||||||
Reference in New Issue
Block a user