feat(import): 批量导入功能增加公司ID参数支持

- 为所有批量导入接口增加可选的companyId参数
- 在导入过程中将companyId设置到实体对象中
- 修复客户导入时的租户ID冲突处理逻辑
- 添加数据完整性验证异常处理机制
- 实现字符串字段的标准化处理功能
- 优化重复数据检测和更新逻辑
This commit is contained in:
2026-01-05 14:30:46 +08:00
parent bb3cf97cc9
commit 064d3b168e
19 changed files with 170 additions and 46 deletions

View File

@@ -131,7 +131,8 @@ public class CreditBreachOfTrustController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditBreachOfTrust:save')")
@Operation(summary = "批量导入失信被执行人")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -155,6 +156,9 @@ public class CreditBreachOfTrustController extends BaseController {
try {
CreditBreachOfTrust item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditCaseFilingController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCaseFiling:save')")
@Operation(summary = "批量导入司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditCaseFilingController extends BaseController {
try {
CreditCaseFiling item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditCompanyController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@Operation(summary = "批量导入企业")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;

View File

@@ -135,7 +135,8 @@ public class CreditCompetitorController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCompetitor:save')")
@Operation(summary = "批量导入竞争对手")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditCompetitorController extends BaseController {
try {
CreditCompetitor item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditCourtAnnouncementController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCourtAnnouncement:save')")
@Operation(summary = "批量导入法院公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditCourtAnnouncementController extends BaseController {
try {
CreditCourtAnnouncement item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditCourtSessionController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCourtSession:save')")
@Operation(summary = "批量导入开庭公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditCourtSessionController extends BaseController {
try {
CreditCourtSession item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -13,6 +13,7 @@ import com.gxwebsoft.credit.service.CreditCustomerService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -130,7 +131,8 @@ public class CreditCustomerController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditCustomer:save')")
@Operation(summary = "批量导入客户")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -151,9 +153,13 @@ public class CreditCustomerController extends BaseController {
for (int i = 0; i < list.size(); i++) {
CreditCustomerImportParam param = list.get(i);
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
try {
CreditCustomer item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
@@ -170,31 +176,58 @@ public class CreditCustomerController extends BaseController {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getName())) {
errorMessages.add("" + excelRowNumber + "行:客户不能为空");
continue;
}
boolean saved = creditCustomerService.save(item);
if (!saved) {
CreditCustomer existing = creditCustomerService.lambdaQuery()
.eq(CreditCustomer::getName, item.getName())
.one();
if (existing != null) {
item.setId(existing.getId());
if (creditCustomerService.updateById(item)) {
CreditCustomer existing = creditCustomerService.lambdaQuery()
.eq(CreditCustomer::getName, item.getName())
.one();
if (existing != null) {
Integer existingTenantId = existing.getTenantId();
if (item.getTenantId() != null
&& existingTenantId != null
&& !item.getTenantId().equals(existingTenantId)) {
errorMessages.add("" + excelRowNumber + "行:客户名称已存在且归属其他租户,无法导入");
continue;
}
item.setId(existing.getId());
if (existingTenantId != null) {
item.setTenantId(existingTenantId);
}
if (creditCustomerService.updateById(item)) {
successCount++;
continue;
}
} else {
try {
if (creditCustomerService.save(item)) {
successCount++;
continue;
}
} catch (DataIntegrityViolationException e) {
if (!isDuplicateCustomerName(e)) {
throw e;
}
CreditCustomer dbExisting = creditCustomerService.lambdaQuery()
.eq(CreditCustomer::getName, item.getName())
.one();
if (dbExisting != null) {
Integer existingTenantId = dbExisting.getTenantId();
item.setId(dbExisting.getId());
if (existingTenantId != null) {
item.setTenantId(existingTenantId);
}
if (creditCustomerService.updateById(item)) {
successCount++;
continue;
}
}
}
} else {
successCount++;
continue;
}
errorMessages.add("" + excelRowNumber + "行:保存失败");
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
@@ -249,14 +282,36 @@ public class CreditCustomerController extends BaseController {
private CreditCustomer convertImportParamToEntity(CreditCustomerImportParam param) {
CreditCustomer entity = new CreditCustomer();
entity.setName(param.getName());
entity.setStatusTxt(param.getStatusTxt());
entity.setPrice(param.getPrice());
entity.setPublicDate(param.getPublicDate());
entity.setDataSource(param.getDataSource());
entity.setComments(param.getComments());
entity.setName(normalizeString(param.getName()));
entity.setStatusTxt(normalizeString(param.getStatusTxt()));
entity.setPrice(normalizeString(param.getPrice()));
entity.setPublicDate(normalizeString(param.getPublicDate()));
entity.setDataSource(normalizeString(param.getDataSource()));
entity.setComments(normalizeString(param.getComments()));
return entity;
}
private String normalizeString(String value) {
if (ImportHelper.isBlank(value)) {
return null;
}
return value.trim();
}
private boolean isDuplicateCustomerName(DataIntegrityViolationException e) {
Throwable mostSpecificCause = e.getMostSpecificCause();
String message = mostSpecificCause != null ? mostSpecificCause.getMessage() : e.getMessage();
if (message == null) {
return false;
}
String lower = message.toLowerCase();
if (!lower.contains("duplicate")) {
return false;
}
return lower.contains("credit_customer.name")
|| lower.contains("for key 'name'")
|| lower.contains("for key `name`");
}
}

View File

@@ -135,7 +135,8 @@ public class CreditDeliveryNoticeController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditDeliveryNotice:save')")
@Operation(summary = "批量导入送达公告司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditDeliveryNoticeController extends BaseController {
try {
CreditDeliveryNotice item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditExternalController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditExternal:save')")
@Operation(summary = "批量导入对外投资")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditExternalController extends BaseController {
try {
CreditExternal item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditFinalVersionController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditFinalVersion:save')")
@Operation(summary = "批量导入终本案件")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditFinalVersionController extends BaseController {
try {
CreditFinalVersion item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditGqdjController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditGqdj:save')")
@Operation(summary = "批量导入股权冻结司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditGqdjController extends BaseController {
try {
CreditGqdj item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -145,7 +145,8 @@ public class CreditJudgmentDebtorController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditJudgmentDebtor:save')")
@Operation(summary = "批量导入被执行人")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
try {
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
@@ -153,9 +154,9 @@ public class CreditJudgmentDebtorController extends BaseController {
ImportOutcome outcome;
if (isZip(file)) {
outcome = importFromZip(file, currentUserId, currentTenantId);
outcome = importFromZip(file, currentUserId, currentTenantId, companyId);
} else {
outcome = importFromExcel(file, safeFileLabel(file.getOriginalFilename()), currentUserId, currentTenantId, false);
outcome = importFromExcel(file, safeFileLabel(file.getOriginalFilename()), currentUserId, currentTenantId, companyId, false);
}
if (!outcome.anyDataRead) {
@@ -260,7 +261,7 @@ public class CreditJudgmentDebtorController extends BaseController {
}
}
private ImportOutcome importFromExcel(MultipartFile excelFile, String fileLabel, Integer currentUserId, Integer currentTenantId, boolean strictDebtorSheet) throws Exception {
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;
@@ -297,6 +298,9 @@ public class CreditJudgmentDebtorController extends BaseController {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
@@ -344,15 +348,15 @@ public class CreditJudgmentDebtorController extends BaseController {
return new ImportOutcome(true, successCount, errorMessages);
}
private ImportOutcome importFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId) throws Exception {
private ImportOutcome importFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId, Integer companyId) throws Exception {
try {
return importFromZip(zipFile, currentUserId, currentTenantId, StandardCharsets.UTF_8);
return importFromZip(zipFile, currentUserId, currentTenantId, companyId, StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
return importFromZip(zipFile, currentUserId, currentTenantId, Charset.forName("GBK"));
return importFromZip(zipFile, currentUserId, currentTenantId, companyId, Charset.forName("GBK"));
}
}
private ImportOutcome importFromZip(MultipartFile zipFile, Integer currentUserId, Integer currentTenantId, Charset charset) throws Exception {
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;
@@ -373,7 +377,7 @@ public class CreditJudgmentDebtorController extends BaseController {
MultipartFile excelFile = new InMemoryMultipartFile(entryFileName, bytes);
try {
ImportOutcome outcome = importFromExcel(excelFile, entryFileName, currentUserId, currentTenantId, true);
ImportOutcome outcome = importFromExcel(excelFile, entryFileName, currentUserId, currentTenantId, companyId, true);
if (outcome.anyDataRead) {
anyDataRead = true;
successCount += outcome.successCount;

View File

@@ -135,7 +135,8 @@ public class CreditJudicialDocumentController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditJudicialDocument:save')")
@Operation(summary = "批量导入裁判文书司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditJudicialDocumentController extends BaseController {
try {
CreditJudicialDocument item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -134,7 +134,8 @@ public class CreditJudiciaryController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditJudiciary:save')")
@Operation(summary = "批量导入司法案件")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -164,6 +165,9 @@ public class CreditJudiciaryController extends BaseController {
CreditJudiciaryImportParam param = list.get(i);
try {
CreditJudiciary item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
// 设置默认值
if (item.getUserId() == null && currentUserId != null) {

View File

@@ -135,7 +135,8 @@ public class CreditMediationController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditMediation:save')")
@Operation(summary = "批量导入诉前调解司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditMediationController extends BaseController {
try {
CreditMediation item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditRiskRelationController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditRiskRelation:save')")
@Operation(summary = "批量导入风险关系表")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -160,6 +161,9 @@ public class CreditRiskRelationController extends BaseController {
try {
CreditRiskRelation item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -135,7 +135,8 @@ public class CreditSupplierController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditSupplier:save')")
@Operation(summary = "批量导入供应商")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditSupplierController extends BaseController {
try {
CreditSupplier item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}

View File

@@ -148,7 +148,8 @@ public class CreditUserController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditUser:save')")
@Operation(summary = "批量导入招投标信息")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -184,6 +185,9 @@ public class CreditUserController extends BaseController {
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
// 设置默认值
if (item.getUserId() == null && currentUserId != null) {

View File

@@ -135,7 +135,8 @@ public class CreditXgxfController extends BaseController {
@PreAuthorize("hasAuthority('credit:creditXgxf:save')")
@Operation(summary = "批量导入限制高消费司法大数据")
@PostMapping("/import")
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file) {
public ApiResult<List<String>> importBatch(@RequestParam("file") MultipartFile file,
@RequestParam(value = "companyId", required = false) Integer companyId) {
List<String> errorMessages = new ArrayList<>();
int successCount = 0;
@@ -159,6 +160,9 @@ public class CreditXgxfController extends BaseController {
try {
CreditXgxf item = convertImportParamToEntity(param);
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}