This commit is contained in:
zwt13703 2026-03-14 15:07:24 +08:00
parent 8d02b59bab
commit 65c1809e95
3 changed files with 599 additions and 531 deletions

View File

@ -8,9 +8,8 @@ spring.boot.admin.client:
metadata:
username: ${spring.boot.admin.client.username}
userpassword: ${spring.boot.admin.client.password}
username: @monitor.username@
password: @monitor.password@
username: ruoyi
password: 123456
--- # snail-job 配置
snail-job:
enabled: ${SNAIL_JOB_ENABLED:false}
@ -27,7 +26,6 @@ snail-job:
port: 2${server.port}
# 客户端ip指定
host:
--- # 数据源配置
spring:
datasource:
@ -42,40 +40,40 @@ spring:
strict: true
datasource:
# 主库数据源
# master:
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
# url: jdbc:mysql://10.13.13.1:3306/yitisheng_ry_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username: root
# password: Db$7Hn#4Jm9Pq2!Xz
# # 从库数据源
# slave:
# lazy: true
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username:
# password:
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# master:
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
# url: jdbc:mysql://10.13.13.1:3306/yitisheng_ry_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username: root
# password: Db$7Hn#4Jm9Pq2!Xz
# # 从库数据源
# slave:
# lazy: true
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username:
# password:
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
postgres:
type: ${spring.datasource.type}
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://10.13.13.1:5432/art_sports_volunteer?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
username: art_sports_volunteer
password: t56kX86WMQ8eNjRz
# sqlserver:
# type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA
# password: root
# sqlserver:
# type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA
# password: root
hikari:
# 最大连接池数量
maxPoolSize: 20
@ -91,7 +89,6 @@ spring:
maxLifetime: 1800000
# 多久检查一次连接的活性
keepaliveTime: 30000
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring.data:
redis:
@ -138,7 +135,6 @@ mail:
port: 465
# 是否需要用户名密码验证
auth: true
--- # 艺术院校导入配置
art:
import:
@ -158,7 +154,6 @@ art:
timeout: 0
# Socket连接超时值单位毫秒缺省值不超时
connectionTimeout: 0
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商
# https://sms4j.com/doc3/ 差异配置文档地址 支持单厂商多配置,可以配置多个同时使用
sms:
@ -191,7 +186,6 @@ sms:
signature: 您的短信签名
sdk-app-id: 您的sdkAppId
--- # 三方授权
justauth:
# 前端外网访问地址

View File

@ -8,9 +8,8 @@ spring.boot.admin.client:
metadata:
username: ${spring.boot.admin.client.username}
userpassword: ${spring.boot.admin.client.password}
username: @monitor.username@
password: @monitor.password@
username: ruoyi
password: 123456
--- # snail-job 配置
snail-job:
enabled: ${SNAIL_JOB_ENABLED:false}
@ -27,7 +26,6 @@ snail-job:
port: 2${server.port}
# 客户端ip指定
host:
--- # 数据源配置
spring:
datasource:
@ -42,40 +40,40 @@ spring:
strict: true
datasource:
# 主库数据源
# master:
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
# url: jdbc:mysql://10.13.13.1:3306/yitisheng_ry_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username: root
# password: Db$7Hn#4Jm9Pq2!Xz
# # 从库数据源
# slave:
# lazy: true
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username:
# password:
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# master:
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
# url: jdbc:mysql://10.13.13.1:3306/yitisheng_ry_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username: root
# password: Db$7Hn#4Jm9Pq2!Xz
# # 从库数据源
# slave:
# lazy: true
# type: ${spring.datasource.type}
# driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
# username:
# password:
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
postgres:
type: ${spring.datasource.type}
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://10.13.13.1:5432/art_sports_volunteer?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true
username: art_sports_volunteer
password: t56kX86WMQ8eNjRz
# sqlserver:
# type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA
# password: root
# sqlserver:
# type: ${spring.datasource.type}
# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true
# username: SA
# password: root
hikari:
# 最大连接池数量
maxPoolSize: 20
@ -91,7 +89,6 @@ spring:
maxLifetime: 1800000
# 多久检查一次连接的活性
keepaliveTime: 30000
--- # redis 单机配置(单机与集群只能开启一个另一个需要注释掉)
spring.data:
redis:
@ -138,7 +135,6 @@ mail:
port: 465
# 是否需要用户名密码验证
auth: true
--- # 艺术院校导入配置
art:
import:
@ -158,7 +154,6 @@ art:
timeout: 0
# Socket连接超时值单位毫秒缺省值不超时
connectionTimeout: 0
--- # sms 短信 支持 阿里云 腾讯云 云片 等等各式各样的短信服务商
# https://sms4j.com/doc3/ 差异配置文档地址 支持单厂商多配置,可以配置多个同时使用
sms:
@ -191,7 +186,6 @@ sms:
signature: 您的短信签名
sdk-app-id: 您的sdkAppId
--- # 三方授权
justauth:
# 前端外网访问地址

View File

@ -2,24 +2,6 @@ package org.dromara.art.controller;
import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import org.dromara.art.domain.bo.*;
import org.dromara.art.domain.vo.ArtSchoolImportDetailVo;
import org.dromara.art.domain.vo.ArtSchoolJsonImportPreviewVo;
import org.dromara.art.domain.vo.ArtSchoolVo;
import org.dromara.art.service.IArtSchoolDetailService;
import org.dromara.art.service.IArtSchoolService;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.core.domain.R;
import org.dromara.common.web.core.BaseController;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
@ -29,6 +11,23 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.dromara.art.domain.bo.*;
import org.dromara.art.domain.vo.ArtSchoolImportDetailVo;
import org.dromara.art.domain.vo.ArtSchoolJsonImportPreviewVo;
import org.dromara.art.domain.vo.ArtSchoolVo;
import org.dromara.art.service.IArtSchoolDetailService;
import org.dromara.art.service.IArtSchoolService;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.web.core.BaseController;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Validated
@RequiredArgsConstructor
@ -38,12 +37,16 @@ public class ArtTestController extends BaseController {
private final IArtSchoolService artSchoolService;
private final IArtSchoolDetailService artSchoolDetailService;
@Value("${art.import.schoolJsonDir:}")
private String schoolJsonDir;
@GetMapping("/importSchoolByJson")
public R<ArtSchoolJsonImportPreviewVo> importSchoolByJson(@RequestParam(defaultValue = "20") Integer previewSize) {
int safePreviewSize = previewSize == null ? 20 : Math.min(Math.max(previewSize, 1), 200);
public R<ArtSchoolJsonImportPreviewVo> importSchoolByJson(
@RequestParam(defaultValue = "20") Integer previewSize
) {
int safePreviewSize =
previewSize == null ? 20 : Math.min(Math.max(previewSize, 1), 200);
Path sourceDir;
if (StringUtils.isNotBlank(schoolJsonDir)) {
sourceDir = Path.of(schoolJsonDir.trim());
@ -77,38 +80,68 @@ public class ArtTestController extends BaseController {
for (Path file : fileList) {
String fileName = file.getFileName().toString();
System.out.println("处理文件:" + fileName);
JsonNode root;
try {
root = JsonUtils.getObjectMapper().readTree(file.toFile());
} catch (Exception e) {
readFailCount++;
appendDetail(details, safePreviewSize, null, null, "FAILED", fileName + " 读取失败: " + e.getMessage());
appendDetail(
details,
safePreviewSize,
null,
null,
"FAILED",
fileName + " 读取失败: " + e.getMessage()
);
continue;
}
List<JsonNode> schoolNodes = extractSchoolNodes(root);
if (CollUtil.isEmpty(schoolNodes)) {
invalidCount++;
appendDetail(details, safePreviewSize, null, null, "INVALID", fileName + " 缺少有效学校对象");
appendDetail(
details,
safePreviewSize,
null,
null,
"INVALID",
fileName + " 缺少有效学校对象"
);
continue;
}
for (int i = 0; i < schoolNodes.size(); i++) {
JsonNode schoolNode = schoolNodes.get(i);
String sourceTag = schoolNodes.size() == 1 ? fileName : (fileName + "#" + i);
String sourceTag =
schoolNodes.size() == 1 ? fileName : (fileName + "#" + i);
Integer univId = asInteger(schoolNode.get("univId"));
String mainName = asText(schoolNode.get("univName"));
if (univId == null || StringUtils.isBlank(mainName)) {
invalidCount++;
appendDetail(details, safePreviewSize, null, mainName, "INVALID", sourceTag + " 缺少必填字段: univId/univName");
appendDetail(
details,
safePreviewSize,
null,
mainName,
"INVALID",
sourceTag + " 缺少必填字段: univId/univName"
);
continue;
}
String mainCode = String.valueOf(univId);
if (!fileUnivIdSet.add(univId) || !fileMainCodeSet.add(mainCode)) {
duplicateInFileCount++;
appendDetail(details, safePreviewSize, mainCode, mainName, "DUPLICATE_FILE", sourceTag + " 文件内重复univId/mainCode");
appendDetail(
details,
safePreviewSize,
mainCode,
mainName,
"DUPLICATE_FILE",
sourceTag + " 文件内重复univId/mainCode"
);
continue;
}
@ -118,9 +151,22 @@ public class ArtTestController extends BaseController {
continue;
}*/
ArtSchoolSubmitBo submitBo = buildSubmitBo(schoolNode, sourceTag, univId, mainCode, mainName);
ArtSchoolSubmitBo submitBo = buildSubmitBo(
schoolNode,
sourceTag,
univId,
mainCode,
mainName
);
readyCount++;
appendDetail(details, safePreviewSize, mainCode, mainName, "READY", sourceTag + " 已完成结构映射,待入库");
appendDetail(
details,
safePreviewSize,
mainCode,
mainName,
"READY",
sourceTag + " 已完成结构映射,待入库"
);
if (submitPreviewList.size() < safePreviewSize) {
submitPreviewList.add(toPreviewSubmitBo(submitBo));
@ -137,9 +183,11 @@ public class ArtTestController extends BaseController {
List<ArtSchoolVo> artSchoolVos = artSchoolService.queryList(artSchoolBo);
if (!artSchoolVos.isEmpty()) {
// 修改
artSchoolSubmitBo.getSchool().setSchoolId(artSchoolVos.get(0).getSchoolId());
artSchoolSubmitBo
.getSchool()
.setSchoolId(artSchoolVos.get(0).getSchoolId());
artSchoolService.updateWithDetailByBo(artSchoolSubmitBo);
}else{
} else {
artSchoolService.insertWithDetailByBo(artSchoolSubmitBo);
}
}
@ -150,7 +198,9 @@ public class ArtTestController extends BaseController {
previewVo.setReadFailCount(readFailCount);
previewVo.setDetails(details);
previewVo.setSubmitPreviewList(submitPreviewList);
previewVo.setServiceCallHint("已预留调用: artSchoolService.insertWithDetailByBo(submitBo)");
previewVo.setServiceCallHint(
"已预留调用: artSchoolService.insertWithDetailByBo(submitBo)"
);
return R.ok(previewVo);
}
@ -196,7 +246,13 @@ public class ArtTestController extends BaseController {
return CollUtil.isNotEmpty(artSchoolDetailService.queryList(detailBo));
}
private ArtSchoolSubmitBo buildSubmitBo(JsonNode node, String sourceTag, Integer univId, String mainCode, String mainName) {
private ArtSchoolSubmitBo buildSubmitBo(
JsonNode node,
String sourceTag,
Integer univId,
String mainCode,
String mainName
) {
ArtSchoolBo school = new ArtSchoolBo();
school.setMainCode(mainCode);
school.setMainName(mainName);
@ -227,8 +283,12 @@ public class ArtTestController extends BaseController {
detail.setIs985(normalizeFlag(asInteger(node.get("is985"))));
detail.setIs211(normalizeFlag(asInteger(node.get("is211"))));
detail.setIsDoubleFirstClass(normalizeFlag(asInteger(node.get("isFirstClass"))));
detail.setIsKeyUniversity(normalizeFlag(asInteger(node.get("isFirstLevel"))));
detail.setIsDoubleFirstClass(
normalizeFlag(asInteger(node.get("isFirstClass")))
);
detail.setIsKeyUniversity(
normalizeFlag(asInteger(node.get("isFirstLevel")))
);
detail.setIsPublic(normalizeFlag(asInteger(node.get("isPublic"))));
detail.setMasterProportionRate(asDecimal(node.get("masterProportion"))); // 考研率
@ -238,7 +298,9 @@ public class ArtTestController extends BaseController {
detail.setHasJunior(normalizeFlag(asInteger(node.get("hasJunior")))); // 是否有专科
detail.setHasMaster(normalizeFlag(asInteger(node.get("hasMaster")))); // 是否有研究生
detail.setIsDoubleHighPlan(normalizeFlag(asInteger(node.get("isDoubleHighPlan")))); // 是否双高计划专科用
detail.setIsDoubleHighPlan(
normalizeFlag(asInteger(node.get("isDoubleHighPlan")))
); // 是否双高计划专科用
detail.setIsStrongPlan(normalizeFlag(asInteger(node.get("isStrongPlan")))); // 是否强基计划
detail.setTwsdlRank(normalizeFlag(asInteger(node.get("twsdl"))));
detail.setXyhRank(normalizeFlag(asInteger(node.get("xyh"))));
@ -280,7 +342,9 @@ public class ArtTestController extends BaseController {
detail.setSubjectReviewsJson(toJsonString(node.get("subjectReviews")));
detail.setResearchJson(toJsonString(node.get("researchJson")));
detail.setUnivMajorsJson(toJsonString(node.get("univMajors")));
detail.setUnivPostgraduateJson(toJsonString(node.get("univPostgraduateList")));
detail.setUnivPostgraduateJson(
toJsonString(node.get("univPostgraduateList"))
);
detail.setUnivId(univId);
//detail.setRemark("source=" + sourceTag);
@ -300,7 +364,9 @@ public class ArtTestController extends BaseController {
if (college.has("majorList")) {
for (JsonNode major : college.get("majorList")) {
artSchoolMajorBo = new ArtSchoolMajorBo();
artSchoolMajorBo.setEducationLevel("(本)".equals(asText(major.get("majorLevel"))) ? "1" : "0");
artSchoolMajorBo.setEducationLevel(
"(本)".equals(asText(major.get("majorLevel"))) ? "1" : "0"
);
artSchoolMajorBo.setMajorName(asText(major.get("majorName")));
artSchoolMajorBo.setMajor51sdxId(asText(major.get("majorId")));
schoolMajorBoList.add(artSchoolMajorBo);
@ -310,8 +376,6 @@ public class ArtTestController extends BaseController {
schoolCollegeBoList.add(schoolCollegeBo);
}
// 其余结构化内容已映射到详情 JSON 字段
ArtSchoolSubmitBo submitBo = new ArtSchoolSubmitBo();
@ -409,12 +473,16 @@ public class ArtTestController extends BaseController {
if (guojiatese != null) {
return guojiatese;
}
return asInteger(node.path("researchJson").path("base").get("重点专业数量"));
return asInteger(
node.path("researchJson").path("base").get("重点专业数量")
);
}
private BigDecimal resolveEmploymentRate(JsonNode node) {
BigDecimal employmentRate = asDecimal(node.get("jiuyelu"));
return employmentRate == null ? null : employmentRate.setScale(2, RoundingMode.HALF_UP);
return employmentRate == null
? null
: employmentRate.setScale(2, RoundingMode.HALF_UP);
}
private BigDecimal resolveSatisfactionRate(JsonNode node) {
@ -423,7 +491,9 @@ public class ArtTestController extends BaseController {
return null;
}
if (score.compareTo(new BigDecimal("5")) <= 0) {
return score.multiply(new BigDecimal("20")).setScale(2, RoundingMode.HALF_UP);
return score
.multiply(new BigDecimal("20"))
.setScale(2, RoundingMode.HALF_UP);
}
return score.setScale(2, RoundingMode.HALF_UP);
}
@ -432,7 +502,9 @@ public class ArtTestController extends BaseController {
if (femaleRatio == null) {
return null;
}
return new BigDecimal("100").subtract(femaleRatio).setScale(2, RoundingMode.HALF_UP);
return new BigDecimal("100")
.subtract(femaleRatio)
.setScale(2, RoundingMode.HALF_UP);
}
private String resolveEducationLevel(JsonNode node) {
@ -510,7 +582,9 @@ public class ArtTestController extends BaseController {
if (node == null || node.isNull()) {
return null;
}
String text = node.isNumber() ? node.numberValue().toString() : asText(node);
String text = node.isNumber()
? node.numberValue().toString()
: asText(node);
if (StringUtils.isBlank(text)) {
return null;
}
@ -529,7 +603,14 @@ public class ArtTestController extends BaseController {
return JsonUtils.toJsonString(node);
}
private void appendDetail(List<ArtSchoolImportDetailVo> details, int maxSize, String mainCode, String mainName, String status, String message) {
private void appendDetail(
List<ArtSchoolImportDetailVo> details,
int maxSize,
String mainCode,
String mainName,
String status,
String message
) {
if (details.size() >= maxSize) {
return;
}
@ -540,5 +621,4 @@ public class ArtTestController extends BaseController {
detailVo.setMessage(message);
details.add(detailVo);
}
}