Files
mp-java/src/main/java/com/gxwebsoft/credit/controller/CreditFinalVersionController.java
赵忠林 f9c693533c feat(credit): 添加数据状态字段并标记历史导入数据为失效
- 在CreditAdministrativeLicense实体中添加dataStatus字段
- 为行政许可控制器中的历史导入数据统一标记为"失效"
- 为失信被执行人控制器中的历史导入数据统一标记为"失效"
- 为法院庭审控制器中的历史导入数据统一标记为"失效"
- 为最终版本控制器中的历史导入数据统一标记为"失效"
- 为工商登记控制器中的历史导入数据统一标记为"失效"
- 为判决债务人控制器中的历史导入数据统一标记为"失效"
- 为司法文书控制器中的历史导入数据统一标记为"失效"
- 为信用修复控制器中的历史导入数据统一标记为"失效"
2026-01-31 13:17:10 +08:00

642 lines
29 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.LinkedHashMap;
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 (creditFinalVersionService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@OperationLog
@Operation(summary = "批量添加终本案件")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditFinalVersion> list) {
if (creditFinalVersionService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:update')")
@OperationLog
@Operation(summary = "批量修改终本案件")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditFinalVersion> batchParam) {
if (batchParam.update(creditFinalVersionService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditFinalVersion:remove')")
@OperationLog
@Operation(summary = "批量删除终本案件")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditFinalVersionService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 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;
BatchImportSupport.CompanyIdRefreshStats stats = batchImportSupport.refreshCompanyIdByCompanyName(
creditFinalVersionService,
creditCompanyService,
currentTenantId,
onlyNull,
limit,
CreditFinalVersion::getId,
CreditFinalVersion::setId,
CreditFinalVersion::getAppellee,
CreditFinalVersion::getCompanyId,
CreditFinalVersion::setCompanyId,
CreditFinalVersion::getHasData,
CreditFinalVersion::setHasData,
CreditFinalVersion::getTenantId,
CreditFinalVersion::new
);
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.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditFinalVersionService,
chunkItems,
CreditFinalVersion::getId,
CreditFinalVersion::setId,
CreditFinalVersion::getCaseNumber,
CreditFinalVersion::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditFinalVersionService.save(rowItem);
if (!saved) {
CreditFinalVersion existing = creditFinalVersionService.lambdaQuery()
.eq(CreditFinalVersion::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditFinalVersionService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditFinalVersionService,
chunkItems,
CreditFinalVersion::getId,
CreditFinalVersion::setId,
CreditFinalVersion::getCaseNumber,
CreditFinalVersion::getCaseNumber,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditFinalVersionService.save(rowItem);
if (!saved) {
CreditFinalVersion existing = creditFinalVersionService.lambdaQuery()
.eq(CreditFinalVersion::getCaseNumber, rowItem.getCaseNumber())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditFinalVersionService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
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);
}
}
/**
* 批量导入历史终本案件(仅解析“历史终本案件”选项卡)
* 规则案号相同则覆盖更新recommend++ 记录更新次数);案号不存在则插入。
*/
@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, "案号");
LinkedHashMap<String, CreditFinalVersion> latestByCaseNumber = new LinkedHashMap<>();
LinkedHashMap<String, Integer> latestRowByCaseNumber = new LinkedHashMap<>();
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("失效");
latestByCaseNumber.put(item.getCaseNumber(), item);
latestRowByCaseNumber.put(item.getCaseNumber(), excelRowNumber);
} catch (Exception e) {
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (latestByCaseNumber.isEmpty()) {
if (errorMessages.isEmpty()) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
return success("导入完成成功0条失败" + errorMessages.size() + "", errorMessages);
}
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditFinalVersion> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (Map.Entry<String, CreditFinalVersion> entry : latestByCaseNumber.entrySet()) {
String caseNumber = entry.getKey();
CreditFinalVersion item = entry.getValue();
Integer rowNo = latestRowByCaseNumber.get(caseNumber);
chunkItems.add(item);
chunkRowNumbers.add(rowNo != null ? rowNo : -1);
if (chunkItems.size() >= chunkSize) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKeyAndIncrementCounterOnUpdate(
creditFinalVersionService,
chunkItems,
CreditFinalVersion::getId,
CreditFinalVersion::setId,
CreditFinalVersion::getCaseNumber,
CreditFinalVersion::getCaseNumber,
CreditFinalVersion::getRecommend,
CreditFinalVersion::setRecommend,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
if (rowItem.getRecommend() == null) {
rowItem.setRecommend(0);
}
boolean saved = creditFinalVersionService.save(rowItem);
if (!saved) {
CreditFinalVersion existing = creditFinalVersionService.lambdaQuery()
.eq(CreditFinalVersion::getCaseNumber, rowItem.getCaseNumber())
.select(CreditFinalVersion::getId, CreditFinalVersion::getRecommend)
.one();
if (existing != null) {
rowItem.setId(existing.getId());
Integer old = existing.getRecommend();
rowItem.setRecommend(old == null ? 1 : old + 1);
if (creditFinalVersionService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKeyAndIncrementCounterOnUpdate(
creditFinalVersionService,
chunkItems,
CreditFinalVersion::getId,
CreditFinalVersion::setId,
CreditFinalVersion::getCaseNumber,
CreditFinalVersion::getCaseNumber,
CreditFinalVersion::getRecommend,
CreditFinalVersion::setRecommend,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
if (rowItem.getRecommend() == null) {
rowItem.setRecommend(0);
}
boolean saved = creditFinalVersionService.save(rowItem);
if (!saved) {
CreditFinalVersion existing = creditFinalVersionService.lambdaQuery()
.eq(CreditFinalVersion::getCaseNumber, rowItem.getCaseNumber())
.select(CreditFinalVersion::getId, CreditFinalVersion::getRecommend)
.one();
if (existing != null) {
rowItem.setId(existing.getId());
Integer old = existing.getRecommend();
rowItem.setRecommend(old == null ? 1 : old + 1);
if (creditFinalVersionService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
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;
}
}