Files
java-10584/src/main/java/com/gxwebsoft/credit/controller/CreditPatentController.java
赵忠林 a1a3d78dd6 feat(generator): 添加代码生成器模板和AI聊天功能
- 新增.gitignore文件配置忽略规则
- 添加Taro页面配置模板add.config.ts.btl
- 添加Taro页面组件模板add.tsx.btl用于动态表单生成
- 实现AiController提供AI聊天消息处理功能
- 集成WebSocket实现AI消息流式传输
- 添加支付宝支付配置工具类AlipayConfigUtil
- 创建支付宝参数实体AlipayParam
- 集成阿里云短信发送工具AliYunSender
- 添加阿里云机器翻译工具AliyunTranslateUtil
- 完善API响应结果包装类ApiResult
- 配置多环境应用参数application.yml
- 添加CMS生产环境配置application-cms.yml
- 添加开发环境配置application-dev.yml
- 添加生产环境配置application-prod.yml
2026-02-13 02:21:21 +08:00

432 lines
18 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.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 (creditPatentService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('credit:creditPatent:save')")
@OperationLog
@Operation(summary = "批量添加专利")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<CreditPatent> list) {
if (creditPatentService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('credit:creditPatent:update')")
@OperationLog
@Operation(summary = "批量修改专利")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<CreditPatent> batchParam) {
if (batchParam.update(creditPatentService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('credit:creditPatent:remove')")
@OperationLog
@Operation(summary = "批量删除专利")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (creditPatentService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
/**
* 根据企业名称匹配企业并更新 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 {
ExcelImportSupport.ImportResult<CreditPatentImportParam> importResult = ExcelImportSupport.readAnySheet(
file, CreditPatentImportParam.class, this::isEmptyImportRow);
List<CreditPatentImportParam> list = importResult.getData();
int usedTitleRows = importResult.getTitleRows();
int usedHeadRows = importResult.getHeadRows();
int usedSheetIndex = importResult.getSheetIndex();
if (CollectionUtils.isEmpty(list)) {
return fail("未读取到数据,请确认模板表头与示例格式一致", null);
}
User loginUser = getLoginUser();
Integer currentUserId = loginUser != null ? loginUser.getUserId() : null;
Integer currentTenantId = loginUser != null ? loginUser.getTenantId() : null;
Map<String, String> urlByRegisterNo = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "申请号");
Map<String, String> urlByName = ExcelImportSupport.readHyperlinksByHeaderKey(file, usedSheetIndex, usedTitleRows, usedHeadRows, "发明名称");
final int chunkSize = 500;
final int mpBatchSize = 500;
List<CreditPatent> chunkItems = new ArrayList<>(chunkSize);
List<Integer> chunkRowNumbers = new ArrayList<>(chunkSize);
for (int i = 0; i < list.size(); i++) {
CreditPatentImportParam param = list.get(i);
try {
CreditPatent item = convertImportParamToEntity(param);
String link = null;
if (!ImportHelper.isBlank(item.getRegisterNo())) {
link = urlByRegisterNo.get(item.getRegisterNo().trim());
}
if ((link == null || link.isEmpty()) && !ImportHelper.isBlank(item.getName())) {
link = urlByName.get(item.getName().trim());
}
if (link != null && !link.isEmpty()) {
item.setUrl(link);
}
if (item.getCompanyId() == null && companyId != null) {
item.setCompanyId(companyId);
}
if (item.getUserId() == null && currentUserId != null) {
item.setUserId(currentUserId);
}
if (item.getTenantId() == null && currentTenantId != null) {
item.setTenantId(currentTenantId);
}
if (item.getStatus() == null) {
item.setStatus(0);
}
if (item.getRecommend() == null) {
item.setRecommend(0);
}
if (item.getDeleted() == null) {
item.setDeleted(0);
}
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
if (ImportHelper.isBlank(item.getRegisterNo())) {
errorMessages.add("" + excelRowNumber + "行:申请号不能为空");
continue;
}
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(
creditPatentService,
chunkItems,
CreditPatent::getId,
CreditPatent::setId,
CreditPatent::getRegisterNo,
CreditPatent::getRegisterNo,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditPatentService.save(rowItem);
if (!saved) {
CreditPatent existing = creditPatentService.lambdaQuery()
.eq(CreditPatent::getRegisterNo, rowItem.getRegisterNo())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditPatentService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
chunkItems.clear();
chunkRowNumbers.clear();
}
} catch (Exception e) {
int excelRowNumber = i + 1 + usedTitleRows + usedHeadRows;
errorMessages.add("" + excelRowNumber + "行:" + e.getMessage());
e.printStackTrace();
}
}
if (!chunkItems.isEmpty()) {
successCount += batchImportSupport.persistChunkWithFallback(
chunkItems,
chunkRowNumbers,
() -> batchImportSupport.upsertBySingleKey(
creditPatentService,
chunkItems,
CreditPatent::getId,
CreditPatent::setId,
CreditPatent::getRegisterNo,
CreditPatent::getRegisterNo,
null,
mpBatchSize
),
(rowItem, rowNumber) -> {
boolean saved = creditPatentService.save(rowItem);
if (!saved) {
CreditPatent existing = creditPatentService.lambdaQuery()
.eq(CreditPatent::getRegisterNo, rowItem.getRegisterNo())
.one();
if (existing != null) {
rowItem.setId(existing.getId());
if (creditPatentService.updateById(rowItem)) {
return true;
}
}
} else {
return true;
}
String prefix = rowNumber > 0 ? ("" + rowNumber + "行:") : "";
errorMessages.add(prefix + "保存失败");
return false;
},
errorMessages
);
}
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.getPublicNo());
}
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;
}
}