Compare commits

...

21 Commits

Author SHA1 Message Date
d49ce6e73e feat(excel): 优化Excel导入功能支持指定工作表名称
- 在CreditBreachOfTrustController中添加对"失信被执行人"工作表的精确匹配
- 在CreditXgxfController中添加对"限制高消费"工作表的精确匹配
- 在CreditJudgmentDebtorController中实现被执行人工作表的优先级排序逻辑
- 新增normalizeSheetName方法统一处理工作表名称的空格和特殊字符
- 改进findDebtorSheetIndices方法优先选择名为"被执行人"的工作表
- 调整ExcelImportSupport调用方式以支持指定工作表索引参数
2026-01-16 15:31:27 +08:00
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
146 changed files with 10341 additions and 422 deletions

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

@@ -38,6 +38,9 @@ public class CreditBreachOfTrustController extends BaseController {
@Resource
private CreditBreachOfTrustService creditBreachOfTrustService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询失信被执行人")
@GetMapping("/page")
public ApiResult<PageResult<CreditBreachOfTrust>> page(CreditBreachOfTrustParam param) {
@@ -131,13 +134,15 @@ public class CreditBreachOfTrustController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@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);
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
file, CreditJudicialImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
@@ -150,11 +155,19 @@ public class CreditBreachOfTrustController extends BaseController {
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);
}
@@ -177,23 +190,46 @@ public class CreditBreachOfTrustController extends BaseController {
continue;
}
boolean saved = creditBreachOfTrustService.save(item);
if (!saved) {
CreditBreachOfTrust existing = creditBreachOfTrustService.lambdaQuery()
.eq(CreditBreachOfTrust::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditBreachOfTrustService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -201,6 +237,43 @@ public class CreditBreachOfTrustController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditCaseFilingController extends BaseController {
@Resource
private CreditCaseFilingService creditCaseFilingService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCaseFiling>> page(CreditCaseFilingParam param) {
@@ -135,7 +138,8 @@ public class CreditCaseFilingController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@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;
@@ -154,11 +158,19 @@ public class CreditCaseFilingController extends BaseController {
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);
}
@@ -181,23 +193,46 @@ public class CreditCaseFilingController extends BaseController {
continue;
}
boolean saved = creditCaseFilingService.save(item);
if (!saved) {
CreditCaseFiling existing = creditCaseFilingService.lambdaQuery()
.eq(CreditCaseFiling::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditCaseFilingService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +240,43 @@ public class CreditCaseFilingController extends BaseController {
}
}
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 {

View File

@@ -11,10 +11,8 @@ 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.entity.CreditCompany;
import com.gxwebsoft.credit.param.CreditCompanyImportParam;
import com.gxwebsoft.credit.param.CreditCompanyParam;
import com.gxwebsoft.credit.param.CreditCompanyImportParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -29,6 +27,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 企业控制器
@@ -40,8 +39,11 @@ import java.util.List;
@RestController
@RequestMapping("/api/credit/credit-company")
public class CreditCompanyController extends BaseController {
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询企业")
@GetMapping("/page")
@@ -136,7 +138,8 @@ public class CreditCompanyController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@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;
@@ -161,11 +164,28 @@ public class CreditCompanyController extends BaseController {
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) {
@@ -185,30 +205,52 @@ public class CreditCompanyController extends BaseController {
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
// 验证必填字段
if (item.getName() == null || item.getName().trim().isEmpty()) {
if (item.getMatchName() == null || item.getMatchName().trim().isEmpty()) {
errorMessages.add("" + excelRowNumber + "行:项目名称不能为空");
continue;
}
if (item.getCode() == null || item.getCode().trim().isEmpty()) {
errorMessages.add("" + excelRowNumber + "行:唯一标识不能为空");
continue;
}
// if (item.getCode() == null || item.getCode().trim().isEmpty()) {
// errorMessages.add("第" + excelRowNumber + "行:唯一标识不能为空");
// continue;
// }
boolean saved = creditCompanyService.save(item);
if (!saved) {
CreditCompany existing = creditCompanyService.getByMatchName(item.getName());
if (existing != null) {
item.setId(existing.getId());
if (creditCompanyService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -216,6 +258,40 @@ public class CreditCompanyController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditCompetitorController extends BaseController {
@Resource
private CreditCompetitorService creditCompetitorService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询竞争对手")
@GetMapping("/page")
public ApiResult<PageResult<CreditCompetitor>> page(CreditCompetitorParam param) {
@@ -135,13 +138,15 @@ public class CreditCompetitorController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCompetitor:save')")
@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, "竞争对手", 2);
ExcelImportSupport.ImportResult<CreditCompetitorImportParam> importResult = ExcelImportSupport.read(
file, CreditCompetitorImportParam.class, this::isEmptyImportRow,2);
file, CreditCompetitorImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCompetitorImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
@@ -154,11 +159,19 @@ public class CreditCompetitorController extends BaseController {
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);
}
@@ -181,23 +194,46 @@ public class CreditCompetitorController extends BaseController {
continue;
}
boolean saved = creditCompetitorService.save(item);
if (!saved) {
CreditCompetitor existing = creditCompetitorService.lambdaQuery()
.eq(CreditCompetitor::getCompanyName, item.getCompanyName())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditCompetitorService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +241,43 @@ public class CreditCompetitorController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditCourtAnnouncementController extends BaseController {
@Resource
private CreditCourtAnnouncementService creditCourtAnnouncementService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询法院公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCourtAnnouncement>> page(CreditCourtAnnouncementParam param) {
@@ -135,7 +138,8 @@ public class CreditCourtAnnouncementController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@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;
@@ -154,11 +158,19 @@ public class CreditCourtAnnouncementController extends BaseController {
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);
}
@@ -181,23 +193,46 @@ public class CreditCourtAnnouncementController extends BaseController {
continue;
}
boolean saved = creditCourtAnnouncementService.save(item);
if (!saved) {
CreditCourtAnnouncement existing = creditCourtAnnouncementService.lambdaQuery()
.eq(CreditCourtAnnouncement::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditCourtAnnouncementService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +240,43 @@ public class CreditCourtAnnouncementController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditCourtSessionController extends BaseController {
@Resource
private CreditCourtSessionService creditCourtSessionService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询开庭公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCourtSession>> page(CreditCourtSessionParam param) {
@@ -135,7 +138,8 @@ public class CreditCourtSessionController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@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;
@@ -154,11 +158,19 @@ public class CreditCourtSessionController extends BaseController {
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);
}
@@ -181,23 +193,46 @@ public class CreditCourtSessionController extends BaseController {
continue;
}
boolean saved = creditCourtSessionService.save(item);
if (!saved) {
CreditCourtSession existing = creditCourtSessionService.lambdaQuery()
.eq(CreditCourtSession::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditCourtSessionService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +240,43 @@ public class CreditCourtSessionController extends BaseController {
}
}
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 {

View File

@@ -13,6 +13,7 @@ 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.*;
@@ -37,6 +38,9 @@ public class CreditCustomerController extends BaseController {
@Resource
private CreditCustomerService creditCustomerService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询客户")
@GetMapping("/page")
public ApiResult<PageResult<CreditCustomer>> page(CreditCustomerParam param) {
@@ -130,13 +134,15 @@ public class CreditCustomerController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCustomer:save')")
@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, "客户", 4);
ExcelImportSupport.ImportResult<CreditCustomerImportParam> importResult = ExcelImportSupport.read(
file, CreditCustomerImportParam.class, this::isEmptyImportRow,4);
file, CreditCustomerImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCustomerImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
@@ -149,11 +155,20 @@ public class CreditCustomerController extends BaseController {
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);
}
@@ -170,36 +185,244 @@ public class CreditCustomerController extends BaseController {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:客户不能为空");
continue;
}
boolean saved = creditCustomerService.save(item);
if (!saved) {
CreditCustomer existing = creditCustomerService.lambdaQuery()
.eq(CreditCustomer::getName, item.getName())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditCustomerService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} 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 (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 {
@@ -249,14 +472,36 @@ public class CreditCustomerController extends BaseController {
private CreditCustomer convertImportParamToEntity(CreditCustomerImportParam param) {
CreditCustomer entity = new CreditCustomer();
entity.setName(param.getName());
entity.setStatusTxt(param.getStatusTxt());
entity.setPrice(param.getPrice());
entity.setPublicDate(param.getPublicDate());
entity.setDataSource(param.getDataSource());
entity.setComments(param.getComments());
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

@@ -37,6 +37,9 @@ public class CreditDeliveryNoticeController extends BaseController {
@Resource
private CreditDeliveryNoticeService creditDeliveryNoticeService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询送达公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditDeliveryNotice>> page(CreditDeliveryNoticeParam param) {
@@ -135,7 +138,8 @@ public class CreditDeliveryNoticeController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@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;
@@ -154,11 +158,19 @@ public class CreditDeliveryNoticeController extends BaseController {
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);
}
@@ -181,23 +193,46 @@ public class CreditDeliveryNoticeController extends BaseController {
continue;
}
boolean saved = creditDeliveryNoticeService.save(item);
if (!saved) {
CreditDeliveryNotice existing = creditDeliveryNoticeService.lambdaQuery()
.eq(CreditDeliveryNotice::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditDeliveryNoticeService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +240,43 @@ public class CreditDeliveryNoticeController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditExternalController extends BaseController {
@Resource
private CreditExternalService creditExternalService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询对外投资")
@GetMapping("/page")
public ApiResult<PageResult<CreditExternal>> page(CreditExternalParam param) {
@@ -135,13 +138,15 @@ public class CreditExternalController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditExternal:save')")
@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);
ExcelImportSupport.ImportResult<CreditExternalImportParam> importResult = ExcelImportSupport.read(
file, CreditExternalImportParam.class, this::isEmptyImportRow);
file, CreditExternalImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditExternalImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
@@ -154,11 +159,19 @@ public class CreditExternalController extends BaseController {
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);
}
@@ -181,23 +194,46 @@ public class CreditExternalController extends BaseController {
continue;
}
boolean saved = creditExternalService.save(item);
if (!saved) {
CreditExternal existing = creditExternalService.lambdaQuery()
.eq(CreditExternal::getName, item.getName())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditExternalService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +241,43 @@ public class CreditExternalController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditFinalVersionController extends BaseController {
@Resource
private CreditFinalVersionService creditFinalVersionService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询终本案件")
@GetMapping("/page")
public ApiResult<PageResult<CreditFinalVersion>> page(CreditFinalVersionParam param) {
@@ -135,7 +138,8 @@ public class CreditFinalVersionController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@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;
@@ -154,11 +158,19 @@ public class CreditFinalVersionController extends BaseController {
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);
}
@@ -181,23 +193,46 @@ public class CreditFinalVersionController extends BaseController {
continue;
}
boolean saved = creditFinalVersionService.save(item);
if (!saved) {
CreditFinalVersion existing = creditFinalVersionService.lambdaQuery()
.eq(CreditFinalVersion::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditFinalVersionService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +240,43 @@ public class CreditFinalVersionController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditGqdjController extends BaseController {
@Resource
private CreditGqdjService creditGqdjService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询股权冻结")
@GetMapping("/page")
public ApiResult<PageResult<CreditGqdj>> page(CreditGqdjParam param) {
@@ -135,7 +138,8 @@ public class CreditGqdjController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@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;
@@ -154,11 +158,19 @@ public class CreditGqdjController extends BaseController {
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);
}
@@ -181,23 +193,46 @@ public class CreditGqdjController extends BaseController {
continue;
}
boolean saved = creditGqdjService.save(item);
if (!saved) {
CreditGqdj existing = creditGqdjService.lambdaQuery()
.eq(CreditGqdj::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditGqdjService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +240,43 @@ public class CreditGqdjController extends BaseController {
}
}
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 {

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

@@ -13,6 +13,7 @@ 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.*;
@@ -20,9 +21,18 @@ 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;
/**
* 被执行人控制器
@@ -37,6 +47,9 @@ public class CreditJudgmentDebtorController extends BaseController {
@Resource
private CreditJudgmentDebtorService creditJudgmentDebtorService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询被执行人")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudgmentDebtor>> page(CreditJudgmentDebtorParam param) {
@@ -135,81 +148,27 @@ public class CreditJudgmentDebtorController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@Operation(summary = "批量导入被执行人")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
try {
ExcelImportSupport.ImportResult<CreditJudgmentDebtorImportParam> importResult = ExcelImportSupport.read(
file, CreditJudgmentDebtorImportParam.class, this::isEmptyImportRow);
List<CreditJudgmentDebtorImportParam> 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;
for (int i = 0; i < list.size(); i++) {
CreditJudgmentDebtorImportParam param = list.get(i);
try {
CreditJudgmentDebtor item = convertImportParamToEntity(param);
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;
}
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)) {
successCount++;
continue;
}
}
} else {
successCount++;
continue;
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
ImportOutcome outcome;
if (isZip(file)) {
outcome = importFromZip(file, currentUserId, currentTenantId, companyId);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
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);
@@ -247,23 +206,399 @@ public class CreditJudgmentDebtorController extends BaseController {
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.setName(param.getName());
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(ImportHelper.parseBigDecimal(param.getAmount(), "执行标的(元)"));
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 {
// Prefer an explicitly-named "被执行人" sheet when present.
List<Integer> preferred = new ArrayList<>();
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)) {
continue;
}
String normalized = normalizeSheetName(sheetName);
if ("被执行人".equals(normalized)) {
preferred.add(i);
} else {
indices.add(i);
}
}
}
preferred.addAll(indices);
return preferred;
}
private static boolean isDebtorSheetName(String sheetName) {
if (sheetName == null) {
return false;
}
String normalized = normalizeSheetName(sheetName);
return normalized.contains("被执行人") && !normalized.contains("失信") && !normalized.contains("历史");
}
private static String normalizeSheetName(String sheetName) {
if (sheetName == null) {
return "";
}
return sheetName.replace(" ", "").replace(" ", "").trim();
}
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

@@ -37,6 +37,9 @@ public class CreditJudicialDocumentController extends BaseController {
@Resource
private CreditJudicialDocumentService creditJudicialDocumentService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询裁判文书司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudicialDocument>> page(CreditJudicialDocumentParam param) {
@@ -135,7 +138,8 @@ public class CreditJudicialDocumentController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@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;
@@ -154,11 +158,19 @@ public class CreditJudicialDocumentController extends BaseController {
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);
}
@@ -181,23 +193,46 @@ public class CreditJudicialDocumentController extends BaseController {
continue;
}
boolean saved = creditJudicialDocumentService.save(item);
if (!saved) {
CreditJudicialDocument existing = creditJudicialDocumentService.lambdaQuery()
.eq(CreditJudicialDocument::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditJudicialDocumentService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +240,43 @@ public class CreditJudicialDocumentController extends BaseController {
}
}
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 {

View File

@@ -38,8 +38,11 @@ import java.util.List;
@RestController
@RequestMapping("/api/credit/credit-judiciary")
public class CreditJudiciaryController extends BaseController {
@Resource
private CreditJudiciaryService creditJudiciaryService;
@Resource
private CreditJudiciaryService creditJudiciaryService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询司法案件")
@GetMapping("/page")
@@ -134,7 +137,8 @@ public class CreditJudiciaryController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@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;
@@ -160,10 +164,18 @@ public class CreditJudiciaryController extends BaseController {
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) {
@@ -195,21 +207,43 @@ public class CreditJudiciaryController extends BaseController {
continue;
}
boolean saved = creditJudiciaryService.save(item);
if (!saved) {
CreditJudiciary existing = creditJudiciaryService.getByName(item.getName());
if (existing != null) {
item.setId(existing.getId());
if (creditJudiciaryService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -217,6 +251,40 @@ public class CreditJudiciaryController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditMediationController extends BaseController {
@Resource
private CreditMediationService creditMediationService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询诉前调解司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditMediation>> page(CreditMediationParam param) {
@@ -135,7 +138,8 @@ public class CreditMediationController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@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;
@@ -154,11 +158,19 @@ public class CreditMediationController extends BaseController {
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);
}
@@ -181,23 +193,46 @@ public class CreditMediationController extends BaseController {
continue;
}
boolean saved = creditMediationService.save(item);
if (!saved) {
CreditMediation existing = creditMediationService.lambdaQuery()
.eq(CreditMediation::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditMediationService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +240,43 @@ public class CreditMediationController extends BaseController {
}
}
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 {

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

@@ -37,6 +37,9 @@ public class CreditRiskRelationController extends BaseController {
@Resource
private CreditRiskRelationService creditRiskRelationService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询风险关系表")
@GetMapping("/page")
public ApiResult<PageResult<CreditRiskRelation>> page(CreditRiskRelationParam param) {
@@ -135,14 +138,15 @@ public class CreditRiskRelationController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditRiskRelation:save')")
@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 {
// 风险关系数据位于第二个选项卡sheetIndex = 1
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "风险关系", 1);
ExcelImportSupport.ImportResult<CreditRiskRelationImportParam> importResult = ExcelImportSupport.read(
file, CreditRiskRelationImportParam.class, this::isEmptyImportRow, 1);
file, CreditRiskRelationImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditRiskRelationImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
@@ -155,11 +159,19 @@ public class CreditRiskRelationController extends BaseController {
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);
}
@@ -182,23 +194,46 @@ public class CreditRiskRelationController extends BaseController {
continue;
}
boolean saved = creditRiskRelationService.save(item);
if (!saved) {
CreditRiskRelation existing = creditRiskRelationService.lambdaQuery()
.eq(CreditRiskRelation::getMainBodyName, item.getMainBodyName())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditRiskRelationService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -206,6 +241,43 @@ public class CreditRiskRelationController extends BaseController {
}
}
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 {

View File

@@ -37,6 +37,9 @@ public class CreditSupplierController extends BaseController {
@Resource
private CreditSupplierService creditSupplierService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询供应商")
@GetMapping("/page")
public ApiResult<PageResult<CreditSupplier>> page(CreditSupplierParam param) {
@@ -135,13 +138,15 @@ public class CreditSupplierController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditSupplier:save')")
@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, "供应商", 3);
ExcelImportSupport.ImportResult<CreditSupplierImportParam> importResult = ExcelImportSupport.read(
file, CreditSupplierImportParam.class, this::isEmptyImportRow,3);
file, CreditSupplierImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditSupplierImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
@@ -154,11 +159,19 @@ public class CreditSupplierController extends BaseController {
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);
}
@@ -181,23 +194,46 @@ public class CreditSupplierController extends BaseController {
continue;
}
boolean saved = creditSupplierService.save(item);
if (!saved) {
CreditSupplier existing = creditSupplierService.lambdaQuery()
.eq(CreditSupplier::getSupplier, item.getSupplier())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditSupplierService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +241,43 @@ public class CreditSupplierController extends BaseController {
}
}
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 {

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

@@ -54,6 +54,9 @@ public class CreditUserController extends BaseController {
@Resource
private CreditUserService creditUserService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询招投标信息表")
@GetMapping("/page")
public ApiResult<PageResult<CreditUser>> page(CreditUserParam param) {
@@ -148,18 +151,20 @@ public class CreditUserController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditUser:save')")
@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];
@@ -173,7 +178,12 @@ 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, 0, usedTitleRows, usedHeadRows);
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);
@@ -184,6 +194,9 @@ public class CreditUserController extends BaseController {
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
// 设置默认值
if (item.getUserId() == null && currentUserId != null) {
@@ -211,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 + "行:更新成功");
}
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;
}
}
} else {
return true;
}
errorMessages.add("" + rowNumber + "行:保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
@@ -227,10 +268,44 @@ 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 {
return success("导入完成,成功" + successCount + "条,更新" + errorMessages.size() + "", errorMessages);
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
@@ -271,11 +346,11 @@ 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);
}

View File

@@ -37,6 +37,9 @@ public class CreditXgxfController extends BaseController {
@Resource
private CreditXgxfService creditXgxfService;
@Resource
private BatchImportSupport batchImportSupport;
@Operation(summary = "分页查询限制高消费")
@GetMapping("/page")
public ApiResult<PageResult<CreditXgxf>> page(CreditXgxfParam param) {
@@ -135,13 +138,15 @@ public class CreditXgxfController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@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);
ExcelImportSupport.ImportResult<CreditJudicialImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialImportParam.class, this::isEmptyImportRow);
file, CreditJudicialImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditJudicialImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
@@ -154,11 +159,19 @@ public class CreditXgxfController extends BaseController {
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);
}
@@ -181,23 +194,46 @@ public class CreditXgxfController extends BaseController {
continue;
}
boolean saved = creditXgxfService.save(item);
if (!saved) {
CreditXgxf existing = creditXgxfService.lambdaQuery()
.eq(CreditXgxf::getCaseNumber, item.getCaseNumber())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditXgxfService.updateById(item)) {
successCount++;
continue;
}
}
} else {
successCount++;
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();
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
@@ -205,6 +241,43 @@ public class CreditXgxfController extends BaseController {
}
}
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 {

View File

@@ -4,11 +4,23 @@ 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;
/**
@@ -20,11 +32,17 @@ public class ExcelImportSupport {
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() {
@@ -38,12 +56,54 @@ public class ExcelImportSupport {
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。
*
@@ -53,7 +113,7 @@ public class ExcelImportSupport {
List<T> list = null;
int usedTitleRows = 0;
int usedHeadRows = 0;
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {0, 2}, {0, 3}};
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);
@@ -63,7 +123,51 @@ public class ExcelImportSupport {
break;
}
}
return new ImportResult<>(list, usedTitleRows, usedHeadRows);
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 {
@@ -83,6 +187,156 @@ public class ExcelImportSupport {
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,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

@@ -61,6 +61,13 @@ public class CreditBreachOfTrust implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

View File

@@ -61,6 +61,13 @@ public class CreditCaseFiling implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

View File

@@ -36,6 +36,9 @@ public class CreditCompany implements Serializable {
@Schema(description = "统一社会信用代码")
private String code;
@Schema(description = "项目网址")
private String url;
@Schema(description = "类型")
private Integer type;

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 com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -50,6 +51,13 @@ public class CreditCompetitor implements Serializable {
@Schema(description = "所属省份")
private String province;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "所属企业名称")
@TableField(exist = false)
private String mainCompanyName;
@Schema(description = "备注")
private String comments;

View File

@@ -61,6 +61,13 @@ public class CreditCourtAnnouncement implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

View File

@@ -61,6 +61,13 @@ public class CreditCourtSession implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

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 com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -44,6 +45,13 @@ public class CreditCustomer implements Serializable {
@Schema(description = "数据来源")
private String dataSource;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

View File

@@ -61,6 +61,13 @@ public class CreditDeliveryNotice implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

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 com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -71,6 +72,13 @@ public class CreditExternal implements Serializable {
@Schema(description = "关联产品/机构")
private String relatedProductsInstitutions;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

View File

@@ -61,6 +61,13 @@ public class CreditFinalVersion implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

View File

@@ -61,6 +61,13 @@ public class CreditGqdj implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

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

@@ -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 com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -12,6 +13,7 @@ import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
* 被执行人
@@ -35,14 +37,20 @@ public class CreditJudgmentDebtor implements Serializable {
@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 BigDecimal amount;
private String amount;
@Schema(description = "法院")
private String courtName;
@@ -50,6 +58,13 @@ public class CreditJudgmentDebtor implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;
@@ -80,4 +95,13 @@ public class CreditJudgmentDebtor implements Serializable {
@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

@@ -61,6 +61,13 @@ public class CreditJudicialDocument implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

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 com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -75,6 +76,13 @@ public class CreditJudiciary implements Serializable {
@Schema(description = "案件金额(元)")
private String caseAmount;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

View File

@@ -61,6 +61,13 @@ public class CreditMediation implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

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

@@ -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 com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -46,6 +47,13 @@ public class CreditRiskRelation implements Serializable {
@Schema(description = "风险关系")
private String riskRelation;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

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 com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -44,6 +45,13 @@ public class CreditSupplier implements Serializable {
@Schema(description = "数据来源")
private String dataSource;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

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

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

@@ -61,6 +61,13 @@ public class CreditXgxf implements Serializable {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "备注")
private String comments;

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

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

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.CreditBranchMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM credit_branch 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.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
<if test="param.curator != null">
AND a.curator LIKE CONCAT('%', #{param.curator}, '%')
</if>
<if test="param.region != null">
AND a.region LIKE CONCAT('%', #{param.region}, '%')
</if>
<if test="param.url != null">
AND a.url LIKE CONCAT('%', #{param.url}, '%')
</if>
<if test="param.establishDate != null">
AND a.establish_date LIKE CONCAT('%', #{param.establishDate}, '%')
</if>
<if test="param.statusText != null">
AND a.status_text LIKE CONCAT('%', #{param.statusText}, '%')
</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.CreditBranch">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditBranch">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_breach_of_trust 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_case_filing 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -188,9 +188,11 @@
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
AND (a.name LIKE CONCAT('%', #{param.keywords}, '%')
OR a.match_name LIKE CONCAT('%', #{param.keywords}, '%')
OR a.code = #{param.keywords}
)
</if>
</where>
</sql>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS mainCompanyName
FROM credit_competitor 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.companyName != null">
AND a.company_name LIKE CONCAT('%', #{param.companyName}, '%')
</if>
@@ -60,6 +64,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_court_announcement 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_court_session 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_customer 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
@@ -54,6 +58,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_delivery_notice 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_external 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
@@ -81,6 +85,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_final_version 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_gqdj 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -0,0 +1,74 @@
<?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.CreditHistoricalLegalPersonMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM credit_historical_legal_person 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.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
<if test="param.registerDate != null">
AND a.register_date LIKE CONCAT('%', #{param.registerDate}, '%')
</if>
<if test="param.publicDate != null">
AND a.public_date LIKE CONCAT('%', #{param.publicDate}, '%')
</if>
<if test="param.url != null">
AND a.url LIKE CONCAT('%', #{param.url}, '%')
</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.CreditHistoricalLegalPerson">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditHistoricalLegalPerson">
<include refid="selectSql"></include>
</select>
</mapper>

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.CreditJudgmentDebtorHistoryMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM credit_judgment_debtor_history 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.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
<if test="param.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
<if test="param.name1 != null">
AND a.name1 LIKE CONCAT('%', #{param.name1}, '%')
</if>
<if test="param.code != null">
AND a.code LIKE CONCAT('%', #{param.code}, '%')
</if>
<if test="param.url != null">
AND a.url LIKE CONCAT('%', #{param.url}, '%')
</if>
<if test="param.type != null">
AND a.type = #{param.type}
</if>
<if test="param.occurrenceTime != null">
AND a.occurrence_time LIKE CONCAT('%', #{param.occurrenceTime}, '%')
</if>
<if test="param.amount != null">
AND a.amount LIKE CONCAT('%', #{param.amount}, '%')
</if>
<if test="param.courtName != null">
AND a.court_name LIKE CONCAT('%', #{param.courtName}, '%')
</if>
<if test="param.dataStatus != null">
AND a.data_status LIKE CONCAT('%', #{param.dataStatus}, '%')
</if>
<if test="param.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.comments != null">
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
</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.CreditJudgmentDebtorHistory">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditJudgmentDebtorHistory">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -4,12 +4,17 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName, c.id as historyId, c.name as historyName
FROM credit_judgment_debtor a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN credit_judgment_debtor_history c ON a.case_number = c.case_number
<where>
<if test="param.id != null">
AND a.id = #{param.id}
</if>
<if test="param.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
@@ -60,6 +65,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_judicial_document 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_judiciary 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
@@ -90,6 +94,7 @@
</if>
<if test="param.keywords != null">
AND (a.name LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_mediation 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -0,0 +1,221 @@
<?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.CreditNearbyCompanyMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM credit_nearby_company 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.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
<if test="param.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.registrationStatus != null">
AND a.registration_status LIKE CONCAT('%', #{param.registrationStatus}, '%')
</if>
<if test="param.legalPerson != null">
AND a.legal_person LIKE CONCAT('%', #{param.legalPerson}, '%')
</if>
<if test="param.registeredCapital != null">
AND a.registered_capital LIKE CONCAT('%', #{param.registeredCapital}, '%')
</if>
<if test="param.establishDate != null">
AND a.establish_date LIKE CONCAT('%', #{param.establishDate}, '%')
</if>
<if test="param.code != null">
AND a.code LIKE CONCAT('%', #{param.code}, '%')
</if>
<if test="param.address != null">
AND a.address LIKE CONCAT('%', #{param.address}, '%')
</if>
<if test="param.postalCode != null">
AND a.postal_code LIKE CONCAT('%', #{param.postalCode}, '%')
</if>
<if test="param.phone != null">
AND a.phone LIKE CONCAT('%', #{param.phone}, '%')
</if>
<if test="param.moreTel != null">
AND a.more_tel LIKE CONCAT('%', #{param.moreTel}, '%')
</if>
<if test="param.email != null">
AND a.email LIKE CONCAT('%', #{param.email}, '%')
</if>
<if test="param.moreEmail != null">
AND a.more_email LIKE CONCAT('%', #{param.moreEmail}, '%')
</if>
<if test="param.country != null">
AND a.country LIKE CONCAT('%', #{param.country}, '%')
</if>
<if test="param.province != null">
AND a.province LIKE CONCAT('%', #{param.province}, '%')
</if>
<if test="param.city != null">
AND a.city LIKE CONCAT('%', #{param.city}, '%')
</if>
<if test="param.region != null">
AND a.region LIKE CONCAT('%', #{param.region}, '%')
</if>
<!-- <if test="param.taxpayerCode != null">-->
<!-- AND a.taxpayer_code LIKE CONCAT('%', #{param.taxpayerCode}, '%')-->
<!-- </if>-->
<if test="param.registrationNumber != null">
AND a.registration_number LIKE CONCAT('%', #{param.registrationNumber}, '%')
</if>
<if test="param.organizationalCode != null">
AND a.organizational_code LIKE CONCAT('%', #{param.organizationalCode}, '%')
</if>
<if test="param.numberOfInsuredPersons != null">
AND a.number_of_insured_persons LIKE CONCAT('%', #{param.numberOfInsuredPersons}, '%')
</if>
<if test="param.annualReport != null">
AND a.annual_report LIKE CONCAT('%', #{param.annualReport}, '%')
</if>
<if test="param.institutionType != null">
AND a.institution_type LIKE CONCAT('%', #{param.institutionType}, '%')
</if>
<if test="param.companySize != null">
AND a.company_size LIKE CONCAT('%', #{param.companySize}, '%')
</if>
<if test="param.businessTerm != null">
AND a.business_term LIKE CONCAT('%', #{param.businessTerm}, '%')
</if>
<if test="param.nationalStandardIndustryCategories != null">
AND a.national_standard_industry_categories LIKE CONCAT('%', #{param.nationalStandardIndustryCategories}, '%')
</if>
<if test="param.nationalStandardIndustryCategories2 != null">
AND a.national_standard_industry_categories2 LIKE CONCAT('%', #{param.nationalStandardIndustryCategories2}, '%')
</if>
<if test="param.nationalStandardIndustryCategories3 != null">
AND a.national_standard_industry_categories3 LIKE CONCAT('%', #{param.nationalStandardIndustryCategories3}, '%')
</if>
<if test="param.nationalStandardIndustryCategories4 != null">
AND a.national_standard_industry_categories4 LIKE CONCAT('%', #{param.nationalStandardIndustryCategories4}, '%')
</if>
<if test="param.formerName != null">
AND a.former_name LIKE CONCAT('%', #{param.formerName}, '%')
</if>
<if test="param.englishName != null">
AND a.english_name LIKE CONCAT('%', #{param.englishName}, '%')
</if>
<if test="param.domain != null">
AND a.domain LIKE CONCAT('%', #{param.domain}, '%')
</if>
<if test="param.mailingAddress != null">
AND a.mailing_address LIKE CONCAT('%', #{param.mailingAddress}, '%')
</if>
<if test="param.mailingEmail != null">
AND a.mailing_email LIKE CONCAT('%', #{param.mailingEmail}, '%')
</if>
<if test="param.companyProfile != null">
AND a.company_profile LIKE CONCAT('%', #{param.companyProfile}, '%')
</if>
<if test="param.natureOfBusiness != null">
AND a.nature_of_business LIKE CONCAT('%', #{param.natureOfBusiness}, '%')
</if>
<if test="param.tel != null">
AND a.tel LIKE CONCAT('%', #{param.tel}, '%')
</if>
<if test="param.nationalStandardIndustryCategories5 != null">
AND a.national_standard_industry_categories5 LIKE CONCAT('%', #{param.nationalStandardIndustryCategories5}, '%')
</if>
<if test="param.nationalStandardIndustryCategories6 != null">
AND a.national_standard_industry_categories6 LIKE CONCAT('%', #{param.nationalStandardIndustryCategories6}, '%')
</if>
<if test="param.nationalStandardIndustryCategories7 != null">
AND a.national_standard_industry_categories7 LIKE CONCAT('%', #{param.nationalStandardIndustryCategories7}, '%')
</if>
<if test="param.nationalStandardIndustryCategories8 != null">
AND a.national_standard_industry_categories8 LIKE CONCAT('%', #{param.nationalStandardIndustryCategories8}, '%')
</if>
<if test="param.url != null">
AND a.url LIKE CONCAT('%', #{param.url}, '%')
</if>
<if test="param.type != null">
AND a.type = #{param.type}
</if>
<if test="param.parentId != null">
AND a.parent_id = #{param.parentId}
</if>
<if test="param.paidinCapital != null">
AND a.paidin_capital LIKE CONCAT('%', #{param.paidinCapital}, '%')
</if>
<if test="param.registrationAuthority != null">
AND a.registration_authority LIKE CONCAT('%', #{param.registrationAuthority}, '%')
</if>
<if test="param.taxpayerQualification != null">
AND a.taxpayer_qualification LIKE CONCAT('%', #{param.taxpayerQualification}, '%')
</if>
<if test="param.latestAnnualReportYear != null">
AND a.latest_annual_report_year LIKE CONCAT('%', #{param.latestAnnualReportYear}, '%')
</if>
<if test="param.latestAnnualReportOnOperatingRevenue != null">
AND a.latest_annual_report_on_operating_revenue LIKE CONCAT('%', #{param.latestAnnualReportOnOperatingRevenue}, '%')
</if>
<if test="param.enterpriseScoreCheck != null">
AND a.enterprise_score_check LIKE CONCAT('%', #{param.enterpriseScoreCheck}, '%')
</if>
<if test="param.creditRating != null">
AND a.credit_rating LIKE CONCAT('%', #{param.creditRating}, '%')
</if>
<if test="param.cechnologyScore != null">
AND a.cechnology_score LIKE CONCAT('%', #{param.cechnologyScore}, '%')
</if>
<if test="param.cechnologyLevel != null">
AND a.cechnology_level LIKE CONCAT('%', #{param.cechnologyLevel}, '%')
</if>
<if test="param.smallEnterprise != null">
AND a.small_enterprise LIKE CONCAT('%', #{param.smallEnterprise}, '%')
</if>
<if test="param.comments != null">
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
</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.CreditNearbyCompany">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditNearbyCompany">
<include refid="selectSql"></include>
</select>
</mapper>

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.CreditPatentMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM credit_patent 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.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
<if test="param.type != null">
AND a.type LIKE CONCAT('%', #{param.type}, '%')
</if>
<if test="param.statusText != null">
AND a.status_text LIKE CONCAT('%', #{param.statusText}, '%')
</if>
<if test="param.registerNo != null">
AND a.register_no LIKE CONCAT('%', #{param.registerNo}, '%')
</if>
<if test="param.registerDate != null">
AND a.register_date LIKE CONCAT('%', #{param.registerDate}, '%')
</if>
<if test="param.publicNo != null">
AND a.public_no LIKE CONCAT('%', #{param.publicNo}, '%')
</if>
<if test="param.publicDate != null">
AND a.public_date LIKE CONCAT('%', #{param.publicDate}, '%')
</if>
<if test="param.inventor != null">
AND a.inventor LIKE CONCAT('%', #{param.inventor}, '%')
</if>
<if test="param.patentApplicant != null">
AND a.patent_applicant LIKE CONCAT('%', #{param.patentApplicant}, '%')
</if>
<if test="param.url != null">
AND a.url LIKE CONCAT('%', #{param.url}, '%')
</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.CreditPatent">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditPatent">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_risk_relation 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.mainBodyName != null">
AND a.main_body_name LIKE CONCAT('%', #{param.mainBodyName}, '%')
</if>
@@ -57,6 +61,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_supplier 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.supplier != null">
AND a.supplier LIKE CONCAT('%', #{param.supplier}, '%')
</if>
@@ -54,6 +58,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -0,0 +1,89 @@
<?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.CreditSuspectedRelationshipMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM credit_suspected_relationship 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.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.legalPerson != null">
AND a.legal_person LIKE CONCAT('%', #{param.legalPerson}, '%')
</if>
<if test="param.registeredCapital != null">
AND a.registered_capital LIKE CONCAT('%', #{param.registeredCapital}, '%')
</if>
<if test="param.createDate != null">
AND a.create_date LIKE CONCAT('%', #{param.createDate}, '%')
</if>
<if test="param.relatedParty != null">
AND a.related_party LIKE CONCAT('%', #{param.relatedParty}, '%')
</if>
<if test="param.type != null">
AND a.type LIKE CONCAT('%', #{param.type}, '%')
</if>
<if test="param.detail != null">
AND a.detail LIKE CONCAT('%', #{param.detail}, '%')
</if>
<if test="param.url != null">
AND a.url LIKE CONCAT('%', #{param.url}, '%')
</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.CreditSuspectedRelationship">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditSuspectedRelationship">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_user 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
@@ -86,6 +90,7 @@
AND (a.name LIKE CONCAT('%', #{param.keywords}, '%')
OR a.procurement_name LIKE CONCAT('%', #{param.keywords}, '%')
OR a.winning_name LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -4,12 +4,16 @@
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
SELECT a.*, b.name AS companyName
FROM credit_xgxf 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.companyId != null">
AND a.company_id = #{param.companyId}
</if>
<if test="param.dataType != null">
AND a.data_type LIKE CONCAT('%', #{param.dataType}, '%')
</if>
@@ -69,6 +73,7 @@
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name = #{param.keywords}
)
</if>
</where>

View File

@@ -0,0 +1,45 @@
package com.gxwebsoft.credit.param;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import java.io.Serializable;
/**
* 行政许可导入参数
*/
@Data
public class CreditAdministrativeLicenseImportParam implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "决定文书/许可编号")
private String code;
@Excel(name = "决定文书/许可证名称")
private String name;
@Excel(name = "许可状态")
private String statusText;
@Excel(name = "许可类型")
private String type;
@Excel(name = "有效期自")
private String validityStart;
@Excel(name = "有效期至")
private String validityEnd;
@Excel(name = "许可机关")
private String licensingAuthority;
@Excel(name = "许可内容")
private String licenseContent;
@Excel(name = "数据来源单位")
private String dataSourceUnit;
@Excel(name = "备注")
private String comments;
}

View File

@@ -0,0 +1,85 @@
package com.gxwebsoft.credit.param;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.gxwebsoft.common.core.annotation.QueryField;
import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 行政许可查询参数
*
* @author 科技小王子
* @since 2026-01-07 13:52:13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(name = "CreditAdministrativeLicenseParam对象", description = "行政许可查询参数")
public class CreditAdministrativeLicenseParam extends BaseParam {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@QueryField(type = QueryType.EQ)
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 = "许可内容")
private String licenseContent;
@Schema(description = "数据来源单位")
private String dataSourceUnit;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
@QueryField(type = QueryType.EQ)
private Integer companyId;
@Schema(description = "是否推荐")
@QueryField(type = QueryType.EQ)
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
@QueryField(type = QueryType.EQ)
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
@QueryField(type = QueryType.EQ)
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@QueryField(type = QueryType.EQ)
private Integer deleted;
@Schema(description = "用户ID")
@QueryField(type = QueryType.EQ)
private Integer userId;
}

View File

@@ -0,0 +1,33 @@
package com.gxwebsoft.credit.param;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import java.io.Serializable;
/**
* 破产重整导入参数
*/
@Data
public class CreditBankruptcyImportParam implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "案号")
private String code;
@Excel(name = "案件类型")
private String type;
@Excel(name = "当事人")
private String party;
@Excel(name = "经办法院")
private String court;
@Excel(name = "公开日期")
private String publicDate;
@Excel(name = "备注")
private String comments;
}

View File

@@ -0,0 +1,73 @@
package com.gxwebsoft.credit.param;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.gxwebsoft.common.core.annotation.QueryField;
import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 破产重整查询参数
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(name = "CreditBankruptcyParam对象", description = "破产重整查询参数")
public class CreditBankruptcyParam extends BaseParam {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@QueryField(type = QueryType.EQ)
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")
@QueryField(type = QueryType.EQ)
private Integer companyId;
@Schema(description = "是否推荐")
@QueryField(type = QueryType.EQ)
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
@QueryField(type = QueryType.EQ)
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
@QueryField(type = QueryType.EQ)
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@QueryField(type = QueryType.EQ)
private Integer deleted;
@Schema(description = "用户ID")
@QueryField(type = QueryType.EQ)
private Integer userId;
}

View File

@@ -0,0 +1,33 @@
package com.gxwebsoft.credit.param;
import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import java.io.Serializable;
/**
* 分支机构导入参数
*/
@Data
public class CreditBranchImportParam implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "分支机构名称")
private String name;
@Excel(name = "负责人")
private String curator;
@Excel(name = "地区")
private String region;
@Excel(name = "成立日期")
private String establishDate;
@Excel(name = "状态")
private String statusText;
@Excel(name = "备注")
private String comments;
}

View File

@@ -0,0 +1,73 @@
package com.gxwebsoft.credit.param;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.gxwebsoft.common.core.annotation.QueryField;
import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 分支机构查询参数
*
* @author 科技小王子
* @since 2026-01-07 13:52:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(name = "CreditBranchParam对象", description = "分支机构查询参数")
public class CreditBranchParam extends BaseParam {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@QueryField(type = QueryType.EQ)
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")
@QueryField(type = QueryType.EQ)
private Integer companyId;
@Schema(description = "是否推荐")
@QueryField(type = QueryType.EQ)
private Integer recommend;
@Schema(description = "排序(数字越小越靠前)")
@QueryField(type = QueryType.EQ)
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
@QueryField(type = QueryType.EQ)
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@QueryField(type = QueryType.EQ)
private Integer deleted;
@Schema(description = "用户ID")
@QueryField(type = QueryType.EQ)
private Integer userId;
}

View File

@@ -58,6 +58,9 @@ public class CreditBreachOfTrustParam extends BaseParam {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "备注")
private String comments;

View File

@@ -57,6 +57,9 @@ public class CreditCaseFilingParam extends BaseParam {
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "备注")
private String comments;

View File

@@ -48,6 +48,9 @@ public class CreditCompetitorParam extends BaseParam {
@Schema(description = "所属省份")
private String province;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "备注")
private String comments;

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