Compare commits

..

30 Commits

Author SHA1 Message Date
e6736d41ff refactor(import): 优化批量导入功能提升性能
- 在多个控制器中引入 BatchImportSupport 工具类
- 实现分块处理机制,每批次处理 500 条记录
- 使用 persistChunkWithFallback 方法替代逐条保存
- 保持原有的数据校验和去重逻辑不变
- 显著提升大量数据导入时的执行效率
- 减少数据库操作次数降低系统负载
2026-01-16 00:55:49 +08:00
e0e15cdd45 feat(mapper): 添加公司关联查询和关键词搜索功能
- 在多个Mapper XML文件中添加LEFT JOIN credit_company表关联
- 扩展关键词搜索范围,支持通过公司名称进行搜索匹配
- 更新CreditNearbyCompany相关功能,支持按公司ID筛选和导入
- 修改CreditNearbyCompanyParam中companyId字段类型为String
- 暂时注释掉纳税人识别号相关的搜索条件
- 统一各信用数据映射文件中的关键词搜索逻辑
2026-01-15 23:58:18 +08:00
2116856167 feat(mapper): 添加公司关联查询和关键词搜索功能
- 在多个Mapper XML文件中添加LEFT JOIN credit_company表关联
- 扩展关键词搜索范围,支持通过公司名称进行搜索匹配
- 更新CreditNearbyCompany相关功能,支持按公司ID筛选和导入
- 修改CreditNearbyCompanyParam中companyId字段类型为String
- 暂时注释掉纳税人识别号相关的搜索条件
- 统一各信用数据映射文件中的关键词搜索逻辑
2026-01-15 23:33:42 +08:00
e810136fbb feat(credit): 添加企业ID字段支持精确查询
- 在CreditNearbyCompany实体中新增companyId字段
- 更新CreditNearbyCompanyMapper.xml添加公司ID查询条件
- 在CreditNearbyCompanyParam参数类中添加companyId查询字段
- 实现基于企业ID的精确筛选功能
2026-01-15 22:42:07 +08:00
45828ad95c feat(car): 更新车辆查询支持组织ID列表筛选
- 添加 organizationIds 参数支持多组织ID筛选
- 实现 IN 查询逻辑替代原有的单个组织ID匹配
- 保留原有 organizationId 单值查询作为备选条件
- 添加 foreach 循环处理组织ID集合
- 优化查询条件避免参数冲突
2026-01-13 15:27:30 +08:00
f0cd200e21 feat(HjmCarParam): 添加组织ID集查询功能
- 引入java.util.Set导入支持
- 新增organizationIds字段用于组织ID集合查询
- 添加@Schema注解描述组织ID集功能
- 配置@QueryField注解支持IN查询类型
2026-01-13 15:22:24 +08:00
4d7f871aad feat(credit): 添加被执行人历史功能模块
- 在CreditJudgmentDebtor实体中增加historyId和historyName字段用于关联历史数据
- 新增CreditJudgmentDebtorHistory实体类用于存储被执行人历史记录
- 创建CreditJudgmentDebtorHistoryController提供完整的CRUD和批量导入导出接口
- 实现CreditJudgmentDebtorHistoryService及其实现类处理业务逻辑
- 添加CreditJudgmentDebtorHistoryMapper及XML映射文件支持数据库操作
- 新增CreditJudgmentDebtorHistoryParam和CreditJudgmentDebtorHistoryImportParam参数类
- 修改CreditJudgmentDebtorMapper.xml添加与历史表的关联查询
- 更新CreditUserMapper.xml在关键词搜索中加入历史被执行人名称匹配
2026-01-12 09:17:15 +08:00
c766f2879d feat(house): 添加租金和面积单位字段
- 为租金字段添加rentUnit单位属性
- 为月租金字段添加monthlyRentUnit单位属性
- 为面积字段添加extentUnit单位属性
- 更新实体类HouseInfo的数据结构定义
2026-01-09 19:08:48 +08:00
6eeadd7ec3 feat(credit): 支持指定工作表索引导入信用用户数据
- 添加 ExcelImportSupport.findSheetIndex 方法查找特定工作表
- 修改 tryImport 方法支持传入工作表索引参数
- 更新导入配置循环使用指定工作表索引
- 修改 readNameHyperlinks 方法使用正确的工作表索引读取超链接
- 设置 ImportParams 的起始工作表索引为动态获取的索引值
2026-01-09 10:13:56 +08:00
0de588321f feat(excel): 优化Excel导入功能支持动态工作表查找
- 添加findSheetIndex方法支持根据工作表名称查找索引
- 实现精确匹配、前缀匹配和包含匹配的查找逻辑
- 在各个控制器中使用动态工作表索引替换固定索引
- 优化CreditCompanyController中的必填字段验证逻辑
- 移除对code字段的必填验证要求
- 添加工作表名称标准化处理功能
2026-01-08 18:29:27 +08:00
3434f4d8e6 feat(excel): 优化Excel导入功能支持动态工作表查找
- 添加findSheetIndex方法支持根据工作表名称查找索引
- 实现精确匹配、前缀匹配和包含匹配的查找逻辑
- 在各个控制器中使用动态工作表索引替换固定索引
- 优化CreditCompanyController中的必填字段验证逻辑
- 移除对code字段的必填验证要求
- 添加工作表名称标准化处理功能
2026-01-08 18:16:44 +08:00
abbcd992a4 feat(credit): 添加批量导入功能和下载模板功能
- 为行政许可控制器添加批量导入和下载模板功能
- 为破产重整控制器添加批量导入和下载模板功能
- 为分支机构控制器添加批量导入和下载模板功能
- 为历史法定代表人控制器添加批量导入和下载模板功能
- 为附近企业控制器添加批量导入和下载模板功能
- 实现Excel导入数据验证和错误处理机制
- 添加导入参数实体类和转换方法
- 实现超链接读取和数据映射功能
- 添加导入模板生成和下载功能
2026-01-07 14:37:59 +08:00
947d1190a9 feat(credit): 添加行政许可、破产重整和分支机构管理功能
- 创建了CreditAdministrativeLicense实体类及对应的Controller、Service、Mapper和XML映射文件
- 创建了CreditBankruptcy实体类及对应的Controller、Service、Mapper和XML映射文件
- 创建了CreditBranch实体类及对应的Controller、Service、Mapper和XML映射文件
- 实现了分页查询、列表查询、详情查询、新增、修改、删除等基础CRUD功能
- 添加了批量操作功能包括批量新增、批量修改和批量删除
- 集成了权限控制和操作日志功能
- 实现了关联查询和排序功能
- 添加了完整的参数验证和查询条件支持
2026-01-07 13:59:30 +08:00
3ed457d7d6 feat(credit): 添加企业名称关联查询功能
- 在多个实体类中添加companyName字段用于显示企业名称
- 为CreditBreachOfTrust、CreditCaseFiling等实体添加TableField注解
- 修改CreditCompetitor实体的字段名称为mainCompanyName
- 在各个Mapper.xml文件中添加LEFT JOIN关联查询企业名称
- 更新查询SQL语句以包含企业名称字段
- 添加必要的TableField导入依赖
2026-01-05 15:21:59 +08:00
064d3b168e feat(import): 批量导入功能增加公司ID参数支持
- 为所有批量导入接口增加可选的companyId参数
- 在导入过程中将companyId设置到实体对象中
- 修复客户导入时的租户ID冲突处理逻辑
- 添加数据完整性验证异常处理机制
- 实现字符串字段的标准化处理功能
- 优化重复数据检测和更新逻辑
2026-01-05 14:30:46 +08:00
bb3cf97cc9 feat(credit): 添加企业ID字段支持
- 在多个信用实体类中添加companyId字段,包括CreditBreachOfTrust、CreditCaseFiling、CreditCompetitor等
- 更新对应的Mapper XML文件,添加基于companyId的查询条件
- 在各个参数类中添加companyId参数支持
- 为CreditJudicialImportParam添加缺失的Schema注解
- 实现基于企业ID的数据过滤功能,提升数据查询的准确性
2026-01-05 13:01:53 +08:00
2f39bd4e0b feat(import): 添加Excel导入时超链接解析功能
- 在CreditCompany和CreditJudgmentDebtor实体中添加url字段
- 实现ExcelImportSupport工具类的超链接读取功能
- 支持通过表头名称定位列并提取超链接地址
- 在企业信息导入时自动解析原文件和匹配名称的超链接
- 在执行人信息导入时解析案号和被执行人名称的超链接
- 移除多余的import语句和调试输出代码
- 扩展ImportResult类以支持工作表索引信息
2026-01-03 22:31:05 +08:00
ce01afcfb0 feat(controller): 增加被执行人批量导入支持ZIP和多sheet解析
- 支持ZIP文件批量导入多个Excel文件
- 增加对多sheet Excel文件的自动识别和解析
- 实现表头配置自动匹配和最优结果选择
- 添加导入结果统计和错误信息汇总
- 优化Excel导入的错误处理和字符编码支持
- 增加对被执行人工作表名称的智能识别
- 实现导入过程中的数据验证和重复检查机制
2026-01-03 22:01:35 +08:00
0dce41f2db fix(credit): 修复执行标的字段类型错误
- 将CreditJudgmentDebtor实体类中的amount字段类型从BigDecimal改为String
- 将CreditJudgmentDebtorParam参数类中的amount字段类型从BigDecimal改为String
- 在导入处理中移除对amount字段的BigDecimal解析
- 添加对name1字段的空值检查
- 调整债务人名称赋值逻辑,优先使用name字段,为空时使用name1字段
- 添加调试日志输出导入数据大小
2026-01-03 19:57:17 +08:00
4f1a931006 feat(credit): 扩展信用公司搜索功能并添加被执行人字段
- 修改CreditCompanyMapper.xml中的搜索条件,增加名称和匹配名称的模糊搜索
- 添加对信用代码的精确搜索功能
- 在CreditJudgmentDebtor实体中新增name1字段用于存储被执行人信息
- 为name1字段添加数据导入参数映射配置
- 更新数据库查询逻辑以支持多字段搜索匹配
2026-01-03 19:22:16 +08:00
0195e12409 led 2025-12-25 13:19:13 +08:00
3536028766 feat(credit): 添加股权冻结导入参数类
- 新增CreditGqdjImportParam类用于股权冻结数据导入
- 定义案号、冻结股权标的企业、被执行人等Excel字段映射
- 配置执行法院、执行标的金额等导入参数属性

refactor(led): 清理调试日志并优化令牌刷新

- 移除searchStopAndReplace方法中的调试打印语句
- 在令牌刷新成功后添加新的调试日志
- 优化令牌缓存和刷新流程的日志输出
2025-12-23 15:54:24 +08:00
c1d045b9b2 feat(credit): 导入功能支持读取项目名称超链接
- 在 CreditUser 实体类中新增 url 字段用于存储项目网址
- 在导入逻辑中增加读取 Excel 超链接的功能
- 新增 readNameHyperlinks 方法解析“项目名称”列的超链接
- 将读取到的超链接地址设置到对应 CreditUser 实体的 url 属性中
- 引入 Apache POI 相关依赖以支持 Excel 文件操作
- 更新导入处理流程,确保超链接与数据行正确匹配
2025-12-22 17:33:00 +08:00
0c6cb13ca7 feat(credit): 调整涉案金额和采购金额为字符串类型并优化Excel导入功能
- 将多个实体类中的involvedAmount字段由BigDecimal改为String类型
- 将CreditCustomer和CreditSupplier中的金额及日期字段调整为String类型
- 移除Excel导入时对金额字段的手动BigDecimal解析
- 增强ExcelImportSupport支持指定sheet索引读取功能
- 为CreditCustomer新增完整的Excel导入和模板下载接口
- 新增CreditCustomerImportParam用于导入数据映
2025-12-22 10:16:56 +08:00
42ebdf5653 feat(credit): 新增客户管理模块并优化字段类型
- 添加客户实体类 CreditCustomer 及相关控制器、服务、映射文件
- 统一将多个实体中的 LocalDate 和 BigDecimal 字段改为 String 类型
- 更新相关控制器逻辑,移除 ImportHelper 的日期和数值解析调用
- 修正 XML 映射文件中字段名引用错误的问题
- 调整部分表字段注释描述,如 defendant Appellee 改为 Appellee
2025-12-22 08:51:12 +08:00
cb8cc3c530 feat(credit): 添加失信被执行人和司法大数据管理功能
- 新增失信被执行人实体类、控制器、Mapper及Service实现
- 新增司法大数据实体类、控制器、Mapper及Service实现
- 实现分页查询、列表查询、详情查询接口
- 支持新增、修改、删除及批量操作接口
- 支持Excel模板下载与数据导入功能
- 配置MQTT生产环境启用开关及连接地址调整
- 移除旧审计报告相关控制器、枚举及DTO定义
2025-12-21 20:41:54 +08:00
6affaba5c3 feat(credit): 新增企业管理功能模块
- 新增企业实体类CreditCompany,包含企业基本信息字段
- 新增企业控制器CreditCompanyController,提供CRUD接口
- 新增企业导入参数类CreditCompanyImportParam,支持Excel导入
- 新增企业查询参数类CreditCompanyParam,支持条件查询
- 新增企业Mapper接口及XML映射文件,实现关联查询
- 实现企业分页查询、列表查询、详情查询接口
- 实现企业新增、修改、删除接口
- 实现企业批量导入功能,支持Excel模板下载
- 实现企业数据校验和重复数据处理逻辑
- 添加企业导入模板下载接口
- 支持企业信息的完整字段映射和转换逻辑
- 添加企业查询条件注解,支持动态SQL查询
- 实现企业关联查询SQL,支持多字段模糊匹配
- 添加企业操作日志记录和权限控制注解
- 完善企业导入异常处理和错误信息收集机制
2025-12-17 14:48:13 +08:00
57cdb72208 feat(credit): 新增企业管理功能模块
- 新增企业实体类CreditCompany,包含企业基本信息字段
- 新增企业控制器CreditCompanyController,提供CRUD接口
- 新增企业导入参数类CreditCompanyImportParam,支持Excel导入
- 新增企业查询参数类CreditCompanyParam,支持条件查询
- 新增企业Mapper接口及XML映射文件,实现关联查询
- 实
2025-12-17 10:04:00 +08:00
6321b69dc2 feat(credit): 新增司法案件管理模块
- 新增司法案件实体类CreditJudiciary,包含案件名称、案号、类型等字段
- 新增司法案件控制器CreditJudiciaryController,提供CRUD及批量操作接口
- 新增司法案件Mapper及XML文件,支持分页和列表查询
- 新增司法案件Service及实现类,封装业务逻辑
- 新增司法案件导入参数类CreditJudiciaryImportParam,支持Excel导入功能
- 新增司法案件查询参数类CreditJudiciaryParam,支持条件查询
- 修改CreditUser相关类注释,将“赊账客户”改为“招投标信息”
- 优化导入功能提示文案,区分新增与更新数量统计
2025-12-16 16:28:47 +08:00
14d1c83139 feat(credit): 新增客户发布日期字段
- 在示例数据中添加 releaseDate 字段
- 在实体映射中增加 releaseDate 属性同步逻辑
2025-12-16 15:01:40 +08:00
237 changed files with 23642 additions and 1445 deletions

View File

@@ -31,7 +31,7 @@
#### 外部服务
- **MQTT服务**: 连接成功 ✅
- 服务器: tcp://1.14.159.185:1883
- 服务器: tcp://132.232.214.96:1883
- 客户端ID: hjm_car_1753549632706
- 主题订阅: /SW_GPS/#
- **Redis**: 连接配置正常 ✅

View File

@@ -1,16 +0,0 @@
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;
}

View File

@@ -1,12 +0,0 @@
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;
}

View File

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

View File

@@ -1,144 +0,0 @@
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);
}
}
}

View File

@@ -1,59 +0,0 @@
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);
}
}

View File

@@ -1,42 +0,0 @@
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;
}

View File

@@ -1,20 +0,0 @@
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;
}

View File

@@ -1,45 +0,0 @@
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;
}
}

View File

@@ -1,23 +0,0 @@
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);
}
}

View File

@@ -1,384 +0,0 @@
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);
}
}
}

View File

@@ -1,145 +0,0 @@
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());
}
}
}

View File

@@ -1,110 +0,0 @@
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());
}
}
}

View File

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

View File

@@ -0,0 +1,260 @@
package com.gxwebsoft.credit.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* credit 模块 Excel 导入批处理支持:
* - 分批 upsert批内一次查库 + 批量 insert/update
* - 每批独立事务REQUIRES_NEW避免单次导入事务过大拖垮数据库
*/
@Component
public class BatchImportSupport {
private final TransactionTemplate requiresNewTx;
public BatchImportSupport(PlatformTransactionManager transactionManager) {
TransactionTemplate template = new TransactionTemplate(transactionManager);
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
this.requiresNewTx = template;
}
public int runInNewTx(Supplier<Integer> supplier) {
return requiresNewTx.execute(status -> supplier.get());
}
/**
* 批量 upsert优先按 code 匹配code 为空时按 name 匹配。
*/
public <T> int upsertByCodeOrName(IService<T> service,
List<T> items,
SFunction<T, Integer> idColumn,
BiConsumer<T, Integer> idSetter,
SFunction<T, String> codeColumn,
Function<T, String> codeGetter,
SFunction<T, String> nameColumn,
Function<T, String> nameGetter,
Consumer<LambdaQueryWrapper<T>> extraConditions,
int batchSize) {
if (CollectionUtils.isEmpty(items)) {
return 0;
}
List<String> codes = new ArrayList<>();
List<String> names = new ArrayList<>();
for (T item : items) {
if (item == null) {
continue;
}
String code = normalize(codeGetter.apply(item));
if (code != null) {
codes.add(code);
} else {
String name = normalize(nameGetter.apply(item));
if (name != null) {
names.add(name);
}
}
}
Map<String, Integer> idByCode = new HashMap<>();
if (!codes.isEmpty()) {
LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
if (extraConditions != null) {
extraConditions.accept(wrapper);
}
wrapper.in(codeColumn, codes);
wrapper.select(idColumn, codeColumn);
for (T dbRow : service.list(wrapper)) {
String code = normalize(codeGetter.apply(dbRow));
Integer id = extractId(dbRow, idColumn);
if (code != null && id != null) {
idByCode.putIfAbsent(code, id);
}
}
}
Map<String, Integer> idByName = new HashMap<>();
if (!names.isEmpty()) {
LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
if (extraConditions != null) {
extraConditions.accept(wrapper);
}
wrapper.in(nameColumn, names);
wrapper.select(idColumn, nameColumn);
for (T dbRow : service.list(wrapper)) {
String name = normalize(nameGetter.apply(dbRow));
Integer id = extractId(dbRow, idColumn);
if (name != null && id != null) {
idByName.putIfAbsent(name, id);
}
}
}
List<T> updates = new ArrayList<>();
List<T> inserts = new ArrayList<>();
for (T item : items) {
if (item == null) {
continue;
}
String code = normalize(codeGetter.apply(item));
Integer id = null;
if (code != null) {
id = idByCode.get(code);
} else {
String name = normalize(nameGetter.apply(item));
if (name != null) {
id = idByName.get(name);
}
}
if (id != null) {
idSetter.accept(item, id);
updates.add(item);
} else {
inserts.add(item);
}
}
if (!updates.isEmpty()) {
service.updateBatchById(updates, batchSize);
}
if (!inserts.isEmpty()) {
service.saveBatch(inserts, batchSize);
}
return updates.size() + inserts.size();
}
/**
* 批量 upsert按单字段 key 匹配key 非空)。
*/
public <T> int upsertBySingleKey(IService<T> service,
List<T> items,
SFunction<T, Integer> idColumn,
BiConsumer<T, Integer> idSetter,
SFunction<T, String> keyColumn,
Function<T, String> keyGetter,
Consumer<LambdaQueryWrapper<T>> extraConditions,
int batchSize) {
if (CollectionUtils.isEmpty(items)) {
return 0;
}
List<String> keys = new ArrayList<>(items.size());
for (T item : items) {
if (item == null) {
continue;
}
String key = normalize(keyGetter.apply(item));
if (key != null) {
keys.add(key);
}
}
Map<String, Integer> idByKey = new HashMap<>();
if (!keys.isEmpty()) {
LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
if (extraConditions != null) {
extraConditions.accept(wrapper);
}
wrapper.in(keyColumn, keys);
wrapper.select(idColumn, keyColumn);
for (T dbRow : service.list(wrapper)) {
String key = normalize(keyGetter.apply(dbRow));
Integer id = extractId(dbRow, idColumn);
if (key != null && id != null) {
idByKey.putIfAbsent(key, id);
}
}
}
List<T> updates = new ArrayList<>();
List<T> inserts = new ArrayList<>();
for (T item : items) {
if (item == null) {
continue;
}
String key = normalize(keyGetter.apply(item));
Integer id = key != null ? idByKey.get(key) : null;
if (id != null) {
idSetter.accept(item, id);
updates.add(item);
} else {
inserts.add(item);
}
}
if (!updates.isEmpty()) {
service.updateBatchById(updates, batchSize);
}
if (!inserts.isEmpty()) {
service.saveBatch(inserts, batchSize);
}
return updates.size() + inserts.size();
}
/**
* 批量失败时降级逐行,尽量保留“第 N 行”错误定位。
*/
public <T> int persistChunkWithFallback(List<T> items,
List<Integer> excelRowNumbers,
Supplier<Integer> batchPersist,
BiFunction<T, Integer, Boolean> rowPersist,
List<String> errorMessages) {
if (CollectionUtils.isEmpty(items)) {
return 0;
}
try {
return runInNewTx(batchPersist);
} catch (Exception batchException) {
int successCount = 0;
for (int i = 0; i < items.size(); i++) {
T item = items.get(i);
int excelRowNumber = (excelRowNumbers != null && i < excelRowNumbers.size()) ? excelRowNumbers.get(i) : -1;
try {
int delta = runInNewTx(() -> rowPersist.apply(item, excelRowNumber) ? 1 : 0);
successCount += delta;
} catch (Exception e) {
if (errorMessages != null) {
if (excelRowNumber > 0) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
} else {
errorMessages.add(e.getMessage());
}
}
}
}
return successCount;
}
}
private static String normalize(String value) {
if (value == null) {
return null;
}
String trimmed = value.trim();
return trimmed.isEmpty() ? null : trimmed;
}
private static <T> Integer extractId(T entity, SFunction<T, Integer> idColumn) {
// SFunction 是 getter method ref直接调用即可
return idColumn.apply(entity);
}
}

View File

@@ -0,0 +1,397 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditAdministrativeLicense;
import com.gxwebsoft.credit.param.CreditAdministrativeLicenseImportParam;
import com.gxwebsoft.credit.param.CreditAdministrativeLicenseParam;
import com.gxwebsoft.credit.service.CreditAdministrativeLicenseService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 行政许可控制器
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Tag(name = "行政许可管理")
@RestController
@RequestMapping("/api/credit/credit-administrative-license")
public class CreditAdministrativeLicenseController extends BaseController {
@Resource
private CreditAdministrativeLicenseService creditAdministrativeLicenseService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询行政许可")
@GetMapping("/page")
public ApiResult<PageResult<CreditAdministrativeLicense>> page(CreditAdministrativeLicenseParam param) {
// 使用关联查询
return success(creditAdministrativeLicenseService.pageRel(param));
}
@Operation(summary = "查询全部行政许可")
@GetMapping()
public ApiResult<List<CreditAdministrativeLicense>> list(CreditAdministrativeLicenseParam param) {
// 使用关联查询
return success(creditAdministrativeLicenseService.listRel(param));
}
@Operation(summary = "根据id查询行政许可")
@GetMapping("/{id}")
public ApiResult<CreditAdministrativeLicense> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditAdministrativeLicenseService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:save')")
@OperationLog
@Operation(summary = "添加行政许可")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditAdministrativeLicense creditAdministrativeLicense) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditAdministrativeLicense.setUserId(loginUser.getUserId());
// }
if (creditAdministrativeLicenseService.save(creditAdministrativeLicense)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:update')")
@OperationLog
@Operation(summary = "修改行政许可")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditAdministrativeLicense creditAdministrativeLicense) {
if (creditAdministrativeLicenseService.updateById(creditAdministrativeLicense)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:remove')")
@OperationLog
@Operation(summary = "删除行政许可")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditAdministrativeLicenseService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:save')")
@OperationLog
@Operation(summary = "批量添加行政许可")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditAdministrativeLicense> list) {
if (creditAdministrativeLicenseService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:update')")
@OperationLog
@Operation(summary = "批量修改行政许可")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditAdministrativeLicense> batchParam) {
if (batchParam.update(creditAdministrativeLicenseService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:remove')")
@OperationLog
@Operation(summary = "批量删除行政许可")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditAdministrativeLicenseService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入行政许可
*/
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:save')")
@Operation(summary = "批量导入行政许可")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditAdministrativeLicenseImportParam> importResult = ExcelImportSupport.readAnySheet(
file, CreditAdministrativeLicenseImportParam.class, this::isEmptyImportRow);
List<CreditAdministrativeLicenseImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByCode = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "决定文书/许可编号");
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "决定文书/许可证名称");
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditAdministrativeLicense> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditAdministrativeLicenseImportParam param = list.get(i);
try {
CreditAdministrativeLicense item = convertImportParamToEntity(param);
String link = null;
if (!ImportHelper.isBlank(item.getCode())) {
link = urlByCode.get(item.getCode().trim());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName())) {
link = urlByName.get(item.getName().trim());
}
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:决定文书/许可证名称不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertByCodeOrName(
creditAdministrativeLicenseService,
chunkItems,
CreditAdministrativeLicense::getId,
CreditAdministrativeLicense::setId,
CreditAdministrativeLicense::getCode,
CreditAdministrativeLicense::getCode,
CreditAdministrativeLicense::getName,
CreditAdministrativeLicense::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditAdministrativeLicenseService.save(rowItem);
if (!saved) {
CreditAdministrativeLicense existing = null;
if (!ImportHelper.isBlank(rowItem.getCode())) {
existing = creditAdministrativeLicenseService.lambdaQuery()
.eq(CreditAdministrativeLicense::getCode, rowItem.getCode())
.one();
}
if (existing == null) {
existing = creditAdministrativeLicenseService.lambdaQuery()
.eq(CreditAdministrativeLicense::getName, rowItem.getName())
.one();
}
if (existing != null) {
rowItem.setId(existing.getId());
if (creditAdministrativeLicenseService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertByCodeOrName(
creditAdministrativeLicenseService,
chunkItems,
CreditAdministrativeLicense::getId,
CreditAdministrativeLicense::setId,
CreditAdministrativeLicense::getCode,
CreditAdministrativeLicense::getCode,
CreditAdministrativeLicense::getName,
CreditAdministrativeLicense::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditAdministrativeLicenseService.save(rowItem);
if (!saved) {
CreditAdministrativeLicense existing = null;
if (!ImportHelper.isBlank(rowItem.getCode())) {
existing = creditAdministrativeLicenseService.lambdaQuery()
.eq(CreditAdministrativeLicense::getCode, rowItem.getCode())
.one();
}
if (existing == null) {
existing = creditAdministrativeLicenseService.lambdaQuery()
.eq(CreditAdministrativeLicense::getName, rowItem.getName())
.one();
}
if (existing != null) {
rowItem.setId(existing.getId());
if (creditAdministrativeLicenseService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载行政许可导入模板
*/
@Operation(summary = "下载行政许可导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditAdministrativeLicenseImportParam> templateList = new ArrayList<>();
CreditAdministrativeLicenseImportParam example = new CreditAdministrativeLicenseImportParam();
example.setCode("2024示例许可编号");
example.setName("示例行政许可名称");
example.setStatusText("有效");
example.setType("行政许可");
example.setValidityStart("2024-01-01");
example.setValidityEnd("2029-01-01");
example.setLicensingAuthority("某某许可机关");
example.setLicenseContent("许可内容示例");
example.setDataSourceUnit("数据来源单位示例");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("行政许可导入模板", "行政许可", CreditAdministrativeLicenseImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_administrative_license_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditAdministrativeLicenseImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getCode())
&& ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getStatusText());
}
private boolean isImportHeaderRow(CreditAdministrativeLicenseImportParam param) {
return isHeaderValue(param.getCode(), "决定文书/许可编号")
|| isHeaderValue(param.getName(), "决定文书/许可证名称")
|| isHeaderValue(param.getStatusText(), "许可状态");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditAdministrativeLicense convertImportParamToEntity(CreditAdministrativeLicenseImportParam param) {
CreditAdministrativeLicense entity = new CreditAdministrativeLicense();
entity.setCode(param.getCode());
entity.setName(param.getName());
entity.setStatusText(param.getStatusText());
entity.setType(param.getType());
entity.setValidityStart(param.getValidityStart());
entity.setValidityEnd(param.getValidityEnd());
entity.setLicensingAuthority(param.getLicensingAuthority());
entity.setLicenseContent(param.getLicenseContent());
entity.setDataSourceUnit(param.getDataSourceUnit());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,364 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditBankruptcy;
import com.gxwebsoft.credit.param.CreditBankruptcyImportParam;
import com.gxwebsoft.credit.param.CreditBankruptcyParam;
import com.gxwebsoft.credit.service.CreditBankruptcyService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 破产重整控制器
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Tag(name = "破产重整管理")
@RestController
@RequestMapping("/api/credit/credit-bankruptcy")
public class CreditBankruptcyController extends BaseController {
@Resource
private CreditBankruptcyService creditBankruptcyService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询破产重整")
@GetMapping("/page")
public ApiResult<PageResult<CreditBankruptcy>> page(CreditBankruptcyParam param) {
// 使用关联查询
return success(creditBankruptcyService.pageRel(param));
}
@Operation(summary = "查询全部破产重整")
@GetMapping()
public ApiResult<List<CreditBankruptcy>> list(CreditBankruptcyParam param) {
// 使用关联查询
return success(creditBankruptcyService.listRel(param));
}
@Operation(summary = "根据id查询破产重整")
@GetMapping("/{id}")
public ApiResult<CreditBankruptcy> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditBankruptcyService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditBankruptcy:save')")
@OperationLog
@Operation(summary = "添加破产重整")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditBankruptcy creditBankruptcy) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditBankruptcy.setUserId(loginUser.getUserId());
// }
if (creditBankruptcyService.save(creditBankruptcy)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditBankruptcy:update')")
@OperationLog
@Operation(summary = "修改破产重整")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditBankruptcy creditBankruptcy) {
if (creditBankruptcyService.updateById(creditBankruptcy)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditBankruptcy:remove')")
@OperationLog
@Operation(summary = "删除破产重整")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditBankruptcyService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditBankruptcy:save')")
@OperationLog
@Operation(summary = "批量添加破产重整")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditBankruptcy> list) {
if (creditBankruptcyService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditBankruptcy:update')")
@OperationLog
@Operation(summary = "批量修改破产重整")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditBankruptcy> batchParam) {
if (batchParam.update(creditBankruptcyService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditBankruptcy:remove')")
@OperationLog
@Operation(summary = "批量删除破产重整")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditBankruptcyService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入破产重整
*/
@PreAuthorize("hasAuthority('credit:creditBankruptcy:save')")
@Operation(summary = "批量导入破产重整")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditBankruptcyImportParam> importResult = ExcelImportSupport.readAnySheet(
file, CreditBankruptcyImportParam.class, this::isEmptyImportRow);
List<CreditBankruptcyImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByCode = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditBankruptcy> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditBankruptcyImportParam param = list.get(i);
try {
CreditBankruptcy item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCode())) {
String link = urlByCode.get(item.getCode().trim());
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCode())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditBankruptcyService,
chunkItems,
CreditBankruptcy::getId,
CreditBankruptcy::setId,
CreditBankruptcy::getCode,
CreditBankruptcy::getCode,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditBankruptcyService.save(rowItem);
if (!saved) {
CreditBankruptcy existing = creditBankruptcyService.lambdaQuery()
.eq(CreditBankruptcy::getCode, rowItem.getCode())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditBankruptcyService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditBankruptcyService,
chunkItems,
CreditBankruptcy::getId,
CreditBankruptcy::setId,
CreditBankruptcy::getCode,
CreditBankruptcy::getCode,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditBankruptcyService.save(rowItem);
if (!saved) {
CreditBankruptcy existing = creditBankruptcyService.lambdaQuery()
.eq(CreditBankruptcy::getCode, rowItem.getCode())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditBankruptcyService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载破产重整导入模板
*/
@Operation(summary = "下载破产重整导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditBankruptcyImportParam> templateList = new ArrayList<>();
CreditBankruptcyImportParam example = new CreditBankruptcyImportParam();
example.setCode("2024示例案号");
example.setType("破产清算");
example.setParty("某某公司");
example.setCourt("某某人民法院");
example.setPublicDate("2024-01-10");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("破产重整导入模板", "破产重整", CreditBankruptcyImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_bankruptcy_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditBankruptcyImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getCode())
&& ImportHelper.isBlank(param.getParty())
&& ImportHelper.isBlank(param.getCourt());
}
private boolean isImportHeaderRow(CreditBankruptcyImportParam param) {
return isHeaderValue(param.getCode(), "案号")
|| isHeaderValue(param.getType(), "案件类型")
|| isHeaderValue(param.getParty(), "当事人");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditBankruptcy convertImportParamToEntity(CreditBankruptcyImportParam param) {
CreditBankruptcy entity = new CreditBankruptcy();
entity.setCode(param.getCode());
entity.setType(param.getType());
entity.setParty(param.getParty());
entity.setCourt(param.getCourt());
entity.setPublicDate(param.getPublicDate());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,364 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditBranch;
import com.gxwebsoft.credit.param.CreditBranchImportParam;
import com.gxwebsoft.credit.param.CreditBranchParam;
import com.gxwebsoft.credit.service.CreditBranchService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 分支机构控制器
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Tag(name = "分支机构管理")
@RestController
@RequestMapping("/api/credit/credit-branch")
public class CreditBranchController extends BaseController {
@Resource
private CreditBranchService creditBranchService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询分支机构")
@GetMapping("/page")
public ApiResult<PageResult<CreditBranch>> page(CreditBranchParam param) {
// 使用关联查询
return success(creditBranchService.pageRel(param));
}
@Operation(summary = "查询全部分支机构")
@GetMapping()
public ApiResult<List<CreditBranch>> list(CreditBranchParam param) {
// 使用关联查询
return success(creditBranchService.listRel(param));
}
@Operation(summary = "根据id查询分支机构")
@GetMapping("/{id}")
public ApiResult<CreditBranch> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditBranchService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditBranch:save')")
@OperationLog
@Operation(summary = "添加分支机构")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditBranch creditBranch) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditBranch.setUserId(loginUser.getUserId());
// }
if (creditBranchService.save(creditBranch)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditBranch:update')")
@OperationLog
@Operation(summary = "修改分支机构")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditBranch creditBranch) {
if (creditBranchService.updateById(creditBranch)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditBranch:remove')")
@OperationLog
@Operation(summary = "删除分支机构")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditBranchService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditBranch:save')")
@OperationLog
@Operation(summary = "批量添加分支机构")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditBranch> list) {
if (creditBranchService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditBranch:update')")
@OperationLog
@Operation(summary = "批量修改分支机构")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditBranch> batchParam) {
if (batchParam.update(creditBranchService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditBranch:remove')")
@OperationLog
@Operation(summary = "批量删除分支机构")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditBranchService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入分支机构
*/
@PreAuthorize("hasAuthority('credit:creditBranch:save')")
@Operation(summary = "批量导入分支机构")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditBranchImportParam> importResult = ExcelImportSupport.readAnySheet(
file, CreditBranchImportParam.class, this::isEmptyImportRow);
List<CreditBranchImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "分支机构名称");
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditBranch> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditBranchImportParam param = list.get(i);
try {
CreditBranch item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getName())) {
String link = urlByName.get(item.getName().trim());
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:分支机构名称不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditBranchService,
chunkItems,
CreditBranch::getId,
CreditBranch::setId,
CreditBranch::getName,
CreditBranch::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditBranchService.save(rowItem);
if (!saved) {
CreditBranch existing = creditBranchService.lambdaQuery()
.eq(CreditBranch::getName, rowItem.getName())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditBranchService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditBranchService,
chunkItems,
CreditBranch::getId,
CreditBranch::setId,
CreditBranch::getName,
CreditBranch::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditBranchService.save(rowItem);
if (!saved) {
CreditBranch existing = creditBranchService.lambdaQuery()
.eq(CreditBranch::getName, rowItem.getName())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditBranchService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载分支机构导入模板
*/
@Operation(summary = "下载分支机构导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditBranchImportParam> templateList = new ArrayList<>();
CreditBranchImportParam example = new CreditBranchImportParam();
example.setName("某某公司分支机构");
example.setCurator("张三");
example.setRegion("广西南宁");
example.setEstablishDate("2020-06-01");
example.setStatusText("存续");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("分支机构导入模板", "分支机构", CreditBranchImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_branch_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditBranchImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getCurator())
&& ImportHelper.isBlank(param.getRegion());
}
private boolean isImportHeaderRow(CreditBranchImportParam param) {
return isHeaderValue(param.getName(), "分支机构名称")
|| isHeaderValue(param.getCurator(), "负责人")
|| isHeaderValue(param.getRegion(), "地区");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditBranch convertImportParamToEntity(CreditBranchImportParam param) {
CreditBranch entity = new CreditBranch();
entity.setName(param.getName());
entity.setCurator(param.getCurator());
entity.setRegion(param.getRegion());
entity.setEstablishDate(param.getEstablishDate());
entity.setStatusText(param.getStatusText());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,346 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditBreachOfTrust;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.param.CreditBreachOfTrustParam;
import com.gxwebsoft.credit.service.CreditBreachOfTrustService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* 失信被执行人控制器
*
* @author 科技小王子
* @since 2025-12-19 19:46:14
*/
@Tag(name = "失信被执行人管理")
@RestController
@RequestMapping("/api/credit/credit-breach-of-trust")
public class CreditBreachOfTrustController extends BaseController {
@Resource
private CreditBreachOfTrustService creditBreachOfTrustService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询失信被执行人")
@GetMapping("/page")
public ApiResult<PageResult<CreditBreachOfTrust>> page(CreditBreachOfTrustParam param) {
// 使用关联查询
return success(creditBreachOfTrustService.pageRel(param));
}
@Operation(summary = "查询全部失信被执行人")
@GetMapping()
public ApiResult<List<CreditBreachOfTrust>> list(CreditBreachOfTrustParam param) {
// 使用关联查询
return success(creditBreachOfTrustService.listRel(param));
}
@Operation(summary = "根据id查询失信被执行人")
@GetMapping("/{id}")
public ApiResult<CreditBreachOfTrust> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditBreachOfTrustService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@OperationLog
@Operation(summary = "添加失信被执行人")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditBreachOfTrust creditBreachOfTrust) {
if (creditBreachOfTrustService.save(creditBreachOfTrust)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:update')")
@OperationLog
@Operation(summary = "修改失信被执行人")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditBreachOfTrust creditBreachOfTrust) {
if (creditBreachOfTrustService.updateById(creditBreachOfTrust)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:remove')")
@OperationLog
@Operation(summary = "删除失信被执行人")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditBreachOfTrustService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@OperationLog
@Operation(summary = "批量添加失信被执行人")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditBreachOfTrust> list) {
if (creditBreachOfTrustService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:update')")
@OperationLog
@Operation(summary = "批量修改失信被执行人")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditBreachOfTrust> batchParam) {
if (batchParam.update(creditBreachOfTrustService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:remove')")
@OperationLog
@Operation(summary = "批量删除失信被执行人")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditBreachOfTrustService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入失信被执行人
*/
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@Operation(summary = "批量导入失信被执行人")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditBreachOfTrust> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditBreachOfTrust item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditBreachOfTrustService,
chunkItems,
CreditBreachOfTrust::getId,
CreditBreachOfTrust::setId,
CreditBreachOfTrust::getCaseNumber,
CreditBreachOfTrust::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditBreachOfTrustService.save(rowItem);
if (!saved) {
CreditBreachOfTrust existing = creditBreachOfTrustService.lambdaQuery()
.eq(CreditBreachOfTrust::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditBreachOfTrustService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditBreachOfTrustService,
chunkItems,
CreditBreachOfTrust::getId,
CreditBreachOfTrust::setId,
CreditBreachOfTrust::getCaseNumber,
CreditBreachOfTrust::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditBreachOfTrustService.save(rowItem);
if (!saved) {
CreditBreachOfTrust existing = creditBreachOfTrustService.lambdaQuery()
.eq(CreditBreachOfTrust::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditBreachOfTrustService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载失信被执行人导入模板
*/
@Operation(summary = "下载失信被执行人导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("失信被执行人");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("失信被执行人导入模板", "失信被执行人", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_breach_of_trust_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditBreachOfTrust convertImportParamToEntity(CreditJudicialImportParam param) {
CreditBreachOfTrust entity = new CreditBreachOfTrust();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCaseFiling;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.param.CreditCaseFilingParam;
import com.gxwebsoft.credit.service.CreditCaseFilingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:47:23
*/
@Tag(name = "司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-case-filing")
public class CreditCaseFilingController extends BaseController {
@Resource
private CreditCaseFilingService creditCaseFilingService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCaseFiling>> page(CreditCaseFilingParam param) {
// 使用关联查询
return success(creditCaseFilingService.pageRel(param));
}
@Operation(summary = "查询全部司法大数据")
@GetMapping()
public ApiResult<List<CreditCaseFiling>> list(CreditCaseFilingParam param) {
// 使用关联查询
return success(creditCaseFilingService.listRel(param));
}
@Operation(summary = "根据id查询司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditCaseFiling> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCaseFilingService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@OperationLog
@Operation(summary = "添加司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCaseFiling creditCaseFiling) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditCaseFiling.setUserId(loginUser.getUserId());
// }
if (creditCaseFilingService.save(creditCaseFiling)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:update')")
@OperationLog
@Operation(summary = "修改司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCaseFiling creditCaseFiling) {
if (creditCaseFilingService.updateById(creditCaseFiling)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:remove')")
@OperationLog
@Operation(summary = "删除司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditCaseFilingService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@OperationLog
@Operation(summary = "批量添加司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCaseFiling> list) {
if (creditCaseFilingService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:update')")
@OperationLog
@Operation(summary = "批量修改司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCaseFiling> batchParam) {
if (batchParam.update(creditCaseFilingService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:remove')")
@OperationLog
@Operation(summary = "批量删除司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditCaseFilingService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@Operation(summary = "批量导入司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditCaseFiling> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditCaseFiling item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCaseFilingService,
chunkItems,
CreditCaseFiling::getId,
CreditCaseFiling::setId,
CreditCaseFiling::getCaseNumber,
CreditCaseFiling::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCaseFilingService.save(rowItem);
if (!saved) {
CreditCaseFiling existing = creditCaseFilingService.lambdaQuery()
.eq(CreditCaseFiling::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCaseFilingService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCaseFilingService,
chunkItems,
CreditCaseFiling::getId,
CreditCaseFiling::setId,
CreditCaseFiling::getCaseNumber,
CreditCaseFiling::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCaseFilingService.save(rowItem);
if (!saved) {
CreditCaseFiling existing = creditCaseFilingService.lambdaQuery()
.eq(CreditCaseFiling::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCaseFilingService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载司法大数据导入模板
*/
@Operation(summary = "下载司法大数据导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("司法大数据");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("司法大数据导入模板", "司法大数据", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_case_filing_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditCaseFiling convertImportParamToEntity(CreditJudicialImportParam param) {
CreditCaseFiling entity = new CreditCaseFiling();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,466 @@
package com.gxwebsoft.credit.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCompany;
import com.gxwebsoft.credit.param.CreditCompanyImportParam;
import com.gxwebsoft.credit.param.CreditCompanyParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 企业控制器
*
* @author 科技小王子
* @since 2025-12-17 08:28:03
*/
@Tag(name = "企业管理")
@RestController
@RequestMapping("/api/credit/credit-company")
public class CreditCompanyController extends BaseController {
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询企业")
@GetMapping("/page")
public ApiResult<PageResult<CreditCompany>> page(CreditCompanyParam param) {
// 使用关联查询
return success(creditCompanyService.pageRel(param));
}
@Operation(summary = "查询全部企业")
@GetMapping()
public ApiResult<List<CreditCompany>> list(CreditCompanyParam param) {
// 使用关联查询
return success(creditCompanyService.listRel(param));
}
@Operation(summary = "根据id查询企业")
@GetMapping("/{id}")
public ApiResult<CreditCompany> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCompanyService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCompany:save')")
@OperationLog
@Operation(summary = "添加企业")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCompany creditCompany) {
if (creditCompanyService.save(creditCompany)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCompany:update')")
@OperationLog
@Operation(summary = "修改企业")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCompany creditCompany) {
if (creditCompanyService.updateById(creditCompany)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCompany:remove')")
@OperationLog
@Operation(summary = "删除企业")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditCompanyService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCompany:save')")
@OperationLog
@Operation(summary = "批量添加企业")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCompany> list) {
if (creditCompanyService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCompany:update')")
@OperationLog
@Operation(summary = "批量修改企业")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCompany> batchParam) {
if (batchParam.update(creditCompanyService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCompany:remove')")
@OperationLog
@Operation(summary = "批量删除企业")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditCompanyService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入企业
*/
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@Operation(summary = "批量导入企业")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
List<CreditCompanyImportParam> list = null;
int usedTitleRows = 0;
int usedHeadRows = 0;
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {0, 2}, {0, 3}};
for (int[] config : tryConfigs) {
list = filterEmptyRows(tryImport(file, config[0], config[1]));
if (!CollectionUtils.isEmpty(list)) {
usedTitleRows = config[0];
usedHeadRows = config[1];
break;
}
}
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, 0, usedTitleRows, usedHeadRows, "原文件导入名称");
Map<String, String> urlByMatchName = ExcelImportSupport.readHyperlinksByHeaderKey(file, 0, usedTitleRows, usedHeadRows, "系统匹配企业名称");
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditCompany> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditCompanyImportParam param = list.get(i);
try {
CreditCompany item = convertImportParamToEntity(param);
String link = null;
if (item.getName() != null) {
link = urlByName.get(item.getName().trim());
}
if ((link == null || link.isEmpty()) && item.getMatchName() != null) {
link = urlByMatchName.get(item.getMatchName().trim());
}
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
// 设置默认值
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
// 验证必填字段
if (item.getMatchName() == null || item.getMatchName().trim().isEmpty()) {
errorMessages.add("" + excelRowNumber + "行:项目名称不能为空");
continue;
}
// if (item.getCode() == null || item.getCode().trim().isEmpty()) {
// errorMessages.add("第" + excelRowNumber + "行:唯一标识不能为空");
// continue;
// }
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCompanyService,
chunkItems,
CreditCompany::getId,
CreditCompany::setId,
CreditCompany::getMatchName,
CreditCompany::getMatchName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCompanyService.save(rowItem);
if (!saved) {
CreditCompany existing = creditCompanyService.getByMatchName(rowItem.getMatchName());
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCompanyService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCompanyService,
chunkItems,
CreditCompany::getId,
CreditCompany::setId,
CreditCompany::getMatchName,
CreditCompany::getMatchName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCompanyService.save(rowItem);
if (!saved) {
CreditCompany existing = creditCompanyService.getByMatchName(rowItem.getMatchName());
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCompanyService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载企业导入模板
*/
@Operation(summary = "下载企业导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditCompanyImportParam> templateList = new ArrayList<>();
CreditCompanyImportParam example = new CreditCompanyImportParam();
example.setName("示例客户");
example.setCode("C0001");
example.setMatchName("匹配名称");
example.setRegistrationStatus("登记状态");
example.setLegalPerson("法定代表人");
example.setRegisteredCapital("注册资本");
example.setPaidinCapital("实缴资本");
example.setEstablishDate("成立日期");
example.setAddress("地址");
example.setTel("电话");
example.setMoreTel("更多电话");
example.setEmail("邮箱");
example.setMoreEmail("更多邮箱");
example.setProvince("");
example.setCity("");
example.setRegion("");
example.setInstitutionType("机构类型");
example.setTaxpayerCode("纳税人识别号");
example.setRegistrationNumber("注册号");
example.setOrganizationalCode("组织机构代码");
example.setNumberOfInsuredPersons("参保人数");
example.setAnnualReport("入库时间");
example.setBusinessTerm("营业期限");
example.setNationalStandardIndustryCategories("国标行业门类");
example.setNationalStandardIndustryCategories2("国标行业大类");
example.setNationalStandardIndustryCategories3("国标行业中类");
example.setNationalStandardIndustryCategories4("国标行业小类");
example.setNationalStandardIndustryCategories5("企查查行业门类");
example.setNationalStandardIndustryCategories6("企查查行业大类");
example.setNationalStandardIndustryCategories7("企查查行业中类");
example.setNationalStandardIndustryCategories8("企查查行业小类");
example.setCompanySize("企业规模");
example.setFormerName("曾用名");
example.setEnglishName("英文名");
example.setDomain("官网");
example.setMailingAddress("通信地址");
example.setCompanyProfile("企业简介");
example.setNatureOfBusiness("经营范围");
example.setRegistrationAuthority("登记机关");
example.setTaxpayerQualification("纳税人资质");
example.setLatestAnnualReportYear("最新年报年份");
example.setLatestAnnualReportOnOperatingRevenue("最新年报营业额");
example.setEnterpriseScoreCheck("企查分");
example.setCreditRating("信用等级");
example.setCechnologyScore("科创分");
example.setCechnologyLevel("科创等级");
example.setSmallEnterprise("是否小微企业");
templateList.add(example);
ExportParams exportParams = new ExportParams("一级企业主表导入模板", "企业");
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, CreditCompanyImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_company_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private List<CreditCompanyImportParam> tryImport(MultipartFile file, int titleRows, int headRows) throws Exception {
ImportParams importParams = new ImportParams();
importParams.setTitleRows(titleRows);
importParams.setHeadRows(headRows);
importParams.setStartSheetIndex(0);
importParams.setSheetNum(1);
return ExcelImportUtil.importExcel(file.getInputStream(), CreditCompanyImportParam.class, importParams);
}
/**
* 过滤掉完全空白的导入行,避免空行导致导入失败
*/
private List<CreditCompanyImportParam> filterEmptyRows(List<CreditCompanyImportParam> rawList) {
if (CollectionUtils.isEmpty(rawList)) {
return rawList;
}
rawList.removeIf(this::isEmptyImportRow);
return rawList;
}
private boolean isEmptyImportRow(CreditCompanyImportParam param) {
if (param == null) {
return true;
}
return isBlank(param.getName())
&& isBlank(param.getCode());
}
private boolean isBlank(String value) {
return value == null || value.trim().isEmpty();
}
/**
* 将CreditCompanyImportParam转换为CreditCompany实体
*/
private CreditCompany convertImportParamToEntity(CreditCompanyImportParam param) {
CreditCompany entity = new CreditCompany();
entity.setCode(param.getCode());
entity.setName(param.getName());
entity.setMatchName(param.getMatchName());
entity.setRegistrationStatus(param.getRegistrationStatus());
entity.setLegalPerson(param.getLegalPerson());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setPaidinCapital(param.getPaidinCapital());
entity.setEstablishDate(param.getEstablishDate());
entity.setAddress(param.getAddress());
entity.setTel(param.getTel());
entity.setMoreTel(param.getMoreTel());
entity.setEmail(param.getEmail());
entity.setMoreEmail(param.getMoreEmail());
entity.setProvince(param.getProvince());
entity.setCity(param.getCity());
entity.setRegion(param.getRegion());
entity.setInstitutionType(param.getInstitutionType());
entity.setTaxpayerCode(param.getTaxpayerCode());
entity.setRegistrationNumber(param.getRegistrationNumber());
entity.setOrganizationalCode(param.getOrganizationalCode());
entity.setNumberOfInsuredPersons(param.getNumberOfInsuredPersons());
entity.setAnnualReport(param.getAnnualReport());
entity.setBusinessTerm(param.getBusinessTerm());
entity.setNationalStandardIndustryCategories(param.getNationalStandardIndustryCategories());
entity.setNationalStandardIndustryCategories2(param.getNationalStandardIndustryCategories2());
entity.setNationalStandardIndustryCategories3(param.getNationalStandardIndustryCategories3());
entity.setNationalStandardIndustryCategories4(param.getNationalStandardIndustryCategories4());
entity.setNationalStandardIndustryCategories5(param.getNationalStandardIndustryCategories5());
entity.setNationalStandardIndustryCategories6(param.getNationalStandardIndustryCategories6());
entity.setNationalStandardIndustryCategories7(param.getNationalStandardIndustryCategories7());
entity.setNationalStandardIndustryCategories8(param.getNationalStandardIndustryCategories8());
entity.setCompanySize(param.getCompanySize());
entity.setFormerName(param.getFormerName());
entity.setEnglishName(param.getEnglishName());
entity.setDomain(param.getDomain());
entity.setMailingAddress(param.getMailingAddress());
entity.setCompanyProfile(param.getCompanyProfile());
entity.setNatureOfBusiness(param.getNatureOfBusiness());
entity.setRegistrationAuthority(param.getRegistrationAuthority());
entity.setTaxpayerQualification(param.getTaxpayerQualification());
entity.setLatestAnnualReportYear(param.getLatestAnnualReportYear());
entity.setLatestAnnualReportOnOperatingRevenue(param.getLatestAnnualReportOnOperatingRevenue());
entity.setEnterpriseScoreCheck(param.getEnterpriseScoreCheck());
entity.setCreditRating(param.getCreditRating());
entity.setCechnologyScore(param.getCechnologyScore());
entity.setCechnologyLevel(param.getCechnologyLevel());
entity.setSmallEnterprise(param.getSmallEnterprise());
return entity;
}
}

View File

@@ -0,0 +1,345 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCompetitor;
import com.gxwebsoft.credit.param.CreditCompetitorImportParam;
import com.gxwebsoft.credit.param.CreditCompetitorParam;
import com.gxwebsoft.credit.service.CreditCompetitorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 竞争对手控制器
*
* @author 科技小王子
* @since 2025-12-19 19:49:05
*/
@Tag(name = "竞争对手管理")
@RestController
@RequestMapping("/api/credit/credit-competitor")
public class CreditCompetitorController extends BaseController {
@Resource
private CreditCompetitorService creditCompetitorService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询竞争对手")
@GetMapping("/page")
public ApiResult<PageResult<CreditCompetitor>> page(CreditCompetitorParam param) {
// 使用关联查询
return success(creditCompetitorService.pageRel(param));
}
@Operation(summary = "查询全部竞争对手")
@GetMapping()
public ApiResult<List<CreditCompetitor>> list(CreditCompetitorParam param) {
// 使用关联查询
return success(creditCompetitorService.listRel(param));
}
@Operation(summary = "根据id查询竞争对手")
@GetMapping("/{id}")
public ApiResult<CreditCompetitor> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCompetitorService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:save')")
@OperationLog
@Operation(summary = "添加竞争对手")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCompetitor creditCompetitor) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditCompetitor.setUserId(loginUser.getUserId());
// }
if (creditCompetitorService.save(creditCompetitor)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:update')")
@OperationLog
@Operation(summary = "修改竞争对手")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCompetitor creditCompetitor) {
if (creditCompetitorService.updateById(creditCompetitor)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:remove')")
@OperationLog
@Operation(summary = "删除竞争对手")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditCompetitorService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:save')")
@OperationLog
@Operation(summary = "批量添加竞争对手")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCompetitor> list) {
if (creditCompetitorService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:update')")
@OperationLog
@Operation(summary = "批量修改竞争对手")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCompetitor> batchParam) {
if (batchParam.update(creditCompetitorService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:remove')")
@OperationLog
@Operation(summary = "批量删除竞争对手")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditCompetitorService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入竞争对手
*/
@PreAuthorize("hasAuthority('credit:creditCompetitor:save')")
@Operation(summary = "批量导入竞争对手")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "竞争对手", 2);
ExcelImportSupport.ImportResult<CreditCompetitorImportParam> importResult = ExcelImportSupport.read(
file, CreditCompetitorImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCompetitorImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditCompetitor> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditCompetitorImportParam param = list.get(i);
try {
CreditCompetitor item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCompanyName())) {
errorMessages.add("" + excelRowNumber + "行:企业名称不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCompetitorService,
chunkItems,
CreditCompetitor::getId,
CreditCompetitor::setId,
CreditCompetitor::getCompanyName,
CreditCompetitor::getCompanyName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCompetitorService.save(rowItem);
if (!saved) {
CreditCompetitor existing = creditCompetitorService.lambdaQuery()
.eq(CreditCompetitor::getCompanyName, rowItem.getCompanyName())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCompetitorService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCompetitorService,
chunkItems,
CreditCompetitor::getId,
CreditCompetitor::setId,
CreditCompetitor::getCompanyName,
CreditCompetitor::getCompanyName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCompetitorService.save(rowItem);
if (!saved) {
CreditCompetitor existing = creditCompetitorService.lambdaQuery()
.eq(CreditCompetitor::getCompanyName, rowItem.getCompanyName())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCompetitorService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载竞争对手导入模板
*/
@Operation(summary = "下载竞争对手导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditCompetitorImportParam> templateList = new ArrayList<>();
CreditCompetitorImportParam example = new CreditCompetitorImportParam();
example.setCompanyName("示例科技有限公司");
example.setLegalRepresentative("张三");
example.setRegisteredCapital("5000");
example.setEstablishmentDate("2015-01-01");
example.setRegistrationStatus("存续");
example.setIndustry("软件和信息服务业");
example.setProvince("广东省");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("竞争对手导入模板", "竞争对手", CreditCompetitorImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_competitor_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditCompetitorImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCompanyName())
&& ImportHelper.isBlank(param.getLegalRepresentative())
&& ImportHelper.isBlank(param.getRegisteredCapital())
&& ImportHelper.isBlank(param.getEstablishmentDate());
}
private CreditCompetitor convertImportParamToEntity(CreditCompetitorImportParam param) {
CreditCompetitor entity = new CreditCompetitor();
entity.setCompanyName(param.getCompanyName());
entity.setLegalRepresentative(param.getLegalRepresentative());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setEstablishmentDate(param.getEstablishmentDate());
entity.setRegistrationStatus(param.getRegistrationStatus());
entity.setIndustry(param.getIndustry());
entity.setProvince(param.getProvince());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCourtAnnouncement;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.param.CreditCourtAnnouncementParam;
import com.gxwebsoft.credit.service.CreditCourtAnnouncementService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 法院公告司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:49:13
*/
@Tag(name = "法院公告司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-court-announcement")
public class CreditCourtAnnouncementController extends BaseController {
@Resource
private CreditCourtAnnouncementService creditCourtAnnouncementService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询法院公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCourtAnnouncement>> page(CreditCourtAnnouncementParam param) {
// 使用关联查询
return success(creditCourtAnnouncementService.pageRel(param));
}
@Operation(summary = "查询全部法院公告司法大数据")
@GetMapping()
public ApiResult<List<CreditCourtAnnouncement>> list(CreditCourtAnnouncementParam param) {
// 使用关联查询
return success(creditCourtAnnouncementService.listRel(param));
}
@Operation(summary = "根据id查询法院公告司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditCourtAnnouncement> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCourtAnnouncementService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@OperationLog
@Operation(summary = "添加法院公告司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCourtAnnouncement creditCourtAnnouncement) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditCourtAnnouncement.setUserId(loginUser.getUserId());
// }
if (creditCourtAnnouncementService.save(creditCourtAnnouncement)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:update')")
@OperationLog
@Operation(summary = "修改法院公告司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCourtAnnouncement creditCourtAnnouncement) {
if (creditCourtAnnouncementService.updateById(creditCourtAnnouncement)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:remove')")
@OperationLog
@Operation(summary = "删除法院公告司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditCourtAnnouncementService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@OperationLog
@Operation(summary = "批量添加法院公告司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCourtAnnouncement> list) {
if (creditCourtAnnouncementService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:update')")
@OperationLog
@Operation(summary = "批量修改法院公告司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCourtAnnouncement> batchParam) {
if (batchParam.update(creditCourtAnnouncementService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:remove')")
@OperationLog
@Operation(summary = "批量删除法院公告司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditCourtAnnouncementService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入法院公告司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@Operation(summary = "批量导入法院公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditCourtAnnouncement> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditCourtAnnouncement item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCourtAnnouncementService,
chunkItems,
CreditCourtAnnouncement::getId,
CreditCourtAnnouncement::setId,
CreditCourtAnnouncement::getCaseNumber,
CreditCourtAnnouncement::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCourtAnnouncementService.save(rowItem);
if (!saved) {
CreditCourtAnnouncement existing = creditCourtAnnouncementService.lambdaQuery()
.eq(CreditCourtAnnouncement::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCourtAnnouncementService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCourtAnnouncementService,
chunkItems,
CreditCourtAnnouncement::getId,
CreditCourtAnnouncement::setId,
CreditCourtAnnouncement::getCaseNumber,
CreditCourtAnnouncement::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCourtAnnouncementService.save(rowItem);
if (!saved) {
CreditCourtAnnouncement existing = creditCourtAnnouncementService.lambdaQuery()
.eq(CreditCourtAnnouncement::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCourtAnnouncementService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载法院公告司法大数据导入模板
*/
@Operation(summary = "下载法院公告司法大数据导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("法院公告");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("法院公告导入模板", "法院公告", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_court_announcement_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditCourtAnnouncement convertImportParamToEntity(CreditJudicialImportParam param) {
CreditCourtAnnouncement entity = new CreditCourtAnnouncement();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCourtSession;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.param.CreditCourtSessionParam;
import com.gxwebsoft.credit.service.CreditCourtSessionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 开庭公告司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:49:33
*/
@Tag(name = "开庭公告司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-court-session")
public class CreditCourtSessionController extends BaseController {
@Resource
private CreditCourtSessionService creditCourtSessionService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询开庭公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCourtSession>> page(CreditCourtSessionParam param) {
// 使用关联查询
return success(creditCourtSessionService.pageRel(param));
}
@Operation(summary = "查询全部开庭公告司法大数据")
@GetMapping()
public ApiResult<List<CreditCourtSession>> list(CreditCourtSessionParam param) {
// 使用关联查询
return success(creditCourtSessionService.listRel(param));
}
@Operation(summary = "根据id查询开庭公告司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditCourtSession> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCourtSessionService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@OperationLog
@Operation(summary = "添加开庭公告司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCourtSession creditCourtSession) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditCourtSession.setUserId(loginUser.getUserId());
// }
if (creditCourtSessionService.save(creditCourtSession)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:update')")
@OperationLog
@Operation(summary = "修改开庭公告司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCourtSession creditCourtSession) {
if (creditCourtSessionService.updateById(creditCourtSession)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:remove')")
@OperationLog
@Operation(summary = "删除开庭公告司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditCourtSessionService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@OperationLog
@Operation(summary = "批量添加开庭公告司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCourtSession> list) {
if (creditCourtSessionService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:update')")
@OperationLog
@Operation(summary = "批量修改开庭公告司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCourtSession> batchParam) {
if (batchParam.update(creditCourtSessionService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:remove')")
@OperationLog
@Operation(summary = "批量删除开庭公告司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditCourtSessionService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入开庭公告司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@Operation(summary = "批量导入开庭公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditCourtSession> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditCourtSession item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCourtSessionService,
chunkItems,
CreditCourtSession::getId,
CreditCourtSession::setId,
CreditCourtSession::getCaseNumber,
CreditCourtSession::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCourtSessionService.save(rowItem);
if (!saved) {
CreditCourtSession existing = creditCourtSessionService.lambdaQuery()
.eq(CreditCourtSession::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCourtSessionService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditCourtSessionService,
chunkItems,
CreditCourtSession::getId,
CreditCourtSession::setId,
CreditCourtSession::getCaseNumber,
CreditCourtSession::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditCourtSessionService.save(rowItem);
if (!saved) {
CreditCourtSession existing = creditCourtSessionService.lambdaQuery()
.eq(CreditCourtSession::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditCourtSessionService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载开庭公告司法大数据导入模板
*/
@Operation(summary = "下载开庭公告司法大数据导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("开庭公告");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("开庭公告导入模板", "开庭公告", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_court_session_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditCourtSession convertImportParamToEntity(CreditJudicialImportParam param) {
CreditCourtSession entity = new CreditCourtSession();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,507 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCustomer;
import com.gxwebsoft.credit.param.CreditCustomerImportParam;
import com.gxwebsoft.credit.param.CreditCustomerParam;
import com.gxwebsoft.credit.service.CreditCustomerService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 客户控制器
*
* @author 科技小王子
* @since 2025-12-21 21:20:58
*/
@Tag(name = "客户管理")
@RestController
@RequestMapping("/api/credit/credit-customer")
public class CreditCustomerController extends BaseController {
@Resource
private CreditCustomerService creditCustomerService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询客户")
@GetMapping("/page")
public ApiResult<PageResult<CreditCustomer>> page(CreditCustomerParam param) {
// 使用关联查询
return success(creditCustomerService.pageRel(param));
}
@Operation(summary = "查询全部客户")
@GetMapping()
public ApiResult<List<CreditCustomer>> list(CreditCustomerParam param) {
// 使用关联查询
return success(creditCustomerService.listRel(param));
}
@Operation(summary = "根据id查询客户")
@GetMapping("/{id}")
public ApiResult<CreditCustomer> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCustomerService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCustomer:save')")
@OperationLog
@Operation(summary = "添加客户")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCustomer creditCustomer) {
if (creditCustomerService.save(creditCustomer)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:update')")
@OperationLog
@Operation(summary = "修改客户")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCustomer creditCustomer) {
if (creditCustomerService.updateById(creditCustomer)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:remove')")
@OperationLog
@Operation(summary = "删除客户")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditCustomerService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:save')")
@OperationLog
@Operation(summary = "批量添加客户")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCustomer> list) {
if (creditCustomerService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:update')")
@OperationLog
@Operation(summary = "批量修改客户")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCustomer> batchParam) {
if (batchParam.update(creditCustomerService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:remove')")
@OperationLog
@Operation(summary = "批量删除客户")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditCustomerService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入客户
*/
@PreAuthorize("hasAuthority('credit:creditCustomer:save')")
@Operation(summary = "批量导入客户")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "客户", 4);
ExcelImportSupport.ImportResult<CreditCustomerImportParam> importResult = ExcelImportSupport.read(
file, CreditCustomerImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCustomerImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditCustomer> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditCustomerImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditCustomer item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:客户不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> {
// 批内一次查库,避免逐行查/写导致数据库压力过大
List<String> names = new ArrayList<>(chunkItems.size());
for (CreditCustomer it : chunkItems) {
if (it != null && !ImportHelper.isBlank(it.getName())) {
names.add(it.getName().trim());
}
}
List<CreditCustomer> existingList = names.isEmpty()
? new ArrayList<>()
: creditCustomerService.lambdaQuery()
.in(CreditCustomer::getName, names)
.list();
java.util.Map<String, CreditCustomer> existingByName = new java.util.HashMap<>();
for (CreditCustomer existing : existingList) {
if (existing != null && !ImportHelper.isBlank(existing.getName())) {
existingByName.putIfAbsent(existing.getName().trim(), existing);
}
}
java.util.Map<String, CreditCustomer> latestByName = new java.util.HashMap<>();
int acceptedRows = 0;
for (int idx = 0; idx < chunkItems.size(); idx++) {
CreditCustomer it = chunkItems.get(idx);
int rowNo = (idx < chunkRowNumbers.size()) ? chunkRowNumbers.get(idx) : -1;
if (it == null || ImportHelper.isBlank(it.getName())) {
continue;
}
String name = it.getName().trim();
CreditCustomer existing = existingByName.get(name);
if (existing != null) {
Integer existingTenantId = existing.getTenantId();
if (it.getTenantId() != null
&& existingTenantId != null
&& !it.getTenantId().equals(existingTenantId)) {
errorMessages.add("" + rowNo + "行:客户名称已存在且归属其他租户,无法导入");
continue;
}
it.setId(existing.getId());
if (existingTenantId != null) {
it.setTenantId(existingTenantId);
}
}
// 同名多行:保留最后一行的值(等价于“先插入/更新,再被后续行更新”)
latestByName.put(name, it);
acceptedRows++;
}
List<CreditCustomer> updates = new ArrayList<>();
List<CreditCustomer> inserts = new ArrayList<>();
for (CreditCustomer it : latestByName.values()) {
if (it.getId() != null) {
updates.add(it);
} else {
inserts.add(it);
}
}
if (!updates.isEmpty()) {
creditCustomerService.updateBatchById(updates, mpBatchSize);
}
if (!inserts.isEmpty()) {
creditCustomerService.saveBatch(inserts, mpBatchSize);
}
return acceptedRows;
},
(rowItem, rowNumber) -> {
CreditCustomer existing = creditCustomerService.lambdaQuery()
.eq(CreditCustomer::getName, rowItem.getName())
.one();
if (existing != null) {
Integer existingTenantId = existing.getTenantId();
if (rowItem.getTenantId() != null
&& existingTenantId != null
&& !rowItem.getTenantId().equals(existingTenantId)) {
errorMessages.add("" + rowNumber + "行:客户名称已存在且归属其他租户,无法导入");
return false;
}
rowItem.setId(existing.getId());
if (existingTenantId != null) {
rowItem.setTenantId(existingTenantId);
}
return creditCustomerService.updateById(rowItem);
}
try {
return creditCustomerService.save(rowItem);
} catch (DataIntegrityViolationException e) {
if (!isDuplicateCustomerName(e)) {
throw e;
}
CreditCustomer dbExisting = creditCustomerService.lambdaQuery()
.eq(CreditCustomer::getName, rowItem.getName())
.one();
if (dbExisting != null) {
Integer existingTenantId = dbExisting.getTenantId();
rowItem.setId(dbExisting.getId());
if (existingTenantId != null) {
rowItem.setTenantId(existingTenantId);
}
return creditCustomerService.updateById(rowItem);
}
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> {
List<String> names = new ArrayList<>(chunkItems.size());
for (CreditCustomer it : chunkItems) {
if (it != null && !ImportHelper.isBlank(it.getName())) {
names.add(it.getName().trim());
}
}
List<CreditCustomer> existingList = names.isEmpty()
? new ArrayList<>()
: creditCustomerService.lambdaQuery()
.in(CreditCustomer::getName, names)
.list();
java.util.Map<String, CreditCustomer> existingByName = new java.util.HashMap<>();
for (CreditCustomer existing : existingList) {
if (existing != null && !ImportHelper.isBlank(existing.getName())) {
existingByName.putIfAbsent(existing.getName().trim(), existing);
}
}
java.util.Map<String, CreditCustomer> latestByName = new java.util.HashMap<>();
int acceptedRows = 0;
for (int idx = 0; idx < chunkItems.size(); idx++) {
CreditCustomer it = chunkItems.get(idx);
int rowNo = (idx < chunkRowNumbers.size()) ? chunkRowNumbers.get(idx) : -1;
if (it == null || ImportHelper.isBlank(it.getName())) {
continue;
}
String name = it.getName().trim();
CreditCustomer existing = existingByName.get(name);
if (existing != null) {
Integer existingTenantId = existing.getTenantId();
if (it.getTenantId() != null
&& existingTenantId != null
&& !it.getTenantId().equals(existingTenantId)) {
errorMessages.add("" + rowNo + "行:客户名称已存在且归属其他租户,无法导入");
continue;
}
it.setId(existing.getId());
if (existingTenantId != null) {
it.setTenantId(existingTenantId);
}
}
latestByName.put(name, it);
acceptedRows++;
}
List<CreditCustomer> updates = new ArrayList<>();
List<CreditCustomer> inserts = new ArrayList<>();
for (CreditCustomer it : latestByName.values()) {
if (it.getId() != null) {
updates.add(it);
} else {
inserts.add(it);
}
}
if (!updates.isEmpty()) {
creditCustomerService.updateBatchById(updates, mpBatchSize);
}
if (!inserts.isEmpty()) {
creditCustomerService.saveBatch(inserts, mpBatchSize);
}
return acceptedRows;
},
(rowItem, rowNumber) -> {
CreditCustomer existing = creditCustomerService.lambdaQuery()
.eq(CreditCustomer::getName, rowItem.getName())
.one();
if (existing != null) {
Integer existingTenantId = existing.getTenantId();
if (rowItem.getTenantId() != null
&& existingTenantId != null
&& !rowItem.getTenantId().equals(existingTenantId)) {
errorMessages.add("" + rowNumber + "行:客户名称已存在且归属其他租户,无法导入");
return false;
}
rowItem.setId(existing.getId());
if (existingTenantId != null) {
rowItem.setTenantId(existingTenantId);
}
return creditCustomerService.updateById(rowItem);
}
try {
return creditCustomerService.save(rowItem);
} catch (DataIntegrityViolationException e) {
if (!isDuplicateCustomerName(e)) {
throw e;
}
CreditCustomer dbExisting = creditCustomerService.lambdaQuery()
.eq(CreditCustomer::getName, rowItem.getName())
.one();
if (dbExisting != null) {
Integer existingTenantId = dbExisting.getTenantId();
rowItem.setId(dbExisting.getId());
if (existingTenantId != null) {
rowItem.setTenantId(existingTenantId);
}
return creditCustomerService.updateById(rowItem);
}
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载客户导入模板
*/
@Operation(summary = "下载客户导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditCustomerImportParam> templateList = new ArrayList<>();
CreditCustomerImportParam example = new CreditCustomerImportParam();
example.setName("示例客户");
example.setStatusTxt("合作中");
example.setPrice("88.8");
example.setPublicDate("2024-01-01");
example.setDataSource("公开渠道");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("客户导入模板", "客户", CreditCustomerImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_customer_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditCustomerImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getStatusTxt())
&& ImportHelper.isBlank(param.getPrice());
}
private CreditCustomer convertImportParamToEntity(CreditCustomerImportParam param) {
CreditCustomer entity = new CreditCustomer();
entity.setName(normalizeString(param.getName()));
entity.setStatusTxt(normalizeString(param.getStatusTxt()));
entity.setPrice(normalizeString(param.getPrice()));
entity.setPublicDate(normalizeString(param.getPublicDate()));
entity.setDataSource(normalizeString(param.getDataSource()));
entity.setComments(normalizeString(param.getComments()));
return entity;
}
private String normalizeString(String value) {
if (ImportHelper.isBlank(value)) {
return null;
}
return value.trim();
}
private boolean isDuplicateCustomerName(DataIntegrityViolationException e) {
Throwable mostSpecificCause = e.getMostSpecificCause();
String message = mostSpecificCause != null ? mostSpecificCause.getMessage() : e.getMessage();
if (message == null) {
return false;
}
String lower = message.toLowerCase();
if (!lower.contains("duplicate")) {
return false;
}
return lower.contains("credit_customer.name")
|| lower.contains("for key 'name'")
|| lower.contains("for key `name`");
}
}

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditDeliveryNotice;
import com.gxwebsoft.credit.param.CreditDeliveryNoticeParam;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.service.CreditDeliveryNoticeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 送达公告司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:49:52
*/
@Tag(name = "送达公告司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-delivery-notice")
public class CreditDeliveryNoticeController extends BaseController {
@Resource
private CreditDeliveryNoticeService creditDeliveryNoticeService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询送达公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditDeliveryNotice>> page(CreditDeliveryNoticeParam param) {
// 使用关联查询
return success(creditDeliveryNoticeService.pageRel(param));
}
@Operation(summary = "查询全部送达公告司法大数据")
@GetMapping()
public ApiResult<List<CreditDeliveryNotice>> list(CreditDeliveryNoticeParam param) {
// 使用关联查询
return success(creditDeliveryNoticeService.listRel(param));
}
@Operation(summary = "根据id查询送达公告司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditDeliveryNotice> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditDeliveryNoticeService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@OperationLog
@Operation(summary = "添加送达公告司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditDeliveryNotice creditDeliveryNotice) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditDeliveryNotice.setUserId(loginUser.getUserId());
// }
if (creditDeliveryNoticeService.save(creditDeliveryNotice)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:update')")
@OperationLog
@Operation(summary = "修改送达公告司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditDeliveryNotice creditDeliveryNotice) {
if (creditDeliveryNoticeService.updateById(creditDeliveryNotice)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:remove')")
@OperationLog
@Operation(summary = "删除送达公告司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditDeliveryNoticeService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@OperationLog
@Operation(summary = "批量添加送达公告司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditDeliveryNotice> list) {
if (creditDeliveryNoticeService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:update')")
@OperationLog
@Operation(summary = "批量修改送达公告司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditDeliveryNotice> batchParam) {
if (batchParam.update(creditDeliveryNoticeService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:remove')")
@OperationLog
@Operation(summary = "批量删除送达公告司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditDeliveryNoticeService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入送达公告司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@Operation(summary = "批量导入送达公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditDeliveryNotice> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditDeliveryNotice item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditDeliveryNoticeService,
chunkItems,
CreditDeliveryNotice::getId,
CreditDeliveryNotice::setId,
CreditDeliveryNotice::getCaseNumber,
CreditDeliveryNotice::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditDeliveryNoticeService.save(rowItem);
if (!saved) {
CreditDeliveryNotice existing = creditDeliveryNoticeService.lambdaQuery()
.eq(CreditDeliveryNotice::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditDeliveryNoticeService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditDeliveryNoticeService,
chunkItems,
CreditDeliveryNotice::getId,
CreditDeliveryNotice::setId,
CreditDeliveryNotice::getCaseNumber,
CreditDeliveryNotice::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditDeliveryNoticeService.save(rowItem);
if (!saved) {
CreditDeliveryNotice existing = creditDeliveryNoticeService.lambdaQuery()
.eq(CreditDeliveryNotice::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditDeliveryNoticeService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载送达公告导入模板
*/
@Operation(summary = "下载送达公告导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("送达公告");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("送达公告导入模板", "送达公告", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_delivery_notice_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditDeliveryNotice convertImportParamToEntity(CreditJudicialImportParam param) {
CreditDeliveryNotice entity = new CreditDeliveryNotice();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,359 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditExternal;
import com.gxwebsoft.credit.param.CreditExternalImportParam;
import com.gxwebsoft.credit.param.CreditExternalParam;
import com.gxwebsoft.credit.service.CreditExternalService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 对外投资控制器
*
* @author 科技小王子
* @since 2025-12-19 19:50:12
*/
@Tag(name = "对外投资管理")
@RestController
@RequestMapping("/api/credit/credit-external")
public class CreditExternalController extends BaseController {
@Resource
private CreditExternalService creditExternalService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询对外投资")
@GetMapping("/page")
public ApiResult<PageResult<CreditExternal>> page(CreditExternalParam param) {
// 使用关联查询
return success(creditExternalService.pageRel(param));
}
@Operation(summary = "查询全部对外投资")
@GetMapping()
public ApiResult<List<CreditExternal>> list(CreditExternalParam param) {
// 使用关联查询
return success(creditExternalService.listRel(param));
}
@Operation(summary = "根据id查询对外投资")
@GetMapping("/{id}")
public ApiResult<CreditExternal> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditExternalService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditExternal:save')")
@OperationLog
@Operation(summary = "添加对外投资")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditExternal creditExternal) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditExternal.setUserId(loginUser.getUserId());
// }
if (creditExternalService.save(creditExternal)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:update')")
@OperationLog
@Operation(summary = "修改对外投资")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditExternal creditExternal) {
if (creditExternalService.updateById(creditExternal)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:remove')")
@OperationLog
@Operation(summary = "删除对外投资")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditExternalService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:save')")
@OperationLog
@Operation(summary = "批量添加对外投资")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditExternal> list) {
if (creditExternalService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:update')")
@OperationLog
@Operation(summary = "批量修改对外投资")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditExternal> batchParam) {
if (batchParam.update(creditExternalService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:remove')")
@OperationLog
@Operation(summary = "批量删除对外投资")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditExternalService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入对外投资
*/
@PreAuthorize("hasAuthority('credit:creditExternal:save')")
@Operation(summary = "批量导入对外投资")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "对外投资", 0);
ExcelImportSupport.ImportResult<CreditExternalImportParam> importResult = ExcelImportSupport.read(
file, CreditExternalImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditExternalImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditExternal> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditExternalImportParam param = list.get(i);
try {
CreditExternal item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:被投资企业名称不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditExternalService,
chunkItems,
CreditExternal::getId,
CreditExternal::setId,
CreditExternal::getName,
CreditExternal::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditExternalService.save(rowItem);
if (!saved) {
CreditExternal existing = creditExternalService.lambdaQuery()
.eq(CreditExternal::getName, rowItem.getName())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditExternalService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditExternalService,
chunkItems,
CreditExternal::getId,
CreditExternal::setId,
CreditExternal::getName,
CreditExternal::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditExternalService.save(rowItem);
if (!saved) {
CreditExternal existing = creditExternalService.lambdaQuery()
.eq(CreditExternal::getName, rowItem.getName())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditExternalService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载对外投资导入模板
*/
@Operation(summary = "下载对外投资导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditExternalImportParam> templateList = new ArrayList<>();
CreditExternalImportParam example = new CreditExternalImportParam();
example.setName("示例科技有限公司");
example.setStatusTxt("存续");
example.setLegalRepresentative("李四");
example.setRegisteredCapital("10000");
example.setEstablishmentDate("2018-06-01");
example.setShareholdingRatio("20");
example.setSubscribedInvestmentAmount("2000");
example.setSubscribedInvestmentDate("2019-01-01");
example.setIndirectShareholdingRatio("5");
example.setInvestmentDate("2019-06-01");
example.setRegion("上海");
example.setIndustry("信息技术");
example.setInvestmentCount(1);
example.setRelatedProductsInstitutions("关联产品示例");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("对外投资导入模板", "对外投资", CreditExternalImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_external_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditExternalImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getLegalRepresentative())
&& ImportHelper.isBlank(param.getRegisteredCapital())
&& ImportHelper.isBlank(param.getEstablishmentDate());
}
private CreditExternal convertImportParamToEntity(CreditExternalImportParam param) {
CreditExternal entity = new CreditExternal();
entity.setName(param.getName());
entity.setStatusTxt(param.getStatusTxt());
entity.setLegalRepresentative(param.getLegalRepresentative());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setEstablishmentDate(param.getEstablishmentDate());
entity.setShareholdingRatio(param.getShareholdingRatio());
entity.setSubscribedInvestmentAmount(param.getSubscribedInvestmentAmount());
entity.setSubscribedInvestmentDate(param.getSubscribedInvestmentDate());
entity.setIndirectShareholdingRatio(param.getIndirectShareholdingRatio());
entity.setInvestmentDate(param.getInvestmentDate());
entity.setRegion(param.getRegion());
entity.setIndustry(param.getIndustry());
entity.setInvestmentCount(param.getInvestmentCount());
entity.setRelatedProductsInstitutions(param.getRelatedProductsInstitutions());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditFinalVersion;
import com.gxwebsoft.credit.param.CreditFinalVersionParam;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.service.CreditFinalVersionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 终本案件控制器
*
* @author 科技小王子
* @since 2025-12-19 19:50:19
*/
@Tag(name = "终本案件管理")
@RestController
@RequestMapping("/api/credit/credit-final-version")
public class CreditFinalVersionController extends BaseController {
@Resource
private CreditFinalVersionService creditFinalVersionService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询终本案件")
@GetMapping("/page")
public ApiResult<PageResult<CreditFinalVersion>> page(CreditFinalVersionParam param) {
// 使用关联查询
return success(creditFinalVersionService.pageRel(param));
}
@Operation(summary = "查询全部终本案件")
@GetMapping()
public ApiResult<List<CreditFinalVersion>> list(CreditFinalVersionParam param) {
// 使用关联查询
return success(creditFinalVersionService.listRel(param));
}
@Operation(summary = "根据id查询终本案件")
@GetMapping("/{id}")
public ApiResult<CreditFinalVersion> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditFinalVersionService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@OperationLog
@Operation(summary = "添加终本案件")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditFinalVersion creditFinalVersion) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditFinalVersion.setUserId(loginUser.getUserId());
// }
if (creditFinalVersionService.save(creditFinalVersion)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:update')")
@OperationLog
@Operation(summary = "修改终本案件")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditFinalVersion creditFinalVersion) {
if (creditFinalVersionService.updateById(creditFinalVersion)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:remove')")
@OperationLog
@Operation(summary = "删除终本案件")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditFinalVersionService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@OperationLog
@Operation(summary = "批量添加终本案件")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditFinalVersion> list) {
if (creditFinalVersionService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:update')")
@OperationLog
@Operation(summary = "批量修改终本案件")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditFinalVersion> batchParam) {
if (batchParam.update(creditFinalVersionService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:remove')")
@OperationLog
@Operation(summary = "批量删除终本案件")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditFinalVersionService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入终本案件
*/
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@Operation(summary = "批量导入终本案件")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditFinalVersion> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditFinalVersion item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditFinalVersionService,
chunkItems,
CreditFinalVersion::getId,
CreditFinalVersion::setId,
CreditFinalVersion::getCaseNumber,
CreditFinalVersion::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditFinalVersionService.save(rowItem);
if (!saved) {
CreditFinalVersion existing = creditFinalVersionService.lambdaQuery()
.eq(CreditFinalVersion::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditFinalVersionService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditFinalVersionService,
chunkItems,
CreditFinalVersion::getId,
CreditFinalVersion::setId,
CreditFinalVersion::getCaseNumber,
CreditFinalVersion::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditFinalVersionService.save(rowItem);
if (!saved) {
CreditFinalVersion existing = creditFinalVersionService.lambdaQuery()
.eq(CreditFinalVersion::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditFinalVersionService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载终本案件导入模板
*/
@Operation(summary = "下载终本案件导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("终本案件");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("终本案件导入模板", "终本案件", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_final_version_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditFinalVersion convertImportParamToEntity(CreditJudicialImportParam param) {
CreditFinalVersion entity = new CreditFinalVersion();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditGqdj;
import com.gxwebsoft.credit.param.CreditGqdjParam;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.service.CreditGqdjService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 股权冻结控制器
*
* @author 科技小王子
* @since 2025-12-19 19:50:37
*/
@Tag(name = "股权冻结管理")
@RestController
@RequestMapping("/api/credit/credit-gqdj")
public class CreditGqdjController extends BaseController {
@Resource
private CreditGqdjService creditGqdjService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询股权冻结")
@GetMapping("/page")
public ApiResult<PageResult<CreditGqdj>> page(CreditGqdjParam param) {
// 使用关联查询
return success(creditGqdjService.pageRel(param));
}
@Operation(summary = "查询全部股权冻结")
@GetMapping()
public ApiResult<List<CreditGqdj>> list(CreditGqdjParam param) {
// 使用关联查询
return success(creditGqdjService.listRel(param));
}
@Operation(summary = "根据id查询股权冻结")
@GetMapping("/{id}")
public ApiResult<CreditGqdj> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditGqdjService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@OperationLog
@Operation(summary = "添加股权冻结")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditGqdj creditGqdj) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditGqdj.setUserId(loginUser.getUserId());
// }
if (creditGqdjService.save(creditGqdj)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:update')")
@OperationLog
@Operation(summary = "修改股权冻结")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditGqdj creditGqdj) {
if (creditGqdjService.updateById(creditGqdj)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:remove')")
@OperationLog
@Operation(summary = "删除股权冻结")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditGqdjService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@OperationLog
@Operation(summary = "批量添加股权冻结")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditGqdj> list) {
if (creditGqdjService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:update')")
@OperationLog
@Operation(summary = "批量修改股权冻结")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditGqdj> batchParam) {
if (batchParam.update(creditGqdjService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:remove')")
@OperationLog
@Operation(summary = "批量删除股权冻结")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditGqdjService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入股权冻结司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@Operation(summary = "批量导入股权冻结司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditGqdj> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditGqdj item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditGqdjService,
chunkItems,
CreditGqdj::getId,
CreditGqdj::setId,
CreditGqdj::getCaseNumber,
CreditGqdj::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditGqdjService.save(rowItem);
if (!saved) {
CreditGqdj existing = creditGqdjService.lambdaQuery()
.eq(CreditGqdj::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditGqdjService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditGqdjService,
chunkItems,
CreditGqdj::getId,
CreditGqdj::setId,
CreditGqdj::getCaseNumber,
CreditGqdj::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditGqdjService.save(rowItem);
if (!saved) {
CreditGqdj existing = creditGqdjService.lambdaQuery()
.eq(CreditGqdj::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditGqdjService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载股权冻结导入模板
*/
@Operation(summary = "下载股权冻结导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("股权冻结");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("股权冻结导入模板", "股权冻结", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_gqdj_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditGqdj convertImportParamToEntity(CreditJudicialImportParam param) {
CreditGqdj entity = new CreditGqdj();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,455 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditHistoricalLegalPerson;
import com.gxwebsoft.credit.param.CreditHistoricalLegalPersonImportParam;
import com.gxwebsoft.credit.param.CreditHistoricalLegalPersonParam;
import com.gxwebsoft.credit.service.CreditHistoricalLegalPersonService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 历史法定代表人控制器
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Tag(name = "历史法定代表人管理")
@RestController
@RequestMapping("/api/credit/credit-historical-legal-person")
public class CreditHistoricalLegalPersonController extends BaseController {
@Resource
private CreditHistoricalLegalPersonService creditHistoricalLegalPersonService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询历史法定代表人")
@GetMapping("/page")
public ApiResult<PageResult<CreditHistoricalLegalPerson>> page(CreditHistoricalLegalPersonParam param) {
// 使用关联查询
return success(creditHistoricalLegalPersonService.pageRel(param));
}
@Operation(summary = "查询全部历史法定代表人")
@GetMapping()
public ApiResult<List<CreditHistoricalLegalPerson>> list(CreditHistoricalLegalPersonParam param) {
// 使用关联查询
return success(creditHistoricalLegalPersonService.listRel(param));
}
@Operation(summary = "根据id查询历史法定代表人")
@GetMapping("/{id}")
public ApiResult<CreditHistoricalLegalPerson> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditHistoricalLegalPersonService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditHistoricalLegalPerson:save')")
@OperationLog
@Operation(summary = "添加历史法定代表人")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditHistoricalLegalPerson creditHistoricalLegalPerson) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditHistoricalLegalPerson.setUserId(loginUser.getUserId());
// }
if (creditHistoricalLegalPersonService.save(creditHistoricalLegalPerson)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditHistoricalLegalPerson:update')")
@OperationLog
@Operation(summary = "修改历史法定代表人")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditHistoricalLegalPerson creditHistoricalLegalPerson) {
if (creditHistoricalLegalPersonService.updateById(creditHistoricalLegalPerson)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditHistoricalLegalPerson:remove')")
@OperationLog
@Operation(summary = "删除历史法定代表人")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditHistoricalLegalPersonService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditHistoricalLegalPerson:save')")
@OperationLog
@Operation(summary = "批量添加历史法定代表人")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditHistoricalLegalPerson> list) {
if (creditHistoricalLegalPersonService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditHistoricalLegalPerson:update')")
@OperationLog
@Operation(summary = "批量修改历史法定代表人")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditHistoricalLegalPerson> batchParam) {
if (batchParam.update(creditHistoricalLegalPersonService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditHistoricalLegalPerson:remove')")
@OperationLog
@Operation(summary = "批量删除历史法定代表人")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditHistoricalLegalPersonService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入历史法定代表人
*/
@PreAuthorize("hasAuthority('credit:creditHistoricalLegalPerson:save')")
@Operation(summary = "批量导入历史法定代表人")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditHistoricalLegalPersonImportParam> importResult = ExcelImportSupport.readAnySheet(
file, CreditHistoricalLegalPersonImportParam.class, this::isEmptyImportRow);
List<CreditHistoricalLegalPersonImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "名称");
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditHistoricalLegalPerson> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditHistoricalLegalPersonImportParam param = list.get(i);
try {
CreditHistoricalLegalPerson item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getName())) {
String link = urlByName.get(item.getName().trim());
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:名称不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> {
// 批内一次查库:按 name in (...) 拉取,再按 registerDate 做内存匹配
List<String> names = new ArrayList<>(chunkItems.size());
for (CreditHistoricalLegalPerson it : chunkItems) {
if (it != null && !ImportHelper.isBlank(it.getName())) {
names.add(it.getName().trim());
}
}
List<CreditHistoricalLegalPerson> existingList = names.isEmpty()
? new ArrayList<>()
: creditHistoricalLegalPersonService.lambdaQuery()
.in(CreditHistoricalLegalPerson::getName, names)
.list();
java.util.Map<String, CreditHistoricalLegalPerson> byName = new java.util.HashMap<>();
java.util.Map<String, CreditHistoricalLegalPerson> byNameDate = new java.util.HashMap<>();
for (CreditHistoricalLegalPerson existing : existingList) {
if (existing == null || ImportHelper.isBlank(existing.getName())) {
continue;
}
String n = existing.getName().trim();
byName.putIfAbsent(n, existing);
String d = ImportHelper.isBlank(existing.getRegisterDate()) ? null : existing.getRegisterDate().trim();
if (d != null) {
byNameDate.putIfAbsent(n + "|" + d, existing);
}
}
List<CreditHistoricalLegalPerson> updates = new ArrayList<>();
List<CreditHistoricalLegalPerson> inserts = new ArrayList<>();
for (CreditHistoricalLegalPerson it : chunkItems) {
if (it == null || ImportHelper.isBlank(it.getName())) {
continue;
}
String n = it.getName().trim();
CreditHistoricalLegalPerson existing;
if (!ImportHelper.isBlank(it.getRegisterDate())) {
String d = it.getRegisterDate().trim();
existing = byNameDate.get(n + "|" + d);
} else {
existing = byName.get(n);
}
if (existing != null) {
it.setId(existing.getId());
updates.add(it);
} else {
inserts.add(it);
}
}
if (!updates.isEmpty()) {
creditHistoricalLegalPersonService.updateBatchById(updates, mpBatchSize);
}
if (!inserts.isEmpty()) {
creditHistoricalLegalPersonService.saveBatch(inserts, mpBatchSize);
}
return updates.size() + inserts.size();
},
(rowItem, rowNumber) -> {
boolean saved = creditHistoricalLegalPersonService.save(rowItem);
if (!saved) {
CreditHistoricalLegalPerson existing = creditHistoricalLegalPersonService.lambdaQuery()
.eq(CreditHistoricalLegalPerson::getName, rowItem.getName())
.eq(!ImportHelper.isBlank(rowItem.getRegisterDate()), CreditHistoricalLegalPerson::getRegisterDate, rowItem.getRegisterDate())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditHistoricalLegalPersonService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> {
List<String> names = new ArrayList<>(chunkItems.size());
for (CreditHistoricalLegalPerson it : chunkItems) {
if (it != null && !ImportHelper.isBlank(it.getName())) {
names.add(it.getName().trim());
}
}
List<CreditHistoricalLegalPerson> existingList = names.isEmpty()
? new ArrayList<>()
: creditHistoricalLegalPersonService.lambdaQuery()
.in(CreditHistoricalLegalPerson::getName, names)
.list();
java.util.Map<String, CreditHistoricalLegalPerson> byName = new java.util.HashMap<>();
java.util.Map<String, CreditHistoricalLegalPerson> byNameDate = new java.util.HashMap<>();
for (CreditHistoricalLegalPerson existing : existingList) {
if (existing == null || ImportHelper.isBlank(existing.getName())) {
continue;
}
String n = existing.getName().trim();
byName.putIfAbsent(n, existing);
String d = ImportHelper.isBlank(existing.getRegisterDate()) ? null : existing.getRegisterDate().trim();
if (d != null) {
byNameDate.putIfAbsent(n + "|" + d, existing);
}
}
List<CreditHistoricalLegalPerson> updates = new ArrayList<>();
List<CreditHistoricalLegalPerson> inserts = new ArrayList<>();
for (CreditHistoricalLegalPerson it : chunkItems) {
if (it == null || ImportHelper.isBlank(it.getName())) {
continue;
}
String n = it.getName().trim();
CreditHistoricalLegalPerson existing;
if (!ImportHelper.isBlank(it.getRegisterDate())) {
String d = it.getRegisterDate().trim();
existing = byNameDate.get(n + "|" + d);
} else {
existing = byName.get(n);
}
if (existing != null) {
it.setId(existing.getId());
updates.add(it);
} else {
inserts.add(it);
}
}
if (!updates.isEmpty()) {
creditHistoricalLegalPersonService.updateBatchById(updates, mpBatchSize);
}
if (!inserts.isEmpty()) {
creditHistoricalLegalPersonService.saveBatch(inserts, mpBatchSize);
}
return updates.size() + inserts.size();
},
(rowItem, rowNumber) -> {
boolean saved = creditHistoricalLegalPersonService.save(rowItem);
if (!saved) {
CreditHistoricalLegalPerson existing = creditHistoricalLegalPersonService.lambdaQuery()
.eq(CreditHistoricalLegalPerson::getName, rowItem.getName())
.eq(!ImportHelper.isBlank(rowItem.getRegisterDate()), CreditHistoricalLegalPerson::getRegisterDate, rowItem.getRegisterDate())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditHistoricalLegalPersonService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载历史法定代表人导入模板
*/
@Operation(summary = "下载历史法定代表人导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditHistoricalLegalPersonImportParam> templateList = new ArrayList<>();
CreditHistoricalLegalPersonImportParam example = new CreditHistoricalLegalPersonImportParam();
example.setName("张三");
example.setRegisterDate("2020-01-01");
example.setPublicDate("2023-06-01");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("历史法定代表人导入模板", "历史法定代表人", CreditHistoricalLegalPersonImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_historical_legal_person_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditHistoricalLegalPersonImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getRegisterDate())
&& ImportHelper.isBlank(param.getPublicDate());
}
private boolean isImportHeaderRow(CreditHistoricalLegalPersonImportParam param) {
return isHeaderValue(param.getName(), "名称")
|| isHeaderValue(param.getRegisterDate(), "任职日期")
|| isHeaderValue(param.getPublicDate(), "卸任日期");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditHistoricalLegalPerson convertImportParamToEntity(CreditHistoricalLegalPersonImportParam param) {
CreditHistoricalLegalPerson entity = new CreditHistoricalLegalPerson();
entity.setName(param.getName());
entity.setRegisterDate(param.getRegisterDate());
entity.setPublicDate(param.getPublicDate());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,588 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditJudgmentDebtor;
import com.gxwebsoft.credit.param.CreditJudgmentDebtorImportParam;
import com.gxwebsoft.credit.param.CreditJudgmentDebtorParam;
import com.gxwebsoft.credit.service.CreditJudgmentDebtorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Locale;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* 被执行人控制器
*
* @author 科技小王子
* @since 2025-12-19 19:50:55
*/
@Tag(name = "被执行人管理")
@RestController
@RequestMapping("/api/credit/credit-judgment-debtor")
public class CreditJudgmentDebtorController extends BaseController {
@Resource
private CreditJudgmentDebtorService creditJudgmentDebtorService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询被执行人")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudgmentDebtor>> page(CreditJudgmentDebtorParam param) {
// 使用关联查询
return success(creditJudgmentDebtorService.pageRel(param));
}
@Operation(summary = "查询全部被执行人")
@GetMapping()
public ApiResult<List<CreditJudgmentDebtor>> list(CreditJudgmentDebtorParam param) {
// 使用关联查询
return success(creditJudgmentDebtorService.listRel(param));
}
@Operation(summary = "根据id查询被执行人")
@GetMapping("/{id}")
public ApiResult<CreditJudgmentDebtor> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditJudgmentDebtorService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@OperationLog
@Operation(summary = "添加被执行人")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditJudgmentDebtor creditJudgmentDebtor) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditJudgmentDebtor.setUserId(loginUser.getUserId());
// }
if (creditJudgmentDebtorService.save(creditJudgmentDebtor)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:update')")
@OperationLog
@Operation(summary = "修改被执行人")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditJudgmentDebtor creditJudgmentDebtor) {
if (creditJudgmentDebtorService.updateById(creditJudgmentDebtor)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:remove')")
@OperationLog
@Operation(summary = "删除被执行人")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditJudgmentDebtorService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@OperationLog
@Operation(summary = "批量添加被执行人")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditJudgmentDebtor> list) {
if (creditJudgmentDebtorService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:update')")
@OperationLog
@Operation(summary = "批量修改被执行人")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditJudgmentDebtor> batchParam) {
if (batchParam.update(creditJudgmentDebtorService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:remove')")
@OperationLog
@Operation(summary = "批量删除被执行人")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditJudgmentDebtorService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入被执行人
*/
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@Operation(summary = "批量导入被执行人")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
try {
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
ImportOutcome outcome;
if (isZip(file)) {
outcome = importFromZip(file, currentUserId, currentTenantId, companyId);
} else {
outcome = importFromExcel(file, safeFileLabel(file.getOriginalFilename()), currentUserId, currentTenantId, companyId, false);
}
if (!outcome.anyDataRead) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
if (outcome.errorMessages.isEmpty()) {
return success("成功导入" + outcome.successCount + "条数据", null);
}
return success("导入完成,成功" + outcome.successCount + "条,失败" + outcome.errorMessages.size() + "", outcome.errorMessages);
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载被执行人导入模板
*/
@Operation(summary = "下载被执行人导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudgmentDebtorImportParam> templateList = new ArrayList<>();
CreditJudgmentDebtorImportParam example = new CreditJudgmentDebtorImportParam();
example.setCaseNumber("2024示例案号");
example.setName("某某公司");
example.setCode("1234567890");
example.setOccurrenceTime("2024-01-10");
example.setAmount("100000");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("被执行人导入模板", "被执行人", CreditJudgmentDebtorImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_judgment_debtor_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudgmentDebtorImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getName1())
&& ImportHelper.isBlank(param.getCode());
}
private boolean isImportHeaderRow(CreditJudgmentDebtorImportParam param) {
return isHeaderValue(param.getName(), "序号")
|| isHeaderValue(param.getName1(), "序号")
|| isHeaderValue(param.getCaseNumber(), "案号")
|| isHeaderValue(param.getName(), "被执行人名称")
|| isHeaderValue(param.getName1(), "被执行人")
|| isHeaderValue(param.getCode(), "证件号/组织机构代码")
|| isHeaderValue(param.getOccurrenceTime(), "立案日期")
|| isHeaderValue(param.getCourtName(), "法院")
|| isHeaderValue(param.getAmount(), "执行标的(元)")
|| isHeaderValue(param.getDataStatus(), "数据状态");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditJudgmentDebtor convertImportParamToEntity(CreditJudgmentDebtorImportParam param) {
CreditJudgmentDebtor entity = new CreditJudgmentDebtor();
entity.setCaseNumber(param.getCaseNumber());
entity.setName1(param.getName1());
String debtorName = ImportHelper.isBlank(param.getName()) ? param.getName1() : param.getName();
entity.setName(debtorName);
entity.setCode(param.getCode());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setAmount(param.getAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
private static class ImportOutcome {
private final boolean anyDataRead;
private final int successCount;
private final List<String> errorMessages;
private ImportOutcome(boolean anyDataRead, int successCount, List<String> errorMessages) {
this.anyDataRead = anyDataRead;
this.successCount = successCount;
this.errorMessages = errorMessages;
}
}
private ImportOutcome importFromExcel(MultipartFile excelFile, String fileLabel, Integer currentUserId, Integer currentTenantId, Integer companyId, boolean strictDebtorSheet) throws Exception {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
ExcelImportSupport.ImportResult<CreditJudgmentDebtorImportParam> importResult = readDebtorImport(excelFile, strictDebtorSheet);
List<CreditJudgmentDebtorImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return new ImportOutcome(false, 0, errorMessages);
}
Map<String, String> urlByCaseNumber = ExcelImportSupport.readHyperlinksByHeaderKey(excelFile, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(excelFile, usedSheetIndex, usedTitleRows, usedHeadRows, "被执行人名称");
Map<String, String> urlByName1 = ExcelImportSupport.readHyperlinksByHeaderKey(excelFile, usedSheetIndex, usedTitleRows, usedHeadRows, "被执行人");
String prefix = ImportHelper.isBlank(fileLabel) ? "" : "" + fileLabel + "";
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditJudgmentDebtor> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudgmentDebtorImportParam param = list.get(i);
try {
CreditJudgmentDebtor item = convertImportParamToEntity(param);
String link = null;
if (!ImportHelper.isBlank(item.getCaseNumber())) {
link = urlByCaseNumber.get(item.getCaseNumber().trim());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName())) {
link = urlByName.get(item.getName().trim());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName1())) {
link = urlByName1.get(item.getName1().trim());
}
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add(prefix + "" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += persistImportChunk(chunkItems, chunkRowNumbers, prefix, mpBatchSize, errorMessages);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add(prefix + "" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += persistImportChunk(chunkItems, chunkRowNumbers, prefix, mpBatchSize, errorMessages);
}
return new ImportOutcome(true, successCount, errorMessages);
}
private int persistImportChunk(List<CreditJudgmentDebtor> items,
List<Integer> excelRowNumbers,
String prefix,
int mpBatchSize,
List<String> errorMessages) {
if (CollectionUtils.isEmpty(items)) {
return 0;
}
try {
return batchImportSupport.runInNewTx(() -> batchImportSupport.upsertBySingleKey(
creditJudgmentDebtorService,
items,
CreditJudgmentDebtor::getId,
CreditJudgmentDebtor::setId,
CreditJudgmentDebtor::getCaseNumber,
CreditJudgmentDebtor::getCaseNumber,
null,
mpBatchSize
));
} catch (Exception batchException) {
int successCount = 0;
for (int i = 0; i < items.size(); i++) {
CreditJudgmentDebtor item = items.get(i);
int excelRowNumber = (excelRowNumbers != null && i < excelRowNumbers.size()) ? excelRowNumbers.get(i) : -1;
try {
int delta = batchImportSupport.runInNewTx(() -> {
boolean saved = creditJudgmentDebtorService.save(item);
if (!saved) {
CreditJudgmentDebtor existing = creditJudgmentDebtorService.lambdaQuery()
.eq(CreditJudgmentDebtor::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditJudgmentDebtorService.updateById(item)) {
return 1;
}
}
} else {
return 1;
}
return 0;
});
if (delta > 0) {
successCount += delta;
} else {
errorMessages.add(prefix + "" + excelRowNumber + "行:保存失败");
}
} catch (Exception e) {
errorMessages.add(prefix + "" + excelRowNumber + "行:" + e.getMessage());
}
}
return successCount;
}
}
private ImportOutcome importFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId, Integer companyId) throws Exception {
try {
return importFromZip(zipFile, currentUserId, currentTenantId, companyId, StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
return importFromZip(zipFile, currentUserId, currentTenantId, companyId, Charset.forName("GBK"));
}
}
private ImportOutcome importFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId, Integer companyId, Charset charset) throws Exception {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
boolean anyDataRead = false;
try (InputStream is = zipFile.getInputStream(); ZipInputStream zis = new ZipInputStream(is, charset)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (entry.isDirectory()) {
continue;
}
String entryName = entry.getName();
if (!isExcelFileName(entryName)) {
continue;
}
byte[] bytes = readAllBytes(zis);
String entryFileName = safeFileLabel(entryName);
MultipartFile excelFile = new InMemoryMultipartFile(entryFileName, bytes);
try {
ImportOutcome outcome = importFromExcel(excelFile, entryFileName, currentUserId, currentTenantId, companyId, true);
if (outcome.anyDataRead) {
anyDataRead = true;
successCount += outcome.successCount;
errorMessages.addAll(outcome.errorMessages);
}
} catch (Exception e) {
errorMessages.add("" + entryFileName + "】解析失败:" + e.getMessage());
}
}
}
return new ImportOutcome(anyDataRead, successCount, errorMessages);
}
private static boolean isZip(MultipartFile file) {
String filename = file != null ? file.getOriginalFilename() : null;
if (filename == null) {
return false;
}
return filename.toLowerCase(Locale.ROOT).endsWith(".zip");
}
private ExcelImportSupport.ImportResult<CreditJudgmentDebtorImportParam> readDebtorImport(MultipartFile excelFile, boolean strictDebtorSheet) throws Exception {
List<Integer> debtorSheetIndices = findDebtorSheetIndices(excelFile);
for (Integer sheetIndex : debtorSheetIndices) {
ExcelImportSupport.ImportResult<CreditJudgmentDebtorImportParam> sheetResult = ExcelImportSupport.readBest(
excelFile,
CreditJudgmentDebtorImportParam.class,
this::isEmptyImportRow,
this::isScoreImportRow,
sheetIndex
);
if (!CollectionUtils.isEmpty(sheetResult.getData())) {
return sheetResult;
}
}
if (strictDebtorSheet) {
return new ExcelImportSupport.ImportResult<>(new ArrayList<>(), 0, 0);
}
return ExcelImportSupport.readAnySheetBest(excelFile, CreditJudgmentDebtorImportParam.class, this::isEmptyImportRow, this::isScoreImportRow);
}
private boolean isScoreImportRow(CreditJudgmentDebtorImportParam param) {
if (param == null) {
return false;
}
if (isImportHeaderRow(param)) {
return false;
}
return !ImportHelper.isBlank(param.getCaseNumber());
}
private List<Integer> findDebtorSheetIndices(MultipartFile excelFile) throws Exception {
List<Integer> indices = new ArrayList<>();
try (InputStream is = excelFile.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
int sheetCount = workbook.getNumberOfSheets();
for (int i = 0; i < sheetCount; i++) {
String sheetName = workbook.getSheetName(i);
if (isDebtorSheetName(sheetName)) {
indices.add(i);
}
}
}
return indices;
}
private static boolean isDebtorSheetName(String sheetName) {
if (sheetName == null) {
return false;
}
String normalized = sheetName.replace(" ", "").trim();
return normalized.contains("被执行人") && !normalized.contains("失信") && !normalized.contains("历史");
}
private static boolean isExcelFileName(String name) {
if (name == null) {
return false;
}
String lower = name.toLowerCase(Locale.ROOT);
return lower.endsWith(".xlsx") || lower.endsWith(".xls") || lower.endsWith(".xlsm");
}
private static String safeFileLabel(String name) {
if (ImportHelper.isBlank(name)) {
return "";
}
int lastSlash = name.lastIndexOf('/');
if (lastSlash >= 0 && lastSlash + 1 < name.length()) {
return name.substring(lastSlash + 1);
}
return name;
}
private static byte[] readAllBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int read;
while ((read = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
return out.toByteArray();
}
private static class InMemoryMultipartFile implements MultipartFile {
private final String originalFilename;
private final byte[] bytes;
private InMemoryMultipartFile(String originalFilename, byte[] bytes) {
this.originalFilename = originalFilename;
this.bytes = bytes != null ? bytes : new byte[0];
}
@Override
public String getName() {
return originalFilename;
}
@Override
public String getOriginalFilename() {
return originalFilename;
}
@Override
public String getContentType() {
return null;
}
@Override
public boolean isEmpty() {
return bytes.length == 0;
}
@Override
public long getSize() {
return bytes.length;
}
@Override
public byte[] getBytes() {
return bytes;
}
@Override
public InputStream getInputStream() {
return new java.io.ByteArrayInputStream(bytes);
}
@Override
public void transferTo(java.io.File dest) throws IOException {
Files.write(dest.toPath(), bytes);
}
}
}

View File

@@ -0,0 +1,604 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditJudgmentDebtorHistory;
import com.gxwebsoft.credit.param.CreditJudgmentDebtorHistoryImportParam;
import com.gxwebsoft.credit.param.CreditJudgmentDebtorHistoryParam;
import com.gxwebsoft.credit.service.CreditJudgmentDebtorHistoryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* 被执行人控制器
*
* @author 科技小王子
* @since 2026-01-12 08:10:44
*/
@Tag(name = "被执行人管理")
@RestController
@RequestMapping("/api/credit/credit-judgment-debtor-history")
public class CreditJudgmentDebtorHistoryController extends BaseController {
@Resource
private CreditJudgmentDebtorHistoryService creditJudgmentDebtorHistoryService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询被执行人")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudgmentDebtorHistory>> page(CreditJudgmentDebtorHistoryParam param) {
// 使用关联查询
return success(creditJudgmentDebtorHistoryService.pageRel(param));
}
@Operation(summary = "查询全部被执行人")
@GetMapping()
public ApiResult<List<CreditJudgmentDebtorHistory>> list(CreditJudgmentDebtorHistoryParam param) {
// 使用关联查询
return success(creditJudgmentDebtorHistoryService.listRel(param));
}
@Operation(summary = "根据id查询被执行人")
@GetMapping("/{id}")
public ApiResult<CreditJudgmentDebtorHistory> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditJudgmentDebtorHistoryService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtorHistory:save')")
@OperationLog
@Operation(summary = "添加被执行人")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditJudgmentDebtorHistory creditJudgmentDebtorHistory) {
if (creditJudgmentDebtorHistoryService.save(creditJudgmentDebtorHistory)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtorHistory:update')")
@OperationLog
@Operation(summary = "修改被执行人")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditJudgmentDebtorHistory creditJudgmentDebtorHistory) {
if (creditJudgmentDebtorHistoryService.updateById(creditJudgmentDebtorHistory)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtorHistory:remove')")
@OperationLog
@Operation(summary = "删除被执行人")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditJudgmentDebtorHistoryService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtorHistory:save')")
@OperationLog
@Operation(summary = "批量添加被执行人")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditJudgmentDebtorHistory> list) {
if (creditJudgmentDebtorHistoryService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtorHistory:update')")
@OperationLog
@Operation(summary = "批量修改被执行人")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditJudgmentDebtorHistory> batchParam) {
if (batchParam.update(creditJudgmentDebtorHistoryService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtorHistory:remove')")
@OperationLog
@Operation(summary = "批量删除被执行人")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditJudgmentDebtorHistoryService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入被执行人历史
*/
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtorHistory:save')")
@Operation(summary = "批量导入被执行人历史")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
try {
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
ImportOutcome outcome;
if (isZip(file)) {
outcome = importFromZip(file, currentUserId, currentTenantId, companyId);
} else {
outcome = importFromExcel(file, safeFileLabel(file.getOriginalFilename()), currentUserId, currentTenantId, companyId, false);
}
if (!outcome.anyDataRead) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
if (outcome.errorMessages.isEmpty()) {
return success("成功导入" + outcome.successCount + "条数据", null);
}
return success("导入完成,成功" + outcome.successCount + "条,失败" + outcome.errorMessages.size() + "", outcome.errorMessages);
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载被执行人历史导入模板
*/
@Operation(summary = "下载被执行人历史导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudgmentDebtorHistoryImportParam> templateList = new ArrayList<>();
CreditJudgmentDebtorHistoryImportParam example = new CreditJudgmentDebtorHistoryImportParam();
example.setCaseNumber("2024示例案号");
example.setName("某某公司");
example.setCode("1234567890");
example.setOccurrenceTime("2024-01-10");
example.setAmount("100000");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("被执行人历史导入模板", "历史被执行人", CreditJudgmentDebtorHistoryImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_judgment_debtor_history_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudgmentDebtorHistoryImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getName1())
&& ImportHelper.isBlank(param.getCode());
}
private boolean isImportHeaderRow(CreditJudgmentDebtorHistoryImportParam param) {
return isHeaderValue(param.getName(), "序号")
|| isHeaderValue(param.getName1(), "序号")
|| isHeaderValue(param.getCaseNumber(), "案号")
|| isHeaderValue(param.getName(), "被执行人名称")
|| isHeaderValue(param.getName1(), "被执行人")
|| isHeaderValue(param.getCode(), "证件号/组织机构代码")
|| isHeaderValue(param.getOccurrenceTime(), "立案日期")
|| isHeaderValue(param.getCourtName(), "法院")
|| isHeaderValue(param.getAmount(), "执行标的(元)")
|| isHeaderValue(param.getDataStatus(), "数据状态");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditJudgmentDebtorHistory convertImportParamToEntity(CreditJudgmentDebtorHistoryImportParam param) {
CreditJudgmentDebtorHistory entity = new CreditJudgmentDebtorHistory();
entity.setCaseNumber(param.getCaseNumber());
entity.setName1(param.getName1());
String debtorName = ImportHelper.isBlank(param.getName()) ? param.getName1() : param.getName();
entity.setName(debtorName);
entity.setCode(param.getCode());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setAmount(param.getAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
private static class ImportOutcome {
private final boolean anyDataRead;
private final int successCount;
private final List<String> errorMessages;
private ImportOutcome(boolean anyDataRead, int successCount, List<String> errorMessages) {
this.anyDataRead = anyDataRead;
this.successCount = successCount;
this.errorMessages = errorMessages;
}
}
private ImportOutcome importFromExcel(MultipartFile excelFile, String fileLabel, Integer currentUserId, Integer currentTenantId, Integer companyId, boolean strictHistorySheet) throws Exception {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
ExcelImportSupport.ImportResult<CreditJudgmentDebtorHistoryImportParam> importResult = readHistoryImport(excelFile, strictHistorySheet);
List<CreditJudgmentDebtorHistoryImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return new ImportOutcome(false, 0, errorMessages);
}
Map<String, String> urlByCaseNumber = ExcelImportSupport.readHyperlinksByHeaderKey(excelFile, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(excelFile, usedSheetIndex, usedTitleRows, usedHeadRows, "被执行人名称");
Map<String, String> urlByName1 = ExcelImportSupport.readHyperlinksByHeaderKey(excelFile, usedSheetIndex, usedTitleRows, usedHeadRows, "被执行人");
String prefix = ImportHelper.isBlank(fileLabel) ? "" : "" + fileLabel + "";
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditJudgmentDebtorHistory> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudgmentDebtorHistoryImportParam param = list.get(i);
try {
CreditJudgmentDebtorHistory item = convertImportParamToEntity(param);
String link = null;
if (!ImportHelper.isBlank(item.getCaseNumber())) {
link = urlByCaseNumber.get(item.getCaseNumber().trim());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName())) {
link = urlByName.get(item.getName().trim());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName1())) {
link = urlByName1.get(item.getName1().trim());
}
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getType() == null) {
item.setType(0);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add(prefix + "" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += persistImportChunk(chunkItems, chunkRowNumbers, prefix, mpBatchSize, errorMessages);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add(prefix + "" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += persistImportChunk(chunkItems, chunkRowNumbers, prefix, mpBatchSize, errorMessages);
}
return new ImportOutcome(true, successCount, errorMessages);
}
private int persistImportChunk(List<CreditJudgmentDebtorHistory> items,
List<Integer> excelRowNumbers,
String prefix,
int mpBatchSize,
List<String> errorMessages) {
if (CollectionUtils.isEmpty(items)) {
return 0;
}
try {
return batchImportSupport.runInNewTx(() -> batchImportSupport.upsertBySingleKey(
creditJudgmentDebtorHistoryService,
items,
CreditJudgmentDebtorHistory::getId,
CreditJudgmentDebtorHistory::setId,
CreditJudgmentDebtorHistory::getCaseNumber,
CreditJudgmentDebtorHistory::getCaseNumber,
null,
mpBatchSize
));
} catch (Exception batchException) {
int successCount = 0;
for (int i = 0; i < items.size(); i++) {
CreditJudgmentDebtorHistory item = items.get(i);
int excelRowNumber = (excelRowNumbers != null && i < excelRowNumbers.size()) ? excelRowNumbers.get(i) : -1;
try {
int delta = batchImportSupport.runInNewTx(() -> {
boolean saved = creditJudgmentDebtorHistoryService.save(item);
if (!saved) {
CreditJudgmentDebtorHistory existing = creditJudgmentDebtorHistoryService.lambdaQuery()
.eq(CreditJudgmentDebtorHistory::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditJudgmentDebtorHistoryService.updateById(item)) {
return 1;
}
}
} else {
return 1;
}
return 0;
});
if (delta > 0) {
successCount += delta;
} else {
errorMessages.add(prefix + "" + excelRowNumber + "行:保存失败");
}
} catch (Exception e) {
errorMessages.add(prefix + "" + excelRowNumber + "行:" + e.getMessage());
}
}
return successCount;
}
}
private ImportOutcome importFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId, Integer companyId) throws Exception {
try {
return importFromZip(zipFile, currentUserId, currentTenantId, companyId, StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
return importFromZip(zipFile, currentUserId, currentTenantId, companyId, Charset.forName("GBK"));
}
}
private ImportOutcome importFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId, Integer companyId, Charset charset) throws Exception {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
boolean anyDataRead = false;
try (InputStream is = zipFile.getInputStream(); ZipInputStream zis = new ZipInputStream(is, charset)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (entry.isDirectory()) {
continue;
}
String entryName = entry.getName();
if (!isExcelFileName(entryName)) {
continue;
}
byte[] bytes = readAllBytes(zis);
String entryFileName = safeFileLabel(entryName);
MultipartFile excelFile = new InMemoryMultipartFile(entryFileName, bytes);
try {
ImportOutcome outcome = importFromExcel(excelFile, entryFileName, currentUserId, currentTenantId, companyId, true);
if (outcome.anyDataRead) {
anyDataRead = true;
successCount += outcome.successCount;
errorMessages.addAll(outcome.errorMessages);
}
} catch (Exception e) {
errorMessages.add("" + entryFileName + "】解析失败:" + e.getMessage());
}
}
}
return new ImportOutcome(anyDataRead, successCount, errorMessages);
}
private static boolean isZip(MultipartFile file) {
String filename = file != null ? file.getOriginalFilename() : null;
if (filename == null) {
return false;
}
return filename.toLowerCase(Locale.ROOT).endsWith(".zip");
}
private ExcelImportSupport.ImportResult<CreditJudgmentDebtorHistoryImportParam> readHistoryImport(MultipartFile excelFile, boolean strictHistorySheet) throws Exception {
int namedSheetIndex = ExcelImportSupport.findSheetIndex(excelFile, "历史被执行人");
if (namedSheetIndex >= 0) {
ExcelImportSupport.ImportResult<CreditJudgmentDebtorHistoryImportParam> namedSheetResult = ExcelImportSupport.readBest(
excelFile,
CreditJudgmentDebtorHistoryImportParam.class,
this::isEmptyImportRow,
this::isScoreImportRow,
namedSheetIndex
);
if (!CollectionUtils.isEmpty(namedSheetResult.getData())) {
return namedSheetResult;
}
}
List<Integer> historySheetIndices = findHistorySheetIndices(excelFile);
for (Integer sheetIndex : historySheetIndices) {
if (sheetIndex != null && sheetIndex == namedSheetIndex) {
continue;
}
ExcelImportSupport.ImportResult<CreditJudgmentDebtorHistoryImportParam> sheetResult = ExcelImportSupport.readBest(
excelFile,
CreditJudgmentDebtorHistoryImportParam.class,
this::isEmptyImportRow,
this::isScoreImportRow,
sheetIndex
);
if (!CollectionUtils.isEmpty(sheetResult.getData())) {
return sheetResult;
}
}
if (strictHistorySheet) {
return new ExcelImportSupport.ImportResult<>(new ArrayList<>(), 0, 0);
}
return ExcelImportSupport.readAnySheetBest(excelFile, CreditJudgmentDebtorHistoryImportParam.class, this::isEmptyImportRow, this::isScoreImportRow);
}
private boolean isScoreImportRow(CreditJudgmentDebtorHistoryImportParam param) {
if (param == null) {
return false;
}
if (isImportHeaderRow(param)) {
return false;
}
return !ImportHelper.isBlank(param.getCaseNumber());
}
private List<Integer> findHistorySheetIndices(MultipartFile excelFile) throws Exception {
List<Integer> indices = new ArrayList<>();
try (InputStream is = excelFile.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
int sheetCount = workbook.getNumberOfSheets();
for (int i = 0; i < sheetCount; i++) {
String sheetName = workbook.getSheetName(i);
if (isHistorySheetName(sheetName)) {
indices.add(i);
}
}
}
return indices;
}
private static boolean isHistorySheetName(String sheetName) {
if (sheetName == null) {
return false;
}
String normalized = sheetName.replace(" ", "").trim();
return normalized.contains("被执行人") && normalized.contains("历史") && !normalized.contains("失信");
}
private static boolean isExcelFileName(String name) {
if (name == null) {
return false;
}
String lower = name.toLowerCase(Locale.ROOT);
return lower.endsWith(".xlsx") || lower.endsWith(".xls") || lower.endsWith(".xlsm");
}
private static String safeFileLabel(String name) {
if (ImportHelper.isBlank(name)) {
return "";
}
int lastSlash = name.lastIndexOf('/');
if (lastSlash >= 0 && lastSlash + 1 < name.length()) {
return name.substring(lastSlash + 1);
}
return name;
}
private static byte[] readAllBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int read;
while ((read = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
return out.toByteArray();
}
private static class InMemoryMultipartFile implements MultipartFile {
private final String originalFilename;
private final byte[] bytes;
private InMemoryMultipartFile(String originalFilename, byte[] bytes) {
this.originalFilename = originalFilename;
this.bytes = bytes != null ? bytes : new byte[0];
}
@Override
public String getName() {
return originalFilename;
}
@Override
public String getOriginalFilename() {
return originalFilename;
}
@Override
public String getContentType() {
return null;
}
@Override
public boolean isEmpty() {
return bytes.length == 0;
}
@Override
public long getSize() {
return bytes.length;
}
@Override
public byte[] getBytes() {
return bytes;
}
@Override
public InputStream getInputStream() {
return new java.io.ByteArrayInputStream(bytes);
}
@Override
public void transferTo(java.io.File dest) throws IOException {
Files.write(dest.toPath(), bytes);
}
}
}

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditJudicialDocument;
import com.gxwebsoft.credit.param.CreditJudicialDocumentParam;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.service.CreditJudicialDocumentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 裁判文书司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:03
*/
@Tag(name = "裁判文书司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-judicial-document")
public class CreditJudicialDocumentController extends BaseController {
@Resource
private CreditJudicialDocumentService creditJudicialDocumentService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询裁判文书司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudicialDocument>> page(CreditJudicialDocumentParam param) {
// 使用关联查询
return success(creditJudicialDocumentService.pageRel(param));
}
@Operation(summary = "查询全部裁判文书司法大数据")
@GetMapping()
public ApiResult<List<CreditJudicialDocument>> list(CreditJudicialDocumentParam param) {
// 使用关联查询
return success(creditJudicialDocumentService.listRel(param));
}
@Operation(summary = "根据id查询裁判文书司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditJudicialDocument> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditJudicialDocumentService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@OperationLog
@Operation(summary = "添加裁判文书司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditJudicialDocument creditJudicialDocument) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditJudicialDocument.setUserId(loginUser.getUserId());
// }
if (creditJudicialDocumentService.save(creditJudicialDocument)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:update')")
@OperationLog
@Operation(summary = "修改裁判文书司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditJudicialDocument creditJudicialDocument) {
if (creditJudicialDocumentService.updateById(creditJudicialDocument)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:remove')")
@OperationLog
@Operation(summary = "删除裁判文书司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditJudicialDocumentService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@OperationLog
@Operation(summary = "批量添加裁判文书司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditJudicialDocument> list) {
if (creditJudicialDocumentService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:update')")
@OperationLog
@Operation(summary = "批量修改裁判文书司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditJudicialDocument> batchParam) {
if (batchParam.update(creditJudicialDocumentService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:remove')")
@OperationLog
@Operation(summary = "批量删除裁判文书司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditJudicialDocumentService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入裁判文书司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@Operation(summary = "批量导入裁判文书司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditJudicialDocument> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditJudicialDocument item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditJudicialDocumentService,
chunkItems,
CreditJudicialDocument::getId,
CreditJudicialDocument::setId,
CreditJudicialDocument::getCaseNumber,
CreditJudicialDocument::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditJudicialDocumentService.save(rowItem);
if (!saved) {
CreditJudicialDocument existing = creditJudicialDocumentService.lambdaQuery()
.eq(CreditJudicialDocument::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditJudicialDocumentService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditJudicialDocumentService,
chunkItems,
CreditJudicialDocument::getId,
CreditJudicialDocument::setId,
CreditJudicialDocument::getCaseNumber,
CreditJudicialDocument::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditJudicialDocumentService.save(rowItem);
if (!saved) {
CreditJudicialDocument existing = creditJudicialDocumentService.lambdaQuery()
.eq(CreditJudicialDocument::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditJudicialDocumentService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载裁判文书导入模板
*/
@Operation(summary = "下载裁判文书导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("裁判文书");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("裁判文书导入模板", "裁判文书", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_judicial_document_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditJudicialDocument convertImportParamToEntity(CreditJudicialImportParam param) {
CreditJudicialDocument entity = new CreditJudicialDocument();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,385 @@
package com.gxwebsoft.credit.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditJudiciary;
import com.gxwebsoft.credit.param.CreditJudiciaryImportParam;
import com.gxwebsoft.credit.param.CreditJudiciaryParam;
import com.gxwebsoft.credit.service.CreditJudiciaryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 司法案件控制器
*
* @author 科技小王子
* @since 2025-12-16 15:23:58
*/
@Tag(name = "司法案件管理")
@RestController
@RequestMapping("/api/credit/credit-judiciary")
public class CreditJudiciaryController extends BaseController {
@Resource
private CreditJudiciaryService creditJudiciaryService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询司法案件")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudiciary>> page(CreditJudiciaryParam param) {
// 使用关联查询
return success(creditJudiciaryService.pageRel(param));
}
@Operation(summary = "查询全部司法案件")
@GetMapping()
public ApiResult<List<CreditJudiciary>> list(CreditJudiciaryParam param) {
// 使用关联查询
return success(creditJudiciaryService.listRel(param));
}
@Operation(summary = "根据id查询司法案件")
@GetMapping("/{id}")
public ApiResult<CreditJudiciary> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditJudiciaryService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@OperationLog
@Operation(summary = "添加司法案件")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditJudiciary creditJudiciary) {
if (creditJudiciaryService.save(creditJudiciary)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:update')")
@OperationLog
@Operation(summary = "修改司法案件")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditJudiciary creditJudiciary) {
if (creditJudiciaryService.updateById(creditJudiciary)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:remove')")
@OperationLog
@Operation(summary = "删除司法案件")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditJudiciaryService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@OperationLog
@Operation(summary = "批量添加司法案件")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditJudiciary> list) {
if (creditJudiciaryService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:update')")
@OperationLog
@Operation(summary = "批量修改司法案件")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditJudiciary> batchParam) {
if (batchParam.update(creditJudiciaryService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:remove')")
@OperationLog
@Operation(summary = "批量删除司法案件")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditJudiciaryService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入司法案件
*/
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@Operation(summary = "批量导入司法案件")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
List<CreditJudiciaryImportParam> list = null;
int usedTitleRows = 0;
int usedHeadRows = 0;
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {0, 2}, {0, 3}};
for (int[] config : tryConfigs) {
list = filterEmptyRows(tryImport(file, config[0], config[1]));
if (!CollectionUtils.isEmpty(list)) {
usedTitleRows = config[0];
usedHeadRows = config[1];
break;
}
}
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditJudiciary> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudiciaryImportParam param = list.get(i);
try {
CreditJudiciary item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
// 设置默认值
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getType() == null) {
item.setType(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
// 验证必填字段
if (item.getName() == null || item.getName().trim().isEmpty()) {
errorMessages.add("" + excelRowNumber + "行:项目名称不能为空");
continue;
}
if (item.getCode() == null || item.getCode().trim().isEmpty()) {
errorMessages.add("" + excelRowNumber + "行:唯一标识不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditJudiciaryService,
chunkItems,
CreditJudiciary::getId,
CreditJudiciary::setId,
CreditJudiciary::getName,
CreditJudiciary::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditJudiciaryService.save(rowItem);
if (!saved) {
CreditJudiciary existing = creditJudiciaryService.getByName(rowItem.getName());
if (existing != null) {
rowItem.setId(existing.getId());
if (creditJudiciaryService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditJudiciaryService,
chunkItems,
CreditJudiciary::getId,
CreditJudiciary::setId,
CreditJudiciary::getName,
CreditJudiciary::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditJudiciaryService.save(rowItem);
if (!saved) {
CreditJudiciary existing = creditJudiciaryService.getByName(rowItem.getName());
if (existing != null) {
rowItem.setId(existing.getId());
if (creditJudiciaryService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载司法案件导入模板
*/
@Operation(summary = "下载司法案件导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudiciaryImportParam> templateList = new ArrayList<>();
CreditJudiciaryImportParam example = new CreditJudiciaryImportParam();
example.setName("示例客户");
example.setCode("C0001");
example.setInfoType("执行案件");
example.setReason("买卖合同纠纷");
example.setProcessDate("2025-08-27");
example.setCaseProgress("首次执行");
example.setCaseIdentity("被执行人");
example.setCode("2025闽0103执5480号");
example.setCourt("福建省福州市台江区人民法院");
example.setCaseAmount("5134060.00");
templateList.add(example);
ExportParams exportParams = new ExportParams("司法案件导入模板", "司法案件");
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, CreditJudiciaryImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_judiciary_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private List<CreditJudiciaryImportParam> tryImport(MultipartFile file, int titleRows, int headRows) throws Exception {
ImportParams importParams = new ImportParams();
importParams.setTitleRows(titleRows);
importParams.setHeadRows(headRows);
importParams.setStartSheetIndex(0);
importParams.setSheetNum(1);
return ExcelImportUtil.importExcel(file.getInputStream(), CreditJudiciaryImportParam.class, importParams);
}
/**
* 过滤掉完全空白的导入行,避免空行导致导入失败
*/
private List<CreditJudiciaryImportParam> filterEmptyRows(List<CreditJudiciaryImportParam> rawList) {
if (CollectionUtils.isEmpty(rawList)) {
return rawList;
}
rawList.removeIf(this::isEmptyImportRow);
return rawList;
}
private boolean isEmptyImportRow(CreditJudiciaryImportParam param) {
if (param == null) {
return true;
}
return isBlank(param.getName())
&& isBlank(param.getCode())
&& isBlank(param.getName())
&& isBlank(param.getInfoType());
}
private boolean isBlank(String value) {
return value == null || value.trim().isEmpty();
}
/**
* 将CreditJudiciaryImportParam转换为CreditJudiciary实体
*/
private CreditJudiciary convertImportParamToEntity(CreditJudiciaryImportParam param) {
CreditJudiciary entity = new CreditJudiciary();
entity.setCode(param.getCode());
entity.setName(param.getName());
entity.setInfoType(param.getInfoType());
entity.setReason(param.getReason());
entity.setProcessDate(param.getProcessDate());
entity.setCaseProgress(param.getCaseProgress());
entity.setCaseIdentity(param.getCaseIdentity());
entity.setCourt(param.getCourt());
entity.setCaseAmount(param.getCaseAmount());
return entity;
}
}

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditMediation;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.param.CreditMediationParam;
import com.gxwebsoft.credit.service.CreditMediationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 诉前调解司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:25
*/
@Tag(name = "诉前调解司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-mediation")
public class CreditMediationController extends BaseController {
@Resource
private CreditMediationService creditMediationService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询诉前调解司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditMediation>> page(CreditMediationParam param) {
// 使用关联查询
return success(creditMediationService.pageRel(param));
}
@Operation(summary = "查询全部诉前调解司法大数据")
@GetMapping()
public ApiResult<List<CreditMediation>> list(CreditMediationParam param) {
// 使用关联查询
return success(creditMediationService.listRel(param));
}
@Operation(summary = "根据id查询诉前调解司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditMediation> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditMediationService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@OperationLog
@Operation(summary = "添加诉前调解司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditMediation creditMediation) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditMediation.setUserId(loginUser.getUserId());
// }
if (creditMediationService.save(creditMediation)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:update')")
@OperationLog
@Operation(summary = "修改诉前调解司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditMediation creditMediation) {
if (creditMediationService.updateById(creditMediation)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:remove')")
@OperationLog
@Operation(summary = "删除诉前调解司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditMediationService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@OperationLog
@Operation(summary = "批量添加诉前调解司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditMediation> list) {
if (creditMediationService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:update')")
@OperationLog
@Operation(summary = "批量修改诉前调解司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditMediation> batchParam) {
if (batchParam.update(creditMediationService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:remove')")
@OperationLog
@Operation(summary = "批量删除诉前调解司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditMediationService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入诉前调解司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@Operation(summary = "批量导入诉前调解司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditMediation> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditMediation item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditMediationService,
chunkItems,
CreditMediation::getId,
CreditMediation::setId,
CreditMediation::getCaseNumber,
CreditMediation::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditMediationService.save(rowItem);
if (!saved) {
CreditMediation existing = creditMediationService.lambdaQuery()
.eq(CreditMediation::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditMediationService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditMediationService,
chunkItems,
CreditMediation::getId,
CreditMediation::setId,
CreditMediation::getCaseNumber,
CreditMediation::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditMediationService.save(rowItem);
if (!saved) {
CreditMediation existing = creditMediationService.lambdaQuery()
.eq(CreditMediation::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditMediationService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载诉前调解导入模板
*/
@Operation(summary = "下载诉前调解导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("诉前调解");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("诉前调解导入模板", "诉前调解", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_mediation_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditMediation convertImportParamToEntity(CreditJudicialImportParam param) {
CreditMediation entity = new CreditMediation();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,420 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditNearbyCompany;
import com.gxwebsoft.credit.param.CreditNearbyCompanyImportParam;
import com.gxwebsoft.credit.param.CreditNearbyCompanyParam;
import com.gxwebsoft.credit.service.CreditNearbyCompanyService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 附近企业控制器
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Tag(name = "附近企业管理")
@RestController
@RequestMapping("/api/credit/credit-nearby-company")
public class CreditNearbyCompanyController extends BaseController {
@Resource
private CreditNearbyCompanyService creditNearbyCompanyService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询附近企业")
@GetMapping("/page")
public ApiResult<PageResult<CreditNearbyCompany>> page(CreditNearbyCompanyParam param) {
// 使用关联查询
return success(creditNearbyCompanyService.pageRel(param));
}
@Operation(summary = "查询全部附近企业")
@GetMapping()
public ApiResult<List<CreditNearbyCompany>> list(CreditNearbyCompanyParam param) {
// 使用关联查询
return success(creditNearbyCompanyService.listRel(param));
}
@Operation(summary = "根据id查询附近企业")
@GetMapping("/{id}")
public ApiResult<CreditNearbyCompany> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditNearbyCompanyService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditNearbyCompany:save')")
@OperationLog
@Operation(summary = "添加附近企业")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditNearbyCompany creditNearbyCompany) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditNearbyCompany.setUserId(loginUser.getUserId());
// }
if (creditNearbyCompanyService.save(creditNearbyCompany)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditNearbyCompany:update')")
@OperationLog
@Operation(summary = "修改附近企业")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditNearbyCompany creditNearbyCompany) {
if (creditNearbyCompanyService.updateById(creditNearbyCompany)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditNearbyCompany:remove')")
@OperationLog
@Operation(summary = "删除附近企业")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditNearbyCompanyService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditNearbyCompany:save')")
@OperationLog
@Operation(summary = "批量添加附近企业")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditNearbyCompany> list) {
if (creditNearbyCompanyService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditNearbyCompany:update')")
@OperationLog
@Operation(summary = "批量修改附近企业")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditNearbyCompany> batchParam) {
if (batchParam.update(creditNearbyCompanyService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditNearbyCompany:remove')")
@OperationLog
@Operation(summary = "批量删除附近企业")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditNearbyCompanyService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入附近企业
*/
@PreAuthorize("hasAuthority('credit:creditNearbyCompany:save')")
@Operation(summary = "批量导入附近企业")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId,
@RequestParam(value = "parentId", required = false) Integer parentId,
@RequestParam(value = "type", required = false) Integer type) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditNearbyCompanyImportParam> importResult = ExcelImportSupport.readAnySheet(
file, CreditNearbyCompanyImportParam.class, this::isEmptyImportRow);
List<CreditNearbyCompanyImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByCode = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "统一社会信用代码");
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "企业名称");
// 避免逐行写库:按批处理,显著降低 SQL 次数与事务开销
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditNearbyCompany> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditNearbyCompanyImportParam param = list.get(i);
try {
CreditNearbyCompany item = convertImportParamToEntity(param);
String link = null;
if (!ImportHelper.isBlank(item.getCode())) {
link = urlByCode.get(item.getCode().trim());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName())) {
link = urlByName.get(item.getName().trim());
}
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getParentId() == null && parentId != null) {
item.setParentId(parentId);
}
if (item.getType() == null && type != null) {
item.setType(type);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:企业名称不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += persistImportChunk(chunkItems, chunkRowNumbers, companyId, parentId, type, currentTenantId, mpBatchSize, errorMessages);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += persistImportChunk(chunkItems, chunkRowNumbers, companyId, parentId, type, currentTenantId, mpBatchSize, errorMessages);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
private int persistImportChunk(List<CreditNearbyCompany> items,
List<Integer> excelRowNumbers,
Integer companyId,
Integer parentId,
Integer type,
Integer tenantId,
int mpBatchSize,
List<String> errorMessages) {
return batchImportSupport.persistChunkWithFallback(
items,
excelRowNumbers,
() -> batchImportSupport.upsertByCodeOrName(
creditNearbyCompanyService,
items,
CreditNearbyCompany::getId,
CreditNearbyCompany::setId,
CreditNearbyCompany::getCode,
CreditNearbyCompany::getCode,
CreditNearbyCompany::getName,
CreditNearbyCompany::getName,
wrapper -> {
if (companyId != null) {
wrapper.eq(CreditNearbyCompany::getCompanyId, companyId);
}
if (parentId != null) {
wrapper.eq(CreditNearbyCompany::getParentId, parentId);
}
if (type != null) {
wrapper.eq(CreditNearbyCompany::getType, type);
}
if (tenantId != null) {
wrapper.eq(CreditNearbyCompany::getTenantId, tenantId);
}
},
mpBatchSize
),
(item, excelRowNumber) -> {
boolean saved = creditNearbyCompanyService.save(item);
if (!saved) {
CreditNearbyCompany existing = creditNearbyCompanyService.lambdaQuery()
.eq(!ImportHelper.isBlank(item.getCode()), CreditNearbyCompany::getCode, item.getCode())
.eq(ImportHelper.isBlank(item.getCode()), CreditNearbyCompany::getName, item.getName())
.eq(item.getCompanyId() != null, CreditNearbyCompany::getCompanyId, item.getCompanyId())
.eq(item.getParentId() != null, CreditNearbyCompany::getParentId, item.getParentId())
.eq(item.getType() != null, CreditNearbyCompany::getType, item.getType())
.eq(item.getTenantId() != null, CreditNearbyCompany::getTenantId, item.getTenantId())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditNearbyCompanyService.updateById(item)) {
return true;
}
}
} else {
return true;
}
String prefix = excelRowNumber > 0 ? ("" + excelRowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
/**
* 下载附近企业导入模板
*/
@Operation(summary = "下载附近企业导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditNearbyCompanyImportParam> templateList = new ArrayList<>();
CreditNearbyCompanyImportParam example = new CreditNearbyCompanyImportParam();
example.setName("示例科技有限公司");
example.setRegistrationStatus("存续");
example.setLegalPerson("李四");
example.setRegisteredCapital("1000万人民币");
example.setPaidinCapital("200万人民币");
example.setEstablishDate("2018-06-01");
example.setCode("91440101MA5XXXXXXX");
example.setAddress("广西南宁市某某路1号");
example.setPhone("13800000000");
example.setEmail("demo@example.com");
example.setProvince("广西");
example.setCity("南宁");
example.setRegion("青秀区");
example.setDomain("https://example.com");
example.setInstitutionType("有限责任公司");
example.setCompanySize("小微企业");
example.setRegistrationAuthority("南宁市市场监督管理局");
example.setTaxpayerQualification("一般纳税人");
example.setLatestAnnualReportYear("2023");
example.setLatestAnnualReportOnOperatingRevenue("1000万");
example.setEnterpriseScoreCheck("85");
example.setCreditRating("A级");
example.setCechnologyScore("70");
example.setCechnologyLevel("良好");
example.setSmallEnterprise("");
example.setCompanyProfile("企业简介示例");
example.setNatureOfBusiness("经营范围示例");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("附近企业导入模板", "附近企业", CreditNearbyCompanyImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_nearby_company_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditNearbyCompanyImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getCode())
&& ImportHelper.isBlank(param.getLegalPerson());
}
private boolean isImportHeaderRow(CreditNearbyCompanyImportParam param) {
return isHeaderValue(param.getName(), "企业名称")
|| isHeaderValue(param.getCode(), "统一社会信用代码")
|| isHeaderValue(param.getLegalPerson(), "法定代表人");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditNearbyCompany convertImportParamToEntity(CreditNearbyCompanyImportParam param) {
CreditNearbyCompany entity = new CreditNearbyCompany();
entity.setName(param.getName());
entity.setRegistrationStatus(param.getRegistrationStatus());
entity.setLegalPerson(param.getLegalPerson());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setPaidinCapital(param.getPaidinCapital());
entity.setEstablishDate(param.getEstablishDate());
entity.setCode(param.getCode());
entity.setAddress(param.getAddress());
entity.setPhone(param.getPhone());
entity.setEmail(param.getEmail());
entity.setProvince(param.getProvince());
entity.setCity(param.getCity());
entity.setRegion(param.getRegion());
entity.setDomain(param.getDomain());
entity.setInstitutionType(param.getInstitutionType());
entity.setCompanySize(param.getCompanySize());
entity.setRegistrationAuthority(param.getRegistrationAuthority());
entity.setTaxpayerQualification(param.getTaxpayerQualification());
entity.setLatestAnnualReportYear(param.getLatestAnnualReportYear());
entity.setLatestAnnualReportOnOperatingRevenue(param.getLatestAnnualReportOnOperatingRevenue());
entity.setEnterpriseScoreCheck(param.getEnterpriseScoreCheck());
entity.setCreditRating(param.getCreditRating());
entity.setCechnologyScore(param.getCechnologyScore());
entity.setCechnologyLevel(param.getCechnologyLevel());
entity.setSmallEnterprise(param.getSmallEnterprise());
entity.setCompanyProfile(param.getCompanyProfile());
entity.setNatureOfBusiness(param.getNatureOfBusiness());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,377 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditPatent;
import com.gxwebsoft.credit.param.CreditPatentImportParam;
import com.gxwebsoft.credit.param.CreditPatentParam;
import com.gxwebsoft.credit.service.CreditPatentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 专利控制器
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Tag(name = "专利管理")
@RestController
@RequestMapping("/api/credit/credit-patent")
public class CreditPatentController extends BaseController {
@Resource
private CreditPatentService creditPatentService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询专利")
@GetMapping("/page")
public ApiResult<PageResult<CreditPatent>> page(CreditPatentParam param) {
// 使用关联查询
return success(creditPatentService.pageRel(param));
}
@Operation(summary = "查询全部专利")
@GetMapping()
public ApiResult<List<CreditPatent>> list(CreditPatentParam param) {
// 使用关联查询
return success(creditPatentService.listRel(param));
}
@Operation(summary = "根据id查询专利")
@GetMapping("/{id}")
public ApiResult<CreditPatent> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditPatentService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditPatent:save')")
@OperationLog
@Operation(summary = "添加专利")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditPatent creditPatent) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditPatent.setUserId(loginUser.getUserId());
// }
if (creditPatentService.save(creditPatent)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditPatent:update')")
@OperationLog
@Operation(summary = "修改专利")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditPatent creditPatent) {
if (creditPatentService.updateById(creditPatent)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditPatent:remove')")
@OperationLog
@Operation(summary = "删除专利")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditPatentService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditPatent:save')")
@OperationLog
@Operation(summary = "批量添加专利")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditPatent> list) {
if (creditPatentService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditPatent:update')")
@OperationLog
@Operation(summary = "批量修改专利")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditPatent> batchParam) {
if (batchParam.update(creditPatentService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditPatent:remove')")
@OperationLog
@Operation(summary = "批量删除专利")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditPatentService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入专利
*/
@PreAuthorize("hasAuthority('credit:creditPatent:save')")
@Operation(summary = "批量导入专利")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditPatentImportParam> importResult = ExcelImportSupport.readAnySheet(
file, CreditPatentImportParam.class, this::isEmptyImportRow);
List<CreditPatentImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByRegisterNo = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "申请号");
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "发明名称");
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditPatent> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditPatentImportParam param = list.get(i);
try {
CreditPatent item = convertImportParamToEntity(param);
String link = null;
if (!ImportHelper.isBlank(item.getRegisterNo())) {
link = urlByRegisterNo.get(item.getRegisterNo().trim());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName())) {
link = urlByName.get(item.getName().trim());
}
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getRegisterNo())) {
errorMessages.add("" + excelRowNumber + "行:申请号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditPatentService,
chunkItems,
CreditPatent::getId,
CreditPatent::setId,
CreditPatent::getRegisterNo,
CreditPatent::getRegisterNo,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditPatentService.save(rowItem);
if (!saved) {
CreditPatent existing = creditPatentService.lambdaQuery()
.eq(CreditPatent::getRegisterNo, rowItem.getRegisterNo())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditPatentService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditPatentService,
chunkItems,
CreditPatent::getId,
CreditPatent::setId,
CreditPatent::getRegisterNo,
CreditPatent::getRegisterNo,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditPatentService.save(rowItem);
if (!saved) {
CreditPatent existing = creditPatentService.lambdaQuery()
.eq(CreditPatent::getRegisterNo, rowItem.getRegisterNo())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditPatentService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载专利导入模板
*/
@Operation(summary = "下载专利导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditPatentImportParam> templateList = new ArrayList<>();
CreditPatentImportParam example = new CreditPatentImportParam();
example.setName("一种示例装置及方法");
example.setType("发明专利");
example.setStatusText("有效");
example.setRegisterNo("CN2024XXXXXXXX.X");
example.setRegisterDate("2024-01-01");
example.setPublicNo("CN1XXXXXXXXX");
example.setPublicDate("2024-06-01");
example.setInventor("张三;李四");
example.setPatentApplicant("示例科技有限公司");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("专利导入模板", "专利", CreditPatentImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_patent_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditPatentImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getRegisterNo())
&& ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getPatentApplicant());
}
private boolean isImportHeaderRow(CreditPatentImportParam param) {
return isHeaderValue(param.getRegisterNo(), "申请号")
|| isHeaderValue(param.getName(), "发明名称")
|| isHeaderValue(param.getPatentApplicant(), "申请(专利权)人");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditPatent convertImportParamToEntity(CreditPatentImportParam param) {
CreditPatent entity = new CreditPatent();
entity.setName(param.getName());
entity.setType(param.getType());
entity.setStatusText(param.getStatusText());
entity.setRegisterNo(param.getRegisterNo());
entity.setRegisterDate(param.getRegisterDate());
entity.setPublicNo(param.getPublicNo());
entity.setPublicDate(param.getPublicDate());
entity.setInventor(param.getInventor());
entity.setPatentApplicant(param.getPatentApplicant());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,342 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditRiskRelation;
import com.gxwebsoft.credit.param.CreditRiskRelationImportParam;
import com.gxwebsoft.credit.param.CreditRiskRelationParam;
import com.gxwebsoft.credit.service.CreditRiskRelationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 风险关系表控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:41
*/
@Tag(name = "风险关系表管理")
@RestController
@RequestMapping("/api/credit/credit-risk-relation")
public class CreditRiskRelationController extends BaseController {
@Resource
private CreditRiskRelationService creditRiskRelationService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询风险关系表")
@GetMapping("/page")
public ApiResult<PageResult<CreditRiskRelation>> page(CreditRiskRelationParam param) {
// 使用关联查询
return success(creditRiskRelationService.pageRel(param));
}
@Operation(summary = "查询全部风险关系表")
@GetMapping()
public ApiResult<List<CreditRiskRelation>> list(CreditRiskRelationParam param) {
// 使用关联查询
return success(creditRiskRelationService.listRel(param));
}
@Operation(summary = "根据id查询风险关系表")
@GetMapping("/{id}")
public ApiResult<CreditRiskRelation> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditRiskRelationService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:save')")
@OperationLog
@Operation(summary = "添加风险关系表")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditRiskRelation creditRiskRelation) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditRiskRelation.setUserId(loginUser.getUserId());
// }
if (creditRiskRelationService.save(creditRiskRelation)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:update')")
@OperationLog
@Operation(summary = "修改风险关系表")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditRiskRelation creditRiskRelation) {
if (creditRiskRelationService.updateById(creditRiskRelation)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:remove')")
@OperationLog
@Operation(summary = "删除风险关系表")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditRiskRelationService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:save')")
@OperationLog
@Operation(summary = "批量添加风险关系表")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditRiskRelation> list) {
if (creditRiskRelationService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:update')")
@OperationLog
@Operation(summary = "批量修改风险关系表")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditRiskRelation> batchParam) {
if (batchParam.update(creditRiskRelationService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:remove')")
@OperationLog
@Operation(summary = "批量删除风险关系表")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditRiskRelationService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入风险关系表
*/
@PreAuthorize("hasAuthority('credit:creditRiskRelation:save')")
@Operation(summary = "批量导入风险关系表")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "风险关系", 1);
ExcelImportSupport.ImportResult<CreditRiskRelationImportParam> importResult = ExcelImportSupport.read(
file, CreditRiskRelationImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditRiskRelationImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditRiskRelation> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditRiskRelationImportParam param = list.get(i);
try {
CreditRiskRelation item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getMainBodyName())) {
errorMessages.add("" + excelRowNumber + "行:主体名称不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditRiskRelationService,
chunkItems,
CreditRiskRelation::getId,
CreditRiskRelation::setId,
CreditRiskRelation::getMainBodyName,
CreditRiskRelation::getMainBodyName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditRiskRelationService.save(rowItem);
if (!saved) {
CreditRiskRelation existing = creditRiskRelationService.lambdaQuery()
.eq(CreditRiskRelation::getMainBodyName, rowItem.getMainBodyName())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditRiskRelationService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditRiskRelationService,
chunkItems,
CreditRiskRelation::getId,
CreditRiskRelation::setId,
CreditRiskRelation::getMainBodyName,
CreditRiskRelation::getMainBodyName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditRiskRelationService.save(rowItem);
if (!saved) {
CreditRiskRelation existing = creditRiskRelationService.lambdaQuery()
.eq(CreditRiskRelation::getMainBodyName, rowItem.getMainBodyName())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditRiskRelationService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载风险关系导入模板
*/
@Operation(summary = "下载风险关系导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditRiskRelationImportParam> templateList = new ArrayList<>();
CreditRiskRelationImportParam example = new CreditRiskRelationImportParam();
example.setMainBodyName("示例企业");
example.setRegistrationStatus("存续");
example.setRegisteredCapital("8000");
example.setProvinceRegion("浙江");
example.setAssociatedRelation("关联企业");
example.setRiskRelation("存在风险关联");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("风险关系导入模板", "风险关系", CreditRiskRelationImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_risk_relation_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditRiskRelationImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getMainBodyName())
&& ImportHelper.isBlank(param.getRegistrationStatus())
&& ImportHelper.isBlank(param.getRegisteredCapital());
}
private CreditRiskRelation convertImportParamToEntity(CreditRiskRelationImportParam param) {
CreditRiskRelation entity = new CreditRiskRelation();
entity.setMainBodyName(param.getMainBodyName());
entity.setRegistrationStatus(param.getRegistrationStatus());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setProvinceRegion(param.getProvinceRegion());
entity.setAssociatedRelation(param.getAssociatedRelation());
entity.setRiskRelation(param.getRiskRelation());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,340 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditSupplier;
import com.gxwebsoft.credit.param.CreditSupplierImportParam;
import com.gxwebsoft.credit.param.CreditSupplierParam;
import com.gxwebsoft.credit.service.CreditSupplierService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 供应商控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:47
*/
@Tag(name = "供应商管理")
@RestController
@RequestMapping("/api/credit/credit-supplier")
public class CreditSupplierController extends BaseController {
@Resource
private CreditSupplierService creditSupplierService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询供应商")
@GetMapping("/page")
public ApiResult<PageResult<CreditSupplier>> page(CreditSupplierParam param) {
// 使用关联查询
return success(creditSupplierService.pageRel(param));
}
@Operation(summary = "查询全部供应商")
@GetMapping()
public ApiResult<List<CreditSupplier>> list(CreditSupplierParam param) {
// 使用关联查询
return success(creditSupplierService.listRel(param));
}
@Operation(summary = "根据id查询供应商")
@GetMapping("/{id}")
public ApiResult<CreditSupplier> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditSupplierService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditSupplier:save')")
@OperationLog
@Operation(summary = "添加供应商")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditSupplier creditSupplier) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditSupplier.setUserId(loginUser.getUserId());
// }
if (creditSupplierService.save(creditSupplier)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:update')")
@OperationLog
@Operation(summary = "修改供应商")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditSupplier creditSupplier) {
if (creditSupplierService.updateById(creditSupplier)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:remove')")
@OperationLog
@Operation(summary = "删除供应商")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditSupplierService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:save')")
@OperationLog
@Operation(summary = "批量添加供应商")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditSupplier> list) {
if (creditSupplierService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:update')")
@OperationLog
@Operation(summary = "批量修改供应商")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditSupplier> batchParam) {
if (batchParam.update(creditSupplierService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:remove')")
@OperationLog
@Operation(summary = "批量删除供应商")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditSupplierService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入供应商
*/
@PreAuthorize("hasAuthority('credit:creditSupplier:save')")
@Operation(summary = "批量导入供应商")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "供应商", 3);
ExcelImportSupport.ImportResult<CreditSupplierImportParam> importResult = ExcelImportSupport.read(
file, CreditSupplierImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditSupplierImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditSupplier> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditSupplierImportParam param = list.get(i);
try {
CreditSupplier item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getSupplier())) {
errorMessages.add("" + excelRowNumber + "行:供应商不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditSupplierService,
chunkItems,
CreditSupplier::getId,
CreditSupplier::setId,
CreditSupplier::getSupplier,
CreditSupplier::getSupplier,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditSupplierService.save(rowItem);
if (!saved) {
CreditSupplier existing = creditSupplierService.lambdaQuery()
.eq(CreditSupplier::getSupplier, rowItem.getSupplier())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditSupplierService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditSupplierService,
chunkItems,
CreditSupplier::getId,
CreditSupplier::setId,
CreditSupplier::getSupplier,
CreditSupplier::getSupplier,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditSupplierService.save(rowItem);
if (!saved) {
CreditSupplier existing = creditSupplierService.lambdaQuery()
.eq(CreditSupplier::getSupplier, rowItem.getSupplier())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditSupplierService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载供应商导入模板
*/
@Operation(summary = "下载供应商导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditSupplierImportParam> templateList = new ArrayList<>();
CreditSupplierImportParam example = new CreditSupplierImportParam();
example.setSupplier("示例供应商");
example.setStatusTxt("合作中");
example.setPurchaseAmount("120");
example.setPublicDate("2024-02-01");
example.setDataSource("公开渠道");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("供应商导入模板", "供应商", CreditSupplierImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_supplier_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditSupplierImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getSupplier())
&& ImportHelper.isBlank(param.getStatusTxt())
&& ImportHelper.isBlank(param.getPurchaseAmount());
}
private CreditSupplier convertImportParamToEntity(CreditSupplierImportParam param) {
CreditSupplier entity = new CreditSupplier();
entity.setSupplier(param.getSupplier());
entity.setStatusTxt(param.getStatusTxt());
entity.setPurchaseAmount(param.getPurchaseAmount());
entity.setPublicDate(param.getPublicDate());
entity.setDataSource(param.getDataSource());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,496 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditSuspectedRelationship;
import com.gxwebsoft.credit.param.CreditSuspectedRelationshipImportParam;
import com.gxwebsoft.credit.param.CreditSuspectedRelationshipParam;
import com.gxwebsoft.credit.service.CreditSuspectedRelationshipService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 疑似关系控制器
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Tag(name = "疑似关系管理")
@RestController
@RequestMapping("/api/credit/credit-suspected-relationship")
public class CreditSuspectedRelationshipController extends BaseController {
@Resource
private CreditSuspectedRelationshipService creditSuspectedRelationshipService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询疑似关系")
@GetMapping("/page")
public ApiResult<PageResult<CreditSuspectedRelationship>> page(CreditSuspectedRelationshipParam param) {
// 使用关联查询
return success(creditSuspectedRelationshipService.pageRel(param));
}
@Operation(summary = "查询全部疑似关系")
@GetMapping()
public ApiResult<List<CreditSuspectedRelationship>> list(CreditSuspectedRelationshipParam param) {
// 使用关联查询
return success(creditSuspectedRelationshipService.listRel(param));
}
@Operation(summary = "根据id查询疑似关系")
@GetMapping("/{id}")
public ApiResult<CreditSuspectedRelationship> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditSuspectedRelationshipService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditSuspectedRelationship:save')")
@OperationLog
@Operation(summary = "添加疑似关系")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditSuspectedRelationship creditSuspectedRelationship) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditSuspectedRelationship.setUserId(loginUser.getUserId());
// }
if (creditSuspectedRelationshipService.save(creditSuspectedRelationship)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditSuspectedRelationship:update')")
@OperationLog
@Operation(summary = "修改疑似关系")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditSuspectedRelationship creditSuspectedRelationship) {
if (creditSuspectedRelationshipService.updateById(creditSuspectedRelationship)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditSuspectedRelationship:remove')")
@OperationLog
@Operation(summary = "删除疑似关系")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditSuspectedRelationshipService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditSuspectedRelationship:save')")
@OperationLog
@Operation(summary = "批量添加疑似关系")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditSuspectedRelationship> list) {
if (creditSuspectedRelationshipService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditSuspectedRelationship:update')")
@OperationLog
@Operation(summary = "批量修改疑似关系")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditSuspectedRelationship> batchParam) {
if (batchParam.update(creditSuspectedRelationshipService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditSuspectedRelationship:remove')")
@OperationLog
@Operation(summary = "批量删除疑似关系")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditSuspectedRelationshipService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入疑似关系
*/
@PreAuthorize("hasAuthority('credit:creditSuspectedRelationship:save')")
@Operation(summary = "批量导入疑似关系")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditSuspectedRelationshipImportParam> importResult = ExcelImportSupport.readAnySheet(
file, CreditSuspectedRelationshipImportParam.class, this::isEmptyImportRow);
List<CreditSuspectedRelationshipImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "企业名称");
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditSuspectedRelationship> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditSuspectedRelationshipImportParam param = list.get(i);
try {
CreditSuspectedRelationship item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getName())) {
String link = urlByName.get(item.getName().trim());
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:企业名称不能为空");
continue;
}
if (ImportHelper.isBlank(item.getRelatedParty())) {
errorMessages.add("" + excelRowNumber + "行:关联方不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> {
List<String> names = new ArrayList<>(chunkItems.size());
List<String> relatedParties = new ArrayList<>(chunkItems.size());
for (CreditSuspectedRelationship it : chunkItems) {
if (it == null) {
continue;
}
if (!ImportHelper.isBlank(it.getName())) {
names.add(it.getName().trim());
}
if (!ImportHelper.isBlank(it.getRelatedParty())) {
relatedParties.add(it.getRelatedParty().trim());
}
}
List<CreditSuspectedRelationship> existingList = (names.isEmpty() || relatedParties.isEmpty())
? new ArrayList<>()
: creditSuspectedRelationshipService.lambdaQuery()
.in(CreditSuspectedRelationship::getName, names)
.in(CreditSuspectedRelationship::getRelatedParty, relatedParties)
.list();
java.util.Map<String, CreditSuspectedRelationship> byNameRelated = new java.util.HashMap<>();
java.util.Map<String, CreditSuspectedRelationship> byNameRelatedType = new java.util.HashMap<>();
for (CreditSuspectedRelationship existing : existingList) {
if (existing == null
|| ImportHelper.isBlank(existing.getName())
|| ImportHelper.isBlank(existing.getRelatedParty())) {
continue;
}
String n = existing.getName().trim();
String r = existing.getRelatedParty().trim();
byNameRelated.putIfAbsent(n + "|" + r, existing);
if (!ImportHelper.isBlank(existing.getType())) {
byNameRelatedType.putIfAbsent(n + "|" + r + "|" + existing.getType().trim(), existing);
}
}
List<CreditSuspectedRelationship> updates = new ArrayList<>();
List<CreditSuspectedRelationship> inserts = new ArrayList<>();
for (CreditSuspectedRelationship it : chunkItems) {
if (it == null
|| ImportHelper.isBlank(it.getName())
|| ImportHelper.isBlank(it.getRelatedParty())) {
continue;
}
String n = it.getName().trim();
String r = it.getRelatedParty().trim();
CreditSuspectedRelationship existing;
if (!ImportHelper.isBlank(it.getType())) {
existing = byNameRelatedType.get(n + "|" + r + "|" + it.getType().trim());
} else {
existing = byNameRelated.get(n + "|" + r);
}
if (existing != null) {
it.setId(existing.getId());
updates.add(it);
} else {
inserts.add(it);
}
}
if (!updates.isEmpty()) {
creditSuspectedRelationshipService.updateBatchById(updates, mpBatchSize);
}
if (!inserts.isEmpty()) {
creditSuspectedRelationshipService.saveBatch(inserts, mpBatchSize);
}
return updates.size() + inserts.size();
},
(rowItem, rowNumber) -> {
boolean saved = creditSuspectedRelationshipService.save(rowItem);
if (!saved) {
CreditSuspectedRelationship existing = creditSuspectedRelationshipService.lambdaQuery()
.eq(CreditSuspectedRelationship::getName, rowItem.getName())
.eq(CreditSuspectedRelationship::getRelatedParty, rowItem.getRelatedParty())
.eq(!ImportHelper.isBlank(rowItem.getType()), CreditSuspectedRelationship::getType, rowItem.getType())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditSuspectedRelationshipService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> {
List<String> names = new ArrayList<>(chunkItems.size());
List<String> relatedParties = new ArrayList<>(chunkItems.size());
for (CreditSuspectedRelationship it : chunkItems) {
if (it == null) {
continue;
}
if (!ImportHelper.isBlank(it.getName())) {
names.add(it.getName().trim());
}
if (!ImportHelper.isBlank(it.getRelatedParty())) {
relatedParties.add(it.getRelatedParty().trim());
}
}
List<CreditSuspectedRelationship> existingList = (names.isEmpty() || relatedParties.isEmpty())
? new ArrayList<>()
: creditSuspectedRelationshipService.lambdaQuery()
.in(CreditSuspectedRelationship::getName, names)
.in(CreditSuspectedRelationship::getRelatedParty, relatedParties)
.list();
java.util.Map<String, CreditSuspectedRelationship> byNameRelated = new java.util.HashMap<>();
java.util.Map<String, CreditSuspectedRelationship> byNameRelatedType = new java.util.HashMap<>();
for (CreditSuspectedRelationship existing : existingList) {
if (existing == null
|| ImportHelper.isBlank(existing.getName())
|| ImportHelper.isBlank(existing.getRelatedParty())) {
continue;
}
String n = existing.getName().trim();
String r = existing.getRelatedParty().trim();
byNameRelated.putIfAbsent(n + "|" + r, existing);
if (!ImportHelper.isBlank(existing.getType())) {
byNameRelatedType.putIfAbsent(n + "|" + r + "|" + existing.getType().trim(), existing);
}
}
List<CreditSuspectedRelationship> updates = new ArrayList<>();
List<CreditSuspectedRelationship> inserts = new ArrayList<>();
for (CreditSuspectedRelationship it : chunkItems) {
if (it == null
|| ImportHelper.isBlank(it.getName())
|| ImportHelper.isBlank(it.getRelatedParty())) {
continue;
}
String n = it.getName().trim();
String r = it.getRelatedParty().trim();
CreditSuspectedRelationship existing;
if (!ImportHelper.isBlank(it.getType())) {
existing = byNameRelatedType.get(n + "|" + r + "|" + it.getType().trim());
} else {
existing = byNameRelated.get(n + "|" + r);
}
if (existing != null) {
it.setId(existing.getId());
updates.add(it);
} else {
inserts.add(it);
}
}
if (!updates.isEmpty()) {
creditSuspectedRelationshipService.updateBatchById(updates, mpBatchSize);
}
if (!inserts.isEmpty()) {
creditSuspectedRelationshipService.saveBatch(inserts, mpBatchSize);
}
return updates.size() + inserts.size();
},
(rowItem, rowNumber) -> {
boolean saved = creditSuspectedRelationshipService.save(rowItem);
if (!saved) {
CreditSuspectedRelationship existing = creditSuspectedRelationshipService.lambdaQuery()
.eq(CreditSuspectedRelationship::getName, rowItem.getName())
.eq(CreditSuspectedRelationship::getRelatedParty, rowItem.getRelatedParty())
.eq(!ImportHelper.isBlank(rowItem.getType()), CreditSuspectedRelationship::getType, rowItem.getType())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditSuspectedRelationshipService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载疑似关系导入模板
*/
@Operation(summary = "下载疑似关系导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditSuspectedRelationshipImportParam> templateList = new ArrayList<>();
CreditSuspectedRelationshipImportParam example = new CreditSuspectedRelationshipImportParam();
example.setName("示例科技有限公司");
example.setStatusText("存续");
example.setLegalPerson("李四");
example.setRegisteredCapital("1000万人民币");
example.setCreateDate("2018-06-01");
example.setRelatedParty("关联方示例");
example.setType("股权关联");
example.setDetail("疑似关系详情示例");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("疑似关系导入模板", "疑似关系", CreditSuspectedRelationshipImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_suspected_relationship_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditSuspectedRelationshipImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getRelatedParty())
&& ImportHelper.isBlank(param.getType());
}
private boolean isImportHeaderRow(CreditSuspectedRelationshipImportParam param) {
return isHeaderValue(param.getName(), "企业名称")
|| isHeaderValue(param.getRelatedParty(), "关联方")
|| isHeaderValue(param.getType(), "疑似关系类型");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private CreditSuspectedRelationship convertImportParamToEntity(CreditSuspectedRelationshipImportParam param) {
CreditSuspectedRelationship entity = new CreditSuspectedRelationship();
entity.setName(param.getName());
entity.setStatusText(param.getStatusText());
entity.setLegalPerson(param.getLegalPerson());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setCreateDate(param.getCreateDate());
entity.setRelatedParty(param.getRelatedParty());
entity.setType(param.getType());
entity.setDetail(param.getDetail());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -17,7 +17,11 @@ import com.gxwebsoft.credit.param.CreditUserParam;
import com.gxwebsoft.credit.service.CreditUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -27,18 +31,21 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 赊账客户表控制器
* 招投标信息表控制器
*
* @author 科技小王子
* @since 2025-12-15 13:16:04
*/
@Tag(name = "赊账客户表管理")
@Tag(name = "招投标信息表管理")
@RestController
@RequestMapping("/api/credit/credit-user")
public class CreditUserController extends BaseController {
@@ -47,21 +54,24 @@ public class CreditUserController extends BaseController {
@Resource
private CreditUserService creditUserService;
@Operation(summary = "分页查询赊账客户表")
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询招投标信息表")
@GetMapping("/page")
public ApiResult<PageResult<CreditUser>> page(CreditUserParam param) {
// 使用关联查询
return success(creditUserService.pageRel(param));
}
@Operation(summary = "查询全部赊账客户")
@Operation(summary = "查询全部招投标信息")
@GetMapping()
public ApiResult<List<CreditUser>> list(CreditUserParam param) {
// 使用关联查询
return success(creditUserService.listRel(param));
}
@Operation(summary = "根据id查询赊账客户")
@Operation(summary = "根据id查询招投标信息")
@GetMapping("/{id}")
public ApiResult<CreditUser> get(@PathVariable("id") Integer id) {
// 使用关联查询
@@ -70,7 +80,7 @@ public class CreditUserController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditUser:save')")
@OperationLog
@Operation(summary = "添加赊账客户")
@Operation(summary = "添加招投标信息")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditUser creditUser) {
if (creditUserService.save(creditUser)) {
@@ -81,7 +91,7 @@ public class CreditUserController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditUser:update')")
@OperationLog
@Operation(summary = "修改赊账客户")
@Operation(summary = "修改招投标信息")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditUser creditUser) {
if (creditUserService.updateById(creditUser)) {
@@ -92,7 +102,7 @@ public class CreditUserController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditUser:remove')")
@OperationLog
@Operation(summary = "删除赊账客户")
@Operation(summary = "删除招投标信息")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditUserService.removeById(id)) {
@@ -103,7 +113,7 @@ public class CreditUserController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditUser:save')")
@OperationLog
@Operation(summary = "批量添加赊账客户")
@Operation(summary = "批量添加招投标信息")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditUser> list) {
if (creditUserService.saveBatch(list)) {
@@ -114,7 +124,7 @@ public class CreditUserController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditUser:update')")
@OperationLog
@Operation(summary = "批量修改赊账客户")
@Operation(summary = "批量修改招投标信息")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditUser> batchParam) {
if (batchParam.update(creditUserService, "id")) {
@@ -125,7 +135,7 @@ public class CreditUserController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditUser:remove')")
@OperationLog
@Operation(summary = "批量删除赊账客户")
@Operation(summary = "批量删除招投标信息")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditUserService.removeByIds(ids)) {
@@ -135,24 +145,26 @@ public class CreditUserController extends BaseController {
}
/**
* 批量导入赊账客户
* 批量导入招投标信息
* Excel表头格式客户名称、唯一标识、类型、企业角色、上级ID、信息类型、所在国家、所在省份、所在城市、所在辖区、街道地址、招采单位名称、中标单位名称、中标金额、备注、是否推荐、到期时间、排序、状态、用户ID、租户ID
*/
@PreAuthorize("hasAuthority('credit:creditUser:save')")
@Operation(summary = "批量导入赊账客户")
@Operation(summary = "批量导入招投标信息")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "招投标", 0);
List<CreditUserImportParam> list = null;
int usedTitleRows = 0;
int usedHeadRows = 0;
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {0, 2}, {0, 3}};
for (int[] config : tryConfigs) {
list = filterEmptyRows(tryImport(file, config[0], config[1]));
list = filterEmptyRows(tryImport(file, config[0], config[1], sheetIndex));
if (!CollectionUtils.isEmpty(list)) {
usedTitleRows = config[0];
usedHeadRows = config[1];
@@ -166,12 +178,26 @@ public class CreditUserController extends BaseController {
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<Integer, String> urlMap = readNameHyperlinks(file, sheetIndex, usedTitleRows, usedHeadRows);
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditUser> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditUserImportParam param = list.get(i);
try {
CreditUser item = convertImportParamToEntity(param);
String link = urlMap.get(i);
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
// 设置默认值
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
@@ -198,14 +224,42 @@ public class CreditUserController extends BaseController {
continue;
}
if (creditUserService.save(item)) {
successCount++;
} else {
CreditUser update = creditUserService.getByName(item.getName());
if (creditUserService.updateById(update)) {
errorMessages.add("" + excelRowNumber + "行:更新成功");
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditUserService,
chunkItems,
CreditUser::getId,
CreditUser::setId,
CreditUser::getName,
CreditUser::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditUserService.save(rowItem);
if (!saved) {
CreditUser existing = creditUserService.getByName(rowItem.getName());
if (existing != null) {
rowItem.setId(existing.getId());
if (creditUserService.updateById(rowItem)) {
return true;
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
}
} else {
return true;
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
@@ -214,6 +268,40 @@ public class CreditUserController extends BaseController {
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditUserService,
chunkItems,
CreditUser::getId,
CreditUser::setId,
CreditUser::getName,
CreditUser::getName,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditUserService.save(rowItem);
if (!saved) {
CreditUser existing = creditUserService.getByName(rowItem.getName());
if (existing != null) {
rowItem.setId(existing.getId());
if (creditUserService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
@@ -227,9 +315,9 @@ public class CreditUserController extends BaseController {
}
/**
* 下载赊账客户导入模板
* 下载招投标信息导入模板
*/
@Operation(summary = "下载赊账客户导入模板")
@Operation(summary = "下载招投标信息导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditUserImportParam> templateList = new ArrayList<>();
@@ -237,6 +325,7 @@ public class CreditUserController extends BaseController {
CreditUserImportParam example = new CreditUserImportParam();
example.setCode("CUS001");
example.setName("示例客户");
example.setReleaseDate("2023-01-01");
example.setType(0);
example.setRole("采购方");
example.setInfoType("企业");
@@ -246,7 +335,7 @@ public class CreditUserController extends BaseController {
example.setWinningPrice("100000");
templateList.add(example);
ExportParams exportParams = new ExportParams("赊账客户导入模板", "赊账客户");
ExportParams exportParams = new ExportParams("招投标信息导入模板", "招投标信息");
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, CreditUserImportParam.class, templateList);
@@ -257,15 +346,55 @@ public class CreditUserController extends BaseController {
workbook.close();
}
private List<CreditUserImportParam> tryImport(MultipartFile file, int titleRows, int headRows) throws Exception {
private List<CreditUserImportParam> tryImport(MultipartFile file, int titleRows, int headRows, int sheetIndex) throws Exception {
ImportParams importParams = new ImportParams();
importParams.setTitleRows(titleRows);
importParams.setHeadRows(headRows);
importParams.setStartSheetIndex(0);
importParams.setStartSheetIndex(sheetIndex);
importParams.setSheetNum(1);
return ExcelImportUtil.importExcel(file.getInputStream(), CreditUserImportParam.class, importParams);
}
/**
* 读取“项目名称”列的超链接,按数据行顺序返回。
*/
private Map<Integer, String> readNameHyperlinks(MultipartFile file, int sheetIndex, int titleRows, int headRows) throws Exception {
Map<Integer, String> result = new HashMap<>();
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
if (sheet == null) {
return result;
}
int headerRowNum = titleRows + headRows - 1;
Row headerRow = sheet.getRow(headerRowNum);
int nameColIndex = 0;
if (headerRow != null) {
for (int c = headerRow.getFirstCellNum(); c < headerRow.getLastCellNum(); c++) {
Cell cell = headerRow.getCell(c);
if (cell != null && "项目名称".equals(cell.getStringCellValue())) {
nameColIndex = c;
break;
}
}
}
int dataStartRow = titleRows + headRows;
for (int r = dataStartRow; r <= sheet.getLastRowNum(); r++) {
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
Cell cell = row.getCell(nameColIndex);
if (cell != null && cell.getHyperlink() != null) {
String address = cell.getHyperlink().getAddress();
if (address != null && !address.isEmpty()) {
result.put(r - dataStartRow, address);
}
}
}
}
return result;
}
/**
* 过滤掉完全空白的导入行,避免空行导致导入失败
*/
@@ -303,6 +432,7 @@ public class CreditUserController extends BaseController {
entity.setCode(param.getCode());
entity.setName(param.getName());
entity.setReleaseDate(param.getReleaseDate());
entity.setType(param.getType());
entity.setRole(param.getRole());
entity.setInfoType(param.getInfoType());

View File

@@ -0,0 +1,350 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditXgxf;
import com.gxwebsoft.credit.param.CreditJudicialImportParam;
import com.gxwebsoft.credit.param.CreditXgxfParam;
import com.gxwebsoft.credit.service.CreditXgxfService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 限制高消费控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:55
*/
@Tag(name = "限制高消费管理")
@RestController
@RequestMapping("/api/credit/credit-xgxf")
public class CreditXgxfController extends BaseController {
@Resource
private CreditXgxfService creditXgxfService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询限制高消费")
@GetMapping("/page")
public ApiResult<PageResult<CreditXgxf>> page(CreditXgxfParam param) {
// 使用关联查询
return success(creditXgxfService.pageRel(param));
}
@Operation(summary = "查询全部限制高消费")
@GetMapping()
public ApiResult<List<CreditXgxf>> list(CreditXgxfParam param) {
// 使用关联查询
return success(creditXgxfService.listRel(param));
}
@Operation(summary = "根据id查询限制高消费")
@GetMapping("/{id}")
public ApiResult<CreditXgxf> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditXgxfService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@OperationLog
@Operation(summary = "添加限制高消费")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditXgxf creditXgxf) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditXgxf.setUserId(loginUser.getUserId());
// }
if (creditXgxfService.save(creditXgxf)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:update')")
@OperationLog
@Operation(summary = "修改限制高消费")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditXgxf creditXgxf) {
if (creditXgxfService.updateById(creditXgxf)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:remove')")
@OperationLog
@Operation(summary = "删除限制高消费")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditXgxfService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@OperationLog
@Operation(summary = "批量添加限制高消费")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditXgxf> list) {
if (creditXgxfService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:update')")
@OperationLog
@Operation(summary = "批量修改限制高消费")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditXgxf> batchParam) {
if (batchParam.update(creditXgxfService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:remove')")
@OperationLog
@Operation(summary = "批量删除限制高消费")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditXgxfService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 批量导入限制高消费司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@Operation(summary = "批量导入限制高消费司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
try {
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditXgxf> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditJudicialImportParam param = list.get(i);
try {
CreditXgxf item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditXgxfService,
chunkItems,
CreditXgxf::getId,
CreditXgxf::setId,
CreditXgxf::getCaseNumber,
CreditXgxf::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditXgxfService.save(rowItem);
if (!saved) {
CreditXgxf existing = creditXgxfService.lambdaQuery()
.eq(CreditXgxf::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditXgxfService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditXgxfService,
chunkItems,
CreditXgxf::getId,
CreditXgxf::setId,
CreditXgxf::getCaseNumber,
CreditXgxf::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditXgxfService.save(rowItem);
if (!saved) {
CreditXgxf existing = creditXgxfService.lambdaQuery()
.eq(CreditXgxf::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditXgxfService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载限制高消费导入模板
*/
@Operation(summary = "下载限制高消费导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudicialImportParam> templateList = new ArrayList<>();
CreditJudicialImportParam example = new CreditJudicialImportParam();
example.setDataType("限制高消费");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("限制高消费导入模板", "限制高消费", CreditJudicialImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_xgxf_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditXgxf convertImportParamToEntity(CreditJudicialImportParam param) {
CreditXgxf entity = new CreditXgxf();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -0,0 +1,344 @@
package com.gxwebsoft.credit.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
/**
* Excel 导入导出通用支持
*/
public class ExcelImportSupport {
public static class ImportResult<T> {
private final List<T> data;
private final int titleRows;
private final int headRows;
private final int sheetIndex;
public ImportResult(List<T> data, int titleRows, int headRows) {
this(data, titleRows, headRows, 0);
}
public ImportResult(List<T> data, int titleRows, int headRows, int sheetIndex) {
this.data = data;
this.titleRows = titleRows;
this.headRows = headRows;
this.sheetIndex = sheetIndex;
}
public List<T> getData() {
return data;
}
public int getTitleRows() {
return titleRows;
}
public int getHeadRows() {
return headRows;
}
public int getSheetIndex() {
return sheetIndex;
}
}
public static <T> ImportResult<T> read(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate) throws Exception {
return read(file, clazz, emptyRowPredicate, 0);
}
/**
* 自动尝试所有 sheet从第 0 个开始),直到读取到非空数据。
*/
public static <T> ImportResult<T> readAnySheet(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate) throws Exception {
ImportResult<T> result = read(file, clazz, emptyRowPredicate, 0);
if (!CollectionUtils.isEmpty(result.getData())) {
return result;
}
int sheetCount = getSheetCount(file);
for (int i = 1; i < sheetCount; i++) {
ImportResult<T> sheetResult = read(file, clazz, emptyRowPredicate, i);
if (!CollectionUtils.isEmpty(sheetResult.getData())) {
return sheetResult;
}
}
return result;
}
/**
* 自动尝试所有 sheet从第 0 个开始),并在每个 sheet 内选择“得分”最高的表头配置。
*/
public static <T> ImportResult<T> readAnySheetBest(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate, Predicate<T> scoreRowPredicate) throws Exception {
ImportResult<T> result = readBest(file, clazz, emptyRowPredicate, scoreRowPredicate, 0);
if (!CollectionUtils.isEmpty(result.getData())) {
return result;
}
int sheetCount = getSheetCount(file);
for (int i = 1; i < sheetCount; i++) {
ImportResult<T> sheetResult = readBest(file, clazz, emptyRowPredicate, scoreRowPredicate, i);
if (!CollectionUtils.isEmpty(sheetResult.getData())) {
return sheetResult;
}
}
return result;
}
/**
* 读取指定 sheet 的 Excel。
*
* @param sheetIndex 目标 sheet 下标,从 0 开始。第二个选项卡传 1。
*/
public static <T> ImportResult<T> read(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate, int sheetIndex) throws Exception {
List<T> list = null;
int usedTitleRows = 0;
int usedHeadRows = 0;
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {2, 1}, {3, 1}, {0, 2}, {0, 3}, {0, 4}};
for (int[] config : tryConfigs) {
list = filterEmptyRows(importSheet(file, clazz, config[0], config[1], sheetIndex), emptyRowPredicate);
if (!CollectionUtils.isEmpty(list)) {
usedTitleRows = config[0];
usedHeadRows = config[1];
break;
}
}
return new ImportResult<>(list, usedTitleRows, usedHeadRows, sheetIndex);
}
/**
* 读取指定 sheet 的 Excel并从多组表头配置中挑选“得分”最高的结果。
*/
public static <T> ImportResult<T> readBest(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate, Predicate<T> scoreRowPredicate, int sheetIndex) throws Exception {
List<T> bestList = null;
int bestTitleRows = 0;
int bestHeadRows = 0;
int bestScore = -1;
int bestSize = -1;
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {2, 1}, {3, 1}, {0, 2}, {0, 3}, {0, 4}, {1, 2}, {1, 3}, {1, 4}, {2, 2}, {2, 3}, {2, 4}, {3, 2}, {3, 3}, {3, 4}};
for (int[] config : tryConfigs) {
List<T> list = filterEmptyRows(importSheet(file, clazz, config[0], config[1], sheetIndex), emptyRowPredicate);
if (CollectionUtils.isEmpty(list)) {
continue;
}
int score = 0;
if (scoreRowPredicate != null) {
for (T row : list) {
if (scoreRowPredicate.test(row)) {
score++;
}
}
}
int size = list.size();
if (score > bestScore || (score == bestScore && size > bestSize)) {
bestList = list;
bestTitleRows = config[0];
bestHeadRows = config[1];
bestScore = score;
bestSize = size;
}
}
if (bestList != null) {
return new ImportResult<>(bestList, bestTitleRows, bestHeadRows, sheetIndex);
}
return read(file, clazz, emptyRowPredicate, sheetIndex);
}
private static <T> List<T> importSheet(MultipartFile file, Class<T> clazz, int titleRows, int headRows, int sheetIndex) throws Exception {
ImportParams importParams = new ImportParams();
importParams.setTitleRows(titleRows);
importParams.setHeadRows(headRows);
importParams.setStartSheetIndex(sheetIndex);
importParams.setSheetNum(1);
return ExcelImportUtil.importExcel(file.getInputStream(), clazz, importParams);
}
private static <T> List<T> filterEmptyRows(List<T> rawList, Predicate<T> emptyRowPredicate) {
if (CollectionUtils.isEmpty(rawList)) {
return rawList;
}
rawList.removeIf(emptyRowPredicate);
return rawList;
}
private static int getSheetCount(MultipartFile file) throws Exception {
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
return workbook.getNumberOfSheets();
}
}
/**
* 根据 sheet 名称查找下标(优先精确匹配,其次前缀匹配/包含匹配)。
*
* @return 找不到返回 -1
*/
public static int findSheetIndex(MultipartFile file, String sheetName) throws Exception {
if (file == null || sheetName == null || sheetName.trim().isEmpty()) {
return -1;
}
String target = normalizeSheetName(sheetName);
if (target.isEmpty()) {
return -1;
}
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
int sheetCount = workbook.getNumberOfSheets();
for (int i = 0; i < sheetCount; i++) {
String candidate = normalizeSheetName(workbook.getSheetName(i));
if (Objects.equals(candidate, target)) {
return i;
}
}
for (int i = 0; i < sheetCount; i++) {
String candidate = normalizeSheetName(workbook.getSheetName(i));
if (candidate.startsWith(target) || candidate.contains(target) || target.startsWith(candidate)) {
return i;
}
}
return -1;
}
}
public static int findSheetIndex(MultipartFile file, String sheetName, int defaultIndex) throws Exception {
int idx = findSheetIndex(file, sheetName);
return idx >= 0 ? idx : defaultIndex;
}
private static String normalizeSheetName(String sheetName) {
if (sheetName == null) {
return "";
}
return sheetName.replace(" ", "").replace(" ", "").trim();
}
/**
* 读取指定列(由表头名定位)的超链接,返回:单元格显示值 -> 超链接地址。
*
* <p>适用于:导入对象没有 url 字段,但 Excel 把链接放在某个“名称/案号”等列的超链接里。</p>
*/
public static Map<String, String> readHyperlinksByHeaderKey(MultipartFile file, int sheetIndex, int titleRows, int headRows, String headerName) throws Exception {
if (file == null || headerName == null || headerName.trim().isEmpty()) {
return Collections.emptyMap();
}
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
if (workbook.getNumberOfSheets() <= sheetIndex) {
return Collections.emptyMap();
}
Sheet sheet = workbook.getSheetAt(sheetIndex);
if (sheet == null) {
return Collections.emptyMap();
}
int colIndex = findColumnIndexByHeader(sheet, titleRows, headRows, headerName);
if (colIndex < 0) {
return Collections.emptyMap();
}
Map<String, String> result = new HashMap<>();
DataFormatter formatter = new DataFormatter();
int dataStartRow = titleRows + headRows;
for (int r = dataStartRow; r <= sheet.getLastRowNum(); r++) {
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
Cell cell = row.getCell(colIndex);
if (cell == null) {
continue;
}
String address = extractHyperlinkAddress(cell);
if (address == null || address.isEmpty()) {
continue;
}
String key = formatter.formatCellValue(cell);
if (key == null || key.trim().isEmpty()) {
continue;
}
result.put(key.trim(), address);
}
return result;
}
}
private static int findColumnIndexByHeader(Sheet sheet, int titleRows, int headRows, String headerName) {
int firstHeaderRow = Math.max(0, titleRows);
int lastHeaderRow = Math.max(0, titleRows + headRows - 1);
for (int r = firstHeaderRow; r <= lastHeaderRow; r++) {
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
Cell cell = row.getCell(c);
if (cell == null) {
continue;
}
if (cell.getCellType() == CellType.STRING) {
String value = cell.getStringCellValue();
if (headerName.equals(value != null ? value.trim() : null)) {
return c;
}
} else {
DataFormatter formatter = new DataFormatter();
String value = formatter.formatCellValue(cell);
if (headerName.equals(value != null ? value.trim() : null)) {
return c;
}
}
}
}
return -1;
}
private static String extractHyperlinkAddress(Cell cell) {
Hyperlink hyperlink = cell.getHyperlink();
if (hyperlink != null && hyperlink.getAddress() != null && !hyperlink.getAddress().isEmpty()) {
return hyperlink.getAddress();
}
if (cell.getCellType() == CellType.FORMULA) {
String formula = cell.getCellFormula();
if (formula != null && formula.toUpperCase().startsWith("HYPERLINK(")) {
int firstQuote = formula.indexOf('\"');
if (firstQuote >= 0) {
int secondQuote = formula.indexOf('\"', firstQuote + 1);
if (secondQuote > firstQuote) {
return formula.substring(firstQuote + 1, secondQuote);
}
}
}
}
return null;
}
public static <T> Workbook buildTemplate(String title, String sheetName, Class<T> clazz, List<T> examples) {
ExportParams exportParams = new ExportParams(title, sheetName);
return ExcelExportUtil.exportExcel(exportParams, clazz, examples);
}
}

View File

@@ -0,0 +1,39 @@
package com.gxwebsoft.credit.controller;
import java.math.BigDecimal;
import java.time.LocalDate;
/**
* 导入解析辅助工具
*/
public final class ImportHelper {
private ImportHelper() {
}
public static boolean isBlank(String value) {
return value == null || value.trim().isEmpty();
}
public static BigDecimal parseBigDecimal(String value, String fieldLabel) {
if (isBlank(value)) {
return null;
}
try {
return new BigDecimal(value.trim());
} catch (Exception e) {
throw new IllegalArgumentException(fieldLabel + "格式不正确");
}
}
public static LocalDate parseLocalDate(String value, String fieldLabel) {
if (isBlank(value)) {
return null;
}
try {
return LocalDate.parse(value.trim());
} catch (Exception e) {
throw new IllegalArgumentException(fieldLabel + "日期格式应为yyyy-MM-dd");
}
}
}

View File

@@ -0,0 +1,95 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 行政许可
*
* @author 科技小王子
* @since 2026-01-07 13:52:13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditAdministrativeLicense对象", description = "行政许可")
public class CreditAdministrativeLicense implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "决定文书/许可编号")
private String code;
@Schema(description = "决定文书/许可证名称")
private String name;
@Schema(description = "许可状态")
private String statusText;
@Schema(description = "许可类型")
private String type;
@Schema(description = "链接")
private String url;
@Schema(description = "有效期自")
private String validityStart;
@Schema(description = "有效期至")
private String validityEnd;
@Schema(description = "许可机关")
private String licensingAuthority;
@Schema(description = "许可内容")
@TableField("License_content")
private String licenseContent;
@Schema(description = "数据来源单位")
private String dataSourceUnit;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,81 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 破产重整
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditBankruptcy对象", description = "破产重整")
public class CreditBankruptcy implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案号")
private String code;
@Schema(description = "案件类型")
private String type;
@Schema(description = "当事人")
private String party;
@Schema(description = "链接")
private String url;
@Schema(description = "经办法院")
private String court;
@Schema(description = "公开日期")
private String publicDate;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,81 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 分支机构
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditBranch对象", description = "分支机构")
public class CreditBranch 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 curator;
@Schema(description = "地区")
private String region;
@Schema(description = "链接")
private String url;
@Schema(description = "成立日期")
private String establishDate;
@Schema(description = "状态")
private String statusText;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 失信被执行人
*
* @author 科技小王子
* @since 2025-12-19 19:46:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditBreachOfTrust对象", description = "失信被执行人")
public class CreditBreachOfTrust implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:47:22
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCaseFiling对象", description = "司法大数据")
public class CreditCaseFiling implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,213 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 企业
*
* @author 科技小王子
* @since 2025-12-17 08:28:03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCompany对象", description = "企业")
public class CreditCompany 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 matchName;
@Schema(description = "统一社会信用代码")
private String code;
@Schema(description = "项目网址")
private String url;
@Schema(description = "类型")
private Integer type;
@Schema(description = "上级id, 0是顶级")
private Integer parentId;
@Schema(description = "登记状态")
private String registrationStatus;
@Schema(description = "法定代表人")
private String legalPerson;
@Schema(description = "注册资本")
private String registeredCapital;
@Schema(description = "实缴资本")
private String paidinCapital;
@Schema(description = "成立日期")
private String establishDate;
@Schema(description = "企业地址")
private String address;
@Schema(description = "电话")
private String tel;
@Schema(description = "更多电话")
private String moreTel;
@Schema(description = "邮箱")
private String email;
@Schema(description = "更多邮箱")
private String moreEmail;
@Schema(description = "所在国家")
private String country;
@Schema(description = "所属省份")
private String province;
@Schema(description = "所属城市")
private String city;
@Schema(description = "所属区县")
private String region;
@Schema(description = "企业(机构)类型")
private String institutionType;
@Schema(description = "纳税人识别号")
private String taxpayerCode;
@Schema(description = "注册号")
private String registrationNumber;
@Schema(description = "组织机构代码")
private String organizationalCode;
@Schema(description = "参保人数")
private String numberOfInsuredPersons;
@Schema(description = "参保人数所属年报")
private String annualReport;
@Schema(description = "营业期限")
private String businessTerm;
@Schema(description = "国标行业门类")
private String nationalStandardIndustryCategories;
@Schema(description = "国标行业大类")
private String nationalStandardIndustryCategories2;
@Schema(description = "国标行业中类")
private String nationalStandardIndustryCategories3;
@Schema(description = "国标行业小类")
private String nationalStandardIndustryCategories4;
@Schema(description = "企查查行业门类")
private String nationalStandardIndustryCategories5;
@Schema(description = "企查查行业大类")
private String nationalStandardIndustryCategories6;
@Schema(description = "企查查行业中类")
private String nationalStandardIndustryCategories7;
@Schema(description = "企查查行业小类")
private String nationalStandardIndustryCategories8;
@Schema(description = "企业规模")
private String companySize;
@Schema(description = "曾用名")
private String formerName;
@Schema(description = "英文名")
private String englishName;
@Schema(description = "官网")
private String domain;
@Schema(description = "通信地址")
private String mailingAddress;
@Schema(description = "企业简介")
private String companyProfile;
@Schema(description = "经营范围")
private String natureOfBusiness;
@Schema(description = "登记机关")
private String registrationAuthority;
@Schema(description = "纳税人资质")
private String taxpayerQualification;
@Schema(description = "最新年报年份")
private String latestAnnualReportYear;
@Schema(description = "最新年报营业收入")
private String latestAnnualReportOnOperatingRevenue;
@Schema(description = "企查分")
private String enterpriseScoreCheck;
@Schema(description = "信用等级")
private String creditRating;
@Schema(description = "科创分")
private String cechnologyScore;
@Schema(description = "科创等级")
private String cechnologyLevel;
@Schema(description = "是否小微企业")
private String smallEnterprise;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,91 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 竞争对手
*
* @author 科技小王子
* @since 2025-12-19 19:49:04
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCompetitor对象", description = "竞争对手")
public class CreditCompetitor implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "序号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "企业名称")
private String companyName;
@Schema(description = "法定代表人")
private String legalRepresentative;
@Schema(description = "注册资本")
private String registeredCapital;
@Schema(description = "成立日期")
private String establishmentDate;
@Schema(description = "登记状态")
private String registrationStatus;
@Schema(description = "所属行业")
private String industry;
@Schema(description = "所属省份")
private String province;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "所属企业名称")
@TableField(exist = false)
private String mainCompanyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 法院公告司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:49:13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCourtAnnouncement对象", description = "法院公告司法大数据")
public class CreditCourtAnnouncement implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 开庭公告司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:49:32
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCourtSession对象", description = "开庭公告司法大数据")
public class CreditCourtSession implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,85 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 客户
*
* @author 科技小王子
* @since 2025-12-21 21:20:58
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCustomer对象", description = "客户")
public class CreditCustomer 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 statusTxt;
@Schema(description = "销售金额(万元)")
private String price;
@Schema(description = "公开日期")
private String publicDate;
@Schema(description = "数据来源")
private String dataSource;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 送达公告司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:49:51
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditDeliveryNotice对象", description = "送达公告司法大数据")
public class CreditDeliveryNotice implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,112 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 对外投资
*
* @author 科技小王子
* @since 2025-12-19 19:50:11
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditExternal对象", description = "对外投资")
public class CreditExternal 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 statusTxt;
@Schema(description = "法定代表人姓名")
private String legalRepresentative;
@Schema(description = "注册资本(金额)")
private String registeredCapital;
@Schema(description = "成立日期")
private String establishmentDate;
@Schema(description = "持股比例")
private String shareholdingRatio;
@Schema(description = "认缴出资额")
private String subscribedInvestmentAmount;
@Schema(description = "认缴出资日期")
private String subscribedInvestmentDate;
@Schema(description = "间接持股比例")
private String indirectShareholdingRatio;
@Schema(description = "投资日期")
private String investmentDate;
@Schema(description = "所属地区")
private String region;
@Schema(description = "所属行业")
private String industry;
@Schema(description = "投资数量")
private Integer investmentCount;
@Schema(description = "关联产品/机构")
private String relatedProductsInstitutions;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 终本案件
*
* @author 科技小王子
* @since 2025-12-19 19:50:19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditFinalVersion对象", description = "终本案件")
public class CreditFinalVersion implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 股权冻结
*
* @author 科技小王子
* @since 2025-12-19 19:50:37
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditGqdj对象", description = "股权冻结")
public class CreditGqdj implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,75 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 历史法定代表人
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditHistoricalLegalPerson对象", description = "历史法定代表人")
public class CreditHistoricalLegalPerson 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 registerDate;
@Schema(description = "卸任日期")
private String publicDate;
@Schema(description = "链接")
private String url;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,107 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
* 被执行人
*
* @author 科技小王子
* @since 2025-12-19 19:50:55
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditJudgmentDebtor对象", description = "被执行人")
public class CreditJudgmentDebtor implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "被执行人名称")
private String name;
@Schema(description = "被执行人")
private String name1;
@Schema(description = "证件号/组织机构代码")
private String code;
@Schema(description = "项目网址")
private String url;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "执行标的(元)")
private String amount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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 = "历史被执行人ID")
@TableField(exist = false)
private Integer historyId;
@Schema(description = "历史被执行人名称")
@TableField(exist = false)
private String historyName;
}

View File

@@ -0,0 +1,93 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 被执行人
*
* @author 科技小王子
* @since 2026-01-12 08:10:43
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditJudgmentDebtorHistory对象", description = "被执行人")
public class CreditJudgmentDebtorHistory implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "被执行人名称")
private String name;
@Schema(description = "被执行人")
private String name1;
@Schema(description = "证件号/组织机构代码")
private String code;
@Schema(description = "链接")
private String url;
@Schema(description = "是否多企业")
private Integer type;
@Schema(description = "立案日期")
private String occurrenceTime;
@Schema(description = "执行标的(元)")
private String amount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 裁判文书司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:51:02
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditJudicialDocument对象", description = "裁判文书司法大数据")
public class CreditJudicialDocument implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,120 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 司法案件
*
* @author 科技小王子
* @since 2025-12-16 15:23:58
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditJudiciary对象", description = "司法案件")
public class CreditJudiciary 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 code;
@Schema(description = "类型, 0普通用户, 1招投标")
private Integer type;
@Schema(description = "案由")
private String reason;
@Schema(description = "上级id, 0是顶级")
private Integer parentId;
@Schema(description = "案件类型")
private String infoType;
@Schema(description = "所在国家")
private String country;
@Schema(description = "所在省份")
private String province;
@Schema(description = "所在城市")
private String city;
@Schema(description = "所在辖区")
private String region;
@Schema(description = "街道地址")
private String address;
@Schema(description = "案件进程")
private String caseProgress;
@Schema(description = "案件身份")
private String caseIdentity;
@Schema(description = "法院")
private String court;
@Schema(description = "进程日期")
private String processDate;
@Schema(description = "案件金额(元)")
private String caseAmount;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "到期时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expirationTime;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 诉前调解司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:51:25
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditMediation对象", description = "诉前调解司法大数据")
public class CreditMediation implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,222 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 附近企业
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditNearbyCompany对象", description = "附近企业")
public class CreditNearbyCompany 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 registrationStatus;
@Schema(description = "法定代表人")
private String legalPerson;
@Schema(description = "注册资本")
private String registeredCapital;
@Schema(description = "成立日期")
private String establishDate;
@Schema(description = "统一社会信用代码")
private String code;
@Schema(description = "注册地址")
private String address;
@Schema(description = "注册地址邮编")
private String postalCode;
@Schema(description = "有效手机号")
private String phone;
@Schema(description = "更多电话")
private String moreTel;
@Schema(description = "邮箱")
private String email;
@Schema(description = "邮箱")
private String moreEmail;
@Schema(description = "所在国家")
private String country;
@Schema(description = "所属省份")
private String province;
@Schema(description = "所属城市")
private String city;
@Schema(description = "所属区县")
private String region;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "纳税人识别号")
private String taxpayerCode;
@Schema(description = "注册号")
private String registrationNumber;
@Schema(description = "组织机构代码")
private String organizationalCode;
@Schema(description = "参保人数")
private String numberOfInsuredPersons;
@Schema(description = "参保人数所属年报")
private String annualReport;
@Schema(description = "企业(机构)类型")
private String institutionType;
@Schema(description = "企业规模")
private String companySize;
@Schema(description = "营业期限")
private String businessTerm;
@Schema(description = "国标行业门类")
private String nationalStandardIndustryCategories;
@Schema(description = "国标行业大类")
private String nationalStandardIndustryCategories2;
@Schema(description = "国标行业中类")
private String nationalStandardIndustryCategories3;
@Schema(description = "国标行业小类")
private String nationalStandardIndustryCategories4;
@Schema(description = "曾用名")
private String formerName;
@Schema(description = "英文名")
private String englishName;
@Schema(description = "官网网址")
private String domain;
@Schema(description = "通信地址")
private String mailingAddress;
@Schema(description = "通信地址邮箱")
private String mailingEmail;
@Schema(description = "企业简介")
private String companyProfile;
@Schema(description = "经营范围")
private String natureOfBusiness;
@Schema(description = "电话")
private String tel;
@Schema(description = "企查查行业门类")
private String nationalStandardIndustryCategories5;
@Schema(description = "企查查行业大类")
private String nationalStandardIndustryCategories6;
@Schema(description = "企查查行业中类")
private String nationalStandardIndustryCategories7;
@Schema(description = "企查查行业小类")
private String nationalStandardIndustryCategories8;
@Schema(description = "链接")
private String url;
@Schema(description = "类型")
private Integer type;
@Schema(description = "上级id, 0是顶级")
private Integer parentId;
@Schema(description = "实缴资本")
private String paidinCapital;
@Schema(description = "登记机关")
private String registrationAuthority;
@Schema(description = "纳税人资质")
private String taxpayerQualification;
@Schema(description = "最新年报年份")
private String latestAnnualReportYear;
@Schema(description = "最新年报营业收入")
private String latestAnnualReportOnOperatingRevenue;
@Schema(description = "企查分")
private String enterpriseScoreCheck;
@Schema(description = "信用等级")
private String creditRating;
@Schema(description = "科创分")
private String cechnologyScore;
@Schema(description = "科创等级")
private String cechnologyLevel;
@Schema(description = "是否小微企业")
private String smallEnterprise;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,93 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 专利
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditPatent对象", description = "专利")
public class CreditPatent 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 type;
@Schema(description = "法律状态")
private String statusText;
@Schema(description = "申请号")
private String registerNo;
@Schema(description = "申请日")
private String registerDate;
@Schema(description = "公开(公告)号")
private String publicNo;
@Schema(description = "公开(公告)日期")
private String publicDate;
@Schema(description = "发明人")
private String inventor;
@Schema(description = "申请(专利权)人")
private String patentApplicant;
@Schema(description = "链接")
private String url;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,87 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 风险关系表
*
* @author 科技小王子
* @since 2025-12-19 19:51:40
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditRiskRelation对象", description = "风险关系表")
public class CreditRiskRelation implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "序号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "主体名称")
private String mainBodyName;
@Schema(description = "登记状态")
private String registrationStatus;
@Schema(description = "注册资本")
private String registeredCapital;
@Schema(description = "省份地区")
private String provinceRegion;
@Schema(description = "关联关系")
private String associatedRelation;
@Schema(description = "风险关系")
private String riskRelation;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,85 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 供应商
*
* @author 科技小王子
* @since 2025-12-19 19:51:47
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditSupplier对象", description = "供应商")
public class CreditSupplier implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "供应商")
private String supplier;
@Schema(description = "状态")
private String statusTxt;
@Schema(description = "采购金额(万元)")
private String purchaseAmount;
@Schema(description = "公开日期")
private String publicDate;
@Schema(description = "数据来源")
private String dataSource;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,90 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 疑似关系
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditSuspectedRelationship对象", description = "疑似关系")
public class CreditSuspectedRelationship 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 statusText;
@Schema(description = "法定代表人")
private String legalPerson;
@Schema(description = "注册资本")
private String registeredCapital;
@Schema(description = "成立日期")
private String createDate;
@Schema(description = "关联方")
private String relatedParty;
@Schema(description = "疑似关系类型")
private String type;
@Schema(description = "疑似关系详情")
private String detail;
@Schema(description = "链接")
private String url;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -1,6 +1,7 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableLogic;
@@ -11,14 +12,14 @@ import lombok.EqualsAndHashCode;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 赊账客户
* 招投标信息
*
* @author 科技小王子
* @since 2025-12-15 13:16:03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditUser对象", description = "赊账客户")
@Schema(name = "CreditUser对象", description = "招投标信息")
public class CreditUser implements Serializable {
private static final long serialVersionUID = 1L;
@@ -29,6 +30,9 @@ public class CreditUser implements Serializable {
@Schema(description = "项目名称")
private String name;
@Schema(description = "项目网址")
private String url;
@Schema(description = "唯一标识")
private String code;
@@ -71,6 +75,13 @@ public class CreditUser implements Serializable {
@Schema(description = "发布日期")
private String releaseDate;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

View File

@@ -0,0 +1,101 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 限制高消费
*
* @author 科技小王子
* @since 2025-12-19 19:51:55
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditXgxf对象", description = "限制高消费")
public class CreditXgxf implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
@TableField("Appellee")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@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;
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditAdministrativeLicense;
import com.gxwebsoft.credit.param.CreditAdministrativeLicenseParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 行政许可Mapper
*
* @author 科技小王子
* @since 2026-01-07 13:52:13
*/
public interface CreditAdministrativeLicenseMapper extends BaseMapper<CreditAdministrativeLicense> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditAdministrativeLicense>
*/
List<CreditAdministrativeLicense> selectPageRel(@Param("page") IPage<CreditAdministrativeLicense> page,
@Param("param") CreditAdministrativeLicenseParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditAdministrativeLicense> selectListRel(@Param("param") CreditAdministrativeLicenseParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditBankruptcy;
import com.gxwebsoft.credit.param.CreditBankruptcyParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 破产重整Mapper
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
public interface CreditBankruptcyMapper extends BaseMapper<CreditBankruptcy> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditBankruptcy>
*/
List<CreditBankruptcy> selectPageRel(@Param("page") IPage<CreditBankruptcy> page,
@Param("param") CreditBankruptcyParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditBankruptcy> selectListRel(@Param("param") CreditBankruptcyParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditBranch;
import com.gxwebsoft.credit.param.CreditBranchParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 分支机构Mapper
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
public interface CreditBranchMapper extends BaseMapper<CreditBranch> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditBranch>
*/
List<CreditBranch> selectPageRel(@Param("page") IPage<CreditBranch> page,
@Param("param") CreditBranchParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditBranch> selectListRel(@Param("param") CreditBranchParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditBreachOfTrust;
import com.gxwebsoft.credit.param.CreditBreachOfTrustParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 失信被执行人Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:46:14
*/
public interface CreditBreachOfTrustMapper extends BaseMapper<CreditBreachOfTrust> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditBreachOfTrust>
*/
List<CreditBreachOfTrust> selectPageRel(@Param("page") IPage<CreditBreachOfTrust> page,
@Param("param") CreditBreachOfTrustParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditBreachOfTrust> selectListRel(@Param("param") CreditBreachOfTrustParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditCaseFiling;
import com.gxwebsoft.credit.param.CreditCaseFilingParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 司法大数据Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:47:22
*/
public interface CreditCaseFilingMapper extends BaseMapper<CreditCaseFiling> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditCaseFiling>
*/
List<CreditCaseFiling> selectPageRel(@Param("page") IPage<CreditCaseFiling> page,
@Param("param") CreditCaseFilingParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditCaseFiling> selectListRel(@Param("param") CreditCaseFilingParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditCompany;
import com.gxwebsoft.credit.param.CreditCompanyParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 企业Mapper
*
* @author 科技小王子
* @since 2025-12-17 08:28:03
*/
public interface CreditCompanyMapper extends BaseMapper<CreditCompany> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditCompany>
*/
List<CreditCompany> selectPageRel(@Param("page") IPage<CreditCompany> page,
@Param("param") CreditCompanyParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditCompany> selectListRel(@Param("param") CreditCompanyParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditCompetitor;
import com.gxwebsoft.credit.param.CreditCompetitorParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 竞争对手Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:49:04
*/
public interface CreditCompetitorMapper extends BaseMapper<CreditCompetitor> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditCompetitor>
*/
List<CreditCompetitor> selectPageRel(@Param("page") IPage<CreditCompetitor> page,
@Param("param") CreditCompetitorParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditCompetitor> selectListRel(@Param("param") CreditCompetitorParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditCourtAnnouncement;
import com.gxwebsoft.credit.param.CreditCourtAnnouncementParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 法院公告司法大数据Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:49:13
*/
public interface CreditCourtAnnouncementMapper extends BaseMapper<CreditCourtAnnouncement> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditCourtAnnouncement>
*/
List<CreditCourtAnnouncement> selectPageRel(@Param("page") IPage<CreditCourtAnnouncement> page,
@Param("param") CreditCourtAnnouncementParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditCourtAnnouncement> selectListRel(@Param("param") CreditCourtAnnouncementParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditCourtSession;
import com.gxwebsoft.credit.param.CreditCourtSessionParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 开庭公告司法大数据Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:49:32
*/
public interface CreditCourtSessionMapper extends BaseMapper<CreditCourtSession> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditCourtSession>
*/
List<CreditCourtSession> selectPageRel(@Param("page") IPage<CreditCourtSession> page,
@Param("param") CreditCourtSessionParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditCourtSession> selectListRel(@Param("param") CreditCourtSessionParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditCustomer;
import com.gxwebsoft.credit.param.CreditCustomerParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 客户Mapper
*
* @author 科技小王子
* @since 2025-12-21 21:20:58
*/
public interface CreditCustomerMapper extends BaseMapper<CreditCustomer> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditCustomer>
*/
List<CreditCustomer> selectPageRel(@Param("page") IPage<CreditCustomer> page,
@Param("param") CreditCustomerParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditCustomer> selectListRel(@Param("param") CreditCustomerParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditDeliveryNotice;
import com.gxwebsoft.credit.param.CreditDeliveryNoticeParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 送达公告司法大数据Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:49:51
*/
public interface CreditDeliveryNoticeMapper extends BaseMapper<CreditDeliveryNotice> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditDeliveryNotice>
*/
List<CreditDeliveryNotice> selectPageRel(@Param("page") IPage<CreditDeliveryNotice> page,
@Param("param") CreditDeliveryNoticeParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditDeliveryNotice> selectListRel(@Param("param") CreditDeliveryNoticeParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditExternal;
import com.gxwebsoft.credit.param.CreditExternalParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 对外投资Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:50:11
*/
public interface CreditExternalMapper extends BaseMapper<CreditExternal> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditExternal>
*/
List<CreditExternal> selectPageRel(@Param("page") IPage<CreditExternal> page,
@Param("param") CreditExternalParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditExternal> selectListRel(@Param("param") CreditExternalParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditFinalVersion;
import com.gxwebsoft.credit.param.CreditFinalVersionParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 终本案件Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:50:19
*/
public interface CreditFinalVersionMapper extends BaseMapper<CreditFinalVersion> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditFinalVersion>
*/
List<CreditFinalVersion> selectPageRel(@Param("page") IPage<CreditFinalVersion> page,
@Param("param") CreditFinalVersionParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditFinalVersion> selectListRel(@Param("param") CreditFinalVersionParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditGqdj;
import com.gxwebsoft.credit.param.CreditGqdjParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 股权冻结Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:50:37
*/
public interface CreditGqdjMapper extends BaseMapper<CreditGqdj> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditGqdj>
*/
List<CreditGqdj> selectPageRel(@Param("page") IPage<CreditGqdj> page,
@Param("param") CreditGqdjParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditGqdj> selectListRel(@Param("param") CreditGqdjParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditHistoricalLegalPerson;
import com.gxwebsoft.credit.param.CreditHistoricalLegalPersonParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 历史法定代表人Mapper
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
public interface CreditHistoricalLegalPersonMapper extends BaseMapper<CreditHistoricalLegalPerson> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditHistoricalLegalPerson>
*/
List<CreditHistoricalLegalPerson> selectPageRel(@Param("page") IPage<CreditHistoricalLegalPerson> page,
@Param("param") CreditHistoricalLegalPersonParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditHistoricalLegalPerson> selectListRel(@Param("param") CreditHistoricalLegalPersonParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditJudgmentDebtorHistory;
import com.gxwebsoft.credit.param.CreditJudgmentDebtorHistoryParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 被执行人Mapper
*
* @author 科技小王子
* @since 2026-01-12 08:10:43
*/
public interface CreditJudgmentDebtorHistoryMapper extends BaseMapper<CreditJudgmentDebtorHistory> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditJudgmentDebtorHistory>
*/
List<CreditJudgmentDebtorHistory> selectPageRel(@Param("page") IPage<CreditJudgmentDebtorHistory> page,
@Param("param") CreditJudgmentDebtorHistoryParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditJudgmentDebtorHistory> selectListRel(@Param("param") CreditJudgmentDebtorHistoryParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditJudgmentDebtor;
import com.gxwebsoft.credit.param.CreditJudgmentDebtorParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 被执行人Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:50:55
*/
public interface CreditJudgmentDebtorMapper extends BaseMapper<CreditJudgmentDebtor> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditJudgmentDebtor>
*/
List<CreditJudgmentDebtor> selectPageRel(@Param("page") IPage<CreditJudgmentDebtor> page,
@Param("param") CreditJudgmentDebtorParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditJudgmentDebtor> selectListRel(@Param("param") CreditJudgmentDebtorParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditJudicialDocument;
import com.gxwebsoft.credit.param.CreditJudicialDocumentParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 裁判文书司法大数据Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:51:02
*/
public interface CreditJudicialDocumentMapper extends BaseMapper<CreditJudicialDocument> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditJudicialDocument>
*/
List<CreditJudicialDocument> selectPageRel(@Param("page") IPage<CreditJudicialDocument> page,
@Param("param") CreditJudicialDocumentParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditJudicialDocument> selectListRel(@Param("param") CreditJudicialDocumentParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditJudiciary;
import com.gxwebsoft.credit.param.CreditJudiciaryParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 司法案件Mapper
*
* @author 科技小王子
* @since 2025-12-16 15:23:58
*/
public interface CreditJudiciaryMapper extends BaseMapper<CreditJudiciary> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditJudiciary>
*/
List<CreditJudiciary> selectPageRel(@Param("page") IPage<CreditJudiciary> page,
@Param("param") CreditJudiciaryParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditJudiciary> selectListRel(@Param("param") CreditJudiciaryParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditMediation;
import com.gxwebsoft.credit.param.CreditMediationParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 诉前调解司法大数据Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:51:25
*/
public interface CreditMediationMapper extends BaseMapper<CreditMediation> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditMediation>
*/
List<CreditMediation> selectPageRel(@Param("page") IPage<CreditMediation> page,
@Param("param") CreditMediationParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditMediation> selectListRel(@Param("param") CreditMediationParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditNearbyCompany;
import com.gxwebsoft.credit.param.CreditNearbyCompanyParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 附近企业Mapper
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
public interface CreditNearbyCompanyMapper extends BaseMapper<CreditNearbyCompany> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditNearbyCompany>
*/
List<CreditNearbyCompany> selectPageRel(@Param("page") IPage<CreditNearbyCompany> page,
@Param("param") CreditNearbyCompanyParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditNearbyCompany> selectListRel(@Param("param") CreditNearbyCompanyParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditPatent;
import com.gxwebsoft.credit.param.CreditPatentParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 专利Mapper
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
public interface CreditPatentMapper extends BaseMapper<CreditPatent> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditPatent>
*/
List<CreditPatent> selectPageRel(@Param("page") IPage<CreditPatent> page,
@Param("param") CreditPatentParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditPatent> selectListRel(@Param("param") CreditPatentParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditRiskRelation;
import com.gxwebsoft.credit.param.CreditRiskRelationParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 风险关系表Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:51:40
*/
public interface CreditRiskRelationMapper extends BaseMapper<CreditRiskRelation> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditRiskRelation>
*/
List<CreditRiskRelation> selectPageRel(@Param("page") IPage<CreditRiskRelation> page,
@Param("param") CreditRiskRelationParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditRiskRelation> selectListRel(@Param("param") CreditRiskRelationParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditSupplier;
import com.gxwebsoft.credit.param.CreditSupplierParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 供应商Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:51:47
*/
public interface CreditSupplierMapper extends BaseMapper<CreditSupplier> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditSupplier>
*/
List<CreditSupplier> selectPageRel(@Param("page") IPage<CreditSupplier> page,
@Param("param") CreditSupplierParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditSupplier> selectListRel(@Param("param") CreditSupplierParam param);
}

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditSuspectedRelationship;
import com.gxwebsoft.credit.param.CreditSuspectedRelationshipParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 疑似关系Mapper
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
public interface CreditSuspectedRelationshipMapper extends BaseMapper<CreditSuspectedRelationship> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditSuspectedRelationship>
*/
List<CreditSuspectedRelationship> selectPageRel(@Param("page") IPage<CreditSuspectedRelationship> page,
@Param("param") CreditSuspectedRelationshipParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditSuspectedRelationship> selectListRel(@Param("param") CreditSuspectedRelationshipParam param);
}

View File

@@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 赊账客户表Mapper
* 招投标信息表Mapper
*
* @author 科技小王子
* @since 2025-12-15 13:16:03

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditXgxf;
import com.gxwebsoft.credit.param.CreditXgxfParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 限制高消费Mapper
*
* @author 科技小王子
* @since 2025-12-19 19:51:55
*/
public interface CreditXgxfMapper extends BaseMapper<CreditXgxf> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditXgxf>
*/
List<CreditXgxf> selectPageRel(@Param("page") IPage<CreditXgxf> page,
@Param("param") CreditXgxfParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditXgxf> selectListRel(@Param("param") CreditXgxfParam param);
}

View File

@@ -0,0 +1,92 @@
<?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.credit.mapper.CreditAdministrativeLicenseMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM credit_administrative_license a
LEFT JOIN credit_company b ON a.company_id = b.id
<where>
<if test="param.id != null">
AND a.id = #{param.id}
</if>
<if test="param.code != null">
AND a.code LIKE CONCAT('%', #{param.code}, '%')
</if>
<if test="param.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
<if test="param.statusText != null">
AND a.status_text LIKE CONCAT('%', #{param.statusText}, '%')
</if>
<if test="param.type != null">
AND a.type LIKE CONCAT('%', #{param.type}, '%')
</if>
<if test="param.url != null">
AND a.url LIKE CONCAT('%', #{param.url}, '%')
</if>
<if test="param.validityStart != null">
AND a.validity_start LIKE CONCAT('%', #{param.validityStart}, '%')
</if>
<if test="param.validityEnd != null">
AND a.validity_end LIKE CONCAT('%', #{param.validityEnd}, '%')
</if>
<if test="param.licensingAuthority != null">
AND a.licensing_authority LIKE CONCAT('%', #{param.licensingAuthority}, '%')
</if>
<if test="param.licenseContent != null">
AND a.License_content LIKE CONCAT('%', #{param.licenseContent}, '%')
</if>
<if test="param.dataSourceUnit != null">
AND a.data_source_unit LIKE CONCAT('%', #{param.dataSourceUnit}, '%')
</if>
<if test="param.comments != null">
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
</if>
<if test="param.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.recommend != null">
AND a.recommend = #{param.recommend}
</if>
<if test="param.sortNumber != null">
AND a.sort_number = #{param.sortNumber}
</if>
<if test="param.status != null">
AND a.status = #{param.status}
</if>
<if test="param.deleted != null">
AND a.deleted = #{param.deleted}
</if>
<if test="param.deleted == null">
AND a.deleted = 0
</if>
<if test="param.userId != null">
AND a.user_id = #{param.userId}
</if>
<if test="param.createTimeStart != null">
AND a.create_time &gt;= #{param.createTimeStart}
</if>
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditAdministrativeLicense">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditAdministrativeLicense">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -0,0 +1,80 @@
<?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.credit.mapper.CreditBankruptcyMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM credit_bankruptcy a
<where>
<if test="param.id != null">
AND a.id = #{param.id}
</if>
<if test="param.code != null">
AND a.code LIKE CONCAT('%', #{param.code}, '%')
</if>
<if test="param.type != null">
AND a.type LIKE CONCAT('%', #{param.type}, '%')
</if>
<if test="param.party != null">
AND a.party LIKE CONCAT('%', #{param.party}, '%')
</if>
<if test="param.url != null">
AND a.url LIKE CONCAT('%', #{param.url}, '%')
</if>
<if test="param.court != null">
AND a.court LIKE CONCAT('%', #{param.court}, '%')
</if>
<if test="param.publicDate != null">
AND a.public_date LIKE CONCAT('%', #{param.publicDate}, '%')
</if>
<if test="param.comments != null">
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
</if>
<if test="param.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.recommend != null">
AND a.recommend = #{param.recommend}
</if>
<if test="param.sortNumber != null">
AND a.sort_number = #{param.sortNumber}
</if>
<if test="param.status != null">
AND a.status = #{param.status}
</if>
<if test="param.deleted != null">
AND a.deleted = #{param.deleted}
</if>
<if test="param.deleted == null">
AND a.deleted = 0
</if>
<if test="param.userId != null">
AND a.user_id = #{param.userId}
</if>
<if test="param.createTimeStart != null">
AND a.create_time &gt;= #{param.createTimeStart}
</if>
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditBankruptcy">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditBankruptcy">
<include refid="selectSql"></include>
</select>
</mapper>

Some files were not shown because too many files have changed in this diff Show More