Compare commits

...

6 Commits

Author SHA1 Message Date
01101d422f fix(hjmCar): 调整无坐标分页查询默认限制及状态
- 将无纬度或经度时的分页限制由2000缩减到500
- 设置无坐标查询时默认状态为1,优化数据筛选
- 删除了历史退款订单修复相关的控制器与服务代码
- 移除多个环境配置文件,清理无用资源
- 删除多项测试代码,去除无用单元测试与集成测试代码
2026-04-29 22:14:07 +08:00
4ec637d7f8 refactor(batch-import): 删除 BatchImportSupport 类及相关批处理支持代码
- 移除 credit 模块中的 Excel 导入批处理支持实现
- 删除硬删除及批量硬删除方法
- 删除按企业名称及文本匹配回填 companyId 的相关刷新方法
- 删除多种批量 upsert 实现及带计数器的更新方法
- 移除带降级逐行持久化的批量保存支持
- 删除处理唯一索引冲突的批量插入辅助逻辑
- 清理所有相关导入和依赖内容
2026-04-29 19:49:02 +08:00
30a53e7283 feat(db): 优化ShopDealerApply查询条件支持接待人过滤
- 修改ShopDealerApplyMapper.xml,增加接待人ID和申请用户ID的联合过滤条件
- 支持当接待人ID与申请用户ID都存在时,进行多条件OR查询
- 支持单独存在接待人ID时的过滤条件
- 在ShopDealerApplyParam中新增receptionistId字段,支持接待人用户ID查询参数
- 完善查询条件逻辑,提高业务灵活性和数据筛选能力
2026-04-16 17:42:21 +08:00
9ec44dbe5c refactor(recommendation): 删除推荐记录相关模块,清理代码和数据结构
- 移除推荐记录管理后台控制器LeadReferralAdminController
- 删除小程序端推荐记录控制器LeadReferralController
- 删除推荐记录实体LeadReferral及相关实体ReferralSettlement、ReferrerInfo
- 删除对应的数据访问层Mapper接口
- 删除推荐记录查询参数类LeadReferralParam
- 删除推荐记录服务接口LeadReferralService及其实现LeadReferralServiceImpl
- 清理相关注解、导入及依赖,彻底移除推荐记录功能模块
2026-04-16 17:04:31 +08:00
89ac0d109c fix(recommendation): 修正分页参数的有效性判断逻辑
- 将分页参数的非空判断改为大于0判断以保证参数有效
- 修改参数名统一为current和size以保持一致性
- 修正了LeadReferralServiceImpl中分页相关方法的分页逻辑
- 确保当分页参数无效时使用默认分页值1和10
2026-04-16 16:47:18 +08:00
7095c4bf96 feat(recommendation): 实现推荐客户管理全流程功能
- 新增推荐记录、推荐人信息、推荐费结算实体及数据库表结构
- 实现推荐记录小程序端接口,包括新增报备、获取推荐码、查询我的推荐及统计
- 实现后台管理端推荐记录分页查询、确认有效、作废、结算及批量结算接口
- 实现推荐人信息查询及推荐统计汇总逻辑
- 实现推荐记录导出功能,支持导出推荐详情数据
- 完成推荐状态变更时推荐人统计数据同步更新
- 添加相关Mapper接口和Service接口及实现
- 使用MyBatis Plus分页插件支持分页查询
- 集成Spring Security权限校验和操作日志注解
- 优化推荐码生成和唯一性校验机制
2026-04-16 16:40:08 +08:00
311 changed files with 111 additions and 39792 deletions

View File

@@ -0,0 +1,17 @@
{
"version": 2,
"sessions": {
"8b8cdf8cb3404efeac18615f9f419cb1": [
{
"expertId": "SeniorDeveloper",
"name": "吴八哥",
"profession": "高级开发工程师",
"avatarUrl": "https://acc-1258344699.cos.accelerate.myqcloud.com/workbuddy/experts/avatars/02-Engineering/SeniorDeveloper/SeniorDeveloper.png",
"promptUrl": "https://acc-1258344699.cos.accelerate.myqcloud.com/workbuddy/experts/experts/02-Engineering/SeniorDeveloper/SeniorDeveloper_zh.md",
"usedAt": 1776323986694,
"industryId": "02-Engineering"
}
]
},
"lastUpdated": 1776324781452
}

View File

@@ -1,543 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditAdministrativeLicense;
import com.gxwebsoft.credit.param.CreditAdministrativeLicenseImportParam;
import com.gxwebsoft.credit.param.CreditAdministrativeLicenseParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 行政许可控制器
*
* @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;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@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 (batchImportSupport.hardRemoveById(CreditAdministrativeLicense.class, 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 (batchImportSupport.hardRemoveByIds(CreditAdministrativeLicense.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditAdministrativeLicenseService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditAdministrativeLicense::getId,
CreditAdministrativeLicense::setId,
CreditAdministrativeLicense::getName,
CreditAdministrativeLicense::getCompanyId,
CreditAdministrativeLicense::setCompanyId,
CreditAdministrativeLicense::setCompanyName,
CreditAdministrativeLicense::getHasData,
CreditAdministrativeLicense::setHasData,
CreditAdministrativeLicense::getTenantId,
CreditAdministrativeLicense::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入行政许可
*/
@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;
Set<Integer> touchedCompanyIds = new HashSet<>();
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, "决定文书/许可证名称");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : null;
}
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 (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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 (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditAdministrativeLicenseService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditAdministrativeLicense::getName,
"",
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.persistInsertOnlyChunk(
creditAdministrativeLicenseService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditAdministrativeLicense::getName,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.ADMINISTRATIVE_LICENSE, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史行政许可(仅解析“历史行政许可”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditAdministrativeLicense:save')")
@Operation(summary = "批量导入历史行政许可")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史行政许可");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史行政许可”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditAdministrativeLicenseImportParam> importResult = ExcelImportSupport.read(
file, CreditAdministrativeLicenseImportParam.class, this::isEmptyImportRow, sheetIndex);
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, "决定文书/许可证名称");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : null;
}
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);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditAdministrativeLicense item = convertImportParamToEntity(param);
if (item.getCode() != null) {
item.setCode(item.getCode().trim());
}
if (item.getName() != null) {
item.setName(item.getName().trim());
}
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:决定文书/许可证名称不能为空");
continue;
}
String link = null;
if (!ImportHelper.isBlank(item.getCode())) {
link = urlByCode.get(item.getCode());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName())) {
link = urlByName.get(item.getName());
}
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
if (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
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.getDeleted() == null) {
item.setDeleted(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditAdministrativeLicenseService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditAdministrativeLicense::getName,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditAdministrativeLicenseService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditAdministrativeLicense::getName,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.ADMINISTRATIVE_LICENSE, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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

@@ -1,507 +0,0 @@
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.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 破产重整控制器
*
* @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;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@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 (batchImportSupport.hardRemoveById(CreditBankruptcy.class, 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 (batchImportSupport.hardRemoveByIds(CreditBankruptcy.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditBankruptcy:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditBankruptcyService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditBankruptcy::getId,
CreditBankruptcy::setId,
CreditBankruptcy::getParty,
CreditBankruptcy::getCompanyId,
CreditBankruptcy::setCompanyId,
CreditBankruptcy::getHasData,
CreditBankruptcy::setHasData,
CreditBankruptcy::getTenantId,
CreditBankruptcy::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入破产重整
*/
@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;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
// Prefer importing from the explicit tab name "破产重整" when present.
// This avoids accidentally importing from other sheets (e.g. "历史破产重整") in multi-sheet workbooks.
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "破产重整");
ExcelImportSupport.ImportResult<CreditBankruptcyImportParam> importResult;
if (sheetIndex >= 0) {
importResult = ExcelImportSupport.read(file, CreditBankruptcyImportParam.class, this::isEmptyImportRow, sheetIndex);
} else {
// Backward compatible: try any sheet for older templates without the expected tab name.
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.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditBankruptcyService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBankruptcy::getCode,
"",
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.persistInsertOnlyChunk(
creditBankruptcyService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBankruptcy::getCode,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.BANKRUPTCY, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史破产重整(仅解析“历史破产重整”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditBankruptcy:save')")
@Operation(summary = "批量导入历史破产重整")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史破产重整");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史破产重整”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditBankruptcyImportParam> importResult = ExcelImportSupport.read(
file, CreditBankruptcyImportParam.class, this::isEmptyImportRow, sheetIndex);
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);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditBankruptcy item = convertImportParamToEntity(param);
if (item.getCode() != null) {
item.setCode(item.getCode().trim());
}
if (ImportHelper.isBlank(item.getCode())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCode.get(item.getCode());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditBankruptcyService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBankruptcy::getCode,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditBankruptcyService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBankruptcy::getCode,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.BANKRUPTCY, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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

@@ -1,380 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditBranch;
import com.gxwebsoft.credit.param.CreditBranchImportParam;
import com.gxwebsoft.credit.param.CreditBranchParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 分支机构控制器
*
* @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;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@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 (batchImportSupport.hardRemoveById(CreditBranch.class, 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 (batchImportSupport.hardRemoveByIds(CreditBranch.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditBranch:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditBranchService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditBranch::getId,
CreditBranch::setId,
CreditBranch::getName,
CreditBranch::getCompanyId,
CreditBranch::setCompanyId,
CreditBranch::setCompanyName,
CreditBranch::getHasData,
CreditBranch::setHasData,
CreditBranch::getTenantId,
CreditBranch::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入分支机构
*/
@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;
Set<Integer> touchedCompanyIds = new HashSet<>();
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, "分支机构名称");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : null;
}
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 (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
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 (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditBranchService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBranch::getName,
"",
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.persistInsertOnlyChunk(
creditBranchService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBranch::getName,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.BRANCH, touchedCompanyIds);
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

@@ -1,513 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditBreachOfTrust;
import com.gxwebsoft.credit.param.CreditBreachOfTrustImportParam;
import com.gxwebsoft.credit.param.CreditBreachOfTrustParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditBreachOfTrustService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 失信被执行人控制器
*
* @author 科技小王子
* @since 2025-12-19 19:46:14
*/
@Tag(name = "失信被执行人管理")
@RestController
@RequestMapping("/api/credit/credit-breach-of-trust")
public class CreditBreachOfTrustController extends BaseController {
@Resource
private CreditBreachOfTrustService creditBreachOfTrustService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询失信被执行人")
@GetMapping("/page")
public ApiResult<PageResult<CreditBreachOfTrust>> page(CreditBreachOfTrustParam param) {
// 使用关联查询
return success(creditBreachOfTrustService.pageRel(param));
}
@Operation(summary = "查询全部失信被执行人")
@GetMapping()
public ApiResult<List<CreditBreachOfTrust>> list(CreditBreachOfTrustParam param) {
// 使用关联查询
return success(creditBreachOfTrustService.listRel(param));
}
@Operation(summary = "根据id查询失信被执行人")
@GetMapping("/{id}")
public ApiResult<CreditBreachOfTrust> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditBreachOfTrustService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@OperationLog
@Operation(summary = "添加失信被执行人")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditBreachOfTrust creditBreachOfTrust) {
if (creditBreachOfTrustService.save(creditBreachOfTrust)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:update')")
@OperationLog
@Operation(summary = "修改失信被执行人")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditBreachOfTrust creditBreachOfTrust) {
if (creditBreachOfTrustService.updateById(creditBreachOfTrust)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:remove')")
@OperationLog
@Operation(summary = "删除失信被执行人")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditBreachOfTrust.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@OperationLog
@Operation(summary = "批量添加失信被执行人")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditBreachOfTrust> list) {
if (creditBreachOfTrustService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:update')")
@OperationLog
@Operation(summary = "批量修改失信被执行人")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditBreachOfTrust> batchParam) {
if (batchParam.update(creditBreachOfTrustService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:remove')")
@OperationLog
@Operation(summary = "批量删除失信被执行人")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditBreachOfTrust.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Party columns may contain multiple roles/names; match if any company name is contained in the text.
// Priority: 原告/上诉人 > 被告/被上诉人 > 其他当事人/第三人
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditBreachOfTrustService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditBreachOfTrust::getId,
CreditBreachOfTrust::setId,
CreditBreachOfTrust::getCompanyId,
CreditBreachOfTrust::setCompanyId,
CreditBreachOfTrust::getHasData,
CreditBreachOfTrust::setHasData,
CreditBreachOfTrust::getTenantId,
CreditBreachOfTrust::new,
CreditBreachOfTrust::getPlaintiffAppellant,
CreditBreachOfTrust::getAppellee,
CreditBreachOfTrust::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入失信被执行人
*/
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@Operation(summary = "批量导入失信被执行人")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "失信被执行人", 0);
ExcelImportSupport.ImportResult<CreditBreachOfTrustImportParam> importResult = ExcelImportSupport.read(
file, CreditBreachOfTrustImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditBreachOfTrustImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditBreachOfTrustImportParam param = list.get(i);
try {
CreditBreachOfTrust item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String link = urlByCaseNumber.get(item.getCaseNumber().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditBreachOfTrustService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBreachOfTrust::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditBreachOfTrustService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBreachOfTrust::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.BREACH_OF_TRUST, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史失信被执行人(仅解析“历史失信被执行人”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@Operation(summary = "批量导入历史失信被执行人")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史失信被执行人");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史失信被执行人”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditBreachOfTrustImportParam> importResult = ExcelImportSupport.read(
file, CreditBreachOfTrustImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditBreachOfTrustImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
// 同案号多条:以导入文件中“最后一条”为准(视为最新)
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++) {
CreditBreachOfTrustImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditBreachOfTrust item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditBreachOfTrustService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBreachOfTrust::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditBreachOfTrustService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditBreachOfTrust::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.BREACH_OF_TRUST, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditBreachOfTrustImportParam> templateList = new ArrayList<>();
CreditBreachOfTrustImportParam example = new CreditBreachOfTrustImportParam();
example.setDataType("失信被执行人");
example.setCaseNumber("2024示例案号");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setInvolvedAmount("20,293.91");
example.setDataStatus("正常");
example.setOccurrenceTime("2024-01-01");
example.setCourtName("示例法院");
example.setReleaseDate("2024-01-01");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("失信被执行人导入模板", "失信被执行人", CreditBreachOfTrustImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_breach_of_trust_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditBreachOfTrustImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getPlaintiffAppellant2())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getAppellee2());
}
private CreditBreachOfTrust convertImportParamToEntity(CreditBreachOfTrustImportParam param) {
CreditBreachOfTrust entity = new CreditBreachOfTrust();
entity.setDataType(param.getDataType());
entity.setCaseNumber(param.getCaseNumber());
String plaintiffAppellant = !ImportHelper.isBlank(param.getPlaintiffAppellant2())
? param.getPlaintiffAppellant2()
: param.getPlaintiffAppellant();
entity.setPlaintiffAppellant(plaintiffAppellant);
String appellee = !ImportHelper.isBlank(param.getAppellee2())
? param.getAppellee2()
: param.getAppellee();
entity.setAppellee(appellee);
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setDataStatus(param.getDataStatus());
entity.setInvolvedAmount(!ImportHelper.isBlank(param.getInvolvedAmount2())
? param.getInvolvedAmount2()
: param.getInvolvedAmount());
entity.setOccurrenceTime(!ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2()
: param.getOccurrenceTime());
entity.setCourtName(!ImportHelper.isBlank(param.getCourtName2())
? param.getCourtName2()
: param.getCourtName());
entity.setReleaseDate(param.getReleaseDate());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,525 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCaseFiling;
import com.gxwebsoft.credit.param.CreditCaseFilingImportParam;
import com.gxwebsoft.credit.param.CreditCaseFilingParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditCaseFilingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:47:23
*/
@Tag(name = "司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-case-filing")
public class CreditCaseFilingController extends BaseController {
@Resource
private CreditCaseFilingService creditCaseFilingService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCaseFiling>> page(CreditCaseFilingParam param) {
// 使用关联查询
return success(creditCaseFilingService.pageRel(param));
}
@Operation(summary = "查询全部司法大数据")
@GetMapping()
public ApiResult<List<CreditCaseFiling>> list(CreditCaseFilingParam param) {
// 使用关联查询
return success(creditCaseFilingService.listRel(param));
}
@Operation(summary = "根据id查询司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditCaseFiling> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCaseFilingService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@OperationLog
@Operation(summary = "添加司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCaseFiling creditCaseFiling) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditCaseFiling.setUserId(loginUser.getUserId());
// }
if (creditCaseFilingService.save(creditCaseFiling)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:update')")
@OperationLog
@Operation(summary = "修改司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCaseFiling creditCaseFiling) {
if (creditCaseFilingService.updateById(creditCaseFiling)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:remove')")
@OperationLog
@Operation(summary = "删除司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditCaseFiling.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@OperationLog
@Operation(summary = "批量添加司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCaseFiling> list) {
if (creditCaseFilingService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:update')")
@OperationLog
@Operation(summary = "批量修改司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCaseFiling> batchParam) {
if (batchParam.update(creditCaseFilingService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCaseFiling:remove')")
@OperationLog
@Operation(summary = "批量删除司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditCaseFiling.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditCaseFiling:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Special: party columns may contain multiple roles/names; match if any company name is contained in the text.
// Priority: 原告/上诉人 > 被告/被上诉人 > 其他当事人/第三人
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditCaseFilingService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditCaseFiling::getId,
CreditCaseFiling::setId,
CreditCaseFiling::getCompanyId,
CreditCaseFiling::setCompanyId,
CreditCaseFiling::getHasData,
CreditCaseFiling::setHasData,
CreditCaseFiling::getTenantId,
CreditCaseFiling::new,
CreditCaseFiling::getPlaintiffAppellant,
CreditCaseFiling::getAppellee,
CreditCaseFiling::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入立案信息
*/
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@Operation(summary = "批量导入立案信息")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "立案信息", 0);
ExcelImportSupport.ImportResult<CreditCaseFilingImportParam> importResult = ExcelImportSupport.read(
file, CreditCaseFilingImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCaseFilingImportParam> 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;
// easypoi 默认不会读取单元格超链接地址url 通常挂在“案号”列的超链接中,需要额外读取回填。
Map<String, String> urlByCaseNumber = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditCaseFilingImportParam param = list.get(i);
try {
CreditCaseFiling item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String link = urlByCaseNumber.get(item.getCaseNumber().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("" + excelRowNumber + "行:案号不能为空");
continue;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCaseFilingService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCaseFiling::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditCaseFilingService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCaseFiling::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.CASE_FILING, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史立案信息(仅解析“历史立案信息”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@Operation(summary = "批量导入历史立案信息")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史立案信息");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史立案信息”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditCaseFilingImportParam> importResult = ExcelImportSupport.read(
file, CreditCaseFilingImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCaseFilingImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditCaseFilingImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditCaseFiling item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCaseFilingService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCaseFiling::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCaseFilingService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCaseFiling::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.CASE_FILING, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditCaseFilingImportParam> templateList = new ArrayList<>();
CreditCaseFilingImportParam example = new CreditCaseFilingImportParam();
example.setDataType("立案信息");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty2("第三人示例");
example.setInvolvedAmount("100000");
example.setDataStatus("正常");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setCourtName("示例法院");
example.setOccurrenceTime("2024-01-01");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("立案信息导入模板", "立案信息", CreditCaseFilingImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_case_filing_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditCaseFilingImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getCauseOfAction())
&& ImportHelper.isBlank(param.getOtherPartiesThirdParty())
&& ImportHelper.isBlank(param.getOtherPartiesThirdParty2())
&& ImportHelper.isBlank(param.getCourtName())
&& ImportHelper.isBlank(param.getCourtName2())
&& ImportHelper.isBlank(param.getOccurrenceTime())
&& ImportHelper.isBlank(param.getOccurrenceTime2())
&& ImportHelper.isBlank(param.getInvolvedAmount())
&& ImportHelper.isBlank(param.getInvolvedAmount2())
&& ImportHelper.isBlank(param.getDataStatus())
&& ImportHelper.isBlank(param.getDataType())
&& ImportHelper.isBlank(param.getComments());
}
private CreditCaseFiling convertImportParamToEntity(CreditCaseFilingImportParam param) {
CreditCaseFiling entity = new CreditCaseFiling();
// Template compatibility: prefer new columns when present.
String occurrenceTime = !ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2()
: param.getOccurrenceTime();
String otherPartiesThirdParty = !ImportHelper.isBlank(param.getOtherPartiesThirdParty2())
? param.getOtherPartiesThirdParty2()
: param.getOtherPartiesThirdParty();
String courtName = !ImportHelper.isBlank(param.getCourtName2())
? param.getCourtName2()
: param.getCourtName();
String involvedAmount = !ImportHelper.isBlank(param.getInvolvedAmount2())
? param.getInvolvedAmount2()
: param.getInvolvedAmount();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setDataStatus(param.getDataStatus());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setOtherPartiesThirdParty(otherPartiesThirdParty);
entity.setCourtName(courtName);
entity.setOccurrenceTime(occurrenceTime);
entity.setInvolvedAmount(involvedAmount);
entity.setComments(param.getComments());
return entity;
}
}

View File

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

View File

@@ -1,372 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditCompetitor;
import com.gxwebsoft.credit.param.CreditCompetitorImportParam;
import com.gxwebsoft.credit.param.CreditCompetitorParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditCompetitorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 竞争对手控制器
*
* @author 科技小王子
* @since 2025-12-19 19:49:05
*/
@Tag(name = "竞争对手管理")
@RestController
@RequestMapping("/api/credit/credit-competitor")
public class CreditCompetitorController extends BaseController {
@Resource
private CreditCompetitorService creditCompetitorService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询竞争对手")
@GetMapping("/page")
public ApiResult<PageResult<CreditCompetitor>> page(CreditCompetitorParam param) {
// 使用关联查询
return success(creditCompetitorService.pageRel(param));
}
@Operation(summary = "查询全部竞争对手")
@GetMapping()
public ApiResult<List<CreditCompetitor>> list(CreditCompetitorParam param) {
// 使用关联查询
return success(creditCompetitorService.listRel(param));
}
@Operation(summary = "根据id查询竞争对手")
@GetMapping("/{id}")
public ApiResult<CreditCompetitor> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCompetitorService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:save')")
@OperationLog
@Operation(summary = "添加竞争对手")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCompetitor creditCompetitor) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditCompetitor.setUserId(loginUser.getUserId());
// }
if (creditCompetitorService.save(creditCompetitor)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:update')")
@OperationLog
@Operation(summary = "修改竞争对手")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCompetitor creditCompetitor) {
if (creditCompetitorService.updateById(creditCompetitor)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:remove')")
@OperationLog
@Operation(summary = "删除竞争对手")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditCompetitor.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:save')")
@OperationLog
@Operation(summary = "批量添加竞争对手")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCompetitor> list) {
if (creditCompetitorService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:update')")
@OperationLog
@Operation(summary = "批量修改竞争对手")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCompetitor> batchParam) {
if (batchParam.update(creditCompetitorService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCompetitor:remove')")
@OperationLog
@Operation(summary = "批量删除竞争对手")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditCompetitor.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditCompetitor:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditCompetitorService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditCompetitor::getId,
CreditCompetitor::setId,
CreditCompetitor::getName,
CreditCompetitor::getCompanyId,
CreditCompetitor::setCompanyId,
CreditCompetitor::setCompanyName,
CreditCompetitor::getHasData,
CreditCompetitor::setHasData,
CreditCompetitor::getTenantId,
CreditCompetitor::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入竞争对手
*/
@PreAuthorize("hasAuthority('credit:creditCompetitor:save')")
@Operation(summary = "批量导入竞争对手")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "竞争对手", 2);
ExcelImportSupport.ImportResult<CreditCompetitorImportParam> importResult = ExcelImportSupport.read(
file, CreditCompetitorImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCompetitorImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
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.readUrlByKey(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "企业名称");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : 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);
// name 为竞争对手企业名称companyName 为主体企业名称。
if (!ImportHelper.isBlank(item.getName())) {
String link = urlByName.get(item.getName().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
if (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
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 (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCompetitorService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCompetitor::getName,
"",
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.persistInsertOnlyChunk(
creditCompetitorService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCompetitor::getName,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.COMPETITOR, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载竞争对手导入模板
*/
@Operation(summary = "下载竞争对手导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditCompetitorImportParam> templateList = new ArrayList<>();
CreditCompetitorImportParam example = new CreditCompetitorImportParam();
example.setName("示例科技有限公司");
example.setLegalRepresentative("张三");
example.setRegisteredCapital("5000");
example.setEstablishmentDate("2015-01-01");
example.setRegistrationStatus("存续");
example.setIndustry("软件和信息服务业");
example.setProvince("广东省");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("竞争对手导入模板", "竞争对手", CreditCompetitorImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_competitor_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditCompetitorImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getLegalRepresentative())
&& ImportHelper.isBlank(param.getRegisteredCapital())
&& ImportHelper.isBlank(param.getEstablishmentDate());
}
private CreditCompetitor convertImportParamToEntity(CreditCompetitorImportParam param) {
CreditCompetitor entity = new CreditCompetitor();
entity.setName(param.getName());
entity.setLegalRepresentative(param.getLegalRepresentative());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setEstablishmentDate(param.getEstablishmentDate());
entity.setRegistrationStatus(param.getRegistrationStatus());
entity.setIndustry(param.getIndustry());
entity.setProvince(param.getProvince());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,517 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCourtAnnouncement;
import com.gxwebsoft.credit.param.CreditCourtAnnouncementImportParam;
import com.gxwebsoft.credit.param.CreditCourtAnnouncementParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditCourtAnnouncementService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 法院公告司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:49:13
*/
@Tag(name = "法院公告司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-court-announcement")
public class CreditCourtAnnouncementController extends BaseController {
@Resource
private CreditCourtAnnouncementService creditCourtAnnouncementService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询法院公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCourtAnnouncement>> page(CreditCourtAnnouncementParam param) {
// 使用关联查询
return success(creditCourtAnnouncementService.pageRel(param));
}
@Operation(summary = "查询全部法院公告司法大数据")
@GetMapping()
public ApiResult<List<CreditCourtAnnouncement>> list(CreditCourtAnnouncementParam param) {
// 使用关联查询
return success(creditCourtAnnouncementService.listRel(param));
}
@Operation(summary = "根据id查询法院公告司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditCourtAnnouncement> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCourtAnnouncementService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@OperationLog
@Operation(summary = "添加法院公告司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCourtAnnouncement creditCourtAnnouncement) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditCourtAnnouncement.setUserId(loginUser.getUserId());
// }
if (creditCourtAnnouncementService.save(creditCourtAnnouncement)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:update')")
@OperationLog
@Operation(summary = "修改法院公告司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCourtAnnouncement creditCourtAnnouncement) {
if (creditCourtAnnouncementService.updateById(creditCourtAnnouncement)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:remove')")
@OperationLog
@Operation(summary = "删除法院公告司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditCourtAnnouncement.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@OperationLog
@Operation(summary = "批量添加法院公告司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCourtAnnouncement> list) {
if (creditCourtAnnouncementService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:update')")
@OperationLog
@Operation(summary = "批量修改法院公告司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCourtAnnouncement> batchParam) {
if (batchParam.update(creditCourtAnnouncementService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:remove')")
@OperationLog
@Operation(summary = "批量删除法院公告司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditCourtAnnouncement.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Party columns may contain multiple roles/names; match if any company name is contained in the text.
// Priority: 原告/上诉人 > 被告/被上诉人 > 其他当事人/第三人
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditCourtAnnouncementService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditCourtAnnouncement::getId,
CreditCourtAnnouncement::setId,
CreditCourtAnnouncement::getCompanyId,
CreditCourtAnnouncement::setCompanyId,
CreditCourtAnnouncement::getHasData,
CreditCourtAnnouncement::setHasData,
CreditCourtAnnouncement::getTenantId,
CreditCourtAnnouncement::new,
CreditCourtAnnouncement::getPlaintiffAppellant,
CreditCourtAnnouncement::getAppellee,
CreditCourtAnnouncement::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入法院公告司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@Operation(summary = "批量导入法院公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
// 兼容多 sheet 文件优先定位“法院公告”sheet否则默认第 0 个。
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "法院公告", 0);
ExcelImportSupport.ImportResult<CreditCourtAnnouncementImportParam> importResult = ExcelImportSupport.read(
file, CreditCourtAnnouncementImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCourtAnnouncementImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditCourtAnnouncementImportParam param = list.get(i);
try {
CreditCourtAnnouncement item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String link = urlByCaseNumber.get(item.getCaseNumber().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCourtAnnouncementService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCourtAnnouncement::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditCourtAnnouncementService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCourtAnnouncement::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.COURT_ANNOUNCEMENT, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史法院公告(仅解析“历史法院公告”选项卡;兼容“历史法庭公告”)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@Operation(summary = "批量导入历史法院公告司法大数据")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史法院公告");
if (sheetIndex < 0) {
// 兼容旧命名
sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史法庭公告");
}
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史法院公告”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditCourtAnnouncementImportParam> importResult = ExcelImportSupport.read(
file, CreditCourtAnnouncementImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCourtAnnouncementImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditCourtAnnouncementImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditCourtAnnouncement item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCourtAnnouncementService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCourtAnnouncement::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCourtAnnouncementService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCourtAnnouncement::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.COURT_ANNOUNCEMENT, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditCourtAnnouncementImportParam> templateList = new ArrayList<>();
CreditCourtAnnouncementImportParam example = new CreditCourtAnnouncementImportParam();
example.setDataType("法院公告");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setCourtName("示例法院");
example.setInvolvedAmount("100000");
example.setDataStatus("正常");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("法院公告导入模板", "法院公告", CreditCourtAnnouncementImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_court_announcement_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditCourtAnnouncementImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditCourtAnnouncement convertImportParamToEntity(CreditCourtAnnouncementImportParam param) {
CreditCourtAnnouncement entity = new CreditCourtAnnouncement();
String dataType = !ImportHelper.isBlank(param.getDataType2())
? param.getDataType2()
: param.getDataType();
String plaintiffAppellant = !ImportHelper.isBlank(param.getPlaintiffAppellant2())
? param.getPlaintiffAppellant2()
: param.getPlaintiffAppellant();
String otherPartiesThirdParty = !ImportHelper.isBlank(param.getOtherPartiesThirdParty2())
? param.getOtherPartiesThirdParty2()
: param.getOtherPartiesThirdParty();
String involvedAmount = !ImportHelper.isBlank(param.getInvolvedAmount2())
? param.getInvolvedAmount2()
: param.getInvolvedAmount();
String occurrenceTime = !ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2()
: param.getOccurrenceTime();
entity.setDataType(dataType);
entity.setPlaintiffAppellant(plaintiffAppellant);
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(otherPartiesThirdParty);
entity.setOccurrenceTime(occurrenceTime);
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setCourtName(param.getCourtName());
entity.setInvolvedAmount(involvedAmount);
entity.setDataStatus(param.getDataStatus());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,512 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCourtSession;
import com.gxwebsoft.credit.param.CreditCourtSessionImportParam;
import com.gxwebsoft.credit.param.CreditCourtSessionParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditCourtSessionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 开庭公告司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:49:33
*/
@Tag(name = "开庭公告司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-court-session")
public class CreditCourtSessionController extends BaseController {
@Resource
private CreditCourtSessionService creditCourtSessionService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询开庭公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditCourtSession>> page(CreditCourtSessionParam param) {
// 使用关联查询
return success(creditCourtSessionService.pageRel(param));
}
@Operation(summary = "查询全部开庭公告司法大数据")
@GetMapping()
public ApiResult<List<CreditCourtSession>> list(CreditCourtSessionParam param) {
// 使用关联查询
return success(creditCourtSessionService.listRel(param));
}
@Operation(summary = "根据id查询开庭公告司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditCourtSession> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCourtSessionService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@OperationLog
@Operation(summary = "添加开庭公告司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCourtSession creditCourtSession) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditCourtSession.setUserId(loginUser.getUserId());
// }
if (creditCourtSessionService.save(creditCourtSession)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:update')")
@OperationLog
@Operation(summary = "修改开庭公告司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCourtSession creditCourtSession) {
if (creditCourtSessionService.updateById(creditCourtSession)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:remove')")
@OperationLog
@Operation(summary = "删除开庭公告司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditCourtSession.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@OperationLog
@Operation(summary = "批量添加开庭公告司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCourtSession> list) {
if (creditCourtSessionService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:update')")
@OperationLog
@Operation(summary = "批量修改开庭公告司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCourtSession> batchParam) {
if (batchParam.update(creditCourtSessionService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCourtSession:remove')")
@OperationLog
@Operation(summary = "批量删除开庭公告司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditCourtSession.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditCourtSession:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Party columns may contain multiple roles/names; match if any company name is contained in the text.
// Priority: 原告/上诉人 > 被告/被上诉人 > 其他当事人/第三人
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditCourtSessionService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditCourtSession::getId,
CreditCourtSession::setId,
CreditCourtSession::getCompanyId,
CreditCourtSession::setCompanyId,
CreditCourtSession::getHasData,
CreditCourtSession::setHasData,
CreditCourtSession::getTenantId,
CreditCourtSession::new,
CreditCourtSession::getPlaintiffAppellant,
CreditCourtSession::getAppellee,
CreditCourtSession::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入开庭公告司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@Operation(summary = "批量导入开庭公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
// 兼容多 sheet 文件优先定位“开庭公告”sheet否则默认第 0 个。
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "开庭公告", 0);
ExcelImportSupport.ImportResult<CreditCourtSessionImportParam> importResult = ExcelImportSupport.read(
file, CreditCourtSessionImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCourtSessionImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditCourtSessionImportParam param = list.get(i);
try {
CreditCourtSession item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String link = urlByCaseNumber.get(item.getCaseNumber().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCourtSessionService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCourtSession::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditCourtSessionService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCourtSession::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.COURT_SESSION, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史开庭公告(仅解析“历史开庭公告”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@Operation(summary = "批量导入历史开庭公告司法大数据")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史开庭公告");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史开庭公告”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditCourtSessionImportParam> importResult = ExcelImportSupport.read(
file, CreditCourtSessionImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCourtSessionImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditCourtSessionImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditCourtSession item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCourtSessionService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCourtSession::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditCourtSessionService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditCourtSession::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.COURT_SESSION, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditCourtSessionImportParam> templateList = new ArrayList<>();
CreditCourtSessionImportParam example = new CreditCourtSessionImportParam();
example.setDataType("开庭公告");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty2("第三人示例");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setCourtName("示例法院");
example.setOccurrenceTime("2024-01-01");
example.setInvolvedAmount("100000");
example.setDataStatus("正常");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("开庭公告导入模板", "开庭公告", CreditCourtSessionImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_court_session_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditCourtSessionImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditCourtSession convertImportParamToEntity(CreditCourtSessionImportParam param) {
CreditCourtSession entity = new CreditCourtSession();
// Template compatibility: prefer new columns ("发生时间"/"其他当事人/第三人") when present.
String occurrenceTime = !ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2()
: param.getOccurrenceTime();
String otherPartiesThirdParty = !ImportHelper.isBlank(param.getOtherPartiesThirdParty2())
? param.getOtherPartiesThirdParty2()
: param.getOtherPartiesThirdParty();
String involvedAmount = !ImportHelper.isBlank(param.getInvolvedAmount2())
? param.getInvolvedAmount2()
: param.getInvolvedAmount();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setDataStatus(param.getDataStatus());
entity.setInvolvedAmount(involvedAmount);
entity.setOtherPartiesThirdParty(otherPartiesThirdParty);
entity.setOccurrenceTime(occurrenceTime);
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setCourtName(param.getCourtName());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,420 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditCustomer;
import com.gxwebsoft.credit.param.CreditCustomerImportParam;
import com.gxwebsoft.credit.param.CreditCustomerParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditCustomerService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 客户控制器
*
* @author 科技小王子
* @since 2025-12-21 21:20:58
*/
@Tag(name = "客户管理")
@RestController
@RequestMapping("/api/credit/credit-customer")
public class CreditCustomerController extends BaseController {
@Resource
private CreditCustomerService creditCustomerService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询客户")
@GetMapping("/page")
public ApiResult<PageResult<CreditCustomer>> page(CreditCustomerParam param) {
// 使用关联查询
return success(creditCustomerService.pageRel(param));
}
@Operation(summary = "查询全部客户")
@GetMapping()
public ApiResult<List<CreditCustomer>> list(CreditCustomerParam param) {
// 使用关联查询
return success(creditCustomerService.listRel(param));
}
@Operation(summary = "根据id查询客户")
@GetMapping("/{id}")
public ApiResult<CreditCustomer> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditCustomerService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditCustomer:save')")
@OperationLog
@Operation(summary = "添加客户")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditCustomer creditCustomer) {
if (creditCustomerService.save(creditCustomer)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:update')")
@OperationLog
@Operation(summary = "修改客户")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditCustomer creditCustomer) {
if (creditCustomerService.updateById(creditCustomer)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:remove')")
@OperationLog
@Operation(summary = "删除客户")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditCustomer.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:save')")
@OperationLog
@Operation(summary = "批量添加客户")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditCustomer> list) {
if (creditCustomerService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:update')")
@OperationLog
@Operation(summary = "批量修改客户")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditCustomer> batchParam) {
if (batchParam.update(creditCustomerService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditCustomer:remove')")
@OperationLog
@Operation(summary = "批量删除客户")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditCustomer.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditCustomer:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditCustomerService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditCustomer::getId,
CreditCustomer::setId,
CreditCustomer::getName,
CreditCustomer::getCompanyId,
CreditCustomer::setCompanyId,
CreditCustomer::setCompanyName,
CreditCustomer::getHasData,
CreditCustomer::setHasData,
CreditCustomer::getTenantId,
CreditCustomer::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入客户
*/
@PreAuthorize("hasAuthority('credit:creditCustomer:save')")
@Operation(summary = "批量导入客户")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "客户", 4);
ExcelImportSupport.ImportResult<CreditCustomerImportParam> importResult = ExcelImportSupport.read(
file, CreditCustomerImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditCustomerImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
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.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "客户");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : 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 (!ImportHelper.isBlank(item.getName())) {
item.setName(item.getName().trim());
String link = urlByName.get(item.getName());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
if (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:客户不能为空");
continue;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += persistImportChunk(chunkItems, chunkRowNumbers, mpBatchSize, errorMessages);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += persistImportChunk(chunkItems, chunkRowNumbers, mpBatchSize, errorMessages);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.CUSTOMER, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载客户导入模板
*/
@Operation(summary = "下载客户导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditCustomerImportParam> templateList = new ArrayList<>();
CreditCustomerImportParam example = new CreditCustomerImportParam();
example.setName("示例客户");
example.setStatusTxt("合作中");
example.setPrice("88.8");
example.setPublicDate("2024-01-01");
example.setDataSource("公开渠道");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("客户导入模板", "客户", CreditCustomerImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_customer_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditCustomerImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getStatusTxt())
&& ImportHelper.isBlank(param.getPrice());
}
private CreditCustomer convertImportParamToEntity(CreditCustomerImportParam param) {
CreditCustomer entity = new CreditCustomer();
entity.setName(normalizeString(param.getName()));
entity.setStatusTxt(normalizeString(param.getStatusTxt()));
entity.setPrice(normalizeString(param.getPrice()));
entity.setPublicDate(normalizeString(param.getPublicDate()));
entity.setDataSource(normalizeString(param.getDataSource()));
entity.setComments(normalizeString(param.getComments()));
return entity;
}
private String normalizeString(String value) {
if (ImportHelper.isBlank(value)) {
return null;
}
return value.trim();
}
private int persistImportChunk(List<CreditCustomer> items,
List<Integer> excelRowNumbers,
int mpBatchSize,
List<String> errorMessages) {
return batchImportSupport.persistChunkWithFallback(
items,
excelRowNumbers,
() -> {
boolean ok = creditCustomerService.saveBatch(items, mpBatchSize);
if (!ok) {
throw new RuntimeException("批量保存失败");
}
return items.size();
},
(rowItem, rowNumber) -> {
try {
boolean saved = creditCustomerService.save(rowItem);
if (saved) {
return true;
}
if (rowNumber != null && rowNumber > 0) {
errorMessages.add("" + rowNumber + "行:保存失败");
} else {
errorMessages.add("保存失败");
}
return false;
} catch (DataIntegrityViolationException e) {
if (isDuplicateKey(e)) {
String name = rowItem != null ? rowItem.getName() : null;
String label = ImportHelper.isBlank(name) ? "数据" : ("客户【" + name.trim() + "");
if (rowNumber != null && rowNumber > 0) {
errorMessages.add("" + rowNumber + "行:" + label + "重复(唯一索引冲突)");
} else {
errorMessages.add(label + "重复(唯一索引冲突)");
}
return false;
}
throw e;
}
},
errorMessages
);
}
private static boolean isDuplicateKey(DataIntegrityViolationException e) {
// Prefer structured detection (SQLState / vendor error code), fall back to message contains.
for (Throwable t = e; t != null; t = t.getCause()) {
if (t instanceof SQLException) {
SQLException se = (SQLException) t;
// MySQL: 1062 Duplicate entry; PostgreSQL/H2: SQLState 23505 unique_violation
if (se.getErrorCode() == 1062) {
return true;
}
if ("23505".equals(se.getSQLState())) {
return true;
}
}
}
Throwable mostSpecificCause = e.getMostSpecificCause();
String message = mostSpecificCause != null ? mostSpecificCause.getMessage() : e.getMessage();
if (message == null) {
return false;
}
String lower = message.toLowerCase();
return lower.contains("duplicate") && lower.contains("key");
}
}

View File

@@ -1,516 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditDeliveryNotice;
import com.gxwebsoft.credit.param.CreditDeliveryNoticeImportParam;
import com.gxwebsoft.credit.param.CreditDeliveryNoticeParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditDeliveryNoticeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 送达公告司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:49:52
*/
@Tag(name = "送达公告司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-delivery-notice")
public class CreditDeliveryNoticeController extends BaseController {
@Resource
private CreditDeliveryNoticeService creditDeliveryNoticeService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询送达公告司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditDeliveryNotice>> page(CreditDeliveryNoticeParam param) {
// 使用关联查询
return success(creditDeliveryNoticeService.pageRel(param));
}
@Operation(summary = "查询全部送达公告司法大数据")
@GetMapping()
public ApiResult<List<CreditDeliveryNotice>> list(CreditDeliveryNoticeParam param) {
// 使用关联查询
return success(creditDeliveryNoticeService.listRel(param));
}
@Operation(summary = "根据id查询送达公告司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditDeliveryNotice> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditDeliveryNoticeService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@OperationLog
@Operation(summary = "添加送达公告司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditDeliveryNotice creditDeliveryNotice) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditDeliveryNotice.setUserId(loginUser.getUserId());
// }
if (creditDeliveryNoticeService.save(creditDeliveryNotice)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:update')")
@OperationLog
@Operation(summary = "修改送达公告司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditDeliveryNotice creditDeliveryNotice) {
if (creditDeliveryNoticeService.updateById(creditDeliveryNotice)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:remove')")
@OperationLog
@Operation(summary = "删除送达公告司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditDeliveryNotice.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@OperationLog
@Operation(summary = "批量添加送达公告司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditDeliveryNotice> list) {
if (creditDeliveryNoticeService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:update')")
@OperationLog
@Operation(summary = "批量修改送达公告司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditDeliveryNotice> batchParam) {
if (batchParam.update(creditDeliveryNoticeService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:remove')")
@OperationLog
@Operation(summary = "批量删除送达公告司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditDeliveryNotice.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Party columns may contain multiple roles/names; match if any company name is contained in the text.
// Priority: 原告/上诉人 > 被告/被上诉人 > 其他当事人/第三人
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditDeliveryNoticeService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditDeliveryNotice::getId,
CreditDeliveryNotice::setId,
CreditDeliveryNotice::getCompanyId,
CreditDeliveryNotice::setCompanyId,
CreditDeliveryNotice::getHasData,
CreditDeliveryNotice::setHasData,
CreditDeliveryNotice::getTenantId,
CreditDeliveryNotice::new,
CreditDeliveryNotice::getPlaintiffAppellant,
CreditDeliveryNotice::getAppellee,
CreditDeliveryNotice::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入送达公告司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@Operation(summary = "批量导入送达公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "送达公告", 0);
ExcelImportSupport.ImportResult<CreditDeliveryNoticeImportParam> importResult = ExcelImportSupport.read(
file, CreditDeliveryNoticeImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditDeliveryNoticeImportParam> 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;
// URL 通常以超链接形式存在于“案号”列里
Map<String, String> urlByCaseNumber = ExcelImportSupport.readHyperlinksByHeaderKey(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditDeliveryNoticeImportParam param = list.get(i);
try {
CreditDeliveryNotice item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String link = urlByCaseNumber.get(item.getCaseNumber().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("" + excelRowNumber + "行:案号不能为空");
continue;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditDeliveryNoticeService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditDeliveryNotice::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditDeliveryNoticeService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditDeliveryNotice::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.DELIVERY_NOTICE, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史送达公告(仅解析“历史送达公告”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@Operation(summary = "批量导入历史送达公告司法大数据")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史送达公告");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史送达公告”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditDeliveryNoticeImportParam> importResult = ExcelImportSupport.read(
file, CreditDeliveryNoticeImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditDeliveryNoticeImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditDeliveryNoticeImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditDeliveryNotice item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditDeliveryNoticeService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditDeliveryNotice::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditDeliveryNoticeService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditDeliveryNotice::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.DELIVERY_NOTICE, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditDeliveryNoticeImportParam> templateList = new ArrayList<>();
CreditDeliveryNoticeImportParam example = new CreditDeliveryNoticeImportParam();
example.setDataType("送达公告");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty2("第三人示例");
example.setInvolvedAmount("100000");
example.setDataStatus("正常");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setCourtName("示例法院");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("送达公告导入模板", "送达公告", CreditDeliveryNoticeImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_delivery_notice_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditDeliveryNoticeImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getCauseOfAction())
&& ImportHelper.isBlank(param.getOtherPartiesThirdParty())
&& ImportHelper.isBlank(param.getOtherPartiesThirdParty2())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getAppellee());
}
private CreditDeliveryNotice convertImportParamToEntity(CreditDeliveryNoticeImportParam param) {
CreditDeliveryNotice entity = new CreditDeliveryNotice();
String occurrenceTime = !ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2()
: param.getOccurrenceTime();
String otherPartiesThirdParty = !ImportHelper.isBlank(param.getOtherPartiesThirdParty2())
? param.getOtherPartiesThirdParty2()
: param.getOtherPartiesThirdParty();
String courtName = !ImportHelper.isBlank(param.getCourtName2())
? param.getCourtName2()
: param.getCourtName();
String involvedAmount = !ImportHelper.isBlank(param.getInvolvedAmount2())
? param.getInvolvedAmount2()
: param.getInvolvedAmount();
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setInvolvedAmount(involvedAmount);
entity.setDataStatus(param.getDataStatus());
entity.setOtherPartiesThirdParty(otherPartiesThirdParty);
entity.setOccurrenceTime(occurrenceTime);
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setCourtName(courtName);
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,384 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditExternal;
import com.gxwebsoft.credit.param.CreditExternalImportParam;
import com.gxwebsoft.credit.param.CreditExternalParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditExternalService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 对外投资控制器
*
* @author 科技小王子
* @since 2025-12-19 19:50:12
*/
@Tag(name = "对外投资管理")
@RestController
@RequestMapping("/api/credit/credit-external")
public class CreditExternalController extends BaseController {
@Resource
private CreditExternalService creditExternalService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询对外投资")
@GetMapping("/page")
public ApiResult<PageResult<CreditExternal>> page(CreditExternalParam param) {
// 使用关联查询
return success(creditExternalService.pageRel(param));
}
@Operation(summary = "查询全部对外投资")
@GetMapping()
public ApiResult<List<CreditExternal>> list(CreditExternalParam param) {
// 使用关联查询
return success(creditExternalService.listRel(param));
}
@Operation(summary = "根据id查询对外投资")
@GetMapping("/{id}")
public ApiResult<CreditExternal> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditExternalService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditExternal:save')")
@OperationLog
@Operation(summary = "添加对外投资")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditExternal creditExternal) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditExternal.setUserId(loginUser.getUserId());
// }
if (creditExternalService.save(creditExternal)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:update')")
@OperationLog
@Operation(summary = "修改对外投资")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditExternal creditExternal) {
if (creditExternalService.updateById(creditExternal)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:remove')")
@OperationLog
@Operation(summary = "删除对外投资")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditExternal.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:save')")
@OperationLog
@Operation(summary = "批量添加对外投资")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditExternal> list) {
if (creditExternalService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:update')")
@OperationLog
@Operation(summary = "批量修改对外投资")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditExternal> batchParam) {
if (batchParam.update(creditExternalService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditExternal:remove')")
@OperationLog
@Operation(summary = "批量删除对外投资")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditExternal.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditExternal:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditExternalService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditExternal::getId,
CreditExternal::setId,
CreditExternal::getName,
CreditExternal::getCompanyId,
CreditExternal::setCompanyId,
CreditExternal::setCompanyName,
CreditExternal::getHasData,
CreditExternal::setHasData,
CreditExternal::getTenantId,
CreditExternal::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入对外投资
*/
@PreAuthorize("hasAuthority('credit:creditExternal:save')")
@Operation(summary = "批量导入对外投资")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "对外投资", 0);
ExcelImportSupport.ImportResult<CreditExternalImportParam> importResult = ExcelImportSupport.read(
file, CreditExternalImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditExternalImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
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.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "被投资企业名称");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : 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 (!ImportHelper.isBlank(item.getName())) {
String link = urlByName.get(item.getName().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
if (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
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 (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditExternalService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditExternal::getName,
"",
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.persistInsertOnlyChunk(
creditExternalService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditExternal::getName,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.EXTERNAL, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载对外投资导入模板
*/
@Operation(summary = "下载对外投资导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditExternalImportParam> templateList = new ArrayList<>();
CreditExternalImportParam example = new CreditExternalImportParam();
example.setName("示例科技有限公司");
example.setStatusTxt("存续");
example.setLegalRepresentative("李四");
example.setRegisteredCapital("10000");
example.setEstablishmentDate("2018-06-01");
example.setShareholdingRatio("20");
example.setSubscribedInvestmentAmount("2000");
example.setSubscribedInvestmentDate("2019-01-01");
example.setIndirectShareholdingRatio("5");
example.setInvestmentDate("2019-06-01");
example.setRegion("上海");
example.setIndustry("信息技术");
example.setInvestmentCount(1);
example.setRelatedProductsInstitutions("关联产品示例");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("对外投资导入模板", "对外投资", CreditExternalImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_external_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditExternalImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getName())
&& ImportHelper.isBlank(param.getLegalRepresentative())
&& ImportHelper.isBlank(param.getRegisteredCapital())
&& ImportHelper.isBlank(param.getEstablishmentDate());
}
private CreditExternal convertImportParamToEntity(CreditExternalImportParam param) {
CreditExternal entity = new CreditExternal();
entity.setName(param.getName());
entity.setStatusTxt(param.getStatusTxt());
entity.setLegalRepresentative(param.getLegalRepresentative());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setEstablishmentDate(param.getEstablishmentDate());
entity.setShareholdingRatio(param.getShareholdingRatio());
entity.setSubscribedInvestmentAmount(param.getSubscribedInvestmentAmount());
entity.setSubscribedInvestmentDate(param.getSubscribedInvestmentDate());
entity.setIndirectShareholdingRatio(param.getIndirectShareholdingRatio());
entity.setInvestmentDate(param.getInvestmentDate());
entity.setRegion(param.getRegion());
entity.setIndustry(param.getIndustry());
entity.setInvestmentCount(param.getInvestmentCount());
entity.setRelatedProductsInstitutions(param.getRelatedProductsInstitutions());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,517 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditFinalVersion;
import com.gxwebsoft.credit.param.CreditFinalVersionImportParam;
import com.gxwebsoft.credit.param.CreditFinalVersionParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditFinalVersionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 终本案件控制器
*
* @author 科技小王子
* @since 2025-12-19 19:50:19
*/
@Tag(name = "终本案件管理")
@RestController
@RequestMapping("/api/credit/credit-final-version")
public class CreditFinalVersionController extends BaseController {
@Resource
private CreditFinalVersionService creditFinalVersionService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询终本案件")
@GetMapping("/page")
public ApiResult<PageResult<CreditFinalVersion>> page(CreditFinalVersionParam param) {
// 使用关联查询
return success(creditFinalVersionService.pageRel(param));
}
@Operation(summary = "查询全部终本案件")
@GetMapping()
public ApiResult<List<CreditFinalVersion>> list(CreditFinalVersionParam param) {
// 使用关联查询
return success(creditFinalVersionService.listRel(param));
}
@Operation(summary = "根据id查询终本案件")
@GetMapping("/{id}")
public ApiResult<CreditFinalVersion> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditFinalVersionService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@OperationLog
@Operation(summary = "添加终本案件")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditFinalVersion creditFinalVersion) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditFinalVersion.setUserId(loginUser.getUserId());
// }
if (creditFinalVersionService.save(creditFinalVersion)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:update')")
@OperationLog
@Operation(summary = "修改终本案件")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditFinalVersion creditFinalVersion) {
if (creditFinalVersionService.updateById(creditFinalVersion)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:remove')")
@OperationLog
@Operation(summary = "删除终本案件")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditFinalVersion.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@OperationLog
@Operation(summary = "批量添加终本案件")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditFinalVersion> list) {
if (creditFinalVersionService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:update')")
@OperationLog
@Operation(summary = "批量修改终本案件")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditFinalVersion> batchParam) {
if (batchParam.update(creditFinalVersionService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:remove')")
@OperationLog
@Operation(summary = "批量删除终本案件")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditFinalVersion.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditFinalVersion:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Party columns may contain multiple roles/names; match if any company name is contained in the text.
// Priority: 原告/上诉人 > 被告/被上诉人 > 其他当事人/第三人
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditFinalVersionService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditFinalVersion::getId,
CreditFinalVersion::setId,
CreditFinalVersion::getCompanyId,
CreditFinalVersion::setCompanyId,
CreditFinalVersion::getHasData,
CreditFinalVersion::setHasData,
CreditFinalVersion::getTenantId,
CreditFinalVersion::new,
CreditFinalVersion::getPlaintiffAppellant,
CreditFinalVersion::getAppellee,
CreditFinalVersion::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入终本案件
*/
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@Operation(summary = "批量导入终本案件")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
// 按选项卡名称读取(客户提供的文件可能不是把目标 sheet 放在第一个)
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "终本案件", 0);
ExcelImportSupport.ImportResult<CreditFinalVersionImportParam> importResult = ExcelImportSupport.read(
file, CreditFinalVersionImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditFinalVersionImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditFinalVersionImportParam param = list.get(i);
try {
CreditFinalVersion item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String link = urlByCaseNumber.get(item.getCaseNumber().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditFinalVersionService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditFinalVersion::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditFinalVersionService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditFinalVersion::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.FINAL_VERSION, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史终本案件(仅解析“历史终本案件”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@Operation(summary = "批量导入历史终本案件")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史终本案件");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史终本案件”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditFinalVersionImportParam> importResult = ExcelImportSupport.read(
file, CreditFinalVersionImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditFinalVersionImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditFinalVersionImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditFinalVersion item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditFinalVersionService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditFinalVersion::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditFinalVersionService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditFinalVersion::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.FINAL_VERSION, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditFinalVersionImportParam> templateList = new ArrayList<>();
CreditFinalVersionImportParam example = new CreditFinalVersionImportParam();
example.setCaseNumber("2024示例案号");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOtherPartiesThirdParty("第三人示例");
example.setInvolvedAmount("20,293.91");
example.setDataStatus("正常");
example.setCourtName("示例法院");
example.setOccurrenceTime("2024-01-01");
example.setFinalDate("2024-01-01");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("终本案件导入模板", "终本案件", CreditFinalVersionImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_final_version_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditFinalVersionImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber());
}
private CreditFinalVersion convertImportParamToEntity(CreditFinalVersionImportParam param) {
CreditFinalVersion entity = new CreditFinalVersion();
String plaintiffAppellant = !ImportHelper.isBlank(param.getPlaintiffAppellant2())
? param.getPlaintiffAppellant2()
: param.getPlaintiffAppellant();
String appellee = !ImportHelper.isBlank(param.getAppellee2())
? param.getAppellee2()
: param.getAppellee();
String otherPartiesThirdParty = !ImportHelper.isBlank(param.getOtherPartiesThirdParty())
? param.getOtherPartiesThirdParty()
: param.getOtherPartiesThirdParty2();
String involvedAmount = !ImportHelper.isBlank(param.getInvolvedAmount2())
? param.getInvolvedAmount2()
: param.getInvolvedAmount();
String courtName = !ImportHelper.isBlank(param.getCourtName2())
? param.getCourtName2()
: param.getCourtName();
String occurrenceTime = !ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2()
: param.getOccurrenceTime();
entity.setCaseNumber(param.getCaseNumber());
entity.setPlaintiffAppellant(plaintiffAppellant);
entity.setAppellee(appellee);
entity.setUnfulfilledAmount(param.getUnfulfilledAmount());
entity.setInvolvedAmount(involvedAmount);
entity.setOtherPartiesThirdParty(otherPartiesThirdParty);
entity.setDataStatus(param.getDataStatus());
entity.setCourtName(courtName);
entity.setOccurrenceTime(occurrenceTime);
entity.setFinalDate(param.getFinalDate());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,686 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditGqdj;
import com.gxwebsoft.credit.param.CreditGqdjImportParam;
import com.gxwebsoft.credit.param.CreditGqdjParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditGqdjService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 股权冻结控制器
*
* @author 科技小王子
* @since 2025-12-19 19:50:37
*/
@Tag(name = "股权冻结管理")
@RestController
@RequestMapping("/api/credit/credit-gqdj")
public class CreditGqdjController extends BaseController {
@Resource
private CreditGqdjService creditGqdjService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询股权冻结")
@GetMapping("/page")
public ApiResult<PageResult<CreditGqdj>> page(CreditGqdjParam param) {
// 使用关联查询
return success(creditGqdjService.pageRel(param));
}
@Operation(summary = "查询全部股权冻结")
@GetMapping()
public ApiResult<List<CreditGqdj>> list(CreditGqdjParam param) {
// 使用关联查询
return success(creditGqdjService.listRel(param));
}
@Operation(summary = "根据id查询股权冻结")
@GetMapping("/{id}")
public ApiResult<CreditGqdj> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditGqdjService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@OperationLog
@Operation(summary = "添加股权冻结")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditGqdj creditGqdj) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditGqdj.setUserId(loginUser.getUserId());
// }
if (creditGqdjService.save(creditGqdj)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:update')")
@OperationLog
@Operation(summary = "修改股权冻结")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditGqdj creditGqdj) {
if (creditGqdjService.updateById(creditGqdj)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:remove')")
@OperationLog
@Operation(summary = "删除股权冻结")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditGqdj.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@OperationLog
@Operation(summary = "批量添加股权冻结")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditGqdj> list) {
if (creditGqdjService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:update')")
@OperationLog
@Operation(summary = "批量修改股权冻结")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditGqdj> batchParam) {
if (batchParam.update(creditGqdjService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditGqdj:remove')")
@OperationLog
@Operation(summary = "批量删除股权冻结")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditGqdj.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据当事人/企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId 为空/0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditGqdj:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Match companyId by any party/company-name column (e.g. plaintiff/appellant, defendant/appellee).
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNames(
creditGqdjService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditGqdj::getId,
CreditGqdj::setId,
CreditGqdj::getCompanyId,
CreditGqdj::setCompanyId,
CreditGqdj::getHasData,
CreditGqdj::setHasData,
CreditGqdj::getTenantId,
CreditGqdj::new,
CreditGqdj::getPlaintiffAppellant,
CreditGqdj::getAppellee
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入股权冻结司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@Operation(summary = "批量导入股权冻结司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "股权冻结", 0);
// Prefer the "best" header configuration; many upstream files have extra title rows or multi-row headers.
ExcelImportSupport.ImportResult<CreditGqdjImportParam> importResult = ExcelImportSupport.readBest(
file,
CreditGqdjImportParam.class,
this::isEmptyImportRow,
// Score rows that look like real data (at least has a case number in either column).
p -> p != null
&& (!ImportHelper.isBlank(p.getCaseNumber())
|| !ImportHelper.isBlank(p.getCaseNumber2())
),
sheetIndex
);
List<CreditGqdjImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
// Fallback: try other sheets if the named/default sheet doesn't match.
importResult = ExcelImportSupport.readAnySheetBest(
file,
CreditGqdjImportParam.class,
this::isEmptyImportRow,
p -> p != null
&& (!ImportHelper.isBlank(p.getCaseNumber())
|| !ImportHelper.isBlank(p.getCaseNumber2()))
);
list = importResult.getData();
usedTitleRows = importResult.getTitleRows();
usedHeadRows = importResult.getHeadRows();
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;
// easypoi 默认不会读取单元格超链接地址url 通常挂在“案号/执行通知文书号”列的超链接中,需要额外读取回填。
String caseNumberHeader = "执行通知文书号";
Map<String, String> urlByCaseNumber = ExcelImportSupport.readHyperlinksByHeaderKey(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader);
// Some upstream sources use "案号" as the case number header.
Map<String, String> urlByCaseNumberFromAh = ExcelImportSupport.readHyperlinksByHeaderKey(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
urlByCaseNumberFromAh.forEach(urlByCaseNumber::putIfAbsent);
// Some upstream sources use "暗号" as the case number header.
Map<String, String> urlByCaseNumberFromAh2 = ExcelImportSupport.readHyperlinksByHeaderKey(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号");
urlByCaseNumberFromAh2.forEach(urlByCaseNumber::putIfAbsent);
// 有些源文件会单独提供“url/网址/链接”等列(可能是纯文本也可能是超链接)
Map<String, String> urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader, "url");
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader, "URL");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader, "网址");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader, "链接");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
// Try again with "案号" as the key column name.
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号", "url");
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号", "URL");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号", "网址");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号", "链接");
}
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
// Try again with "暗号" as the key column name.
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号", "url");
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号", "URL");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号", "网址");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号", "链接");
}
}
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++) {
CreditGqdjImportParam param = list.get(i);
try {
CreditGqdj item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String key = item.getCaseNumber().trim();
String link = urlByCaseNumber.get(key);
if (ImportHelper.isBlank(link)) {
link = urlByCaseNumberFromUrlCol.get(key);
}
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditGqdjService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditGqdj::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditGqdjService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditGqdj::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.GQDJ, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史股权冻结(仅解析“历史股权冻结”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@Operation(summary = "批量导入历史股权冻结司法大数据")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史股权冻结");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史股权冻结”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditGqdjImportParam> importResult = ExcelImportSupport.readBest(
file,
CreditGqdjImportParam.class,
this::isEmptyImportRow,
p -> p != null
&& (!ImportHelper.isBlank(p.getCaseNumber())
|| !ImportHelper.isBlank(p.getCaseNumber2())),
sheetIndex
);
List<CreditGqdjImportParam> 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;
String caseNumberHeader = "执行通知文书号";
Map<String, String> urlByCaseNumber = ExcelImportSupport.readHyperlinksByHeaderKey(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader);
Map<String, String> urlByCaseNumberFromAh = ExcelImportSupport.readHyperlinksByHeaderKey(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
urlByCaseNumberFromAh.forEach(urlByCaseNumber::putIfAbsent);
Map<String, String> urlByCaseNumberFromAh2 = ExcelImportSupport.readHyperlinksByHeaderKey(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号");
urlByCaseNumberFromAh2.forEach(urlByCaseNumber::putIfAbsent);
Map<String, String> urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader, "url");
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader, "URL");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader, "网址");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, caseNumberHeader, "链接");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号", "url");
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号", "URL");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号", "网址");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号", "链接");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号", "url");
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号", "URL");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号", "网址");
}
if (urlByCaseNumberFromUrlCol.isEmpty()) {
urlByCaseNumberFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(
file, usedSheetIndex, usedTitleRows, usedHeadRows, "暗号", "链接");
}
}
}
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++) {
CreditGqdjImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditGqdj item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String key = item.getCaseNumber();
String link = urlByCaseNumber.get(key);
if (ImportHelper.isBlank(link)) {
link = urlByCaseNumberFromUrlCol.get(key);
}
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataType("失效");
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditGqdjService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditGqdj::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditGqdjService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditGqdj::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.GQDJ, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditGqdjImportParam> templateList = new ArrayList<>();
CreditGqdjImportParam example = new CreditGqdjImportParam();
example.setDataType("股权冻结");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setCaseNumber("2024示例案号");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setDataStatus("已公开");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("股权冻结导入模板", "股权冻结", CreditGqdjImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_gqdj_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditGqdjImportParam param) {
if (param == null) {
return true;
}
// Don't over-filter here: if some columns are mapped but case number header differs,
// we still want to read the row and report "案号不能为空" instead of "未读取到数据".
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getCaseNumber2())
&& ImportHelper.isBlank(param.getAppellee())
&& ImportHelper.isBlank(param.getAppellee2())
&& ImportHelper.isBlank(param.getPlaintiffAppellant())
&& ImportHelper.isBlank(param.getPlaintiffAppellant2())
&& ImportHelper.isBlank(param.getInvolvedAmount())
&& ImportHelper.isBlank(param.getCourtName())
&& ImportHelper.isBlank(param.getDataType())
&& ImportHelper.isBlank(param.getDataStatus())
&& ImportHelper.isBlank(param.getDataStatus2())
&& ImportHelper.isBlank(param.getFreezeDateStart())
&& ImportHelper.isBlank(param.getFreezeDateEnd())
&& ImportHelper.isBlank(param.getFreezeDateStart2())
&& ImportHelper.isBlank(param.getFreezeDateEnd2())
&& ImportHelper.isBlank(param.getPublicDate());
}
private CreditGqdj convertImportParamToEntity(CreditGqdjImportParam param) {
CreditGqdj entity = new CreditGqdj();
// Template compatibility: some sources use alternate headers for the same columns.
String appellee = !ImportHelper.isBlank(param.getAppellee()) ? param.getAppellee() : param.getAppellee2();
String plaintiffAppellant = !ImportHelper.isBlank(param.getPlaintiffAppellant())
? param.getPlaintiffAppellant()
: param.getPlaintiffAppellant2();
if (!ImportHelper.isBlank(param.getCaseNumber2())) {
entity.setCaseNumber(param.getCaseNumber2());
} else {
entity.setCaseNumber(param.getCaseNumber());
}
entity.setAppellee(appellee);
entity.setPlaintiffAppellant(plaintiffAppellant);
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setCourtName(param.getCourtName());
if (!ImportHelper.isBlank(param.getDataStatus2())) {
entity.setDataStatus(param.getDataStatus2());
} else {
entity.setDataStatus(param.getDataStatus());
}
entity.setDataType(param.getDataType());
entity.setPublicDate(param.getPublicDate());
if (!ImportHelper.isBlank(param.getFreezeDateStart2())) {
entity.setFreezeDateStart(param.getFreezeDateStart2());
} else {
entity.setFreezeDateStart(param.getFreezeDateStart());
}
if (!ImportHelper.isBlank(param.getFreezeDateEnd2())) {
entity.setFreezeDateEnd(param.getFreezeDateEnd2());
} else {
entity.setFreezeDateEnd(param.getFreezeDateEnd());
}
return entity;
}
}

View File

@@ -1,376 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditHistoricalLegalPerson;
import com.gxwebsoft.credit.param.CreditHistoricalLegalPersonImportParam;
import com.gxwebsoft.credit.param.CreditHistoricalLegalPersonParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 历史法定代表人控制器
*
* @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;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@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 (batchImportSupport.hardRemoveById(CreditHistoricalLegalPerson.class, 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 (batchImportSupport.hardRemoveByIds(CreditHistoricalLegalPerson.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditHistoricalLegalPerson:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditHistoricalLegalPersonService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditHistoricalLegalPerson::getId,
CreditHistoricalLegalPerson::setId,
CreditHistoricalLegalPerson::getName,
CreditHistoricalLegalPerson::getCompanyId,
CreditHistoricalLegalPerson::setCompanyId,
CreditHistoricalLegalPerson::setCompanyName,
CreditHistoricalLegalPerson::getHasData,
CreditHistoricalLegalPerson::setHasData,
CreditHistoricalLegalPerson::getTenantId,
CreditHistoricalLegalPerson::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入历史法定代表人
*/
@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;
Set<Integer> touchedCompanyIds = new HashSet<>();
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, "名称");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : null;
}
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 (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
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 (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditHistoricalLegalPersonService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditHistoricalLegalPerson::getName,
"",
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.persistInsertOnlyChunk(
creditHistoricalLegalPersonService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditHistoricalLegalPerson::getName,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.HISTORICAL_LEGAL_PERSON, touchedCompanyIds);
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

@@ -1,881 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditJudgmentDebtor;
import com.gxwebsoft.credit.param.CreditJudgmentDebtorImportParam;
import com.gxwebsoft.credit.param.CreditJudgmentDebtorParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditJudgmentDebtorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Locale;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* 被执行人控制器
*
* @author 科技小王子
* @since 2025-12-19 19:50:55
*/
@Tag(name = "被执行人管理")
@RestController
@RequestMapping("/api/credit/credit-judgment-debtor")
public class CreditJudgmentDebtorController extends BaseController {
@Resource
private CreditJudgmentDebtorService creditJudgmentDebtorService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询被执行人")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudgmentDebtor>> page(CreditJudgmentDebtorParam param) {
// 使用关联查询
return success(creditJudgmentDebtorService.pageRel(param));
}
@Operation(summary = "查询全部被执行人")
@GetMapping()
public ApiResult<List<CreditJudgmentDebtor>> list(CreditJudgmentDebtorParam param) {
// 使用关联查询
return success(creditJudgmentDebtorService.listRel(param));
}
@Operation(summary = "根据id查询被执行人")
@GetMapping("/{id}")
public ApiResult<CreditJudgmentDebtor> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditJudgmentDebtorService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@OperationLog
@Operation(summary = "添加被执行人")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditJudgmentDebtor creditJudgmentDebtor) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditJudgmentDebtor.setUserId(loginUser.getUserId());
// }
if (creditJudgmentDebtorService.save(creditJudgmentDebtor)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:update')")
@OperationLog
@Operation(summary = "修改被执行人")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditJudgmentDebtor creditJudgmentDebtor) {
if (creditJudgmentDebtorService.updateById(creditJudgmentDebtor)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:remove')")
@OperationLog
@Operation(summary = "删除被执行人")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditJudgmentDebtor.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@OperationLog
@Operation(summary = "批量添加被执行人")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditJudgmentDebtor> list) {
if (creditJudgmentDebtorService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:update')")
@OperationLog
@Operation(summary = "批量修改被执行人")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditJudgmentDebtor> batchParam) {
if (batchParam.update(creditJudgmentDebtorService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:remove')")
@OperationLog
@Operation(summary = "批量删除被执行人")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditJudgmentDebtor.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "topLevelOnly", required = false, defaultValue = "true") Boolean topLevelOnly
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Match only on "name" column: debtor.name contains a (top-level) CreditCompany name/matchName.
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditJudgmentDebtorService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditJudgmentDebtor::getId,
CreditJudgmentDebtor::setId,
CreditJudgmentDebtor::getCompanyId,
CreditJudgmentDebtor::setCompanyId,
CreditJudgmentDebtor::getHasData,
CreditJudgmentDebtor::setHasData,
CreditJudgmentDebtor::getTenantId,
CreditJudgmentDebtor::new,
q -> {
if (!Boolean.TRUE.equals(topLevelOnly)) {
return;
}
// "一级企业"parentId=0部分历史数据可能为 NULL兼容处理
q.and(w -> w.eq(com.gxwebsoft.credit.entity.CreditCompany::getParentId, 0)
.or()
.isNull(com.gxwebsoft.credit.entity.CreditCompany::getParentId));
},
CreditJudgmentDebtor::getName
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入被执行人
*/
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@Operation(summary = "批量导入被执行人")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
try {
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
ImportOutcome outcome;
if (isZip(file)) {
outcome = importFromZip(file, currentUserId, currentTenantId, companyId);
} else {
outcome = importFromExcel(file, safeFileLabel(file.getOriginalFilename()), currentUserId, currentTenantId, companyId, false);
}
if (!outcome.anyDataRead) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.JUDGMENT_DEBTOR, outcome.touchedCompanyIds);
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);
}
}
/**
* 批量导入历史被执行人(写入被执行人表 credit_judgment_debtor仅解析“历史被执行人”选项卡
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@Operation(summary = "批量导入历史被执行人")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@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 = importHistoryFromZip(file, currentUserId, currentTenantId, companyId);
} else {
outcome = importHistoryFromExcel(file, safeFileLabel(file.getOriginalFilename()), currentUserId, currentTenantId, companyId);
}
if (!outcome.anyDataRead) {
return fail("未读取到数据,请确认文件中存在“历史被执行人”选项卡且表头与示例格式一致", null);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.JUDGMENT_DEBTOR, outcome.touchedCompanyIds);
if (outcome.errorMessages.isEmpty()) {
return success("成功导入" + outcome.successCount + "条数据", null);
}
return success("导入完成,成功" + outcome.successCount + "条,失败" + outcome.errorMessages.size() + "", outcome.errorMessages);
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载被执行人导入模板
*/
@Operation(summary = "下载被执行人导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudgmentDebtorImportParam> templateList = new ArrayList<>();
CreditJudgmentDebtorImportParam example = new CreditJudgmentDebtorImportParam();
example.setCaseNumber("2024示例案号");
example.setName("某某公司");
example.setCode("1234567890");
example.setOccurrenceTime("2024-01-10");
example.setDataStatus("已公开");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("被执行人导入模板", "被执行人", CreditJudgmentDebtorImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_judgment_debtor_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudgmentDebtorImportParam param) {
if (param == null) {
return true;
}
if (isImportHeaderRow(param)) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber());
}
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.getCourtNameQcc(), "执行法院")
|| isHeaderValue(param.getInvolvedAmount(), "涉案金额")
|| isHeaderValue(param.getInvolvedAmountQcc(), "执行标的(元)")
|| isHeaderValue(param.getDataStatus(), "数据状态");
}
private static boolean isHeaderValue(String value, String headerText) {
if (value == null) {
return false;
}
return headerText.equals(value.trim());
}
private static boolean hasMeaningfulPartyValue(String value) {
if (ImportHelper.isBlank(value)) {
return false;
}
return !"-".equals(value.trim());
}
private CreditJudgmentDebtor convertImportParamToEntity(CreditJudgmentDebtorImportParam param) {
CreditJudgmentDebtor entity = new CreditJudgmentDebtor();
entity.setCaseNumber(param.getCaseNumber());
entity.setName1(param.getName1());
String debtorName = ImportHelper.isBlank(param.getName()) ? param.getName1() : param.getName();
if (debtorName != null) {
debtorName = debtorName.trim();
}
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
// Some upstream XLS templates store party/company name in "原告/上诉人/被告/第三人" columns.
// When present, use them to populate the debtor "name" for compatibility.
if (hasMeaningfulPartyValue(param.getPlaintiffAppellant())) {
debtorName = param.getPlaintiffAppellant().trim();
} else if (hasMeaningfulPartyValue(param.getAppellee())) {
debtorName = param.getAppellee().trim();
} else if (hasMeaningfulPartyValue(param.getOtherPartiesThirdParty())) {
debtorName = param.getOtherPartiesThirdParty().trim();
}
entity.setName(debtorName);
entity.setCode(param.getCode());
String occurrenceTime = !ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2().trim()
: (param.getOccurrenceTime() != null ? param.getOccurrenceTime().trim() : null);
entity.setOccurrenceTime(occurrenceTime);
// 兼容企查查历史被执行人:执行标的(元) / 执行法院
String amount = !ImportHelper.isBlank(param.getInvolvedAmountQcc())
? param.getInvolvedAmountQcc()
: param.getInvolvedAmount();
if (amount != null) {
amount = amount.trim();
}
entity.setAmount(amount);
String courtName = !ImportHelper.isBlank(param.getCourtName())
? param.getCourtName()
: param.getCourtNameQcc();
if (courtName != null) {
courtName = courtName.trim();
}
entity.setCourtName(courtName);
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 final Set<Integer> touchedCompanyIds;
private ImportOutcome(boolean anyDataRead, int successCount, List<String> errorMessages, Set<Integer> touchedCompanyIds) {
this.anyDataRead = anyDataRead;
this.successCount = successCount;
this.errorMessages = errorMessages;
this.touchedCompanyIds = touchedCompanyIds != null ? touchedCompanyIds : new HashSet<>();
}
}
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;
Set<Integer> touchedCompanyIds = new HashSet<>();
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, touchedCompanyIds);
}
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.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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, touchedCompanyIds);
}
private ImportOutcome importHistoryFromExcel(MultipartFile excelFile, String fileLabel, Integer currentUserId, Integer currentTenantId, Integer companyId) throws Exception {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
int historySheetIndex = ExcelImportSupport.findSheetIndex(excelFile, "历史被执行人");
if (historySheetIndex < 0) {
return new ImportOutcome(false, 0, errorMessages, touchedCompanyIds);
}
ExcelImportSupport.ImportResult<CreditJudgmentDebtorImportParam> importResult = ExcelImportSupport.readBest(
excelFile,
CreditJudgmentDebtorImportParam.class,
this::isEmptyImportRow,
this::isScoreImportRow,
historySheetIndex
);
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, touchedCompanyIds);
}
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);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditJudgmentDebtor item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add(prefix + "" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
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.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += persistHistoryImportChunk(chunkItems, chunkRowNumbers, prefix, mpBatchSize, errorMessages);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add(prefix + "" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += persistHistoryImportChunk(chunkItems, chunkRowNumbers, prefix, mpBatchSize, errorMessages);
}
return new ImportOutcome(true, successCount, errorMessages, touchedCompanyIds);
}
private int persistHistoryImportChunk(List<CreditJudgmentDebtor> items,
List<Integer> excelRowNumbers,
String prefix,
int mpBatchSize,
List<String> errorMessages) {
return batchImportSupport.persistInsertOnlyChunk(
creditJudgmentDebtorService,
items,
excelRowNumbers,
mpBatchSize,
CreditJudgmentDebtor::getCaseNumber,
prefix,
errorMessages
);
}
private int persistImportChunk(List<CreditJudgmentDebtor> items,
List<Integer> excelRowNumbers,
String prefix,
int mpBatchSize,
List<String> errorMessages) {
return batchImportSupport.persistInsertOnlyChunk(
creditJudgmentDebtorService,
items,
excelRowNumbers,
mpBatchSize,
CreditJudgmentDebtor::getCaseNumber,
prefix,
errorMessages
);
}
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;
Set<Integer> touchedCompanyIds = new HashSet<>();
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);
touchedCompanyIds.addAll(outcome.touchedCompanyIds);
}
} catch (Exception e) {
errorMessages.add("" + entryFileName + "】解析失败:" + e.getMessage());
}
}
}
return new ImportOutcome(anyDataRead, successCount, errorMessages, touchedCompanyIds);
}
private ImportOutcome importHistoryFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId, Integer companyId) throws Exception {
try {
return importHistoryFromZip(zipFile, currentUserId, currentTenantId, companyId, StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
return importHistoryFromZip(zipFile, currentUserId, currentTenantId, companyId, Charset.forName("GBK"));
}
}
private ImportOutcome importHistoryFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId, Integer companyId, Charset charset) throws Exception {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
boolean anyDataRead = false;
Set<Integer> touchedCompanyIds = new HashSet<>();
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 = importHistoryFromExcel(excelFile, entryFileName, currentUserId, currentTenantId, companyId);
if (outcome.anyDataRead) {
anyDataRead = true;
successCount += outcome.successCount;
errorMessages.addAll(outcome.errorMessages);
touchedCompanyIds.addAll(outcome.touchedCompanyIds);
}
} catch (Exception e) {
errorMessages.add("" + entryFileName + "】解析失败:" + e.getMessage());
}
}
}
return new ImportOutcome(anyDataRead, successCount, errorMessages, touchedCompanyIds);
}
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

@@ -1,513 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditJudicialDocument;
import com.gxwebsoft.credit.param.CreditJudicialDocumentImportParam;
import com.gxwebsoft.credit.param.CreditJudicialDocumentParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditJudicialDocumentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 裁判文书司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:03
*/
@Tag(name = "裁判文书司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-judicial-document")
public class CreditJudicialDocumentController extends BaseController {
@Resource
private CreditJudicialDocumentService creditJudicialDocumentService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询裁判文书司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudicialDocument>> page(CreditJudicialDocumentParam param) {
// 使用关联查询
return success(creditJudicialDocumentService.pageRel(param));
}
@Operation(summary = "查询全部裁判文书司法大数据")
@GetMapping()
public ApiResult<List<CreditJudicialDocument>> list(CreditJudicialDocumentParam param) {
// 使用关联查询
return success(creditJudicialDocumentService.listRel(param));
}
@Operation(summary = "根据id查询裁判文书司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditJudicialDocument> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditJudicialDocumentService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@OperationLog
@Operation(summary = "添加裁判文书司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditJudicialDocument creditJudicialDocument) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditJudicialDocument.setUserId(loginUser.getUserId());
// }
if (creditJudicialDocumentService.save(creditJudicialDocument)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:update')")
@OperationLog
@Operation(summary = "修改裁判文书司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditJudicialDocument creditJudicialDocument) {
if (creditJudicialDocumentService.updateById(creditJudicialDocument)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:remove')")
@OperationLog
@Operation(summary = "删除裁判文书司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditJudicialDocument.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@OperationLog
@Operation(summary = "批量添加裁判文书司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditJudicialDocument> list) {
if (creditJudicialDocumentService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:update')")
@OperationLog
@Operation(summary = "批量修改裁判文书司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditJudicialDocument> batchParam) {
if (batchParam.update(creditJudicialDocumentService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:remove')")
@OperationLog
@Operation(summary = "批量删除裁判文书司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditJudicialDocument.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据“当事人/第三人”文本中包含的企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:update')")
@OperationLog
@Operation(summary = "根据当事人字段包含企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditJudicialDocumentService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditJudicialDocument::getId,
CreditJudicialDocument::setId,
CreditJudicialDocument::getCompanyId,
CreditJudicialDocument::setCompanyId,
CreditJudicialDocument::getHasData,
CreditJudicialDocument::setHasData,
CreditJudicialDocument::getTenantId,
CreditJudicialDocument::new,
// 需求otherPartiesThirdParty 字段包含企业名称时,回填 companyId
CreditJudicialDocument::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入裁判文书司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@Operation(summary = "批量导入裁判文书司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
// 支持按选项卡名称导入默认读取“裁判文书”sheet不存在则回退到第 0 个sheet
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "裁判文书", 0);
ExcelImportSupport.ImportResult<CreditJudicialDocumentImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialDocumentImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditJudicialDocumentImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
Map<String, String> urlByTitle = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "文书标题");
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++) {
CreditJudicialDocumentImportParam param = list.get(i);
try {
CreditJudicialDocument item = convertImportParamToEntity(param);
String link = null;
if (!ImportHelper.isBlank(item.getCaseNumber())) {
link = urlByCaseNumber.get(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(link) && !ImportHelper.isBlank(item.getTitle())) {
link = urlByTitle.get(item.getTitle().trim());
}
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditJudicialDocumentService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditJudicialDocument::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditJudicialDocumentService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditJudicialDocument::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.JUDICIAL_DOCUMENT, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史裁判文书(仅解析“历史裁判文书”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@Operation(summary = "批量导入历史裁判文书司法大数据")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史裁判文书");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史裁判文书”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditJudicialDocumentImportParam> importResult = ExcelImportSupport.read(
file, CreditJudicialDocumentImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditJudicialDocumentImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
Map<String, String> urlByTitle = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "文书标题");
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++) {
CreditJudicialDocumentImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditJudicialDocument item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = null;
if (!ImportHelper.isBlank(item.getCaseNumber())) {
link = urlByCaseNumber.get(item.getCaseNumber());
}
if (ImportHelper.isBlank(link) && !ImportHelper.isBlank(item.getTitle())) {
link = urlByTitle.get(item.getTitle().trim());
}
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditJudicialDocumentService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditJudicialDocument::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditJudicialDocumentService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditJudicialDocument::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.JUDICIAL_DOCUMENT, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditJudicialDocumentImportParam> templateList = new ArrayList<>();
CreditJudicialDocumentImportParam example = new CreditJudicialDocumentImportParam();
example.setTitle("裁判文书");
example.setOtherPartiesThirdParty("第三人示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setInvolvedAmount("100000");
example.setDefendantAppellee("裁判结果示例");
example.setCourtName("示例法院");
example.setReleaseDate("2024-01-02");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("裁判文书导入模板", "裁判文书", CreditJudicialDocumentImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_judicial_document_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditJudicialDocumentImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber());
}
private CreditJudicialDocument convertImportParamToEntity(CreditJudicialDocumentImportParam param) {
CreditJudicialDocument entity = new CreditJudicialDocument();
String involvedAmount = !ImportHelper.isBlank(param.getInvolvedAmount2())
? param.getInvolvedAmount2()
: param.getInvolvedAmount();
entity.setTitle(param.getTitle());
entity.setDocumentType(param.getDocumentType());
entity.setDataStatus(param.getDataStatus());
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setInvolvedAmount(involvedAmount);
// Excel导入字段映射补全否则对应数据库字段(defendant_appellee/release_date)会一直为空
entity.setDefendantAppellee(param.getDefendantAppellee());
entity.setReleaseDate(param.getReleaseDate());
entity.setCourtName(param.getCourtName());
entity.setComments(param.getComments());
System.out.println("entity = " + entity);
return entity;
}
}

View File

@@ -1,430 +0,0 @@
package com.gxwebsoft.credit.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditJudiciary;
import com.gxwebsoft.credit.param.CreditJudiciaryImportParam;
import com.gxwebsoft.credit.param.CreditJudiciaryParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditJudiciaryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 司法案件控制器
*
* @author 科技小王子
* @since 2025-12-16 15:23:58
*/
@Tag(name = "司法案件管理")
@RestController
@RequestMapping("/api/credit/credit-judiciary")
public class CreditJudiciaryController extends BaseController {
@Resource
private CreditJudiciaryService creditJudiciaryService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询司法案件")
@GetMapping("/page")
public ApiResult<PageResult<CreditJudiciary>> page(CreditJudiciaryParam param) {
// 使用关联查询
return success(creditJudiciaryService.pageRel(param));
}
@Operation(summary = "查询全部司法案件")
@GetMapping()
public ApiResult<List<CreditJudiciary>> list(CreditJudiciaryParam param) {
// 使用关联查询
return success(creditJudiciaryService.listRel(param));
}
@Operation(summary = "根据id查询司法案件")
@GetMapping("/{id}")
public ApiResult<CreditJudiciary> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditJudiciaryService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@OperationLog
@Operation(summary = "添加司法案件")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditJudiciary creditJudiciary) {
if (creditJudiciaryService.save(creditJudiciary)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:update')")
@OperationLog
@Operation(summary = "修改司法案件")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditJudiciary creditJudiciary) {
if (creditJudiciaryService.updateById(creditJudiciary)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:remove')")
@OperationLog
@Operation(summary = "删除司法案件")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditJudiciary.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@OperationLog
@Operation(summary = "批量添加司法案件")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditJudiciary> list) {
if (creditJudiciaryService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:update')")
@OperationLog
@Operation(summary = "批量修改司法案件")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditJudiciary> batchParam) {
if (batchParam.update(creditJudiciaryService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditJudiciary:remove')")
@OperationLog
@Operation(summary = "批量删除司法案件")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditJudiciary.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditJudiciary:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditJudiciaryService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditJudiciary::getId,
CreditJudiciary::setId,
CreditJudiciary::getName,
CreditJudiciary::getCompanyId,
CreditJudiciary::setCompanyId,
CreditJudiciary::getHasData,
CreditJudiciary::setHasData,
CreditJudiciary::getTenantId,
CreditJudiciary::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入司法案件
*/
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@Operation(summary = "批量导入司法案件")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
// 支持按选项卡名称导入默认读取“司法案件”sheet不存在则回退到第 0 个sheet
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "司法案件", 0);
List<CreditJudiciaryImportParam> list = null;
int usedTitleRows = 0;
int usedHeadRows = 0;
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {0, 2}, {0, 3}};
for (int[] config : tryConfigs) {
list = filterEmptyRows(tryImport(file, config[0], config[1], sheetIndex));
if (!CollectionUtils.isEmpty(list)) {
usedTitleRows = config[0];
usedHeadRows = config[1];
break;
}
}
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// easypoi 默认不会读取单元格超链接地址url 可能挂在“案号/案件名称”等列的超链接中,需要额外读取回填。
Map<String, String> urlByCode = ExcelImportSupport.readHyperlinksByHeaderKey(file, sheetIndex, usedTitleRows, usedHeadRows, "案号");
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, sheetIndex, usedTitleRows, usedHeadRows, "案件名称");
// 有些源文件会单独提供“url/网址/链接”等列(可能是纯文本也可能是超链接)
Map<String, String> urlByCodeFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(file, sheetIndex, usedTitleRows, usedHeadRows, "案号", "url");
if (urlByCodeFromUrlCol.isEmpty()) {
urlByCodeFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(file, sheetIndex, usedTitleRows, usedHeadRows, "案号", "URL");
}
if (urlByCodeFromUrlCol.isEmpty()) {
urlByCodeFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(file, sheetIndex, usedTitleRows, usedHeadRows, "案号", "网址");
}
if (urlByCodeFromUrlCol.isEmpty()) {
urlByCodeFromUrlCol = ExcelImportSupport.readKeyValueByHeaders(file, sheetIndex, usedTitleRows, usedHeadRows, "案号", "链接");
}
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 (!isBlank(item.getCode())) {
String key = item.getCode().trim();
String link = urlByCode.get(key);
if (isBlank(link)) {
link = urlByCodeFromUrlCol.get(key);
}
if (!isBlank(link)) {
item.setUrl(link.trim());
}
} else if (!isBlank(item.getName())) {
String link = urlByName.get(item.getName().trim());
if (!isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
// 设置默认值
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getType() == null) {
item.setType(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
// 验证必填字段
// if (item.getName() == null || item.getName().trim().isEmpty()) {
// errorMessages.add("第" + excelRowNumber + "行:项目名称不能为空");
// continue;
// }
if (item.getCode() == null || item.getCode().trim().isEmpty()) {
errorMessages.add("" + excelRowNumber + "行:唯一标识不能为空");
continue;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditJudiciaryService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditJudiciary::getCode,
"",
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.persistInsertOnlyChunk(
creditJudiciaryService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditJudiciary::getCode,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.JUDICIARY, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载司法案件导入模板
*/
@Operation(summary = "下载司法案件导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditJudiciaryImportParam> templateList = new ArrayList<>();
CreditJudiciaryImportParam example = new CreditJudiciaryImportParam();
example.setName("示例客户");
example.setCode("C0001");
example.setInfoType("执行案件");
example.setReason("买卖合同纠纷");
example.setProcessDate("2025-08-27");
example.setCaseProgress("首次执行");
example.setCaseIdentity("被执行人");
example.setCode("2025闽0103执5480号");
example.setCourt("福建省福州市台江区人民法院");
example.setCaseAmount("5134060.00");
templateList.add(example);
ExportParams exportParams = new ExportParams("司法案件导入模板", "司法案件");
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, CreditJudiciaryImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_judiciary_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private List<CreditJudiciaryImportParam> tryImport(MultipartFile file, int titleRows, int headRows, int sheetIndex) throws Exception {
ImportParams importParams = new ImportParams();
importParams.setTitleRows(titleRows);
importParams.setHeadRows(headRows);
importParams.setStartSheetIndex(sheetIndex);
importParams.setSheetNum(1);
return ExcelImportUtil.importExcel(file.getInputStream(), CreditJudiciaryImportParam.class, importParams);
}
/**
* 过滤掉完全空白的导入行,避免空行导致导入失败
*/
private List<CreditJudiciaryImportParam> filterEmptyRows(List<CreditJudiciaryImportParam> rawList) {
if (CollectionUtils.isEmpty(rawList)) {
return rawList;
}
rawList.removeIf(this::isEmptyImportRow);
return rawList;
}
private boolean isEmptyImportRow(CreditJudiciaryImportParam param) {
if (param == null) {
return true;
}
return isBlank(param.getName())
&& isBlank(param.getCode())
&& isBlank(param.getName())
&& isBlank(param.getInfoType());
}
private boolean isBlank(String value) {
return value == null || value.trim().isEmpty();
}
/**
* 将CreditJudiciaryImportParam转换为CreditJudiciary实体
*/
private CreditJudiciary convertImportParamToEntity(CreditJudiciaryImportParam param) {
CreditJudiciary entity = new CreditJudiciary();
entity.setCode(param.getCode());
entity.setName(param.getName());
entity.setInfoType(param.getInfoType());
entity.setReason(param.getReason());
entity.setProcessDate(param.getProcessDate());
entity.setCaseProgress(param.getCaseProgress());
entity.setCaseIdentity(param.getCaseIdentity());
entity.setCourt(param.getCourt());
entity.setCaseAmount(param.getCaseAmount());
return entity;
}
}

View File

@@ -1,498 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditMediation;
import com.gxwebsoft.credit.param.CreditMediationImportParam;
import com.gxwebsoft.credit.param.CreditMediationParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditMediationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 诉前调解司法大数据控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:25
*/
@Tag(name = "诉前调解司法大数据管理")
@RestController
@RequestMapping("/api/credit/credit-mediation")
public class CreditMediationController extends BaseController {
@Resource
private CreditMediationService creditMediationService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询诉前调解司法大数据")
@GetMapping("/page")
public ApiResult<PageResult<CreditMediation>> page(CreditMediationParam param) {
// 使用关联查询
return success(creditMediationService.pageRel(param));
}
@Operation(summary = "查询全部诉前调解司法大数据")
@GetMapping()
public ApiResult<List<CreditMediation>> list(CreditMediationParam param) {
// 使用关联查询
return success(creditMediationService.listRel(param));
}
@Operation(summary = "根据id查询诉前调解司法大数据")
@GetMapping("/{id}")
public ApiResult<CreditMediation> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditMediationService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@OperationLog
@Operation(summary = "添加诉前调解司法大数据")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditMediation creditMediation) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditMediation.setUserId(loginUser.getUserId());
// }
if (creditMediationService.save(creditMediation)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:update')")
@OperationLog
@Operation(summary = "修改诉前调解司法大数据")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditMediation creditMediation) {
if (creditMediationService.updateById(creditMediation)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:remove')")
@OperationLog
@Operation(summary = "删除诉前调解司法大数据")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditMediation.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@OperationLog
@Operation(summary = "批量添加诉前调解司法大数据")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditMediation> list) {
if (creditMediationService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:update')")
@OperationLog
@Operation(summary = "批量修改诉前调解司法大数据")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditMediation> batchParam) {
if (batchParam.update(creditMediationService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditMediation:remove')")
@OperationLog
@Operation(summary = "批量删除诉前调解司法大数据")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditMediation.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditMediation:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Party columns may contain multiple roles/names; match if any company name is contained in the text.
// Priority: 原告/上诉人 > 被告/被上诉人 > 其他当事人/第三人
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditMediationService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditMediation::getId,
CreditMediation::setId,
CreditMediation::getCompanyId,
CreditMediation::setCompanyId,
CreditMediation::getHasData,
CreditMediation::setHasData,
CreditMediation::getTenantId,
CreditMediation::new,
CreditMediation::getPlaintiffAppellant,
CreditMediation::getAppellee,
CreditMediation::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入诉前调解司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@Operation(summary = "批量导入诉前调解司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "诉前调解", 0);
ExcelImportSupport.ImportResult<CreditMediationImportParam> importResult = ExcelImportSupport.read(
file, CreditMediationImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditMediationImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditMediationImportParam param = list.get(i);
try {
CreditMediation item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String link = urlByCaseNumber.get(item.getCaseNumber().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditMediationService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditMediation::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditMediationService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditMediation::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.MEDIATION, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史诉前调解(仅解析“历史诉前调解”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@Operation(summary = "批量导入历史诉前调解")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史诉前调解");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史诉前调解”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditMediationImportParam> importResult = ExcelImportSupport.read(
file, CreditMediationImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditMediationImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditMediationImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditMediation item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditMediationService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditMediation::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditMediationService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditMediation::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.MEDIATION, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditMediationImportParam> templateList = new ArrayList<>();
CreditMediationImportParam example = new CreditMediationImportParam();
example.setOtherPartiesThirdParty("当事人");
example.setCaseNumber("2024示例案号");
example.setCauseOfAction("案由示例");
example.setCourtName("示例法院");
example.setOccurrenceTime("2024-01-01");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("诉前调解导入模板", "诉前调解", CreditMediationImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_mediation_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditMediationImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber())
&& ImportHelper.isBlank(param.getCauseOfAction());
}
private CreditMediation convertImportParamToEntity(CreditMediationImportParam param) {
CreditMediation entity = new CreditMediation();
// Template compatibility: prefer new columns ("发生时间"/"其他当事人/第三人"), fallback to legacy ones ("立案日期"/"当事人").
String occurrenceTime = !ImportHelper.isBlank(param.getOccurrenceTime2())
? param.getOccurrenceTime2()
: param.getOccurrenceTime();
String otherPartiesThirdParty = !ImportHelper.isBlank(param.getOtherPartiesThirdParty2())
? param.getOtherPartiesThirdParty2()
: param.getOtherPartiesThirdParty();
entity.setOccurrenceTime(occurrenceTime);
entity.setOtherPartiesThirdParty(otherPartiesThirdParty);
entity.setCaseNumber(param.getCaseNumber());
entity.setCauseOfAction(param.getCauseOfAction());
entity.setCourtName(param.getCourtName());
entity.setComments(param.getComments());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setAppellee(param.getAppellee());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setDataStatus(param.getDataStatus());
return entity;
}
}

View File

@@ -1,178 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.credit.service.CreditMpCustomerService;
import com.gxwebsoft.credit.entity.CreditMpCustomer;
import com.gxwebsoft.credit.param.CreditMpCustomerParam;
import com.gxwebsoft.credit.param.BatchFollowStepApprovalDTO;
import com.gxwebsoft.credit.param.EndFollowProcessDTO;
import com.gxwebsoft.credit.param.FollowStepApprovalDTO;
import com.gxwebsoft.credit.param.FollowStepQueryDTO;
import com.gxwebsoft.credit.vo.FollowStatisticsDTO;
import com.gxwebsoft.credit.vo.PendingApprovalStepVO;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 小程序端客户控制器
*
* @author 科技小王子
* @since 2026-03-16 20:59:17
*/
@Tag(name = "小程序端客户管理")
@RestController
@RequestMapping("/api/credit/credit-mp-customer")
public class CreditMpCustomerController extends BaseController {
@Resource
private CreditMpCustomerService creditMpCustomerService;
@PreAuthorize("hasAuthority('credit:creditMpCustomer:list')")
@Operation(summary = "分页查询小程序端客户")
@GetMapping("/page")
public ApiResult<PageResult<CreditMpCustomer>> page(CreditMpCustomerParam param) {
// 使用关联查询
return success(creditMpCustomerService.pageRel(param));
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:list')")
@Operation(summary = "查询全部小程序端客户")
@GetMapping()
public ApiResult<List<CreditMpCustomer>> list(CreditMpCustomerParam param) {
// 使用关联查询
return success(creditMpCustomerService.listRel(param));
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:list')")
@Operation(summary = "根据id查询小程序端客户")
@GetMapping("/{id}")
public ApiResult<CreditMpCustomer> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditMpCustomerService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:save')")
@OperationLog
@Operation(summary = "添加小程序端客户")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditMpCustomer creditMpCustomer) {
// 记录当前登录用户id
User loginUser = getLoginUser();
if (loginUser != null) {
creditMpCustomer.setUserId(loginUser.getUserId());
}
if (creditMpCustomerService.save(creditMpCustomer)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:update')")
@OperationLog
@Operation(summary = "修改小程序端客户")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditMpCustomer creditMpCustomer) {
if (creditMpCustomerService.updateById(creditMpCustomer)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:remove')")
@OperationLog
@Operation(summary = "删除小程序端客户")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (creditMpCustomerService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:save')")
@OperationLog
@Operation(summary = "批量添加小程序端客户")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditMpCustomer> list) {
if (creditMpCustomerService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:update')")
@OperationLog
@Operation(summary = "批量修改小程序端客户")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditMpCustomer> batchParam) {
if (batchParam.update(creditMpCustomerService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:remove')")
@OperationLog
@Operation(summary = "批量删除小程序端客户")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditMpCustomerService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:update')")
@OperationLog
@Operation(summary = "审核跟进步骤")
@PostMapping("/approve-follow-step")
public ApiResult<?> approveFollowStep(@RequestBody FollowStepApprovalDTO dto) {
creditMpCustomerService.approveFollowStep(dto);
return success("审核成功");
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:update')")
@OperationLog
@Operation(summary = "批量审核跟进步骤")
@PostMapping("/batch-approve-follow-steps")
public ApiResult<?> batchApproveFollowSteps(@RequestBody BatchFollowStepApprovalDTO dto) {
creditMpCustomerService.batchApproveFollowSteps(dto);
return success("批量审核成功");
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:list')")
@Operation(summary = "获取待审核的跟进步骤")
@GetMapping("/pending-approval-steps")
public ApiResult<List<PendingApprovalStepVO>> getPendingApprovalSteps(FollowStepQueryDTO query) {
List<PendingApprovalStepVO> list = creditMpCustomerService.getPendingApprovalSteps(query);
return success(list);
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:list')")
@Operation(summary = "获取客户跟进统计")
@GetMapping("/follow-statistics/{customerId}")
public ApiResult<FollowStatisticsDTO> getFollowStatistics(@PathVariable Long customerId) {
FollowStatisticsDTO statistics = creditMpCustomerService.getFollowStatistics(customerId);
return success(statistics);
}
@PreAuthorize("hasAuthority('credit:creditMpCustomer:update')")
@OperationLog
@Operation(summary = "结束客户跟进流程")
@PostMapping("/end-follow-process")
public ApiResult<?> endFollowProcess(@RequestBody EndFollowProcessDTO dto) {
creditMpCustomerService.endFollowProcess(dto);
return success("流程结束成功");
}
}

View File

@@ -1,462 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditNearbyCompany;
import com.gxwebsoft.credit.param.CreditNearbyCompanyImportParam;
import com.gxwebsoft.credit.param.CreditNearbyCompanyParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 附近企业控制器
*
* @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;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@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 (batchImportSupport.hardRemoveById(CreditNearbyCompany.class, 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 (batchImportSupport.hardRemoveByIds(CreditNearbyCompany.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditNearbyCompany:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditNearbyCompanyService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditNearbyCompany::getId,
CreditNearbyCompany::setId,
CreditNearbyCompany::getName,
CreditNearbyCompany::getCompanyId,
CreditNearbyCompany::setCompanyId,
CreditNearbyCompany::setCompanyName,
CreditNearbyCompany::getHasData,
CreditNearbyCompany::setHasData,
CreditNearbyCompany::getTenantId,
CreditNearbyCompany::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入附近企业
*/
@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;
Set<Integer> touchedCompanyIds = new HashSet<>();
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, "企业名称");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : null;
}
// 避免逐行写库:按批处理,显著降低 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 (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.NEARBY_COMPANY, touchedCompanyIds);
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.persistInsertOnlyChunk(
creditNearbyCompanyService,
items,
excelRowNumbers,
mpBatchSize,
it -> {
if (it == null) {
return null;
}
String code = it.getCode();
if (code != null && !code.trim().isEmpty()) {
return code;
}
return it.getName();
},
"",
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.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.setTaxpayerCode(param.getTaxpayerCode());
entity.setRegistrationNumber(param.getRegistrationNumber());
entity.setOrganizationalCode(param.getOrganizationalCode());
entity.setNumberOfInsuredPersons(param.getNumberOfInsuredPersons());
entity.setAnnualReport(param.getAnnualReport());
entity.setDomain(param.getDomain());
entity.setBusinessTerm(param.getBusinessTerm());
entity.setNationalStandardIndustryCategories(param.getNationalStandardIndustryCategories());
entity.setNationalStandardIndustryCategories2(param.getNationalStandardIndustryCategories2());
entity.setNationalStandardIndustryCategories3(param.getNationalStandardIndustryCategories3());
entity.setNationalStandardIndustryCategories4(param.getNationalStandardIndustryCategories4());
entity.setFormerName(param.getFormerName());
entity.setEnglishName(param.getEnglishName());
entity.setMailingAddress(param.getMailingAddress());
entity.setMailingEmail(param.getMailingEmail());
entity.setTel(param.getTel());
entity.setPostalCode(param.getPostalCode());
entity.setNationalStandardIndustryCategories5(param.getNationalStandardIndustryCategories5());
entity.setNationalStandardIndustryCategories6(param.getNationalStandardIndustryCategories6());
entity.setNationalStandardIndustryCategories7(param.getNationalStandardIndustryCategories7());
entity.setNationalStandardIndustryCategories8(param.getNationalStandardIndustryCategories8());
entity.setType(param.getType());
entity.setInstitutionType(param.getInstitutionType());
entity.setCompanySize(param.getCompanySize());
entity.setCompanyProfile(param.getCompanyProfile());
entity.setNatureOfBusiness(param.getNatureOfBusiness());
entity.setComments(param.getComments());
entity.setMoreEmail(param.getMoreEmail());
entity.setMoreTel(param.getMoreTel());
return entity;
}
}

View File

@@ -1,395 +0,0 @@
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.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 专利控制器
*
* @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;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@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 (batchImportSupport.hardRemoveById(CreditPatent.class, 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 (batchImportSupport.hardRemoveByIds(CreditPatent.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditPatent:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditPatentService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditPatent::getId,
CreditPatent::setId,
CreditPatent::getPatentApplicant,
CreditPatent::getCompanyId,
CreditPatent::setCompanyId,
CreditPatent::getHasData,
CreditPatent::setHasData,
CreditPatent::getTenantId,
CreditPatent::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入专利
*/
@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;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
// 单企业表通常是多 sheet专利页签名一般为“专利”
int preferredSheetIndex = ExcelImportSupport.findSheetIndex(file, "专利", 0);
ExcelImportSupport.ImportResult<CreditPatentImportParam> importResult = ExcelImportSupport.read(
file, CreditPatentImportParam.class, this::isEmptyImportRow, preferredSheetIndex);
if (CollectionUtils.isEmpty(importResult.getData())) {
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditPatentService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditPatent::getRegisterNo,
"",
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.persistInsertOnlyChunk(
creditPatentService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditPatent::getRegisterNo,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.PATENT, touchedCompanyIds);
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.getName())
&& ImportHelper.isBlank(param.getType())
&& ImportHelper.isBlank(param.getStatusText())
&& ImportHelper.isBlank(param.getRegisterNo())
&& ImportHelper.isBlank(param.getRegisterDate())
&& ImportHelper.isBlank(param.getPublicNo())
&& ImportHelper.isBlank(param.getPublicDate())
&& ImportHelper.isBlank(param.getInventor())
&& ImportHelper.isBlank(param.getPatentApplicant())
&& ImportHelper.isBlank(param.getComments());
}
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

@@ -1,359 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditRiskRelation;
import com.gxwebsoft.credit.param.CreditRiskRelationImportParam;
import com.gxwebsoft.credit.param.CreditRiskRelationParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditRiskRelationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 风险关系表控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:41
*/
@Tag(name = "风险关系表管理")
@RestController
@RequestMapping("/api/credit/credit-risk-relation")
public class CreditRiskRelationController extends BaseController {
@Resource
private CreditRiskRelationService creditRiskRelationService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询风险关系表")
@GetMapping("/page")
public ApiResult<PageResult<CreditRiskRelation>> page(CreditRiskRelationParam param) {
// 使用关联查询
return success(creditRiskRelationService.pageRel(param));
}
@Operation(summary = "查询全部风险关系表")
@GetMapping()
public ApiResult<List<CreditRiskRelation>> list(CreditRiskRelationParam param) {
// 使用关联查询
return success(creditRiskRelationService.listRel(param));
}
@Operation(summary = "根据id查询风险关系表")
@GetMapping("/{id}")
public ApiResult<CreditRiskRelation> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditRiskRelationService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:save')")
@OperationLog
@Operation(summary = "添加风险关系表")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditRiskRelation creditRiskRelation) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditRiskRelation.setUserId(loginUser.getUserId());
// }
if (creditRiskRelationService.save(creditRiskRelation)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:update')")
@OperationLog
@Operation(summary = "修改风险关系表")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditRiskRelation creditRiskRelation) {
if (creditRiskRelationService.updateById(creditRiskRelation)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:remove')")
@OperationLog
@Operation(summary = "删除风险关系表")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditRiskRelation.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:save')")
@OperationLog
@Operation(summary = "批量添加风险关系表")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditRiskRelation> list) {
if (creditRiskRelationService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:update')")
@OperationLog
@Operation(summary = "批量修改风险关系表")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditRiskRelation> batchParam) {
if (batchParam.update(creditRiskRelationService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditRiskRelation:remove')")
@OperationLog
@Operation(summary = "批量删除风险关系表")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditRiskRelation.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditRiskRelation:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditRiskRelationService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditRiskRelation::getId,
CreditRiskRelation::setId,
CreditRiskRelation::getMainBodyName,
CreditRiskRelation::getCompanyId,
CreditRiskRelation::setCompanyId,
CreditRiskRelation::setCompanyName,
CreditRiskRelation::getHasData,
CreditRiskRelation::setHasData,
CreditRiskRelation::getTenantId,
CreditRiskRelation::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入风险关系表
*/
@PreAuthorize("hasAuthority('credit:creditRiskRelation:save')")
@Operation(summary = "批量导入风险关系表")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "风险关系", 1);
ExcelImportSupport.ImportResult<CreditRiskRelationImportParam> importResult = ExcelImportSupport.read(
file, CreditRiskRelationImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditRiskRelationImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : 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 (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getMainBodyName())) {
errorMessages.add("" + excelRowNumber + "行:主体名称不能为空");
continue;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditRiskRelationService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditRiskRelation::getMainBodyName,
"",
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.persistInsertOnlyChunk(
creditRiskRelationService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditRiskRelation::getMainBodyName,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.RISK_RELATION, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载风险关系导入模板
*/
@Operation(summary = "下载风险关系导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditRiskRelationImportParam> templateList = new ArrayList<>();
CreditRiskRelationImportParam example = new CreditRiskRelationImportParam();
example.setMainBodyName("示例企业");
example.setRegistrationStatus("存续");
example.setRegisteredCapital("8000");
example.setProvinceRegion("浙江");
example.setAssociatedRelation("关联企业");
example.setRiskRelation("存在风险关联");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("风险关系导入模板", "风险关系", CreditRiskRelationImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_risk_relation_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditRiskRelationImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getMainBodyName())
&& ImportHelper.isBlank(param.getRegistrationStatus())
&& ImportHelper.isBlank(param.getRegisteredCapital());
}
private CreditRiskRelation convertImportParamToEntity(CreditRiskRelationImportParam param) {
CreditRiskRelation entity = new CreditRiskRelation();
entity.setMainBodyName(param.getMainBodyName());
entity.setRegistrationStatus(param.getRegistrationStatus());
entity.setRegisteredCapital(param.getRegisteredCapital());
entity.setProvinceRegion(param.getProvinceRegion());
entity.setAssociatedRelation(param.getAssociatedRelation());
entity.setRiskRelation(param.getRiskRelation());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,365 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditSupplier;
import com.gxwebsoft.credit.param.CreditSupplierImportParam;
import com.gxwebsoft.credit.param.CreditSupplierParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditSupplierService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 供应商控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:47
*/
@Tag(name = "供应商管理")
@RestController
@RequestMapping("/api/credit/credit-supplier")
public class CreditSupplierController extends BaseController {
@Resource
private CreditSupplierService creditSupplierService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询供应商")
@GetMapping("/page")
public ApiResult<PageResult<CreditSupplier>> page(CreditSupplierParam param) {
// 使用关联查询
return success(creditSupplierService.pageRel(param));
}
@Operation(summary = "查询全部供应商")
@GetMapping()
public ApiResult<List<CreditSupplier>> list(CreditSupplierParam param) {
// 使用关联查询
return success(creditSupplierService.listRel(param));
}
@Operation(summary = "根据id查询供应商")
@GetMapping("/{id}")
public ApiResult<CreditSupplier> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditSupplierService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditSupplier:save')")
@OperationLog
@Operation(summary = "添加供应商")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditSupplier creditSupplier) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditSupplier.setUserId(loginUser.getUserId());
// }
if (creditSupplierService.save(creditSupplier)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:update')")
@OperationLog
@Operation(summary = "修改供应商")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditSupplier creditSupplier) {
if (creditSupplierService.updateById(creditSupplier)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:remove')")
@OperationLog
@Operation(summary = "删除供应商")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditSupplier.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:save')")
@OperationLog
@Operation(summary = "批量添加供应商")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditSupplier> list) {
if (creditSupplierService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:update')")
@OperationLog
@Operation(summary = "批量修改供应商")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditSupplier> batchParam) {
if (batchParam.update(creditSupplierService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditSupplier:remove')")
@OperationLog
@Operation(summary = "批量删除供应商")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditSupplier.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditSupplier:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditSupplierService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditSupplier::getId,
CreditSupplier::setId,
CreditSupplier::getSupplier,
CreditSupplier::getCompanyId,
CreditSupplier::setCompanyId,
CreditSupplier::setCompanyName,
CreditSupplier::getHasData,
CreditSupplier::setHasData,
CreditSupplier::getTenantId,
CreditSupplier::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入供应商
*/
@PreAuthorize("hasAuthority('credit:creditSupplier:save')")
@Operation(summary = "批量导入供应商")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "供应商", 3);
ExcelImportSupport.ImportResult<CreditSupplierImportParam> importResult = ExcelImportSupport.read(
file, CreditSupplierImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditSupplierImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
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> urlBySupplier = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "供应商");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : 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 (!ImportHelper.isBlank(item.getSupplier())) {
String link = urlBySupplier.get(item.getSupplier().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
if (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getSupplier())) {
errorMessages.add("" + excelRowNumber + "行:供应商不能为空");
continue;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditSupplierService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditSupplier::getSupplier,
"",
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.persistInsertOnlyChunk(
creditSupplierService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditSupplier::getSupplier,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.SUPPLIER, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 下载供应商导入模板
*/
@Operation(summary = "下载供应商导入模板")
@GetMapping("/import/template")
public void downloadTemplate(HttpServletResponse response) throws IOException {
List<CreditSupplierImportParam> templateList = new ArrayList<>();
CreditSupplierImportParam example = new CreditSupplierImportParam();
example.setSupplier("示例供应商");
example.setStatusTxt("合作中");
example.setPurchaseAmount("120");
example.setPublicDate("2024-02-01");
example.setDataSource("公开渠道");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("供应商导入模板", "供应商", CreditSupplierImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_supplier_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditSupplierImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getSupplier())
&& ImportHelper.isBlank(param.getStatusTxt())
&& ImportHelper.isBlank(param.getPurchaseAmount());
}
private CreditSupplier convertImportParamToEntity(CreditSupplierImportParam param) {
CreditSupplier entity = new CreditSupplier();
entity.setSupplier(param.getSupplier());
entity.setStatusTxt(param.getStatusTxt());
entity.setPurchaseAmount(param.getPurchaseAmount());
entity.setPublicDate(param.getPublicDate());
entity.setDataSource(param.getDataSource());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,422 +0,0 @@
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.CreditCompany;
import com.gxwebsoft.credit.entity.CreditSuspectedRelationship;
import com.gxwebsoft.credit.param.CreditSuspectedRelationshipImportParam;
import com.gxwebsoft.credit.param.CreditSuspectedRelationshipParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 疑似关系控制器
*
* @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;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@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 (batchImportSupport.hardRemoveById(CreditSuspectedRelationship.class, 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 (batchImportSupport.hardRemoveByIds(CreditSuspectedRelationship.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditSuspectedRelationship:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditSuspectedRelationshipService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditSuspectedRelationship::getId,
CreditSuspectedRelationship::setId,
CreditSuspectedRelationship::getName,
CreditSuspectedRelationship::getCompanyId,
CreditSuspectedRelationship::setCompanyId,
CreditSuspectedRelationship::setCompanyName,
CreditSuspectedRelationship::getHasData,
CreditSuspectedRelationship::setHasData,
CreditSuspectedRelationship::getTenantId,
CreditSuspectedRelationship::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入疑似关系
*/
@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;
Set<Integer> touchedCompanyIds = new HashSet<>();
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, "企业名称");
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : null;
}
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 (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditSuspectedRelationshipService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
it -> {
if (it == null) {
return null;
}
String n = it.getName();
String r = it.getRelatedParty();
if (n != null) {
n = n.trim();
}
if (r != null) {
r = r.trim();
}
if (n != null && !n.isEmpty() && r != null && !r.isEmpty()) {
return n + "->" + r;
}
return n;
},
"",
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.persistInsertOnlyChunk(
creditSuspectedRelationshipService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
it -> {
if (it == null) {
return null;
}
String n = it.getName();
String r = it.getRelatedParty();
if (n != null) {
n = n.trim();
}
if (r != null) {
r = r.trim();
}
if (n != null && !n.isEmpty() && r != null && !r.isEmpty()) {
return n + "->" + r;
}
return n;
},
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.SUSPECTED_RELATIONSHIP, touchedCompanyIds);
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

@@ -1,453 +0,0 @@
package com.gxwebsoft.credit.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditCompany;
import com.gxwebsoft.credit.entity.CreditUser;
import com.gxwebsoft.credit.param.CreditUserImportParam;
import com.gxwebsoft.credit.param.CreditUserParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.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.io.InputStream;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 招投标信息表控制器
*
* @author 科技小王子
* @since 2025-12-15 13:16:04
*/
@Tag(name = "招投标信息表管理")
@RestController
@RequestMapping("/api/credit/credit-user")
public class CreditUserController extends BaseController {
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Resource
private CreditUserService creditUserService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询招投标信息表")
@GetMapping("/page")
public ApiResult<PageResult<CreditUser>> page(CreditUserParam param) {
// 使用关联查询
return success(creditUserService.pageRel(param));
}
@Operation(summary = "查询全部招投标信息表")
@GetMapping()
public ApiResult<List<CreditUser>> list(CreditUserParam param) {
// 使用关联查询
return success(creditUserService.listRel(param));
}
@Operation(summary = "根据id查询招投标信息表")
@GetMapping("/{id}")
public ApiResult<CreditUser> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditUserService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditUser:save')")
@OperationLog
@Operation(summary = "添加招投标信息表")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditUser creditUser) {
if (creditUserService.save(creditUser)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditUser:update')")
@OperationLog
@Operation(summary = "修改招投标信息表")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditUser creditUser) {
if (creditUserService.updateById(creditUser)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditUser:remove')")
@OperationLog
@Operation(summary = "删除招投标信息表")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditUser.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditUser:save')")
@OperationLog
@Operation(summary = "批量添加招投标信息表")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditUser> list) {
if (creditUserService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditUser:update')")
@OperationLog
@Operation(summary = "批量修改招投标信息表")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditUser> batchParam) {
if (batchParam.update(creditUserService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditUser:remove')")
@OperationLog
@Operation(summary = "批量删除招投标信息表")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditUser.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditUser:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditUserService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditUser::getId,
CreditUser::setId,
CreditUser::getWinningName,
CreditUser::getCompanyId,
CreditUser::setCompanyId,
CreditUser::setCompanyName,
CreditUser::getHasData,
CreditUser::setHasData,
CreditUser::getTenantId,
CreditUser::new
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入招投标信息
* Excel表头格式客户名称、唯一标识、类型、企业角色、上级ID、信息类型、所在国家、所在省份、所在城市、所在辖区、街道地址、招采单位名称、中标单位名称、中标金额、备注、是否推荐、到期时间、排序、状态、用户ID、租户ID
*/
@PreAuthorize("hasAuthority('credit:creditUser: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;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "招投标", 0);
ExcelImportSupport.ImportResult<CreditUserImportParam> importResult =
ExcelImportSupport.read(file, CreditUserImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditUserImportParam> 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;
Map<Integer, String> urlMap = readNameHyperlinks(file, sheetIndex, usedTitleRows, usedHeadRows);
String fixedCompanyName = null;
if (companyId != null && companyId > 0) {
CreditCompany fixedCompany = creditCompanyService.getById(companyId);
fixedCompanyName = fixedCompany != null ? fixedCompany.getName() : null;
}
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditUser> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditUserImportParam param = list.get(i);
try {
CreditUser item = convertImportParamToEntity(param);
String link = urlMap.get(i);
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
if (ImportHelper.isBlank(item.getCompanyName()) && !ImportHelper.isBlank(fixedCompanyName)) {
item.setCompanyName(fixedCompanyName);
}
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
// 设置默认值
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getType() == null) {
item.setType(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
// 验证必填字段
if (item.getName() == null || item.getName().trim().isEmpty()) {
errorMessages.add("" + excelRowNumber + "行:项目名称不能为空");
continue;
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditUserService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditUser::getName,
"",
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.persistInsertOnlyChunk(
creditUserService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditUser::getName,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.USER, touchedCompanyIds);
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<CreditUserImportParam> templateList = new ArrayList<>();
CreditUserImportParam example = new CreditUserImportParam();
example.setCode("CUS001");
example.setName("示例客户");
example.setReleaseDate("2023-01-01");
example.setType(0);
example.setRole("采购方");
example.setInfoType("企业");
example.setAddress("广东省-广州市-南沙区");
example.setProcurementName("示例招采单位");
example.setWinningName("示例中标单位");
example.setWinningPrice("100000");
templateList.add(example);
ExportParams exportParams = new ExportParams("招投标信息导入模板", "招投标信息");
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, CreditUserImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_user_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
/**
* 读取“项目名称”列的超链接,按数据行顺序返回。
*/
private Map<Integer, String> readNameHyperlinks(MultipartFile file, int sheetIndex, int titleRows, int headRows) throws Exception {
Map<Integer, String> result = new HashMap<>();
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
if (sheet == null) {
return result;
}
int headerRowNum = titleRows + headRows - 1;
Row headerRow = sheet.getRow(headerRowNum);
int nameColIndex = 0;
if (headerRow != null) {
for (int c = headerRow.getFirstCellNum(); c < headerRow.getLastCellNum(); c++) {
Cell cell = headerRow.getCell(c);
if (cell != null && "项目名称".equals(normalizeHeaderText(cell.getStringCellValue()))) {
nameColIndex = c;
break;
}
}
}
int dataStartRow = titleRows + headRows;
for (int r = dataStartRow; r <= sheet.getLastRowNum(); r++) {
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
Cell cell = row.getCell(nameColIndex);
if (cell != null && cell.getHyperlink() != null) {
String address = cell.getHyperlink().getAddress();
if (address != null && !address.isEmpty()) {
result.put(r - dataStartRow, address);
}
}
}
}
return result;
}
/**
* 用于表头匹配:仅做最常见的空白字符规整(避免表头中存在换行/空格导致无法定位列)。
*/
private static String normalizeHeaderText(String text) {
if (text == null) {
return "";
}
return text
.replace(" ", "")
.replace("\t", "")
.replace("\r", "")
.replace("\n", "")
.replace("\u00A0", "")
.replace(" ", "")
.trim();
}
private boolean isEmptyImportRow(CreditUserImportParam param) {
if (param == null) {
return true;
}
return isBlank(param.getName())
&& isBlank(param.getCode())
&& isBlank(param.getRole())
&& isBlank(param.getInfoType())
&& isBlank(param.getAddress())
&& isBlank(param.getProcurementName())
&& isBlank(param.getWinningName())
&& isBlank(param.getWinningPrice());
}
private boolean isBlank(String value) {
return value == null || value.trim().isEmpty();
}
/**
* 将CreditUserImportParam转换为CreditUser实体
*/
private CreditUser convertImportParamToEntity(CreditUserImportParam param) {
CreditUser entity = new CreditUser();
entity.setCode(param.getCode());
entity.setName(param.getName());
entity.setReleaseDate(param.getReleaseDate());
entity.setType(param.getType());
entity.setRole(param.getRole());
entity.setInfoType(param.getInfoType());
entity.setAddress(param.getAddress());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setProcurementName(param.getProcurementName());
entity.setWinningName(param.getWinningName());
entity.setWinningPrice(param.getWinningPrice());
return entity;
}
}

View File

@@ -1,510 +0,0 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.credit.entity.CreditXgxf;
import com.gxwebsoft.credit.param.CreditXgxfImportParam;
import com.gxwebsoft.credit.param.CreditXgxfParam;
import com.gxwebsoft.credit.service.CreditCompanyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
import com.gxwebsoft.credit.service.CreditXgxfService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 限制高消费控制器
*
* @author 科技小王子
* @since 2025-12-19 19:51:55
*/
@Tag(name = "限制高消费管理")
@RestController
@RequestMapping("/api/credit/credit-xgxf")
public class CreditXgxfController extends BaseController {
@Resource
private CreditXgxfService creditXgxfService;
@Resource
private BatchImportSupport batchImportSupport;
@Resource
private CreditCompanyService creditCompanyService;
@Resource
private CreditCompanyRecordCountService creditCompanyRecordCountService;
@Operation(summary = "分页查询限制高消费")
@GetMapping("/page")
public ApiResult<PageResult<CreditXgxf>> page(CreditXgxfParam param) {
// 使用关联查询
return success(creditXgxfService.pageRel(param));
}
@Operation(summary = "查询全部限制高消费")
@GetMapping()
public ApiResult<List<CreditXgxf>> list(CreditXgxfParam param) {
// 使用关联查询
return success(creditXgxfService.listRel(param));
}
@Operation(summary = "根据id查询限制高消费")
@GetMapping("/{id}")
public ApiResult<CreditXgxf> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(creditXgxfService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@OperationLog
@Operation(summary = "添加限制高消费")
@PostMapping()
public ApiResult<?> save(@RequestBody CreditXgxf creditXgxf) {
// 记录当前登录用户id
// User loginUser = getLoginUser();
// if (loginUser != null) {
// creditXgxf.setUserId(loginUser.getUserId());
// }
if (creditXgxfService.save(creditXgxf)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:update')")
@OperationLog
@Operation(summary = "修改限制高消费")
@PutMapping()
public ApiResult<?> update(@RequestBody CreditXgxf creditXgxf) {
if (creditXgxfService.updateById(creditXgxf)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:remove')")
@OperationLog
@Operation(summary = "删除限制高消费")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (batchImportSupport.hardRemoveById(CreditXgxf.class, id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@OperationLog
@Operation(summary = "批量添加限制高消费")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditXgxf> list) {
if (creditXgxfService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:update')")
@OperationLog
@Operation(summary = "批量修改限制高消费")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditXgxf> batchParam) {
if (batchParam.update(creditXgxfService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditXgxf:remove')")
@OperationLog
@Operation(summary = "批量删除限制高消费")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (batchImportSupport.hardRemoveByIds(CreditXgxf.class, ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 companyId匹配 CreditCompany.name / CreditCompany.matchName
*
* <p>默认仅更新 companyId=0 的记录;如需覆盖更新,传 onlyNull=false。</p>
*/
@PreAuthorize("hasAuthority('credit:creditXgxf:update')")
@OperationLog
@Operation(summary = "根据企业名称匹配并更新companyId")
@PostMapping("/company-id/refresh")
public ApiResult<Map<String, Object>> refreshCompanyIdByCompanyName(
@RequestParam(value = "onlyNull", required = false, defaultValue = "true") Boolean onlyNull,
@RequestParam(value = "limit", required = false) Integer limit
) {
User loginUser = getLoginUser();
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
// Party columns may contain multiple roles/names; match if any company name is contained in the text.
// Priority: 原告/上诉人 > 被告/被上诉人 > 其他当事人/第三人
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyNameContainedInText(
creditXgxfService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditXgxf::getId,
CreditXgxf::setId,
CreditXgxf::getCompanyId,
CreditXgxf::setCompanyId,
CreditXgxf::getHasData,
CreditXgxf::setHasData,
CreditXgxf::getTenantId,
CreditXgxf::new,
CreditXgxf::getPlaintiffAppellant,
CreditXgxf::getAppellee,
CreditXgxf::getOtherPartiesThirdParty
);
if (!stats.anyDataRead) {
return success("无可更新数据", stats.toMap());
}
return success("更新完成,更新" + stats.updated + "", stats.toMap());
}
/**
* 批量导入限制高消费司法大数据
*/
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@Operation(summary = "批量导入限制高消费司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "限制高消费", 0);
ExcelImportSupport.ImportResult<CreditXgxfImportParam> importResult = ExcelImportSupport.read(
file, CreditXgxfImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditXgxfImportParam> 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;
// easypoi 默认不会读取单元格超链接地址url 可能挂在“案号”等列的超链接中,或单独提供 url/网址/链接 列。
Map<String, String> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditXgxfImportParam param = list.get(i);
try {
CreditXgxf item = convertImportParamToEntity(param);
if (!ImportHelper.isBlank(item.getCaseNumber())) {
String link = urlByCaseNumber.get(item.getCaseNumber().trim());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
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;
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditXgxfService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditXgxf::getCaseNumber,
"",
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.persistInsertOnlyChunk(
creditXgxfService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditXgxf::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.XGXF, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
} else {
return success("导入完成,成功" + successCount + "条,失败" + errorMessages.size() + "", errorMessages);
}
} catch (Exception e) {
e.printStackTrace();
return fail("导入失败:" + e.getMessage(), null);
}
}
/**
* 批量导入历史限制高消费(仅解析“历史限制高消费”选项卡)
* 规则:使用数据库唯一索引约束,重复数据不导入。
*/
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@Operation(summary = "批量导入历史限制高消费司法大数据")
@PostMapping("/import/history")
public ApiResult<List<String>> importHistoryBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
Set<Integer> touchedCompanyIds = new HashSet<>();
try {
int sheetIndex = ExcelImportSupport.findSheetIndex(file, "历史限制高消费");
if (sheetIndex < 0) {
return fail("未读取到数据,请确认文件中存在“历史限制高消费”选项卡且表头与示例格式一致", null);
}
ExcelImportSupport.ImportResult<CreditXgxfImportParam> importResult = ExcelImportSupport.read(
file, CreditXgxfImportParam.class, this::isEmptyImportRow, sheetIndex);
List<CreditXgxfImportParam> 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> urlByCaseNumber = ExcelImportSupport.readUrlByKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "案号");
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++) {
CreditXgxfImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditXgxf item = convertImportParamToEntity(param);
if (item.getCaseNumber() != null) {
item.setCaseNumber(item.getCaseNumber().trim());
}
if (ImportHelper.isBlank(item.getCaseNumber())) {
errorMessages.add("" + excelRowNumber + "行:案号不能为空");
continue;
}
String link = urlByCaseNumber.get(item.getCaseNumber());
if (!ImportHelper.isBlank(link)) {
item.setUrl(link.trim());
}
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.getDeleted() == null) {
item.setDeleted(0);
}
// 历史导入的数据统一标记为“失效”
item.setDataStatus("失效");
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getCompanyId() != null && item.getCompanyId() > 0) {
touchedCompanyIds.add(item.getCompanyId());
}
chunkItems.add(item);
chunkRowNumbers.add(excelRowNumber);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditXgxfService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditXgxf::getCaseNumber,
"",
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistInsertOnlyChunk(
creditXgxfService,
chunkItems,
chunkRowNumbers,
mpBatchSize,
CreditXgxf::getCaseNumber,
"",
errorMessages
);
}
creditCompanyRecordCountService.refresh(CreditCompanyRecordCountService.CountType.XGXF, touchedCompanyIds);
if (errorMessages.isEmpty()) {
return success("成功导入" + successCount + "条数据", null);
}
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<CreditXgxfImportParam> templateList = new ArrayList<>();
CreditXgxfImportParam example = new CreditXgxfImportParam();
example.setDataType("限制高消费");
example.setPlaintiffAppellant("原告示例");
example.setAppellee("被告示例");
example.setOccurrenceTime("2024-01-01");
example.setCaseNumber("2024示例案号");
example.setInvolvedAmount("100000");
example.setCourtName("示例法院");
example.setComments("备注信息");
templateList.add(example);
Workbook workbook = ExcelImportSupport.buildTemplate("限制高消费导入模板", "限制高消费", CreditXgxfImportParam.class, templateList);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=credit_xgxf_import_template.xlsx");
workbook.write(response.getOutputStream());
workbook.close();
}
private boolean isEmptyImportRow(CreditXgxfImportParam param) {
if (param == null) {
return true;
}
return ImportHelper.isBlank(param.getCaseNumber());
}
private CreditXgxf convertImportParamToEntity(CreditXgxfImportParam param) {
CreditXgxf entity = new CreditXgxf();
// Template compatibility: some upstream multi-company exports use alternate headers for the same columns.
String plaintiffAppellant = !ImportHelper.isBlank(param.getPlaintiffAppellant())
? param.getPlaintiffAppellant()
: param.getPlaintiffAppellant2();
String appellee = !ImportHelper.isBlank(param.getAppellee())
? param.getAppellee()
: param.getDataType();
String courtName = !ImportHelper.isBlank(param.getCourtName())
? param.getCourtName()
: param.getCourtName2();
entity.setCaseNumber(param.getCaseNumber());
entity.setType(param.getType());
entity.setDataType(param.getDataType());
entity.setPlaintiffAppellant(plaintiffAppellant);
entity.setAppellee(appellee);
entity.setOtherPartiesThirdParty(param.getOtherPartiesThirdParty());
entity.setDataStatus(param.getDataStatus());
entity.setInvolvedAmount(param.getInvolvedAmount());
entity.setOccurrenceTime(param.getOccurrenceTime());
entity.setCourtName(courtName);
entity.setReleaseDate(param.getReleaseDate());
entity.setComments(param.getComments());
return entity;
}
}

View File

@@ -1,719 +0,0 @@
package com.gxwebsoft.credit.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.gxwebsoft.credit.excel.ExcelHeaderAlias;
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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
/**
* Excel 导入导出通用支持
*/
public class ExcelImportSupport {
public static class ImportResult<T> {
private final List<T> data;
private final int titleRows;
private final int headRows;
private final int sheetIndex;
public ImportResult(List<T> data, int titleRows, int headRows) {
this(data, titleRows, headRows, 0);
}
public ImportResult(List<T> data, int titleRows, int headRows, int sheetIndex) {
this.data = data;
this.titleRows = titleRows;
this.headRows = headRows;
this.sheetIndex = sheetIndex;
}
public List<T> getData() {
return data;
}
public int getTitleRows() {
return titleRows;
}
public int getHeadRows() {
return headRows;
}
public int getSheetIndex() {
return sheetIndex;
}
}
public static <T> ImportResult<T> read(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate) throws Exception {
return read(file, clazz, emptyRowPredicate, 0);
}
/**
* 自动尝试所有 sheet从第 0 个开始),直到读取到非空数据。
*/
public static <T> ImportResult<T> readAnySheet(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate) throws Exception {
ImportResult<T> result = read(file, clazz, emptyRowPredicate, 0);
if (!CollectionUtils.isEmpty(result.getData())) {
return result;
}
int sheetCount = getSheetCount(file);
for (int i = 1; i < sheetCount; i++) {
ImportResult<T> sheetResult = read(file, clazz, emptyRowPredicate, i);
if (!CollectionUtils.isEmpty(sheetResult.getData())) {
return sheetResult;
}
}
return result;
}
/**
* 自动尝试所有 sheet从第 0 个开始),并在每个 sheet 内选择“得分”最高的表头配置。
*/
public static <T> ImportResult<T> readAnySheetBest(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate, Predicate<T> scoreRowPredicate) throws Exception {
ImportResult<T> result = readBest(file, clazz, emptyRowPredicate, scoreRowPredicate, 0);
if (!CollectionUtils.isEmpty(result.getData())) {
return result;
}
int sheetCount = getSheetCount(file);
for (int i = 1; i < sheetCount; i++) {
ImportResult<T> sheetResult = readBest(file, clazz, emptyRowPredicate, scoreRowPredicate, i);
if (!CollectionUtils.isEmpty(sheetResult.getData())) {
return sheetResult;
}
}
return result;
}
/**
* 读取指定 sheet 的 Excel。
*
* @param sheetIndex 目标 sheet 下标,从 0 开始。第二个选项卡传 1。
*/
public static <T> ImportResult<T> read(MultipartFile file, Class<T> clazz, Predicate<T> emptyRowPredicate, int sheetIndex) throws Exception {
List<T> list = null;
int usedTitleRows = 0;
int usedHeadRows = 0;
int[][] tryConfigs = new int[][]{{1, 1}, {0, 1}, {2, 1}, {3, 1}, {0, 2}, {0, 3}, {0, 4}};
Exception lastFailure = null;
boolean anyImported = false;
for (int[] config : tryConfigs) {
try {
list = filterEmptyRows(importSheet(file, clazz, config[0], config[1], sheetIndex), emptyRowPredicate);
anyImported = true;
} catch (Exception e) {
// Some source files can trigger easypoi/POI runtime exceptions for certain title/head row combinations.
// Keep trying other configurations instead of failing the whole import.
lastFailure = e;
continue;
}
if (!CollectionUtils.isEmpty(list)) {
usedTitleRows = config[0];
usedHeadRows = config[1];
break;
}
}
// Fallback for upstream files with extra banner/title rows or wider multi-row headers.
// Keep the default fast path above for common templates.
if (CollectionUtils.isEmpty(list)) {
final int maxTitleRows = 10;
final int maxHeadRows = 6;
outer:
for (int titleRows = 0; titleRows <= maxTitleRows; titleRows++) {
for (int headRows = 1; headRows <= maxHeadRows; headRows++) {
try {
list = filterEmptyRows(importSheet(file, clazz, titleRows, headRows, sheetIndex), emptyRowPredicate);
anyImported = true;
} catch (Exception e) {
lastFailure = e;
continue;
}
if (!CollectionUtils.isEmpty(list)) {
usedTitleRows = titleRows;
usedHeadRows = headRows;
break outer;
}
}
}
}
if (list == null) {
if (!anyImported && lastFailure != null) {
throw lastFailure;
}
list = Collections.emptyList();
}
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;
Exception lastFailure = null;
boolean anyImported = false;
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;
try {
list = filterEmptyRows(importSheet(file, clazz, config[0], config[1], sheetIndex), emptyRowPredicate);
anyImported = true;
} catch (Exception e) {
lastFailure = e;
continue;
}
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;
}
}
// Fallback scan: broaden the search space for messy source files (extra title rows, multi-row headers).
if (bestList == null) {
final int maxTitleRows = 10;
final int maxHeadRows = 6;
for (int titleRows = 0; titleRows <= maxTitleRows; titleRows++) {
for (int headRows = 1; headRows <= maxHeadRows; headRows++) {
List<T> list;
try {
list = filterEmptyRows(importSheet(file, clazz, titleRows, headRows, sheetIndex), emptyRowPredicate);
anyImported = true;
} catch (Exception e) {
lastFailure = e;
continue;
}
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 = titleRows;
bestHeadRows = headRows;
bestScore = score;
bestSize = size;
}
}
}
}
if (bestList != null) {
return new ImportResult<>(bestList, bestTitleRows, bestHeadRows, sheetIndex);
}
if (!anyImported && lastFailure != null) {
throw lastFailure;
}
return read(file, clazz, emptyRowPredicate, sheetIndex);
}
private static <T> List<T> importSheet(MultipartFile file, Class<T> clazz, int titleRows, int headRows, int sheetIndex) throws Exception {
ImportParams importParams = new ImportParams();
importParams.setTitleRows(titleRows);
importParams.setHeadRows(headRows);
importParams.setStartSheetIndex(sheetIndex);
importParams.setSheetNum(1);
// Easypoi matches headers by exact string. Some upstream files contain extra spaces/tabs/newlines in header cells
// (e.g. "原告 / 上诉人" or "原告/上诉人\t"), which makes specific columns silently not mapped.
// Normalize header cells first to make imports robust.
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
if (workbook.getNumberOfSheets() > sheetIndex) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
if (sheet != null) {
normalizeHeaderCells(sheet, titleRows, headRows, clazz);
}
}
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
workbook.write(bos);
try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray())) {
return ExcelImportUtil.importExcel(bis, clazz, importParams);
}
}
}
}
private static void normalizeHeaderCells(Sheet sheet, int titleRows, int headRows, Class<?> clazz) {
if (sheet == null || headRows <= 0) {
return;
}
Map<String, String> expectedHeadersByKey = buildExpectedHeaderKeyMap(clazz);
if (expectedHeadersByKey.isEmpty()) {
return;
}
int headerStart = Math.max(titleRows, 0);
int headerEnd = headerStart + headRows - 1;
for (int r = headerStart; r <= headerEnd; r++) {
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
short last = row.getLastCellNum();
for (int c = 0; c < last; c++) {
Cell cell = row.getCell(c);
if (cell == null) {
continue;
}
String text = null;
CellType type = cell.getCellType();
if (type == CellType.STRING) {
text = cell.getStringCellValue();
} else if (type == CellType.FORMULA && cell.getCachedFormulaResultType() == CellType.STRING) {
text = cell.getStringCellValue();
} else {
continue;
}
String canonical = findCanonicalHeader(text, expectedHeadersByKey);
if (canonical != null && !canonical.equals(text)) {
cell.setCellValue(canonical);
}
}
}
}
private static Map<String, String> buildExpectedHeaderKeyMap(Class<?> clazz) {
if (clazz == null) {
return Collections.emptyMap();
}
Map<String, String> map = new HashMap<>();
Class<?> current = clazz;
while (current != null && current != Object.class) {
Field[] fields = current.getDeclaredFields();
for (Field field : fields) {
Excel excel = field.getAnnotation(Excel.class);
if (excel == null) {
continue;
}
String name = excel.name();
if (name == null || name.trim().isEmpty()) {
continue;
}
String key = normalizeHeaderKey(name);
if (!key.isEmpty()) {
// key -> canonical annotation name
map.putIfAbsent(key, name);
}
// Allow import-time header aliases without changing the exported template header.
ExcelHeaderAlias alias = field.getAnnotation(ExcelHeaderAlias.class);
if (alias != null && alias.value() != null) {
for (String aliasName : alias.value()) {
if (aliasName == null || aliasName.trim().isEmpty()) {
continue;
}
String aliasKey = normalizeHeaderKey(aliasName);
if (!aliasKey.isEmpty()) {
map.putIfAbsent(aliasKey, name);
}
}
}
}
current = current.getSuperclass();
}
return map;
}
private static String findCanonicalHeader(String rawHeaderText, Map<String, String> expectedHeadersByKey) {
if (rawHeaderText == null) {
return null;
}
String key = normalizeHeaderKey(rawHeaderText);
if (key.isEmpty()) {
return null;
}
String canonical = expectedHeadersByKey.get(key);
if (canonical != null) {
return canonical;
}
// Some upstream templates append explanations in brackets, e.g. "原告/上诉人(申请执行人)".
// Only strip trailing bracket groups when the full header doesn't match any known expected header.
String strippedKey = stripTrailingBracketSuffix(key);
if (!strippedKey.equals(key)) {
canonical = expectedHeadersByKey.get(strippedKey);
if (canonical != null) {
return canonical;
}
}
return null;
}
/**
* Normalize header text for matching purposes only.
*
* <p>Do NOT drop bracket content (e.g. keep "(元)" or "(公告)" in the middle), because many templates use them as
* part of the canonical header name. We only remove whitespace and unify common full-width punctuation.</p>
*/
private static String normalizeHeaderKey(String text) {
if (text == null) {
return "";
}
String normalized = text
// unify common full-width punctuation
.replace("", "/")
.replace("", "[")
.replace("", "]")
// remove common invisible whitespace characters, including full-width space.
.replace(" ", "")
.replace("\t", "")
.replace("\r", "")
.replace("\n", "")
.replace("\u00A0", "")
.replace(" ", "")
.trim();
// Make ( ) and comparable by normalizing both to ASCII.
normalized = normalized.replace('', '(').replace('', ')');
return normalized;
}
private static String stripTrailingBracketSuffix(String text) {
if (text == null) {
return "";
}
String s = text.trim();
while (true) {
if (s.endsWith(")")) {
int idx = s.lastIndexOf('(');
if (idx >= 0) {
s = s.substring(0, idx).trim();
continue;
}
}
if (s.endsWith("]")) {
int idx = s.lastIndexOf('[');
if (idx >= 0) {
s = s.substring(0, idx).trim();
continue;
}
}
return s;
}
}
private static <T> List<T> filterEmptyRows(List<T> rawList, Predicate<T> emptyRowPredicate) {
if (CollectionUtils.isEmpty(rawList)) {
return rawList;
}
rawList.removeIf(emptyRowPredicate);
return rawList;
}
private static int getSheetCount(MultipartFile file) throws Exception {
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
return workbook.getNumberOfSheets();
}
}
/**
* 根据 sheet 名称查找下标(优先精确匹配,其次前缀匹配/包含匹配)。
*
* @return 找不到返回 -1
*/
public static int findSheetIndex(MultipartFile file, String sheetName) throws Exception {
if (file == null || sheetName == null || sheetName.trim().isEmpty()) {
return -1;
}
String target = normalizeSheetName(sheetName);
if (target.isEmpty()) {
return -1;
}
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
int sheetCount = workbook.getNumberOfSheets();
for (int i = 0; i < sheetCount; i++) {
String candidate = normalizeSheetName(workbook.getSheetName(i));
if (Objects.equals(candidate, target)) {
return i;
}
}
for (int i = 0; i < sheetCount; i++) {
String candidate = normalizeSheetName(workbook.getSheetName(i));
if (candidate.startsWith(target) || candidate.contains(target) || target.startsWith(candidate)) {
return i;
}
}
return -1;
}
}
public static int findSheetIndex(MultipartFile file, String sheetName, int defaultIndex) throws Exception {
int idx = findSheetIndex(file, sheetName);
return idx >= 0 ? idx : defaultIndex;
}
private static String normalizeSheetName(String sheetName) {
if (sheetName == null) {
return "";
}
return sheetName.replace(" ", "").replace(" ", "").trim();
}
/**
* 读取指定列(由表头名定位)的超链接,返回:单元格显示值 -> 超链接地址。
*
* <p>适用于:导入对象没有 url 字段,但 Excel 把链接放在某个“名称/案号”等列的超链接里。</p>
*/
public static Map<String, String> readHyperlinksByHeaderKey(MultipartFile file, int sheetIndex, int titleRows, int headRows, String headerName) throws Exception {
if (file == null || headerName == null || headerName.trim().isEmpty()) {
return Collections.emptyMap();
}
try (InputStream is = file.getInputStream(); Workbook workbook = WorkbookFactory.create(is)) {
if (workbook.getNumberOfSheets() <= sheetIndex) {
return Collections.emptyMap();
}
Sheet sheet = workbook.getSheetAt(sheetIndex);
if (sheet == null) {
return Collections.emptyMap();
}
int colIndex = findColumnIndexByHeader(sheet, titleRows, headRows, headerName);
if (colIndex < 0) {
return Collections.emptyMap();
}
Map<String, String> result = new HashMap<>();
DataFormatter formatter = new DataFormatter();
int dataStartRow = titleRows + headRows;
for (int r = dataStartRow; r <= sheet.getLastRowNum(); r++) {
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
Cell cell = row.getCell(colIndex);
if (cell == null) {
continue;
}
String address = extractHyperlinkAddress(cell);
if (address == null || address.isEmpty()) {
continue;
}
String key = formatter.formatCellValue(cell);
if (key == null || key.trim().isEmpty()) {
continue;
}
result.put(key.trim(), address);
}
return result;
}
}
/**
* 读取两列(由表头名定位)的文本/超链接返回key列显示值 -> value列优先超链接地址其次单元格文本
*
* <p>适用于Excel 把 url 放在单独一列(可能是纯文本,也可能是超链接)。</p>
*/
public static Map<String, String> readKeyValueByHeaders(MultipartFile file,
int sheetIndex,
int titleRows,
int headRows,
String keyHeaderName,
String valueHeaderName) throws Exception {
if (file == null
|| keyHeaderName == null || keyHeaderName.trim().isEmpty()
|| valueHeaderName == null || valueHeaderName.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 keyCol = findColumnIndexByHeader(sheet, titleRows, headRows, keyHeaderName);
int valCol = findColumnIndexByHeader(sheet, titleRows, headRows, valueHeaderName);
if (keyCol < 0 || valCol < 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 keyCell = row.getCell(keyCol);
if (keyCell == null) {
continue;
}
String key = formatter.formatCellValue(keyCell);
if (key == null || key.trim().isEmpty()) {
continue;
}
Cell valCell = row.getCell(valCol);
if (valCell == null) {
continue;
}
String value = extractHyperlinkAddress(valCell);
if (value == null || value.trim().isEmpty()) {
value = formatter.formatCellValue(valCell);
}
if (value == null || value.trim().isEmpty()) {
continue;
}
result.put(key.trim(), value.trim());
}
return result;
}
}
/**
* 读取“key列 -> url”的映射
* - 优先读取 key 列自身的超链接url 常挂在名称/案号等列的超链接里)
* - 如果源文件提供独立的 url/URL/网址/链接/链接地址 等列,则读取该列(支持文本或超链接)
*/
public static Map<String, String> readUrlByKey(MultipartFile file,
int sheetIndex,
int titleRows,
int headRows,
String keyHeaderName) throws Exception {
if (file == null || keyHeaderName == null || keyHeaderName.trim().isEmpty()) {
return Collections.emptyMap();
}
Map<String, String> result = new HashMap<>();
// 1) url 挂在 key 列超链接里(最常见)
Map<String, String> fromKeyHyperlinks = readHyperlinksByHeaderKey(file, sheetIndex, titleRows, headRows, keyHeaderName);
if (!fromKeyHyperlinks.isEmpty()) {
result.putAll(fromKeyHyperlinks);
}
// 2) url 作为单独一列(多种表头命名)
String[] urlHeaders = new String[]{"url", "URL", "网址", "链接", "链接地址"};
for (String urlHeader : urlHeaders) {
Map<String, String> fromUrlCol = readKeyValueByHeaders(file, sheetIndex, titleRows, headRows, keyHeaderName, urlHeader);
if (fromUrlCol.isEmpty()) {
continue;
}
for (Map.Entry<String, String> entry : fromUrlCol.entrySet()) {
// 不覆盖已从 key 超链接读取到的地址
result.putIfAbsent(entry.getKey(), entry.getValue());
}
}
return result;
}
private static int findColumnIndexByHeader(Sheet sheet, int titleRows, int headRows, String headerName) {
String targetKey = normalizeHeaderKey(headerName);
if (targetKey.isEmpty()) {
return -1;
}
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;
}
DataFormatter formatter = new DataFormatter();
String value = formatter.formatCellValue(cell);
if (targetKey.equals(normalizeHeaderKey(value))) {
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

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

View File

@@ -1,112 +0,0 @@
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 Boolean hasData;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "主体企业")
@TableField(exist = false)
private String companyName;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,93 +0,0 @@
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: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 Boolean hasData;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "主体企业")
@TableField(exist = false)
private String companyName;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,96 +0,0 @@
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: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 Boolean hasData;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "主题企业")
@TableField(exist = false)
private String companyName;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,113 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 失信被执行人
*
* @author 科技小王子
* @since 2025-12-19 19:46:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditBreachOfTrust对象", description = "失信被执行人")
public class CreditBreachOfTrust implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "失信被执行人")
private String plaintiffAppellant;
@Schema(description = "疑似申请执行人")
private String appellee;
@Schema(description = "涉案金额(元)")
private String involvedAmount;
@Schema(description = "执行法院")
private String courtName;
@Schema(description = "立案日期")
private String occurrenceTime;
@Schema(description = "发布日期")
private String releaseDate;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "链接地址")
private String url;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,110 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:47:22
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCaseFiling对象", description = "司法大数据")
public class CreditCaseFiling implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "立案日期")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "项目网址")
private String url;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,297 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 企业
*
* @author 科技小王子
* @since 2025-12-17 08:28:03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCompany对象", description = "企业")
public class CreditCompany implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "原文件导入名称")
private String name;
@Schema(description = "系统匹配企业名称")
private String matchName;
@Schema(description = "登记状态")
private String registrationStatus;
@Schema(description = "法定代表人")
private String legalPerson;
@Schema(description = "注册资本")
private String registeredCapital;
@Schema(description = "实缴资本")
private String paidinCapital;
@Schema(description = "成立日期")
private String establishDate;
@Schema(description = "统一社会信用代码")
private String code;
@Schema(description = "企业地址")
private String address;
@Schema(description = "所属省份")
private String province;
@Schema(description = "所属城市")
private String city;
@Schema(description = "所属区县")
private String region;
@Schema(description = "电话")
private String tel;
@Schema(description = "更多电话")
private String moreTel;
@Schema(description = "邮箱")
private String email;
@Schema(description = "更多邮箱")
private String moreEmail;
@Schema(description = "企业(机构)类型")
private String institutionType;
@Schema(description = "纳税人识别号")
private String taxpayerCode;
@Schema(description = "注册号")
private String registrationNumber;
@Schema(description = "组织机构代码")
private String organizationalCode;
@Schema(description = "参保人数")
private String numberOfInsuredPersons;
@Schema(description = "参保人数所属年报")
private String annualReport;
@Schema(description = "营业期限")
private String businessTerm;
@Schema(description = "国标行业门类")
private String nationalStandardIndustryCategories;
@Schema(description = "国标行业大类")
private String nationalStandardIndustryCategories2;
@Schema(description = "国标行业中类")
private String nationalStandardIndustryCategories3;
@Schema(description = "国标行业小类")
private String nationalStandardIndustryCategories4;
@Schema(description = "企查查行业门类")
private String nationalStandardIndustryCategories5;
@Schema(description = "企查查行业大类")
private String nationalStandardIndustryCategories6;
@Schema(description = "企查查行业中类")
private String nationalStandardIndustryCategories7;
@Schema(description = "企查查行业小类")
private String nationalStandardIndustryCategories8;
@Schema(description = "企业规模")
private String companySize;
@Schema(description = "曾用名")
private String formerName;
@Schema(description = "英文名")
private String englishName;
@Schema(description = "官网")
private String domain;
@Schema(description = "通信地址")
private String mailingAddress;
@Schema(description = "企业简介")
private String companyProfile;
@Schema(description = "经营范围")
private String natureOfBusiness;
@Schema(description = "登记机关")
private String registrationAuthority;
@Schema(description = "纳税人资质")
private String taxpayerQualification;
@Schema(description = "最新年报年份")
private String latestAnnualReportYear;
@Schema(description = "最新年报营业收入")
private String latestAnnualReportOnOperatingRevenue;
@Schema(description = "企查分")
private String enterpriseScoreCheck;
@Schema(description = "信用等级")
private String creditRating;
@Schema(description = "科创分")
private String cechnologyScore;
@Schema(description = "科创等级")
private String cechnologyLevel;
@Schema(description = "是否小微企业")
private String smallEnterprise;
@Schema(description = "项目网址")
private String url;
@Schema(description = "类型")
private Integer type;
@Schema(description = "是否客户")
private Integer isCustomer;
@Schema(description = "上级id, 0是顶级")
private Integer parentId;
@Schema(description = "所在国家")
private String country;
@Schema(description = "记录数")
private Integer creditAdministrativeLicense;
@Schema(description = "记录数")
private Integer creditBankruptcy;
@Schema(description = "记录数")
private Integer creditBranch;
@Schema(description = "记录数")
private Integer creditBreachOfTrust;
@Schema(description = "记录数")
private Integer creditCaseFiling;
@Schema(description = "记录数")
private Integer creditCompetitor;
@Schema(description = "记录数")
private Integer creditCourtAnnouncement;
@Schema(description = "记录数")
private Integer creditCourtSession;
@Schema(description = "记录数")
private Integer creditCustomer;
@Schema(description = "记录数")
private Integer creditDeliveryNotice;
@Schema(description = "记录数")
private Integer creditExternal;
@Schema(description = "记录数")
private Integer creditFinalVersion;
@Schema(description = "记录数")
private Integer creditGqdj;
@Schema(description = "记录数")
private Integer creditHistoricalLegalPerson;
@Schema(description = "记录数")
private Integer creditJudgmentDebtor;
@Schema(description = "记录数")
private Integer creditJudicialDocument;
@Schema(description = "记录数")
private Integer creditJudiciary;
@Schema(description = "记录数")
private Integer creditMediation;
@Schema(description = "记录数")
private Integer creditNearbyCompany;
@Schema(description = "记录数")
private Integer creditPatent;
@Schema(description = "记录数")
private Integer creditRiskRelation;
@Schema(description = "记录数")
private Integer creditSupplier;
@Schema(description = "记录数")
private Integer creditSuspectedRelationship;
@Schema(description = "记录数")
private Integer creditUser;
@Schema(description = "记录数")
private Integer creditXgxf;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,107 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 竞争对手
*
* @author 科技小王子
* @since 2025-12-19 19:49:04
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCompetitor对象", description = "竞争对手")
public class CreditCompetitor implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "序号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "企业名称")
private String name;
@Schema(description = "链接地址")
private String url;
@Schema(description = "法定代表人")
private String legalRepresentative;
@Schema(description = "注册资本")
private String registeredCapital;
@Schema(description = "成立日期")
private String establishmentDate;
@Schema(description = "登记状态")
private String registrationStatus;
@Schema(description = "所属行业")
private String industry;
@Schema(description = "所属省份")
private String province;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "企业名称")
private String companyName;
@Schema(description = "所属企业名称")
@TableField(exist = false)
private String mainCompanyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,110 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 法院公告司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:49:13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCourtAnnouncement对象", description = "法院公告司法大数据")
public class CreditCourtAnnouncement implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "当事人")
private String otherPartiesThirdParty;
@Schema(description = "公告类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "刊登日期")
private String occurrenceTime;
@Schema(description = "被告/被上诉人")
private String appellee;
@Schema(description = "链接地址")
private String url;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,110 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 开庭公告司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:49:32
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCourtSession对象", description = "开庭公告司法大数据")
public class CreditCourtSession implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "链接地址")
private String url;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,97 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 客户
*
* @author 科技小王子
* @since 2025-12-21 21:20:58
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditCustomer对象", description = "客户")
public class CreditCustomer implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "客户")
private String name;
@Schema(description = "链接地址")
private String url;
@Schema(description = "状态")
private String statusTxt;
@Schema(description = "销售金额(万元)")
private String price;
@Schema(description = "公开日期")
private String publicDate;
@Schema(description = "数据来源")
private String dataSource;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "企业名称")
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,110 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 送达公告司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:49:51
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditDeliveryNotice对象", description = "送达公告司法大数据")
public class CreditDeliveryNotice implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "链接地址")
private String url;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "当事人")
private String otherPartiesThirdParty;
@Schema(description = "法院")
private String courtName;
@Schema(description = "发布日期")
private String occurrenceTime;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
private String appellee;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,124 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 对外投资
*
* @author 科技小王子
* @since 2025-12-19 19:50:11
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditExternal对象", description = "对外投资")
public class CreditExternal implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "被投资企业名称")
private String name;
@Schema(description = "状态")
private String statusTxt;
@Schema(description = "链接地址")
private String url;
@Schema(description = "法定代表人")
private String legalRepresentative;
@Schema(description = "注册资本(金额)")
private String registeredCapital;
@Schema(description = "成立日期")
private String establishmentDate;
@Schema(description = "持股比例")
private String shareholdingRatio;
@Schema(description = "认缴出资额")
private String subscribedInvestmentAmount;
@Schema(description = "认缴出资日期")
private String subscribedInvestmentDate;
@Schema(description = "间接持股比例")
private String indirectShareholdingRatio;
@Schema(description = "投资日期")
private String investmentDate;
@Schema(description = "所属地区")
private String region;
@Schema(description = "所属行业")
private String industry;
@Schema(description = "投资数量")
private Integer investmentCount;
@Schema(description = "关联产品/机构")
private String relatedProductsInstitutions;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "企业名称")
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,110 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 终本案件
*
* @author 科技小王子
* @since 2025-12-19 19:50:19
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditFinalVersion对象", description = "终本案件")
public class CreditFinalVersion implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "链接地址")
private String url;
@Schema(description = "被执行人")
private String appellee;
@Schema(description = "疑似申请执行人")
private String plaintiffAppellant;
@Schema(description = "未履行金额(元)")
private String unfulfilledAmount;
@Schema(description = "执行标的(元)")
private String involvedAmount;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "执行法院")
private String courtName;
@Schema(description = "立案日期")
private String occurrenceTime;
@Schema(description = "终本日期")
private String finalDate;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,110 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 股权冻结
*
* @author 科技小王子
* @since 2025-12-19 19:50:37
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditGqdj对象", description = "股权冻结")
public class CreditGqdj implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "执行通知文书号")
private String caseNumber;;
@Schema(description = "被执行人")
private String appellee;
@Schema(description = "冻结股权标的企业")
private String plaintiffAppellant;
@Schema(description = "被执行人持有股权、其他投资权益数额")
private String involvedAmount;
@Schema(description = "执行法院")
private String courtName;
@Schema(description = "类型")
private String dataType;
@Schema(description = "状态")
private String dataStatus;
@Schema(description = "详情链接")
private String url;
@Schema(description = "冻结日期自")
private String freezeDateStart;
@Schema(description = "冻结日期至")
private String freezeDateEnd;
@Schema(description = "公示日期")
private String publicDate;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,90 +0,0 @@
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: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 Boolean hasData;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "主体企业")
@TableField(exist = false)
private String companyName;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,126 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
* 被执行人
*
* @author 科技小王子
* @since 2025-12-19 19:50:55
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditJudgmentDebtor对象", description = "被执行人")
public class CreditJudgmentDebtor implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "被执行人名称")
private String name;
@Schema(description = "被执行人")
private String name1;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "证件号/组织机构代码")
private String code;
@Schema(description = "项目网址")
private String url;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "涉案金额")
private String amount;
@Schema(description = "执行标的(元)")
private String involvedAmountQcc;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@Schema(description = "租户id")
private Integer tenantId;
@Schema(description = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@Schema(description = "修改时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
@Schema(description = "历史被执行人ID")
@TableField(exist = false)
private Integer historyId;
@Schema(description = "历史被执行人名称")
@TableField(exist = false)
private String historyName;
}

View File

@@ -1,116 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 裁判文书司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:51:02
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditJudicialDocument对象", description = "裁判文书司法大数据")
public class CreditJudicialDocument implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "文书标题")
private String title;
@Schema(description = "文书类型")
private String documentType;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "链接地址")
private String url;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "当事人")
private String otherPartiesThirdParty;
@Schema(description = "案件金额")
private String involvedAmount;
@Schema(description = "裁判结果")
private String defendantAppellee;
@Schema(description = "裁判日期")
private String occurrenceTime;
@Schema(description = "发布日期")
private String releaseDate;
@Schema(description = "被告/被上诉人")
private String appellee;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,130 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 司法案件
*
* @author 科技小王子
* @since 2025-12-16 15:23:58
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditJudiciary对象", description = "司法案件")
public class CreditJudiciary implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "案件名称")
private String name;
@Schema(description = "案号")
private String code;
@Schema(description = "详情链接")
private String url;
@Schema(description = "类型, 0普通用户, 1招投标")
private Integer type;
@Schema(description = "案由")
private String reason;
@Schema(description = "上级id, 0是顶级")
private Integer parentId;
@Schema(description = "案件类型")
private String infoType;
@Schema(description = "所在国家")
private String country;
@Schema(description = "所在省份")
private String province;
@Schema(description = "所在城市")
private String city;
@Schema(description = "所在辖区")
private String region;
@Schema(description = "街道地址")
private String address;
@Schema(description = "案件进程")
private String caseProgress;
@Schema(description = "案件身份")
private String caseIdentity;
@Schema(description = "法院")
private String court;
@Schema(description = "进程日期")
private String processDate;
@Schema(description = "案件金额(元)")
private String caseAmount;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@Schema(description = "备注")
private String comments;
@Schema(description = "是否推荐")
private Integer recommend;
@Schema(description = "到期时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expirationTime;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1冻结")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@Schema(description = "用户ID")
private Integer userId;
@Schema(description = "真实姓名")
@TableField(exist = false)
private String realName;
@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,114 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 诉前调解司法大数据
*
* @author 科技小王子
* @since 2025-12-19 19:51:25
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditMediation对象", description = "诉前调解司法大数据")
public class CreditMediation implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "数据类型")
private String dataType;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "链接地址")
private String url;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@Schema(description = "租户id")
private Integer tenantId;
@Schema(description = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@Schema(description = "修改时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
@Schema(description = "发生时间")
@TableField(exist = false)
private String occurrenceTime2;
}

View File

@@ -1,295 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 小程序端客户
*
* @author 科技小王子
* @since 2026-03-16 20:59:17
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditMpCustomer对象", description = "小程序端客户")
public class CreditMpCustomer implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "拖欠方")
private String toUser;
@Schema(description = "拖欠金额")
private String price;
@Schema(description = "拖欠年数")
private String years;
@Schema(description = "链接")
private String url;
@Schema(description = "状态")
private String statusTxt;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "所在省份")
private String province;
@Schema(description = "所在城市")
private String city;
@Schema(description = "所在辖区")
private String region;
@Schema(description = "文件路径")
private String files;
@Schema(description = "是否有数据")
private Boolean hasData;
@Schema(description = "步骤, 0未受理1已受理2材料提交3合同签订4执行回款5完结")
private Integer step;
@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 = "用户昵称")
@TableField(exist = false)
private String nickname;
@Schema(description = "用户手机号")
@TableField(exist = false)
private String phone;
@Schema(description = "用户头像")
@TableField(exist = false)
private String avatar;
@Schema(description = "真实姓名")
@TableField(exist = false)
private String realName;
@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;
// 第1步案件受理字段
@Schema(description = "第1步是否已提交")
private Integer followStep1Submitted;
@Schema(description = "第1步提交时间")
private String followStep1SubmittedAt;
@Schema(description = "第1步联系人")
private String followStep1Contact;
@Schema(description = "第1步联系电话")
private String followStep1Phone;
@Schema(description = "第1步电话录音URL")
private String followStep1AudioUrl;
@Schema(description = "第1步电话录音文件名")
private String followStep1AudioName;
@Schema(description = "第1步短信截图JSON")
private String followStep1SmsShots;
@Schema(description = "第1步电话沟通截图JSON")
private String followStep1CallShots;
@Schema(description = "第1步沟通情况")
private String followStep1Remark;
@Schema(description = "第1步意向(无意向/有意向)")
private String followStep1Intention;
@Schema(description = "第1步沟通次数")
private Integer followStep1CommunicationCount;
@Schema(description = "第1步是否需要审核")
private Integer followStep1NeedApproval;
@Schema(description = "第1步是否审核通过")
private Integer followStep1Approved;
@Schema(description = "第1步审核时间")
private String followStep1ApprovedAt;
@Schema(description = "第1步审核人ID")
private Long followStep1ApprovedBy;
// 第2步材料准备字段
@Schema(description = "第2步是否已提交")
private Integer followStep2Submitted;
@Schema(description = "第2步提交时间")
private String followStep2SubmittedAt;
@Schema(description = "第2步是否需要审核")
private Integer followStep2NeedApproval;
@Schema(description = "第2步是否审核通过")
private Integer followStep2Approved;
@Schema(description = "第2步审核时间")
private String followStep2ApprovedAt;
@Schema(description = "第2步审核人ID")
private Long followStep2ApprovedBy;
// 第3步案件办理字段
@Schema(description = "第3步是否已提交")
private Integer followStep3Submitted;
@Schema(description = "第3步提交时间")
private String followStep3SubmittedAt;
@Schema(description = "第3步是否需要审核")
private Integer followStep3NeedApproval;
@Schema(description = "第3步是否审核通过")
private Integer followStep3Approved;
@Schema(description = "第3步审核时间")
private String followStep3ApprovedAt;
@Schema(description = "第3步审核人ID")
private Long followStep3ApprovedBy;
// 第4步送达签收字段
@Schema(description = "第4步是否已提交")
private Integer followStep4Submitted;
@Schema(description = "第4步提交时间")
private String followStep4SubmittedAt;
@Schema(description = "第4步是否需要审核")
private Integer followStep4NeedApproval;
@Schema(description = "第4步是否审核通过")
private Integer followStep4Approved;
@Schema(description = "第4步审核时间")
private String followStep4ApprovedAt;
@Schema(description = "第4步审核人ID")
private Long followStep4ApprovedBy;
// 第5步合同签订字段
@Schema(description = "第5步是否已提交")
private Integer followStep5Submitted;
@Schema(description = "第5步提交时间")
private String followStep5SubmittedAt;
@Schema(description = "第5步合同信息JSON数组")
private String followStep5Contracts;
@Schema(description = "第5步是否需要审核")
private Integer followStep5NeedApproval;
@Schema(description = "第5步是否审核通过")
private Integer followStep5Approved;
@Schema(description = "第5步审核时间")
private String followStep5ApprovedAt;
@Schema(description = "第5步审核人ID")
private Long followStep5ApprovedBy;
// 第6步订单回款字段
@Schema(description = "第6步是否已提交")
private Integer followStep6Submitted;
@Schema(description = "第6步提交时间")
private String followStep6SubmittedAt;
@Schema(description = "第6步财务录入的回款记录JSON数组")
private String followStep6PaymentRecords;
@Schema(description = "第6步预计回款JSON数组")
private String followStep6ExpectedPayments;
@Schema(description = "第6步是否需要审核")
private Integer followStep6NeedApproval;
@Schema(description = "第6步是否审核通过")
private Integer followStep6Approved;
@Schema(description = "第6步审核时间")
private String followStep6ApprovedAt;
@Schema(description = "第6步审核人ID")
private Long followStep6ApprovedBy;
// 第7步电话回访字段
@Schema(description = "第7步是否已提交")
private Integer followStep7Submitted;
@Schema(description = "第7步提交时间")
private String followStep7SubmittedAt;
@Schema(description = "第7步回访记录JSON数组")
private String followStep7VisitRecords;
@Schema(description = "第7步是否需要审核")
private Integer followStep7NeedApproval;
@Schema(description = "第7步是否审核通过")
private Integer followStep7Approved;
@Schema(description = "第7步审核时间")
private String followStep7ApprovedAt;
@Schema(description = "第7步审核人ID")
private Long followStep7ApprovedBy;
// 流程结束字段
@Schema(description = "流程是否已结束")
private Integer followProcessEnded;
@Schema(description = "流程结束时间")
private String followProcessEndTime;
@Schema(description = "流程结束原因")
private String followProcessEndReason;
}

View File

@@ -1,247 +0,0 @@
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: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 companyAlias;
@Schema(description = "主体企业")
@TableField(exist = false)
private String companyName;
@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 = "实缴资本")
// @TableField(exist = false)
// private String paidinCapital;
//
// @Schema(description = "登记机关")
// @TableField(exist = false)
// private String registrationAuthority;
//
// @Schema(description = "纳税人资质")
// @TableField(exist = false)
// private String taxpayerQualification;
//
// @Schema(description = "最新年报年份")
// @TableField(exist = false)
// private String latestAnnualReportYear;
//
// @Schema(description = "最新年报营业收入")
// @TableField(exist = false)
// private String latestAnnualReportOnOperatingRevenue;
//
// @Schema(description = "企查分")
// @TableField(exist = false)
// private String enterpriseScoreCheck;
//
// @Schema(description = "信用等级")
// @TableField(exist = false)
// private String creditRating;
//
// @Schema(description = "科创分")
// @TableField(exist = false)
// private String cechnologyScore;
//
// @Schema(description = "科创等级")
// @TableField(exist = false)
// private String cechnologyLevel;
//
// @Schema(description = "是否小微企业")
// @TableField(exist = false)
// private String smallEnterprise;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,105 +0,0 @@
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: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 Boolean hasData;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "主体企业")
@TableField(exist = false)
private String companyName;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,96 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 风险关系表
*
* @author 科技小王子
* @since 2025-12-19 19:51:40
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditRiskRelation对象", description = "风险关系表")
public class CreditRiskRelation implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "序号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "主体名称")
private String mainBodyName;
@Schema(description = "登记状态")
private String registrationStatus;
@Schema(description = "注册资本")
private String registeredCapital;
@Schema(description = "省份地区")
private String provinceRegion;
@Schema(description = "关联关系")
private String associatedRelation;
@Schema(description = "风险关系")
private String riskRelation;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "企业名称")
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,97 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 供应商
*
* @author 科技小王子
* @since 2025-12-19 19:51:47
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditSupplier对象", description = "供应商")
public class CreditSupplier implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "供应商")
private String supplier;
@Schema(description = "链接地址")
private String url;
@Schema(description = "状态")
private String statusTxt;
@Schema(description = "采购金额(万元)")
private String purchaseAmount;
@Schema(description = "公开日期")
private String publicDate;
@Schema(description = "数据来源")
private String dataSource;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "企业名称")
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,105 +0,0 @@
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: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 Boolean hasData;
@Schema(description = "备注")
private String comments;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "主体企业")
@TableField(exist = false)
private String companyName;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,127 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 招投标信息表
*
* @author 科技小王子
* @since 2025-12-15 13:16:03
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditUser对象", description = "招投标信息表")
public class CreditUser 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 url;
@Schema(description = "唯一标识")
private String code;
@Schema(description = "类型, 0普通用户, 1招投标")
private Integer type;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "企业角色")
private String role;
@Schema(description = "上级id, 0是顶级")
private Integer parentId;
@Schema(description = "信息类型")
private String infoType;
@Schema(description = "所在国家")
private String country;
@Schema(description = "所在省份")
private String province;
@Schema(description = "所在城市")
private String city;
@Schema(description = "所在辖区")
private String region;
@Schema(description = "街道地址")
private String address;
@Schema(description = "招采单位")
private String procurementName;
@Schema(description = "中标单位")
private String winningName;
@Schema(description = "中标金额")
private String winningPrice;
@Schema(description = "发布日期")
private String releaseDate;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业别名")
private String companyAlias;
@Schema(description = "企业名称")
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,122 +0,0 @@
package com.gxwebsoft.credit.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 限制高消费
*
* @author 科技小王子
* @since 2025-12-19 19:51:55
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "CreditXgxf对象", description = "限制高消费")
public class CreditXgxf implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "ID")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "链接地址")
private String url;
@Schema(description = "数据类型")
private String type;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "被告/被上诉人")
private String appellee;
@Schema(description = "其他当事人/第三人")
private String otherPartiesThirdParty;
@Schema(description = "发生时间")
private String occurrenceTime;
@Schema(description = "案号")
private String caseNumber;
@Schema(description = "涉案金额")
private String involvedAmount;
@Schema(description = "法院")
private String courtName;
@Schema(description = "数据状态")
private String dataStatus;
@Schema(description = "限消令对象")
private String dataType;
@Schema(description = "原告/上诉人2")
private String plaintiffUser;
@Schema(description = "被告/被上诉人2")
private String defendantUser;
@Schema(description = "发布日期")
private String releaseDate;
@Schema(description = "案由")
private String causeOfAction;
@Schema(description = "企业ID")
private Integer companyId;
@Schema(description = "企业名称")
@TableField(exist = false)
private String companyName;
@Schema(description = "是否有数据")
private Boolean hasData;
@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 = "真实姓名")
@TableField(exist = false)
private String realName;
@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,23 +0,0 @@
package com.gxwebsoft.credit.excel;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Excel 导入表头别名。
*
* <p>EasyPOI 的 {@code @Excel(name=...)} 仅支持一个表头名;当上游模板存在多种表头写法时,
* 可用此注解声明别名,让 {@link com.gxwebsoft.credit.controller.ExcelImportSupport} 在导入前把别名规范化为 canonical 表头。</p>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelHeaderAlias {
/**
* 允许匹配的表头别名列表(任意一个匹配即视为该列)。
*/
String[] value();
}

View File

@@ -1,37 +0,0 @@
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

@@ -1,37 +0,0 @@
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

@@ -1,37 +0,0 @@
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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,37 +0,0 @@
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

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

View File

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

View File

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

View File

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

View File

@@ -1,47 +0,0 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditMpCustomer;
import com.gxwebsoft.credit.param.CreditMpCustomerParam;
import com.gxwebsoft.credit.param.FollowStepQueryDTO;
import com.gxwebsoft.credit.vo.PendingApprovalStepVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 小程序端客户Mapper
*
* @author 科技小王子
* @since 2026-03-16 20:59:17
*/
public interface CreditMpCustomerMapper extends BaseMapper<CreditMpCustomer> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditMpCustomer>
*/
List<CreditMpCustomer> selectPageRel(@Param("page") IPage<CreditMpCustomer> page,
@Param("param") CreditMpCustomerParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditMpCustomer> selectListRel(@Param("param") CreditMpCustomerParam param);
/**
* 获取待审核的跟进步骤列表
*
* @param query 查询参数
* @return 待审核步骤列表
*/
List<PendingApprovalStepVO> selectPendingApprovalSteps(@Param("param") FollowStepQueryDTO query);
}

View File

@@ -1,37 +0,0 @@
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

@@ -1,37 +0,0 @@
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

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

View File

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

View File

@@ -1,37 +0,0 @@
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

@@ -1,37 +0,0 @@
package com.gxwebsoft.credit.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.credit.entity.CreditUser;
import com.gxwebsoft.credit.param.CreditUserParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 招投标信息表Mapper
*
* @author 科技小王子
* @since 2025-12-15 13:16:03
*/
public interface CreditUserMapper extends BaseMapper<CreditUser> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<CreditUser>
*/
List<CreditUser> selectPageRel(@Param("page") IPage<CreditUser> page,
@Param("param") CreditUserParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<CreditUser> selectListRel(@Param("param") CreditUserParam param);
}

View File

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

View File

@@ -1,94 +0,0 @@
<?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.*, b.match_name AS companyName, u.real_name AS realName
FROM credit_administrative_license a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.code LIKE CONCAT('%', #{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

@@ -1,83 +0,0 @@
<?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.*, b.name AS companyName, u.real_name AS realName
FROM credit_bankruptcy a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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.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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.code LIKE CONCAT('%', #{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

@@ -1,83 +0,0 @@
<?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.*, b.match_name AS companyName, u.real_name AS realName
FROM credit_branch a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.name LIKE CONCAT('%', #{param.keywords}, '%')
OR a.curator LIKE CONCAT('%', #{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

@@ -1,83 +0,0 @@
<?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.CreditBreachOfTrustMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_breach_of_trust a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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.plaintiffAppellant != null">
AND a.plaintiff_appellant LIKE CONCAT('%', #{param.plaintiffAppellant}, '%')
</if>
<if test="param.appellee != null">
AND a.appellee LIKE CONCAT('%', #{param.appellee}, '%')
</if>
<if test="param.occurrenceTime != null">
AND a.occurrence_time LIKE CONCAT('%', #{param.occurrenceTime}, '%')
</if>
<if test="param.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
<if test="param.involvedAmount != null">
AND a.involved_amount = #{param.involvedAmount}
</if>
<if test="param.courtName != null">
AND a.court_name LIKE CONCAT('%', #{param.courtName}, '%')
</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 a.case_number = #{param.keywords}
OR b.name LIKE CONCAT('%', #{param.keywords}, '%')
OR a.case_number LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditBreachOfTrust">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditBreachOfTrust">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,94 +0,0 @@
<?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.CreditCaseFilingMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_case_filing a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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>
<if test="param.plaintiffAppellant != null">
AND a.plaintiff_appellant LIKE CONCAT('%', #{param.plaintiffAppellant}, '%')
</if>
<if test="param.appellee != null">
AND a.appellee LIKE CONCAT('%', #{param.appellee}, '%')
</if>
<if test="param.otherPartiesThirdParty != null">
AND a.other_parties_third_party LIKE CONCAT('%', #{param.otherPartiesThirdParty}, '%')
</if>
<if test="param.occurrenceTime != null">
AND a.occurrence_time LIKE CONCAT('%', #{param.occurrenceTime}, '%')
</if>
<if test="param.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
<if test="param.causeOfAction != null">
AND a.cause_of_action LIKE CONCAT('%', #{param.causeOfAction}, '%')
</if>
<if test="param.involvedAmount != null">
AND a.involved_amount = #{param.involvedAmount}
</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.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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.case_number LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditCaseFiling">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditCaseFiling">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,213 +0,0 @@
<?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.CreditCompanyMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, u.real_name AS realName
FROM credit_company a
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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.matchName != null">
AND a.match_name LIKE CONCAT('%', #{param.matchName}, '%')
</if>
<if test="param.code != null">
AND a.code LIKE CONCAT('%', #{param.code}, '%')
</if>
<if test="param.type != null">
AND a.type = #{param.type}
</if>
<if test="param.isCustomer != null">
AND a.is_customer = #{param.isCustomer}
</if>
<if test="param.parentId != null">
AND a.parent_id = #{param.parentId}
</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.paidinCapital != null">
AND a.paidin_capital LIKE CONCAT('%', #{param.paidinCapital}, '%')
</if>
<if test="param.establishDate != null">
AND a.establish_date LIKE CONCAT('%', #{param.establishDate}, '%')
</if>
<if test="param.address != null">
AND a.address LIKE CONCAT('%', #{param.address}, '%')
</if>
<if test="param.tel != null">
AND a.tel LIKE CONCAT('%', #{param.tel}, '%')
</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.institutionType != null">
AND a.institution_type LIKE CONCAT('%', #{param.institutionType}, '%')
</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.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.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.companySize != null">
AND a.company_size LIKE CONCAT('%', #{param.companySize}, '%')
</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.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.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.name LIKE CONCAT('%', #{param.keywords}, '%')
OR a.match_name LIKE CONCAT('%', #{param.keywords}, '%')
OR a.code = #{param.keywords}
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditCompany">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditCompany">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,85 +0,0 @@
<?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.CreditCompetitorMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_competitor a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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>
<if test="param.legalRepresentative != null">
AND a.legal_representative LIKE CONCAT('%', #{param.legalRepresentative}, '%')
</if>
<if test="param.registeredCapital != null">
AND a.registered_capital = #{param.registeredCapital}
</if>
<if test="param.establishmentDate != null">
AND a.establishment_date LIKE CONCAT('%', #{param.establishmentDate}, '%')
</if>
<if test="param.registrationStatus != null">
AND a.registration_status LIKE CONCAT('%', #{param.registrationStatus}, '%')
</if>
<if test="param.industry != null">
AND a.industry LIKE CONCAT('%', #{param.industry}, '%')
</if>
<if test="param.province != null">
AND a.province LIKE CONCAT('%', #{param.province}, '%')
</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 a.name LIKE CONCAT('%', #{param.keywords}, '%')
OR b.name LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditCompetitor">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditCompetitor">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,94 +0,0 @@
<?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.CreditCourtAnnouncementMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_court_announcement a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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>
<if test="param.plaintiffAppellant != null">
AND a.plaintiff_appellant LIKE CONCAT('%', #{param.plaintiffAppellant}, '%')
</if>
<if test="param.appellee != null">
AND a.appellee LIKE CONCAT('%', #{param.appellee}, '%')
</if>
<if test="param.otherPartiesThirdParty != null">
AND a.other_parties_third_party LIKE CONCAT('%', #{param.otherPartiesThirdParty}, '%')
</if>
<if test="param.occurrenceTime != null">
AND a.occurrence_time LIKE CONCAT('%', #{param.occurrenceTime}, '%')
</if>
<if test="param.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
<if test="param.causeOfAction != null">
AND a.cause_of_action LIKE CONCAT('%', #{param.causeOfAction}, '%')
</if>
<if test="param.involvedAmount != null">
AND a.involved_amount = #{param.involvedAmount}
</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.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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.case_number LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditCourtAnnouncement">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditCourtAnnouncement">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,94 +0,0 @@
<?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.CreditCourtSessionMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_court_session a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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>
<if test="param.plaintiffAppellant != null">
AND a.plaintiff_appellant LIKE CONCAT('%', #{param.plaintiffAppellant}, '%')
</if>
<if test="param.appellee != null">
AND a.appellee LIKE CONCAT('%', #{param.appellee}, '%')
</if>
<if test="param.otherPartiesThirdParty != null">
AND a.other_parties_third_party LIKE CONCAT('%', #{param.otherPartiesThirdParty}, '%')
</if>
<if test="param.occurrenceTime != null">
AND a.occurrence_time LIKE CONCAT('%', #{param.occurrenceTime}, '%')
</if>
<if test="param.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
<if test="param.causeOfAction != null">
AND a.cause_of_action LIKE CONCAT('%', #{param.causeOfAction}, '%')
</if>
<if test="param.involvedAmount != null">
AND a.involved_amount = #{param.involvedAmount}
</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.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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.case_number LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditCourtSession">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditCourtSession">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,79 +0,0 @@
<?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.CreditCustomerMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_customer a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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>
<if test="param.statusTxt != null">
AND a.status_txt LIKE CONCAT('%', #{param.statusTxt}, '%')
</if>
<if test="param.price != null">
AND a.price = #{param.price}
</if>
<if test="param.publicDate != null">
AND a.public_date LIKE CONCAT('%', #{param.publicDate}, '%')
</if>
<if test="param.dataSource != null">
AND a.data_source LIKE CONCAT('%', #{param.dataSource}, '%')
</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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.name LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditCustomer">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditCustomer">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,79 +0,0 @@
<?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.CreditDeliveryNoticeMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_delivery_notice a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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.otherPartiesThirdParty != null">
AND a.other_parties_third_party LIKE CONCAT('%', #{param.otherPartiesThirdParty}, '%')
</if>
<if test="param.occurrenceTime != null">
AND a.occurrence_time LIKE CONCAT('%', #{param.occurrenceTime}, '%')
</if>
<if test="param.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
<if test="param.causeOfAction != null">
AND a.cause_of_action LIKE CONCAT('%', #{param.causeOfAction}, '%')
</if>
<if test="param.courtName != null">
AND a.court_name LIKE CONCAT('%', #{param.courtName}, '%')
</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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.case_number LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditDeliveryNotice">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditDeliveryNotice">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,106 +0,0 @@
<?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.CreditExternalMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_external a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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>
<if test="param.statusTxt != null">
AND a.status_txt LIKE CONCAT('%', #{param.statusTxt}, '%')
</if>
<if test="param.legalRepresentative != null">
AND a.legal_representative LIKE CONCAT('%', #{param.legalRepresentative}, '%')
</if>
<if test="param.registeredCapital != null">
AND a.registered_capital = #{param.registeredCapital}
</if>
<if test="param.establishmentDate != null">
AND a.establishment_date LIKE CONCAT('%', #{param.establishmentDate}, '%')
</if>
<if test="param.shareholdingRatio != null">
AND a.shareholding_ratio = #{param.shareholdingRatio}
</if>
<if test="param.subscribedInvestmentAmount != null">
AND a.subscribed_investment_amount = #{param.subscribedInvestmentAmount}
</if>
<if test="param.subscribedInvestmentDate != null">
AND a.subscribed_investment_date LIKE CONCAT('%', #{param.subscribedInvestmentDate}, '%')
</if>
<if test="param.indirectShareholdingRatio != null">
AND a.indirect_shareholding_ratio = #{param.indirectShareholdingRatio}
</if>
<if test="param.investmentDate != null">
AND a.investment_date LIKE CONCAT('%', #{param.investmentDate}, '%')
</if>
<if test="param.region != null">
AND a.region LIKE CONCAT('%', #{param.region}, '%')
</if>
<if test="param.industry != null">
AND a.industry LIKE CONCAT('%', #{param.industry}, '%')
</if>
<if test="param.investmentCount != null">
AND a.investment_count = #{param.investmentCount}
</if>
<if test="param.relatedProductsInstitutions != null">
AND a.related_products_institutions LIKE CONCAT('%', #{param.relatedProductsInstitutions}, '%')
</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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.name LIKE CONCAT('%', #{param.name}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditExternal">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditExternal">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,82 +0,0 @@
<?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.CreditFinalVersionMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_final_version a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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.plaintiffAppellant != null">
AND a.plaintiff_appellant LIKE CONCAT('%', #{param.plaintiffAppellant}, '%')
</if>
<if test="param.appellee != null">
AND a.appellee LIKE CONCAT('%', #{param.appellee}, '%')
</if>
<if test="param.occurrenceTime != null">
AND a.occurrence_time LIKE CONCAT('%', #{param.occurrenceTime}, '%')
</if>
<if test="param.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
<if test="param.involvedAmount != null">
AND a.involved_amount = #{param.involvedAmount}
</if>
<if test="param.courtName != null">
AND a.court_name LIKE CONCAT('%', #{param.courtName}, '%')
</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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.case_number = #{param.keywords}
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditFinalVersion">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditFinalVersion">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -1,85 +0,0 @@
<?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.CreditGqdjMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*, b.name AS companyName, u.real_name AS realName
FROM credit_gqdj a
LEFT JOIN credit_company b ON a.company_id = b.id
LEFT JOIN gxwebsoft_core.sys_user u ON a.user_id = u.user_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>
<if test="param.plaintiffAppellant != null">
AND a.plaintiff_appellant LIKE CONCAT('%', #{param.plaintiffAppellant}, '%')
</if>
<if test="param.appellee != null">
AND a.appellee LIKE CONCAT('%', #{param.appellee}, '%')
</if>
<if test="param.caseNumber != null">
AND a.case_number LIKE CONCAT('%', #{param.caseNumber}, '%')
</if>
<if test="param.involvedAmount != null">
AND a.involved_amount = #{param.involvedAmount}
</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.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 LIKE CONCAT('%', #{param.keywords}, '%')
OR a.case_number = #{param.keywords}
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.credit.entity.CreditGqdj">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.credit.entity.CreditGqdj">
<include refid="selectSql"></include>
</select>
</mapper>

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