Files
mp-java/src/main/java/com/gxwebsoft/credit/controller/CreditCompetitorController.java
赵忠林 50f6b49da9 fix(import): 修复Excel导入时企业名称字段处理问题
- 移除CreditCompetitor、CreditCustomer、CreditExternal、CreditRiskRelation、CreditSupplier和CreditUser实体中companyName字段的@TableField(exist = false)注解
- 在各控制器的convertImportParamToEntity方法中添加CreditCompany::setCompanyName方法引用
- 从companyId获取对应的企业名称并设置到fixedCompanyName变量中
- 更新导入逻辑中的注释说明,明确name和companyName字段的不同用途
- 在导入过程中当companyName为空且存在固定公司名称时进行赋值处理
2026-03-15 11:55:24 +08:00

373 lines
15 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.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;
}
}