diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/LicenseController.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/LicenseController.java index 7c5c323..d904f6f 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/LicenseController.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/LicenseController.java @@ -140,7 +140,7 @@ public class LicenseController { @PreAuthorize("@ss.hasPermission('license:license:export')") @ApiAccessLog(operateType = EXPORT) public void exportLicenseExcel(@Valid LicensePageReqVO pageReqVO, - HttpServletResponse response) throws IOException { + HttpServletResponse response) throws IOException { pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); List voList = licenseService.getLicensePage(pageReqVO).getList(); @@ -198,17 +198,33 @@ public class LicenseController { public void importTemplate(HttpServletResponse response) throws IOException { // 手动创建导出 demo List list = Arrays.asList( - LicenseImportExcelVO.builder().serialNo("20002000") - .expiryDateExt(LocalDate.now()).userNumber(100).ranNumber(10).neListStr("AMF") - .activationCode("C097A721D68F07694FBA5EFB31626A623FB6A0FAE8E3002CA9C2561F3A9D54E63619E047F0E06862") + LicenseImportExcelVO.builder() + .customerName("测试客户") + .projectName("测试项目") + .applicationTime(LocalDate.of(2025, 2, 10)) + .serialNo("20002000") + .expiryDateExt("2026/5/1").neListStr("AMF+IMS") + .operatingSystem(1) + .contractCode("0") + .businessStatus(1) + .status(1) + .businessOwner(143L) + .technicalOwnerA(143L) + .technicalOwnerB(143L) .build(), - LicenseImportExcelVO.builder().serialNo("20002000") - .expiryDateExt(LocalDate.now()).userNumber(100).ranNumber(10).neListStr("SMF_UDM") - .activationCode("C097A721D68F07694FBA5EFB31626A623FB6A0FAE8E3002CA9C2561F3A9D54E63619E047F0E06862") - .build(), - LicenseImportExcelVO.builder().serialNo("20012001") - .expiryDateExt(LocalDate.now()).userNumber(200).ranNumber(30).neListStr("IMS") - .activationCode("C097A721D68F07694FBA5EFB31626A623FB6A0FAE8E3002CA9C2561F3A9D54E63619E047F0E06862") + LicenseImportExcelVO.builder() + .customerName("测试客户2") + .projectName("测试项目2") + .applicationTime(LocalDate.of(2025, 2, 10)) + .serialNo("20002000") + .expiryDateExt("2028/5/1").neListStr("AMF") + .operatingSystem(1) + .contractCode("0") + .businessStatus(1) + .status(1) + .businessOwner(143L) + .technicalOwnerA(143L) + .technicalOwnerB(143L) .build() ); // 输出 diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseImportExcelVO.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseImportExcelVO.java index 77dc049..ee7fb6c 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseImportExcelVO.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseImportExcelVO.java @@ -1,12 +1,19 @@ package org.agt.module.license.controller.admin.license.vo; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.fhs.core.trans.anno.Trans; +import com.fhs.core.trans.constant.TransType; +import com.fhs.core.trans.vo.VO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; +import org.agt.framework.excel.core.annotations.DictFormat; +import org.agt.framework.excel.core.convert.DictConvert; +import org.agt.module.system.api.user.AdminUserApi; import java.time.LocalDate; @@ -18,30 +25,90 @@ import java.time.LocalDate; @AllArgsConstructor @NoArgsConstructor @Accessors(chain = false) // 设置 chain = false,避免导入有问题 -public class LicenseImportExcelVO { +@ExcelIgnoreUnannotated +public class LicenseImportExcelVO implements VO { + + @Schema(description = "客户") + @ExcelProperty("客户") + private String customerName; + + @Schema(description = "项目") + @ExcelProperty("项目") + private String projectName; @Schema(description = "sn") @ExcelProperty("SN") private String serialNo; - @Schema(description = "到期时间") - @ExcelProperty("到期时间") - private LocalDate expiryDateExt; + @Schema(description = "创建日期") + @ExcelProperty("创建日期") + private LocalDate applicationTime; @Schema(description = "网元") - @ExcelProperty("网元") + @ExcelProperty("安装网元") private String neListStr; - @Schema(description = "激活码") - @ExcelProperty("激活码") - private String activationCode; + @Schema(description = "到期时间") + @ExcelProperty("license有效期") + private String expiryDateExt; - @Schema(description = "用户数") - @ExcelProperty("用户数") - private Integer userNumber; + @Schema(description = "操作系统") + @ExcelProperty(value = "操作系统平台", converter = DictConvert.class) + @DictFormat("lic_operating_system") + private Integer operatingSystem; - @Schema(description = "基站数") - @ExcelProperty("基站数") - private Integer ranNumber; + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1111") + @ExcelProperty("合同编号") + private String contractCode; + + @Schema(description = "商务状态", example = "2") + @ExcelProperty(value = "商务状态", converter = DictConvert.class) + @DictFormat("lic_business_status") + private Integer businessStatus; + + @Schema(description = "项目状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @ExcelProperty(value = "项目状态", converter = DictConvert.class) + @DictFormat("lic_project_status") + private Integer status; + + @Schema(description = "业务负责人ID", requiredMode = Schema.RequiredMode.REQUIRED) + @Trans(type = TransType.AUTO_TRANS, key = AdminUserApi.PREFIX, fields = "nickname", ref = "businessOwnerName") + private Long businessOwner; + + @Schema(description = "业务负责人", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("业务负责人") + private String businessOwnerName; + + @Schema(description = "技术负责人1ID", requiredMode = Schema.RequiredMode.REQUIRED) + @Trans(type = TransType.AUTO_TRANS, key = AdminUserApi.PREFIX, fields = "nickname", ref = "technicalOwnerAName") + private Long technicalOwnerA; + + @Schema(description = "技术负责人1", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("技术负责人1") + private String technicalOwnerAName; + + @Schema(description = "技术负责人2ID", requiredMode = Schema.RequiredMode.REQUIRED) + @Trans(type = TransType.AUTO_TRANS, key = AdminUserApi.PREFIX, fields = "nickname", ref = "technicalOwnerBName") + private Long technicalOwnerB; + + @Schema(description = "技术负责人2", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("技术负责人2") + private String technicalOwnerBName; + + @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("备注") + private String remark; + +// @Schema(description = "激活码") +// @ExcelProperty("激活码") +// private String activationCode; +// +// @Schema(description = "用户数") +// @ExcelProperty("用户数") +// private Integer userNumber; +// +// @Schema(description = "基站数") +// @ExcelProperty("基站数") +// private Integer ranNumber; } diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/customer/CustomerMapper.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/customer/CustomerMapper.java index 1689902..7ea67dc 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/customer/CustomerMapper.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/customer/CustomerMapper.java @@ -46,4 +46,6 @@ public interface CustomerMapper extends BaseMapperX { Long selectUserCount(); Long getUserByName(@Param("nickname") String nickname); + + Integer selectOldMaxCode(); } diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/project/ProjectMapper.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/project/ProjectMapper.java index e4b06f3..69860b3 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/project/ProjectMapper.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/project/ProjectMapper.java @@ -80,5 +80,7 @@ public interface ProjectMapper extends BaseMapperX { Integer selectMaxCode(); + Integer selectOldMaxCode(); + IPage queryPage(IPage page, @Param("query") ProjectPageReqVO reqVO); } \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/license/LicenseServiceImpl.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/license/LicenseServiceImpl.java index 2a419a9..87a0ab0 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/license/LicenseServiceImpl.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/license/LicenseServiceImpl.java @@ -45,10 +45,12 @@ import org.springframework.validation.annotation.Validated; import java.io.ByteArrayInputStream; import java.io.File; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -645,79 +647,71 @@ public class LicenseServiceImpl implements LicenseService { throw exception(LICENSE_IMPORT_LIST_IS_EMPTY); } + list = list.stream().filter(c -> StrUtil.isNotBlank(c.getSerialNo())).collect(Collectors.toList()); + for (LicenseImportExcelVO importExcelVO : list) { + if (StrUtil.isBlank(importExcelVO.getProjectName())) { + importExcelVO.setProjectName(importExcelVO.getCustomerName() + "-" + importExcelVO.getSerialNo()); + } + } + // 根据sn分组 ImportRespVO respVO = ImportRespVO.builder().creates(new ArrayList<>()) .updates(new ArrayList<>()).failures(new LinkedHashMap<>()).build(); Map> map = list.stream().collect(Collectors.groupingBy(LicenseImportExcelVO::getSerialNo)); + + List imports = new ArrayList<>(); for (Map.Entry> entry : map.entrySet()) { String serialNo = entry.getKey(); List importList = entry.getValue(); - if (StrUtil.isBlank(serialNo)) { - respVO.getFailures().put(serialNo, "SN不能为空"); + + if (importList.size() > 1) { + importList.sort(Comparator.comparing(LicenseImportExcelVO::getApplicationTime).reversed()); + imports.add(importList.get(0)); + for (int i = 1; i < importList.size(); i++) { + respVO.getFailures().put(serialNo, "SN重复,以最新的为准"); + } + } else { + imports.addAll(importList); + } + } + for (LicenseImportExcelVO importVO : imports) { + String serialNo = importVO.getSerialNo(); + if (StrUtil.isBlank(importVO.getCustomerName())) { + respVO.getFailures().put(importVO.getCustomerName(), "客户名称不能为空"); continue; } - Long customerId = null; + CustomerDO customerDO = customerMapper.selectOne(Wrappers.lambdaQuery().eq(CustomerDO::getName, importVO.getCustomerName()), false); + if (customerDO == null) { + Integer maxCustomerCode = customerMapper.selectOldMaxCode(); + customerDO = new CustomerDO(); + customerDO.setName(importVO.getCustomerName()); + customerDO.setCode(maxCustomerCode == null ? "1000" : maxCustomerCode + 1 + ""); + customerMapper.insert(customerDO); + } + Long customerId = customerDO.getId(); + + ProjectDO projectDO = projectMapper.selectOne(Wrappers.lambdaQuery().eq(ProjectDO::getName, importVO.getProjectName()), false); Long projectId = null; - try { - String customerCode = serialNo.substring(0, 4); - String projectCode = serialNo.substring(4); - CustomerDO customerDO = customerMapper.selectOne(Wrappers.lambdaQuery().eq(CustomerDO::getCode, customerCode)); - customerId = customerDO.getId(); - ProjectDO projectDO = projectMapper.selectOne(Wrappers.lambdaQuery().eq(ProjectDO::getCode, projectCode)); + + if (projectDO == null) { + Integer maxProjectCode = projectMapper.selectOldMaxCode(); + projectDO = BeanUtils.toBean(importVO, ProjectDO.class); + projectDO.setCustomerId(customerId); + projectDO.setName(importVO.getProjectName()); + projectDO.setCode(maxProjectCode == null ? "1000" : maxProjectCode + 1 + ""); + projectDO.setBusinessOwner(customerMapper.getUserByName(importVO.getBusinessOwnerName())); + projectDO.setTechnicalOwnerA(customerMapper.getUserByName(importVO.getTechnicalOwnerAName())); + projectDO.setTechnicalOwnerB(customerMapper.getUserByName(importVO.getTechnicalOwnerBName())); + projectMapper.insert(projectDO); projectId = projectDO.getId(); - } catch (Exception e) { - log.info("导入报错:{}", e.getMessage()); - } - if (customerId == null || projectId == null) { - respVO.getFailures().put(serialNo, "SN不存在"); - continue; - } - LicenseImportExcelVO importVO = importList.get(0); - - List licenseDetails = new ArrayList<>(); - for (LicenseImportExcelVO importDetailVO : importList) { - - if (StrUtil.isBlank(importDetailVO.getActivationCode())) { - respVO.getFailures().put(serialNo, "激活码不能为空"); - continue; - } - String neListStr = importDetailVO.getNeListStr(); - List neLabels = StrUtil.split(neListStr, "_"); - - List neList = new ArrayList<>(); - for (String ne : neLabels) { - String value = DictFrameworkUtils.parseDictDataValue("lic_ne_all", ne); - if (StrUtil.isBlank(value)) { - value = DictFrameworkUtils.parseDictDataValue("lic_ne_5g", ne); - if (StrUtil.isBlank(value)) { - value = DictFrameworkUtils.parseDictDataValue("lic_ne_4g", ne); - if (StrUtil.isBlank(value)) { - value = DictFrameworkUtils.parseDictDataValue("lic_ne_23g", ne); - if (StrUtil.isBlank(value)) { - value = DictFrameworkUtils.parseDictDataValue("lic_ne_add", ne); - } - } - } - } - if (StrUtil.isNotBlank(value)) { - neList.add(Integer.parseInt(value)); - } - - } - if (CollUtil.isEmpty(neList)) { - respVO.getFailures().put(serialNo, "网元不能为空"); - continue; - } - - LicenseDetailDO licenseDetailDO = new LicenseDetailDO(); - licenseDetailDO.setNeList(neList); - licenseDetailDO.setActivationCode(importDetailVO.getActivationCode()); - licenseDetails.add(licenseDetailDO); - - } - if (CollUtil.isEmpty(licenseDetails)) { - respVO.getFailures().put(serialNo, "网元或激活码不能为空"); - continue; + } else { + projectId = projectDO.getId(); + projectDO = BeanUtils.toBean(importVO, ProjectDO.class); + projectDO.setId(projectId); + projectDO.setBusinessOwner(customerMapper.getUserByName(importVO.getBusinessOwnerName())); + projectDO.setTechnicalOwnerA(customerMapper.getUserByName(importVO.getTechnicalOwnerAName())); + projectDO.setTechnicalOwnerB(customerMapper.getUserByName(importVO.getTechnicalOwnerBName())); + projectMapper.updateById(projectDO); } LicenseDO licenseDO = new LicenseDO(); @@ -726,50 +720,107 @@ public class LicenseServiceImpl implements LicenseService { licenseDO.setSerialNo(serialNo); licenseDO.setStatus(LicenseStatusEnum.COMPLETED.getCode()); licenseDO.setApplicant(WebFrameworkUtils.getLoginUserId()); - licenseDO.setExpiryDate(LocalDateTime.of(importVO.getExpiryDateExt(), LocalTime.of(23, 59, 59))); - licenseDO.setApplicationTime(LocalDateTime.now()); - licenseDO.setUserNumber(importVO.getUserNumber()); - licenseDO.setRanNumber(importVO.getRanNumber()); + String expiryDateExt = importVO.getExpiryDateExt(); + LocalDateTime expiryDate; + if ("永久".equals(expiryDateExt)) { + expiryDate = LocalDateTime.of(2099, 12, 31, 23, 59, 59); + } else { + expiryDate = LocalDateTime.of(LocalDate.parse(expiryDateExt, DateTimeFormatter.ofPattern("yyyy/M/d")), LocalTime.of(23, 59, 59)); + } + licenseDO.setExpiryDate(expiryDate); + licenseDO.setApplicationTime(LocalDateTime.of(importVO.getApplicationTime(), LocalTime.of(0, 0, 0))); +// licenseDO.setUserNumber(importVO.getUserNumber()); +// licenseDO.setRanNumber(importVO.getRanNumber()); licenseDO.setApprover(161L); + String neListStr = importVO.getNeListStr(); + List neList = getNeList(neListStr); + if (CollUtil.isEmpty(neList)) { + respVO.getFailures().put(serialNo, "网元不能为空"); + continue; + } + LicenseDO license = licenseMapper.selectBySn(serialNo); if (license == null) { licenseMapper.insert(licenseDO); - for (LicenseDetailDO licenseDetail : licenseDetails) { - licenseDetail.setLicenseId(licenseDO.getId()); - } - - licenseDetailMapper.insertBatch(licenseDetails); + LicenseDetailDO licenseDetailDO = new LicenseDetailDO(); + licenseDetailDO.setLicenseId(licenseDO.getId()); + licenseDetailDO.setNeList(neList); + licenseDetailMapper.insert(licenseDetailDO); respVO.getCreates().add(serialNo); continue; } - if (!updateSupport) { respVO.getFailures().put(serialNo, "已存在该SN的License"); continue; } + licenseDO.setId(license.getId()); licenseMapper.updateById(licenseDO); - for (LicenseDetailDO licenseDetail : licenseDetails) { - licenseDetail.setLicenseId(licenseDO.getId()); - } licenseDetailMapper.delete(Wrappers.lambdaQuery().eq(LicenseDetailDO::getLicenseId, licenseDO.getId())); + LicenseDetailDO licenseDetailDO = new LicenseDetailDO(); + licenseDetailDO.setLicenseId(licenseDO.getId()); + licenseDetailDO.setNeList(neList); + licenseDetailMapper.insert(licenseDetailDO); + List licenseHistoryDOS = licenseHistoryMapper.selectList(Wrappers.lambdaQuery().eq(LicenseHistoryDO::getLicenseId, licenseDO.getId())); for (LicenseHistoryDO licenseHistoryDO : licenseHistoryDOS) { licenseDetailHistoryMapper.delete(Wrappers.lambdaQuery().eq(LicenseDetailHistoryDO::getLicenseId, licenseHistoryDO.getId())); } licenseHistoryMapper.delete(Wrappers.lambdaQuery().eq(LicenseHistoryDO::getLicenseId, licenseDO.getId())); - - licenseDetailMapper.insertBatch(licenseDetails); respVO.getUpdates().add(serialNo); - } return respVO; } + private static List getNeList(String neListStr) { + + List neList = new ArrayList<>(); + + try { + List neLabels = StrUtil.split(neListStr, "+"); + for (String ne : neLabels) { + + if ("5GC".equals(ne)) { + List licNe5gStr = DictFrameworkUtils.getDictDataValueList("lic_ne_5g"); + List licNe5g = licNe5gStr.stream().map(Integer::parseInt).toList(); + neList.addAll(licNe5g); + continue; + } + if ("4GC".equals(ne)) { + List licNe5gStr = DictFrameworkUtils.getDictDataValueList("lic_ne_4g"); + List licNe5g = licNe5gStr.stream().map(Integer::parseInt).toList(); + neList.addAll(licNe5g); + continue; + } + + String value = DictFrameworkUtils.parseDictDataValue("lic_ne_all", ne); + if (StrUtil.isBlank(value)) { + value = DictFrameworkUtils.parseDictDataValue("lic_ne_5g", ne); + if (StrUtil.isBlank(value)) { + value = DictFrameworkUtils.parseDictDataValue("lic_ne_4g", ne); + if (StrUtil.isBlank(value)) { + value = DictFrameworkUtils.parseDictDataValue("lic_ne_23g", ne); + if (StrUtil.isBlank(value)) { + value = DictFrameworkUtils.parseDictDataValue("lic_ne_add", ne); + } + } + } + } + if (StrUtil.isNotBlank(value)) { + neList.add(Integer.parseInt(value)); + } + + } + } catch (NumberFormatException e) { + log.error("导入网元转换失败{}", e.getMessage()); + } + return neList; + } + private void fillLicenseHistoryRespVO(LicenseRespVO license) { List licenseDetailDOS = licenseDetailHistoryMapper.selectList(Wrappers.lambdaQuery().eq(LicenseDetailHistoryDO::getLicenseId, license.getId())); List details = BeanUtils.toBean(licenseDetailDOS, LicenseDetailVO.class); diff --git a/agt-module-license/agt-module-license-server/src/main/resources/mapper/customer/CustomerMapper.xml b/agt-module-license/agt-module-license-server/src/main/resources/mapper/customer/CustomerMapper.xml index 5e8f238..eea902d 100644 --- a/agt-module-license/agt-module-license-server/src/main/resources/mapper/customer/CustomerMapper.xml +++ b/agt-module-license/agt-module-license-server/src/main/resources/mapper/customer/CustomerMapper.xml @@ -14,4 +14,9 @@ select id from system_users where deleted = 0 and nickname = #{nickname} limit 1; + + + \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/resources/mapper/project/ProjectMapper.xml b/agt-module-license/agt-module-license-server/src/main/resources/mapper/project/ProjectMapper.xml index 85766a8..8a02e91 100644 --- a/agt-module-license/agt-module-license-server/src/main/resources/mapper/project/ProjectMapper.xml +++ b/agt-module-license/agt-module-license-server/src/main/resources/mapper/project/ProjectMapper.xml @@ -6,13 +6,17 @@ SELECT max(`code` + 0) from crm_project; + +