Browse Source

feat(ai): 初始化审计报告生成与知识库管理模块新增审计报告生成接口,支持通过AI模型生成审计内容并下载为Word文档。

新增知识库配置与查询接口,集成阿里云百炼平台实现文档检索功能。
新增相关DTO、枚举、常量及工具类,支持审计报告模块化生成与知识库管理。
新增模板配置与知识库客户端工厂,优化阿里云相关配置注入方式。
dev3
科技小王子 3 weeks ago
parent
commit
eb87baba6e
  1. 7
      pom.xml
  2. 16
      src/main/java/com/gxwebsoft/ai/config/KnowledgeBaseConfig.java
  3. 12
      src/main/java/com/gxwebsoft/ai/config/TemplateConfig.java
  4. 19
      src/main/java/com/gxwebsoft/ai/constants/KnowledgeBaseConstants.java
  5. 144
      src/main/java/com/gxwebsoft/ai/controller/AuditReportController.java
  6. 59
      src/main/java/com/gxwebsoft/ai/controller/KnowledgeBaseController.java
  7. 42
      src/main/java/com/gxwebsoft/ai/dto/AuditReportRequest.java
  8. 20
      src/main/java/com/gxwebsoft/ai/dto/KnowledgeBaseRequest.java
  9. 45
      src/main/java/com/gxwebsoft/ai/enums/AuditReportEnum.java
  10. 23
      src/main/java/com/gxwebsoft/ai/factory/KnowledgeBaseClientFactory.java
  11. 384
      src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseCreate.java
  12. 145
      src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseManage.java
  13. 110
      src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseRetrieve.java
  14. 384
      src/main/java/com/gxwebsoft/ai/util/KnowledgeBaseUpdate.java
  15. 7
      src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java
  16. 2
      src/main/java/com/gxwebsoft/cms/param/CmsWebsiteParam.java
  17. 2
      src/main/java/com/gxwebsoft/common/system/service/impl/SettingServiceImpl.java
  18. 147
      src/main/java/com/gxwebsoft/enterprise/controller/EnterpriseController.java
  19. 67
      src/main/java/com/gxwebsoft/enterprise/entity/Enterprise.java
  20. 13
      src/main/java/com/gxwebsoft/enterprise/mapper/EnterpriseMapper.java
  21. 7
      src/main/java/com/gxwebsoft/enterprise/mapper/xml/EnterpriseMapper.xml
  22. 13
      src/main/java/com/gxwebsoft/enterprise/service/EnterpriseService.java
  23. 17
      src/main/java/com/gxwebsoft/enterprise/service/impl/EnterpriseServiceImpl.java
  24. 3
      src/main/java/com/gxwebsoft/hjm/entity/HjmCar.java
  25. 4
      src/main/java/com/gxwebsoft/hjm/mapper/xml/HjmCarMapper.xml
  26. 3
      src/main/java/com/gxwebsoft/hjm/param/HjmCarParam.java
  27. 14
      src/main/java/com/gxwebsoft/shop/service/impl/ShopWebsiteServiceImpl.java
  28. 2
      src/main/resources/application.yml

7
pom.xml

@ -352,6 +352,13 @@
<version>3.1.8</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>bailian20231229</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.freewayso</groupId>
<artifactId>image-combiner</artifactId>

16
src/main/java/com/gxwebsoft/ai/config/KnowledgeBaseConfig.java

@ -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

@ -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;
}

19
src/main/java/com/gxwebsoft/ai/constants/KnowledgeBaseConstants.java

@ -0,0 +1,19 @@
package com.gxwebsoft.ai.constants;
public class KnowledgeBaseConstants {
public static final String[] KEY_WORDS = {
"",
"审计依据 法律法规 审计业务约定书 经济责任审计管理办法 中共中央办公厅 国务院办公厅 党政主要领导干部审计规定 国家法规 公司管理制度 年度工作目标 党政主要领导干部经济责任审计规定",
"审计目标 经济责任审计目标 资产负债损益真实性 合法性 效益性 经济指标完成情况 重大决策执行 遵守财经法规 国有资产保值增值 经济责任评价 任职期间履职评价 责任界定 业绩评价",
"审计对象 审计范围 被审计领导干部 [职务] [姓名] 任职期间 [开始日期]至[结束日期] 职务任期 重大问题追溯 重要事项延伸 审计时限 下属子公司 代管企业",
"被审计单位基本情况 单位概况 组织机构 人员结构 财务会计政策 合并口径财务数据 资产总额 负债总额 营业收入 利润 内部控制制度 子公司 代管企业 职能部门设置 合并财务报表",
"审计内容 审计重点 贯彻执行经济方针 重大决策执行 发展战略 年度目标完成 法人治理结构 内部控制 财务真实性 风险管控 党风廉政建设 以往审计整改 三重一大经济决策 资产管理 采购管理 债权债务",
"审计风险 证据不充分 评价不客观 内部控制失效 法律法规变化 风险应对策略 审计证据充分性 评价客观性 内部控制审查 法规政策跟踪 重要性水平",
"审计方法 穿行测试 趋势分析 比率分析 访谈法 数据分析 分析性程序 检查 监盘 观察 询问 函证 计算 重新执行",
"审计步骤 时间安排 准备阶段 实施阶段 报告阶段 归档阶段 审计人员安排 资料收集 实质性程序 审计报告编写 交换意见 审计归档 进点会 进度表",
"审计组织实施 审计组人员分工 职责分配 审计工作计划 前期调研 审前培训 实地审计 质量控制 内部培训 沟通协调 分级复核 集体讨论 重大事项汇报 里程碑事件清单 审计工作组 项目负责人 主审"
};
}

144
src/main/java/com/gxwebsoft/ai/controller/AuditReportController.java

@ -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);
}
}
}

59
src/main/java/com/gxwebsoft/ai/controller/KnowledgeBaseController.java

@ -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

@ -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

@ -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

@ -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;
}
}

23
src/main/java/com/gxwebsoft/ai/factory/KnowledgeBaseClientFactory.java

@ -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

@ -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

@ -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

@ -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

@ -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("知识库更新失败。");
}
}
}

7
src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java

@ -178,9 +178,12 @@ public class CmsWebsiteController extends BaseController {
@Operation(summary = "网站基本信息")
@GetMapping("/getSiteInfo")
public ApiResult<CmsWebsite> getSiteInfo() {
log.info("开始获取网站基本信息...");
try {
Integer tenantId = getTenantId();
log.info("获取到租户ID: {}", tenantId);
if (ObjectUtil.isEmpty(tenantId)) {
log.warn("租户ID为空");
return fail("租户ID不能为空", null);
}
@ -201,13 +204,15 @@ public class CmsWebsiteController extends BaseController {
// 获取站点信息
CmsWebsite website = null;
try {
log.info("开始查询租户{}的站点信息", tenantId);
website = cmsWebsiteService.getOne(new LambdaQueryWrapper<CmsWebsite>()
.eq(CmsWebsite::getTenantId, tenantId)
.eq(CmsWebsite::getDeleted, 0)
.last("limit 1"));
log.info("查询站点信息完成, website: {}", website != null ? "存在" : "不存在");
} catch (Exception e) {
log.error("查询站点信息失败: {}", e.getMessage(), e);
return fail("查询站点信息失败", null);
return fail("查询站点信息失败: " + e.getMessage(), null);
}
// 创建默认站点

2
src/main/java/com/gxwebsoft/cms/param/CmsWebsiteParam.java

@ -81,7 +81,7 @@ public class CmsWebsiteParam extends BaseParam {
@Schema(description = "服务到期时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expirationTime;
private String expirationTime;
@Schema(description = "模版ID")
@QueryField(type = QueryType.EQ)

2
src/main/java/com/gxwebsoft/common/system/service/impl/SettingServiceImpl.java

@ -115,7 +115,7 @@ public class SettingServiceImpl extends ServiceImpl<SettingMapper, Setting> impl
public JSONObject getBySettingKeyIgnoreTenant(String key, Integer tenantId) {
System.out.println("跨租户查询设置 - key: " + key + ", tenantId: " + tenantId);
final List<Setting> list = list(new LambdaQueryWrapper<Setting>().eq(Setting::getTenantId, tenantId));
System.out.println("list = " + list);
System.out.println("跨租户获取指定租户的设置配置 list = " + list);
// 使用跨租户查询,指定租户ID
Setting setting = this.getOne(new QueryWrapper<Setting>()

147
src/main/java/com/gxwebsoft/enterprise/controller/EnterpriseController.java

@ -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("删除失败");
}
}

67
src/main/java/com/gxwebsoft/enterprise/entity/Enterprise.java

@ -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;
}

13
src/main/java/com/gxwebsoft/enterprise/mapper/EnterpriseMapper.java

@ -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> {
}

7
src/main/java/com/gxwebsoft/enterprise/mapper/xml/EnterpriseMapper.xml

@ -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>

13
src/main/java/com/gxwebsoft/enterprise/service/EnterpriseService.java

@ -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> {
}

17
src/main/java/com/gxwebsoft/enterprise/service/impl/EnterpriseServiceImpl.java

@ -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 {
}

3
src/main/java/com/gxwebsoft/hjm/entity/HjmCar.java

@ -46,6 +46,9 @@ public class HjmCar implements Serializable {
@Schema(description = "车辆编号")
private String code;
@Schema(description = "车辆车架号")
private String vinCode;
@Schema(description = "司机")
private Integer driverId;

4
src/main/java/com/gxwebsoft/hjm/mapper/xml/HjmCarMapper.xml

@ -43,6 +43,10 @@
<if test="param.code != null">
AND a.code LIKE CONCAT('%', #{param.code}, '%')
</if>
<if test="param.vinCode != null">
AND a.vin_code LIKE CONCAT('%', #{param.vinCode}, '%')
</if>
<if test="param.driver != null">
AND a.driver = #{param.driver}
</if>

3
src/main/java/com/gxwebsoft/hjm/param/HjmCarParam.java

@ -46,6 +46,9 @@ public class HjmCarParam extends BaseParam {
@Schema(description = "车辆编号")
private String code;
@Schema(description = "车辆车架号")
private String vinCode;
@Schema(description = "司机ID")
@QueryField(type = QueryType.EQ)
private Integer driverId;

14
src/main/java/com/gxwebsoft/shop/service/impl/ShopWebsiteServiceImpl.java

@ -46,11 +46,11 @@ public class ShopWebsiteServiceImpl implements ShopWebsiteService {
String shopInfo = redisUtil.get(cacheKey);
if (StrUtil.isNotBlank(shopInfo)) {
log.info("从缓存获取商城信息,租户ID: {}", tenantId);
try {
return JSONUtil.parseObject(shopInfo, ShopVo.class);
} catch (Exception e) {
log.warn("商城缓存解析失败,从数据库重新获取: {}", e.getMessage());
}
// try {
// return JSONUtil.parseObject(shopInfo, ShopVo.class);
// } catch (Exception e) {
// log.warn("商城缓存解析失败,从数据库重新获取: {}", e.getMessage());
// }
}
// 直接调用 CMS 服务获取站点信息,然后使用商城专用缓存
@ -59,9 +59,9 @@ public class ShopWebsiteServiceImpl implements ShopWebsiteService {
throw new RuntimeException("请先创建商城");
}
// 缓存结果(商城信息缓存时间设置为12小时)
// 缓存结果(商城信息缓存时间设置为1小时)
try {
redisUtil.set(cacheKey, shopVO, 12L, TimeUnit.HOURS);
redisUtil.set(cacheKey, shopVO, 1L, TimeUnit.HOURS);
} catch (Exception e) {
log.warn("缓存商城信息失败: {}", e.getMessage());
}

2
src/main/resources/application.yml

@ -4,7 +4,7 @@ server:
# 多环境配置
spring:
profiles:
active: test
active: dev
application:
name: server

Loading…
Cancel
Save