feat: 导入License
This commit is contained in:
@@ -15,7 +15,8 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode PROJECT_NAME_DUPLICATE = new ErrorCode(1_100_001_002, "项目名称`{}`已存在");
|
||||
ErrorCode PROJECT_CODE_DUPLICATE = new ErrorCode(1_100_001_003, "项目编号`{}`已存在");
|
||||
ErrorCode LICENSE_NOT_EXISTS = new ErrorCode(1_100_002_001, "License不存在");
|
||||
ErrorCode LICENSE_SN_DUPLICATE = new ErrorCode(1_100_001_002, "License SN`{}`已存在");
|
||||
ErrorCode LICENSE_SN_DUPLICATE = new ErrorCode(1_100_002_002, "License SN`{}`已存在");
|
||||
ErrorCode LICENSE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_100_002_003, "导入License数据不能为空!");
|
||||
|
||||
ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1_100_003_001, "评论不存在");
|
||||
ErrorCode COMMENT_EXITS_CHILDREN = new ErrorCode(1_100_003_002, "存在子评论,无法删除");
|
||||
|
||||
@@ -134,7 +134,7 @@ public class CustomerController {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
PageResult<CustomerDO> pageResult = customerService.getCustomerPage(pageReqVO);
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "客户.xls", "数据", CustomerRespVO.class,
|
||||
ExcelUtils.write(response, "客户.xlsx", "数据", CustomerRespVO.class,
|
||||
buildCustomerVOList(pageResult).getList());
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@@ -16,7 +17,9 @@ import org.agt.framework.common.util.object.BeanUtils;
|
||||
import org.agt.framework.dict.core.DictFrameworkUtils;
|
||||
import org.agt.framework.excel.core.util.ExcelUtils;
|
||||
import org.agt.framework.translate.core.TranslateUtils;
|
||||
import org.agt.module.license.controller.admin.license.vo.ImportRespVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseDetailVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseImportExcelVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicensePageReqVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseRespVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseSaveReqVO;
|
||||
@@ -31,9 +34,12 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.agt.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
@@ -168,7 +174,7 @@ public class LicenseController {
|
||||
|
||||
}
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "License.xls", "数据", LicenseRespVO.class,
|
||||
ExcelUtils.write(response, "License.xlsx", "数据", LicenseRespVO.class,
|
||||
TranslateUtils.translate(results));
|
||||
}
|
||||
|
||||
@@ -178,4 +184,39 @@ public class LicenseController {
|
||||
Boolean isExists = licenseService.validateLicenseSnUnique(sn, id);
|
||||
return success(isExists);
|
||||
}
|
||||
|
||||
@GetMapping("/get-import-template")
|
||||
@Operation(summary = "获得导入用户模板")
|
||||
public void importTemplate(HttpServletResponse response) throws IOException {
|
||||
// 手动创建导出 demo
|
||||
List<LicenseImportExcelVO> list = Arrays.asList(
|
||||
LicenseImportExcelVO.builder().serialNo("20002000")
|
||||
.expiryDateExt(LocalDate.now()).userNumber(100).ranNumber(10).neListStr("AMF")
|
||||
.activationCode("C097A721D68F07694FBA5EFB31626A623FB6A0FAE8E3002CA9C2561F3A9D54E63619E047F0E06862")
|
||||
.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")
|
||||
.build()
|
||||
);
|
||||
// 输出
|
||||
ExcelUtils.write(response, "用户导入模板.xlsx", "用户列表", LicenseImportExcelVO.class, list);
|
||||
}
|
||||
|
||||
@PostMapping("/import")
|
||||
@Operation(summary = "导入License")
|
||||
@Parameters({
|
||||
@Parameter(name = "file", description = "Excel 文件", required = true),
|
||||
@Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
|
||||
})
|
||||
@PreAuthorize("@ss.hasPermission('system:user:import')")
|
||||
public CommonResult<ImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
|
||||
List<LicenseImportExcelVO> list = ExcelUtils.read(file, LicenseImportExcelVO.class);
|
||||
return success(licenseService.importList(list, updateSupport));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.agt.module.license.controller.admin.license.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "管理后台 - 导入 Response VO")
|
||||
@Data
|
||||
@Builder
|
||||
public class ImportRespVO {
|
||||
|
||||
@Schema(description = "创建成功的数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<String> creates;
|
||||
|
||||
@Schema(description = "更新成功的数组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private List<String> updates;
|
||||
|
||||
@Schema(description = "导入失败的集合,key 为导入关键字段,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Map<String, String> failures;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.agt.module.license.controller.admin.license.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
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 java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* License Excel 导入 VO
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = false) // 设置 chain = false,避免导入有问题
|
||||
public class LicenseImportExcelVO {
|
||||
|
||||
@Schema(description = "sn")
|
||||
@ExcelProperty("SN")
|
||||
private String serialNo;
|
||||
|
||||
@Schema(description = "到期时间")
|
||||
@ExcelProperty("到期时间")
|
||||
private LocalDate expiryDateExt;
|
||||
|
||||
@Schema(description = "网元")
|
||||
@ExcelProperty("网元")
|
||||
private String neListStr;
|
||||
|
||||
@Schema(description = "激活码")
|
||||
@ExcelProperty("激活码")
|
||||
private String activationCode;
|
||||
|
||||
@Schema(description = "用户数")
|
||||
@ExcelProperty("用户数")
|
||||
private Integer userNumber;
|
||||
|
||||
@Schema(description = "基站数")
|
||||
@ExcelProperty("基站数")
|
||||
private Integer ranNumber;
|
||||
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import org.agt.module.license.controller.admin.project.vo.ProjectPageReqVO;
|
||||
import org.agt.module.license.controller.admin.project.vo.ProjectRespVO;
|
||||
import org.agt.module.license.controller.admin.project.vo.ProjectSaveReqVO;
|
||||
import org.agt.module.license.dal.dataobject.project.ProjectDO;
|
||||
import org.agt.module.license.dal.mysql.license.LicenseMapper;
|
||||
import org.agt.module.license.service.project.ProjectService;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -46,9 +45,6 @@ public class ProjectController {
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
|
||||
@Resource
|
||||
private LicenseMapper licenseMapper;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建项目")
|
||||
@PreAuthorize("@ss.hasPermission('license:project:create')")
|
||||
@@ -107,7 +103,7 @@ public class ProjectController {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<ProjectRespVO> list = projectService.getProjectPage(pageReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "项目.xls", "数据", ProjectRespVO.class,
|
||||
ExcelUtils.write(response, "项目.xlsx", "数据", ProjectRespVO.class,
|
||||
TranslateUtils.translate(list));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.agt.module.license.service.license;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import org.agt.framework.common.pojo.PageResult;
|
||||
import org.agt.module.license.controller.admin.license.vo.ImportRespVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseImportExcelVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicensePageReqVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseRespVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseSaveReqVO;
|
||||
@@ -87,4 +89,6 @@ public interface LicenseService {
|
||||
Boolean validateLicenseSnUnique(String sn, Long id);
|
||||
|
||||
List<LicenseRespVO> getLicenseHistory(Long id);
|
||||
|
||||
ImportRespVO importList(List<LicenseImportExcelVO> list, Boolean updateSupport);
|
||||
}
|
||||
@@ -13,7 +13,9 @@ import org.agt.framework.common.util.object.BeanUtils;
|
||||
import org.agt.framework.dict.core.DictFrameworkUtils;
|
||||
import org.agt.framework.web.core.util.WebFrameworkUtils;
|
||||
import org.agt.module.infra.api.file.FileApi;
|
||||
import org.agt.module.license.controller.admin.license.vo.ImportRespVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseDetailVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseImportExcelVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicensePageReqVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseRespVO;
|
||||
import org.agt.module.license.controller.admin.license.vo.LicenseSaveReqVO;
|
||||
@@ -47,11 +49,14 @@ import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.agt.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static org.agt.module.license.enums.ErrorCodeConstants.LICENSE_IMPORT_LIST_IS_EMPTY;
|
||||
import static org.agt.module.license.enums.ErrorCodeConstants.LICENSE_NOT_EXISTS;
|
||||
import static org.agt.module.license.enums.ErrorCodeConstants.LICENSE_SN_DUPLICATE;
|
||||
|
||||
@@ -587,6 +592,138 @@ public class LicenseServiceImpl implements LicenseService {
|
||||
return voList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ImportRespVO importList(List<LicenseImportExcelVO> list, Boolean updateSupport) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
throw exception(LICENSE_IMPORT_LIST_IS_EMPTY);
|
||||
}
|
||||
|
||||
// 根据sn分组
|
||||
ImportRespVO respVO = ImportRespVO.builder().creates(new ArrayList<>())
|
||||
.updates(new ArrayList<>()).failures(new LinkedHashMap<>()).build();
|
||||
Map<String, List<LicenseImportExcelVO>> map = list.stream().collect(Collectors.groupingBy(LicenseImportExcelVO::getSerialNo));
|
||||
for (Map.Entry<String, List<LicenseImportExcelVO>> entry : map.entrySet()) {
|
||||
String serialNo = entry.getKey();
|
||||
List<LicenseImportExcelVO> importList = entry.getValue();
|
||||
if (StrUtil.isBlank(serialNo)) {
|
||||
respVO.getFailures().put(serialNo, "SN不能为空");
|
||||
continue;
|
||||
}
|
||||
Long customerId = null;
|
||||
Long projectId = null;
|
||||
try {
|
||||
String customerCode = serialNo.substring(0, 4);
|
||||
String projectCode = serialNo.substring(4);
|
||||
CustomerDO customerDO = customerMapper.selectOne(Wrappers.<CustomerDO>lambdaQuery().eq(CustomerDO::getCode, customerCode));
|
||||
customerId = customerDO.getId();
|
||||
ProjectDO projectDO = projectMapper.selectOne(Wrappers.<ProjectDO>lambdaQuery().eq(ProjectDO::getCode, projectCode));
|
||||
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<LicenseDetailDO> licenseDetails = new ArrayList<>();
|
||||
for (LicenseImportExcelVO importDetailVO : importList) {
|
||||
|
||||
if (StrUtil.isBlank(importDetailVO.getActivationCode())) {
|
||||
respVO.getFailures().put(serialNo, "激活码不能为空");
|
||||
continue;
|
||||
}
|
||||
String neListStr = importDetailVO.getNeListStr();
|
||||
List<String> neLabels = StrUtil.split(neListStr, "_");
|
||||
|
||||
List<Integer> 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;
|
||||
}
|
||||
|
||||
LicenseDO licenseDO = new LicenseDO();
|
||||
licenseDO.setCustomerId(customerId);
|
||||
licenseDO.setProjectId(projectId);
|
||||
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());
|
||||
licenseDO.setApprover(161L);
|
||||
|
||||
LicenseDO license = licenseMapper.selectBySn(serialNo);
|
||||
if (license == null) {
|
||||
licenseMapper.insert(licenseDO);
|
||||
for (LicenseDetailDO licenseDetail : licenseDetails) {
|
||||
licenseDetail.setLicenseId(licenseDO.getId());
|
||||
}
|
||||
|
||||
licenseDetailMapper.insertBatch(licenseDetails);
|
||||
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.<LicenseDetailDO>lambdaQuery().eq(LicenseDetailDO::getLicenseId, licenseDO.getId()));
|
||||
|
||||
List<LicenseHistoryDO> licenseHistoryDOS = licenseHistoryMapper.selectList(Wrappers.<LicenseHistoryDO>lambdaQuery().eq(LicenseHistoryDO::getLicenseId, licenseDO.getId()));
|
||||
for (LicenseHistoryDO licenseHistoryDO : licenseHistoryDOS) {
|
||||
licenseDetailHistoryMapper.delete(Wrappers.<LicenseDetailHistoryDO>lambdaQuery().eq(LicenseDetailHistoryDO::getLicenseId, licenseHistoryDO.getId()));
|
||||
}
|
||||
licenseHistoryMapper.delete(Wrappers.<LicenseHistoryDO>lambdaQuery().eq(LicenseHistoryDO::getLicenseId, licenseDO.getId()));
|
||||
|
||||
licenseDetailMapper.insertBatch(licenseDetails);
|
||||
respVO.getUpdates().add(serialNo);
|
||||
|
||||
}
|
||||
|
||||
return respVO;
|
||||
}
|
||||
|
||||
private void fillLicenseHistoryRespVO(LicenseRespVO license) {
|
||||
List<LicenseDetailHistoryDO> licenseDetailDOS = licenseDetailHistoryMapper.selectList(Wrappers.<LicenseDetailHistoryDO>lambdaQuery().eq(LicenseDetailHistoryDO::getLicenseId, license.getId()));
|
||||
List<LicenseDetailVO> details = BeanUtils.toBean(licenseDetailDOS, LicenseDetailVO.class);
|
||||
|
||||
Reference in New Issue
Block a user