diff --git a/agt-module-license/agt-module-license-api/src/main/java/org/agt/module/license/enums/LicenseStatusEnum.java b/agt-module-license/agt-module-license-api/src/main/java/org/agt/module/license/enums/LicenseStatusEnum.java index a0b8c28..6046cb9 100644 --- a/agt-module-license/agt-module-license-api/src/main/java/org/agt/module/license/enums/LicenseStatusEnum.java +++ b/agt-module-license/agt-module-license-api/src/main/java/org/agt/module/license/enums/LicenseStatusEnum.java @@ -13,7 +13,8 @@ public enum LicenseStatusEnum { NOT_APPLIED(0, "未申请"), IN_APPLICATION(1, "申请中"), GENERATING(2, "生成中"), - COMPLETED(3, "已完成"); // CRM 系统专用 + COMPLETED(3, "已完成"), + REAPPLYING(4, "重新申请中"), ; /** 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 8bfdf0b..31b8c40 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 @@ -71,6 +71,14 @@ public class LicenseController { return success(true); } + @PutMapping("/reapply") + @Operation(summary = "重新申请License") + @PreAuthorize("@ss.hasPermission('license:license:apply')") + public CommonResult reapplyLicense(@Valid @RequestBody LicenseSaveReqVO updateReqVO) { + licenseService.reapplyLicense(updateReqVO); + return success(true); + } + @GetMapping("/generate") @Operation(summary = "生成License") @PreAuthorize("@ss.hasPermission('license:license:generate')") diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseDetailVO.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseDetailVO.java index 2738dbc..b71895a 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseDetailVO.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseDetailVO.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; +import java.util.Map; /** * @description: License网元和激活码表单 @@ -31,6 +32,15 @@ public class LicenseDetailVO { @Schema(description = "文件url列表") private List fileUrlList; + @Schema(description = "激活码Map") + private Map activationCodeMap; + + @Schema(description = "网元Map") + private Map> neListMap; + + @Schema(description = "文件url列表Map") + private Map> fileUrlListMap; + @Schema(description = "提供者ID") private Long providerId; } diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseRespVO.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseRespVO.java index dd90d77..c46d2bb 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseRespVO.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/license/vo/LicenseRespVO.java @@ -109,4 +109,6 @@ public class LicenseRespVO implements VO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") private LocalDateTime createTime; + + private LicenseRespVO oldLicense; } \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/dataobject/license/LicenseDetailHistoryDO.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/dataobject/license/LicenseDetailHistoryDO.java new file mode 100644 index 0000000..416a2eb --- /dev/null +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/dataobject/license/LicenseDetailHistoryDO.java @@ -0,0 +1,67 @@ +package org.agt.module.license.dal.dataobject.license; + +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.agt.framework.mybatis.core.dataobject.BaseDO; + +import java.util.List; + +/** + * LicenseDetailHistory DO + * + * @author 管理员 + */ +@TableName(value = "crm_license_detail_history", autoResultMap = true) +@KeySequence("crm_license_detail_history_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class LicenseDetailHistoryDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + /** + * 客户ID + */ + private Long licenseId; + + /** + * 网元开关 + * + * 枚举 {@link TODO lic_ne_switch 对应的类} + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List neList; + /** + * 激活码 + */ + private String activationCode; + /** + * 文件URL + */ + private String fileUrl; + /** + * 文件URL-Legacy + */ + private String fileUrlLegacy; + /** + * 提供者ID + */ + private Long providerId; + +} \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/dataobject/license/LicenseHistoryDO.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/dataobject/license/LicenseHistoryDO.java new file mode 100644 index 0000000..96a2ea8 --- /dev/null +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/dataobject/license/LicenseHistoryDO.java @@ -0,0 +1,92 @@ +package org.agt.module.license.dal.dataobject.license; + +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.agt.framework.mybatis.core.dataobject.BaseDO; + +import java.time.LocalDateTime; + +/** + * LicenseHistory DO + * + * @author 管理员 + */ +@TableName(value = "crm_license_server_history", autoResultMap = true) +@KeySequence("crm_license_server_history_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class LicenseHistoryDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + /** + * License ID + */ + private Long licenseId; + /** + * 客户ID + */ + private Long customerId; + /** + * 项目ID + */ + private Long projectId; + /** + * sn + */ + private String serialNo; + /** + * 到期时间 + */ + private LocalDateTime expiryDate; + + /** + * 用户数 + */ + private Integer userNumber; + /** + * 基站数 + */ + private Integer ranNumber; + /** + * 文件URL + */ + private String fileUrl; + /** + * 申请人 + */ + private Long applicant; + /** + * 申请时间 + */ + private LocalDateTime applicationTime; + /** + * 审批人 + */ + private Long approver; + /** + * 状态 + * + * 枚举 {@link TODO lic_license_status 对应的类} + */ + private Integer status; + /** + * 备注 + */ + private String remark; + +} \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/license/LicenseDetailHistoryMapper.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/license/LicenseDetailHistoryMapper.java new file mode 100644 index 0000000..9448fe1 --- /dev/null +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/license/LicenseDetailHistoryMapper.java @@ -0,0 +1,16 @@ +package org.agt.module.license.dal.mysql.license; + + +import org.agt.framework.mybatis.core.mapper.BaseMapperX; +import org.agt.module.license.dal.dataobject.license.LicenseDetailHistoryDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * CRM-License History Mapper + * + * @author super + */ +@Mapper +public interface LicenseDetailHistoryMapper extends BaseMapperX { + +} \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/license/LicenseHistoryMapper.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/license/LicenseHistoryMapper.java new file mode 100644 index 0000000..08bca59 --- /dev/null +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/dal/mysql/license/LicenseHistoryMapper.java @@ -0,0 +1,15 @@ +package org.agt.module.license.dal.mysql.license; + +import org.agt.framework.mybatis.core.mapper.BaseMapperX; +import org.agt.module.license.dal.dataobject.license.LicenseHistoryDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * LicenseHistory Mapper + * + * @author 管理员 + */ +@Mapper +public interface LicenseHistoryMapper extends BaseMapperX { + +} \ 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/LicenseService.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/license/LicenseService.java index 34f28c5..3c9d4d8 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/license/LicenseService.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/license/LicenseService.java @@ -38,6 +38,14 @@ public interface LicenseService { */ void applyLicense(@Valid LicenseSaveReqVO updateReqVO, List licenseDetails); + /** + * 重新申请License + * + * @param updateReqVO 更新信息 + */ + void reapplyLicense(@Valid LicenseSaveReqVO updateReqVO); + + /** * 生成License * 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 36672ed..90720eb 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 @@ -20,10 +20,14 @@ import org.agt.module.license.controller.admin.license.vo.LicenseSaveReqVO; import org.agt.module.license.dal.dataobject.customer.CustomerDO; import org.agt.module.license.dal.dataobject.license.LicenseDO; import org.agt.module.license.dal.dataobject.license.LicenseDetailDO; +import org.agt.module.license.dal.dataobject.license.LicenseDetailHistoryDO; +import org.agt.module.license.dal.dataobject.license.LicenseHistoryDO; import org.agt.module.license.dal.dataobject.license.LicenseProviderDO; import org.agt.module.license.dal.dataobject.project.ProjectDO; import org.agt.module.license.dal.mysql.customer.CustomerMapper; +import org.agt.module.license.dal.mysql.license.LicenseDetailHistoryMapper; import org.agt.module.license.dal.mysql.license.LicenseDetailMapper; +import org.agt.module.license.dal.mysql.license.LicenseHistoryMapper; import org.agt.module.license.dal.mysql.license.LicenseMapper; import org.agt.module.license.dal.mysql.license.LicenseProviderMapper; import org.agt.module.license.dal.mysql.project.ProjectMapper; @@ -45,6 +49,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; import static org.agt.framework.common.exception.util.ServiceExceptionUtil.exception; import static org.agt.module.license.enums.ErrorCodeConstants.LICENSE_NOT_EXISTS; @@ -84,6 +90,12 @@ public class LicenseServiceImpl implements LicenseService { @Resource private LicenseDetailMapper licenseDetailMapper; + @Resource + private LicenseHistoryMapper licenseHistoryMapper; + + @Resource + private LicenseDetailHistoryMapper licenseDetailHistoryMapper; + @Override @Transactional(rollbackFor = Exception.class) public Long createLicense(LicenseSaveReqVO createReqVO) { @@ -198,10 +210,43 @@ public class LicenseServiceImpl implements LicenseService { updateReqVO.setStatus(LicenseStatusEnum.IN_APPLICATION.getCode()); updateReqVO.setApplicant(WebFrameworkUtils.getLoginUserId()); updateReqVO.setApplicationTime(LocalDateTime.now()); -// updateReqVO.setNeCodeList(neCodeList); updateLicense(updateReqVO); } + @Override + @Transactional(rollbackFor = Exception.class) + public void reapplyLicense(LicenseSaveReqVO updateReqVO) { + // 校验存在 + validateLicenseExists(updateReqVO.getId()); + // 将现有的license迁移到历史表 + LicenseDO licenseDO = licenseMapper.selectById(updateReqVO.getId()); + List licenseDetailDOS = licenseDetailMapper.selectList(Wrappers.lambdaQuery().eq(LicenseDetailDO::getLicenseId, licenseDO.getId())); + + LicenseHistoryDO historyDO = BeanUtils.toBean(licenseDO, LicenseHistoryDO.class); + + licenseMapper.deleteById(updateReqVO.getId()); + licenseDetailMapper.delete(Wrappers.lambdaQuery().eq(LicenseDetailDO::getLicenseId, licenseDO.getId())); + + updateReqVO.setId(null); + Long licenseId = createLicense(updateReqVO); + + historyDO.setLicenseId(licenseId); + historyDO.setFileUrl(null); + licenseHistoryMapper.insert(historyDO); + + if (CollUtil.isNotEmpty(licenseDetailDOS)) { + List detailHistoryDOList = BeanUtils.toBean(licenseDetailDOS, LicenseDetailHistoryDO.class); + detailHistoryDOList.forEach(c -> { + c.setLicenseId(licenseId); + c.setFileUrlLegacy(null); + c.setFileUrl(null); + c.setProviderId(null); + }); + licenseDetailHistoryMapper.insertBatch(detailHistoryDOList); + } + licenseMapper.updateById(new LicenseDO().setId(licenseId).setStatus(LicenseStatusEnum.REAPPLYING.getCode())); + } + @Override @Transactional(rollbackFor = Exception.class) public String generate(Long id) { @@ -390,8 +435,74 @@ public class LicenseServiceImpl implements LicenseService { public LicenseRespVO getLicense(Long id) { LicenseDO licenseDO = licenseMapper.selectById(id); LicenseRespVO licenseRespVO = BeanUtils.toBean(licenseDO, LicenseRespVO.class); - List licenseDetailDOS = licenseDetailMapper.selectList(Wrappers.lambdaQuery().eq(LicenseDetailDO::getLicenseId, licenseDO.getId())); + fillLicenseRespVO(licenseRespVO); + return licenseRespVO; + } + + private void fillLicenseRespVO(LicenseRespVO license) { + List licenseDetailDOS = licenseDetailMapper.selectList(Wrappers.lambdaQuery().eq(LicenseDetailDO::getLicenseId, license.getId())); List details = BeanUtils.toBean(licenseDetailDOS, LicenseDetailVO.class); + fillDetail(details, license); + if (LicenseStatusEnum.REAPPLYING.getCode().equals(license.getStatus())) { + List historyList = licenseHistoryMapper.selectList(Wrappers.lambdaQuery() + .eq(LicenseHistoryDO::getLicenseId, license.getId()) + .orderByDesc(LicenseHistoryDO::getApplicationTime)); + Optional histroyOptional = historyList.stream().findFirst(); + if (histroyOptional.isPresent()) { + LicenseHistoryDO historyDO = histroyOptional.get(); + LicenseRespVO oldLicense = BeanUtils.toBean(historyDO, LicenseRespVO.class); + + List oldDetailDOS = licenseDetailHistoryMapper.selectList(Wrappers.lambdaQuery().eq(LicenseDetailHistoryDO::getLicenseId, oldLicense.getId())); + List oldDetails = BeanUtils.toBean(oldDetailDOS, LicenseDetailVO.class); + fillDetail(oldDetails, oldLicense); + + license.setOldLicense(oldLicense); + + int maxLength = oldDetails.size(); + if (oldDetails.size() < details.size()) { + maxLength = details.size(); + } + + List mergeDetails = new ArrayList<>(); + for (int i = 0; i < maxLength; i++) { + Map activationCodeMap = new HashMap<>(); + Map> neListMap = new HashMap<>(); + Map> fileUrlListMap = new HashMap<>(); + + LicenseDetailVO mergeDetail = new LicenseDetailVO(); + if (i < oldDetails.size()) { + activationCodeMap.put("old", oldDetails.get(i).getActivationCode()); + neListMap.put("old", oldDetails.get(i).getNeList()); + fileUrlListMap.put("old", oldDetails.get(i).getFileUrlList()); + mergeDetail.setFileUrl(oldDetails.get(i).getFileUrl()); + mergeDetail.setNeList(oldDetails.get(i).getNeList()); + mergeDetail.setActivationCode(oldDetails.get(i).getActivationCode()); + mergeDetail.setFileUrlList(oldDetails.get(i).getFileUrlList()); + } + + if (i < details.size()) { + if (!(i < oldDetails.size() && Objects.equals(oldDetails.get(i).getActivationCode(), details.get(i).getActivationCode()))) { + activationCodeMap.put("new", details.get(i).getActivationCode()); + } + if (!(i < oldDetails.size() && Objects.equals(oldDetails.get(i).getNeList(), details.get(i).getNeList()))) { + neListMap.put("new", details.get(i).getNeList()); + } + if (!(i < oldDetails.size() && Objects.equals(oldDetails.get(i).getFileUrlList(), details.get(i).getFileUrlList()))) { + fileUrlListMap.put("new", details.get(i).getFileUrlList()); + } + } + mergeDetail.setActivationCodeMap(activationCodeMap); + mergeDetail.setNeListMap(neListMap); + mergeDetail.setFileUrlListMap(fileUrlListMap); + mergeDetails.add(mergeDetail); + } + license.setNeCodeList(mergeDetails); + } + } + + } + + private void fillDetail(List details, LicenseRespVO licenseRespVO) { for (LicenseDetailVO detail : details) { List fileUrlList = new ArrayList<>(); if (StrUtil.isNotBlank(detail.getFileUrl())) { @@ -401,9 +512,20 @@ public class LicenseServiceImpl implements LicenseService { fileUrlList.add(detail.getFileUrlLegacy()); } detail.setFileUrlList(fileUrlList); + + Map activationCodeMap = new HashMap<>(); + activationCodeMap.put("old", detail.getActivationCode()); + detail.setActivationCodeMap(activationCodeMap); + + Map> neListMap = new HashMap<>(); + neListMap.put("old", detail.getNeList()); + detail.setNeListMap(neListMap); + + Map> fileUrlListMap = new HashMap<>(); + fileUrlListMap.put("old", detail.getFileUrlList()); + detail.setFileUrlListMap(fileUrlListMap); } licenseRespVO.setNeCodeList(details); - return licenseRespVO; } @Override @@ -411,19 +533,7 @@ public class LicenseServiceImpl implements LicenseService { PageResult pageResult = licenseMapper.selectPage(pageReqVO); PageResult voPageResult = BeanUtils.toBean(pageResult, LicenseRespVO.class); for (LicenseRespVO licenseRespVO : voPageResult.getList()) { - List licenseDetailDOS = licenseDetailMapper.selectList(Wrappers.lambdaQuery().eq(LicenseDetailDO::getLicenseId, licenseRespVO.getId())); - List details = BeanUtils.toBean(licenseDetailDOS, LicenseDetailVO.class); - for (LicenseDetailVO detail : details) { - List fileUrlList = new ArrayList<>(); - if (StrUtil.isNotBlank(detail.getFileUrl())) { - fileUrlList.add(detail.getFileUrl()); - } - if (StrUtil.isNotBlank(detail.getFileUrlLegacy())) { - fileUrlList.add(detail.getFileUrlLegacy()); - } - detail.setFileUrlList(fileUrlList); - } - licenseRespVO.setNeCodeList(details); + fillLicenseRespVO(licenseRespVO); } return voPageResult; }