feat: 客户管理和项目管理导入支持

This commit is contained in:
caiyuchao
2025-08-07 15:33:19 +08:00
parent 9bf30280b9
commit 7a4f588f1d
11 changed files with 437 additions and 42 deletions

View File

@@ -11,20 +11,22 @@ public interface ErrorCodeConstants {
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_100_001_001, "客户不存在"); ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_100_001_001, "客户不存在");
ErrorCode CUSTOMER_NAME_DUPLICATE = new ErrorCode(1_100_001_002, "客户名称`{}`已存在"); ErrorCode CUSTOMER_NAME_DUPLICATE = new ErrorCode(1_100_001_002, "客户名称`{}`已存在");
ErrorCode CUSTOMER_CODE_DUPLICATE = new ErrorCode(1_100_001_003, "客户编号`{}`已存在"); ErrorCode CUSTOMER_CODE_DUPLICATE = new ErrorCode(1_100_001_003, "客户编号`{}`已存在");
ErrorCode CUSTOMER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_100_001_004, "导入客户数据不能为空!");
ErrorCode PROJECT_NOT_EXISTS = new ErrorCode(1_100_002_001, "项目不存在"); ErrorCode PROJECT_NOT_EXISTS = new ErrorCode(1_100_002_001, "项目不存在");
ErrorCode PROJECT_NAME_DUPLICATE = new ErrorCode(1_100_001_002, "项目名称`{}`已存在"); ErrorCode PROJECT_NAME_DUPLICATE = new ErrorCode(1_100_002_002, "项目名称`{}`已存在");
ErrorCode PROJECT_CODE_DUPLICATE = new ErrorCode(1_100_001_003, "项目编号`{}`已存在"); ErrorCode PROJECT_CODE_DUPLICATE = new ErrorCode(1_100_002_003, "项目编号`{}`已存在");
ErrorCode LICENSE_NOT_EXISTS = new ErrorCode(1_100_002_001, "License不存在"); ErrorCode PROJECT_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_100_002_004, "导入项目数据不能为空!");
ErrorCode LICENSE_SN_DUPLICATE = new ErrorCode(1_100_002_002, "License SN`{}`已存在"); ErrorCode LICENSE_NOT_EXISTS = new ErrorCode(1_100_003_001, "License存在");
ErrorCode LICENSE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_100_002_003, "导入License数据不能为空!"); ErrorCode LICENSE_SN_DUPLICATE = new ErrorCode(1_100_003_002, "License SN`{}`已存在");
ErrorCode LICENSE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_100_003_003, "导入License数据不能为空");
ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1_100_003_001, "评论不存在"); ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1_100_004_001, "评论不存在");
ErrorCode COMMENT_EXITS_CHILDREN = new ErrorCode(1_100_003_002, "存在子评论,无法删除"); ErrorCode COMMENT_EXITS_CHILDREN = new ErrorCode(1_100_004_002, "存在子评论,无法删除");
ErrorCode COMMENT_PARENT_NOT_EXITS = new ErrorCode(1_100_003_003,"父级评论不存在"); ErrorCode COMMENT_PARENT_NOT_EXITS = new ErrorCode(1_100_004_003,"父级评论不存在");
ErrorCode COMMENT_PARENT_ERROR = new ErrorCode(1_100_003_004, "不能设置自己为父评论"); ErrorCode COMMENT_PARENT_ERROR = new ErrorCode(1_100_004_004, "不能设置自己为父评论");
ErrorCode COMMENT_CONTENT_DUPLICATE = new ErrorCode(1_100_003_005, "已经存在该内容的评论"); ErrorCode COMMENT_CONTENT_DUPLICATE = new ErrorCode(1_100_004_005, "已经存在该内容的评论");
ErrorCode COMMENT_PARENT_IS_CHILD = new ErrorCode(1_100_003_006, "不能设置自己的子Comment为父Comment"); ErrorCode COMMENT_PARENT_IS_CHILD = new ErrorCode(1_100_004_006, "不能设置自己的子Comment为父Comment");
ErrorCode ALERT_NOT_EXISTS = new ErrorCode(1_100_004_001, "告警不存在"); ErrorCode ALERT_NOT_EXISTS = new ErrorCode(1_100_005_001, "告警不存在");
} }

View File

@@ -2,6 +2,7 @@ package org.agt.module.license.controller.admin.customer;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@@ -13,10 +14,12 @@ import org.agt.framework.common.pojo.PageResult;
import org.agt.framework.common.util.object.BeanUtils; import org.agt.framework.common.util.object.BeanUtils;
import org.agt.framework.excel.core.util.ExcelUtils; import org.agt.framework.excel.core.util.ExcelUtils;
import org.agt.framework.ip.core.utils.AreaUtils; import org.agt.framework.ip.core.utils.AreaUtils;
import org.agt.module.license.controller.admin.customer.vo.CustomerImportRespVO;
import org.agt.module.license.controller.admin.customer.vo.CustomerPageReqVO; import org.agt.module.license.controller.admin.customer.vo.CustomerPageReqVO;
import org.agt.module.license.controller.admin.customer.vo.CustomerRespVO; import org.agt.module.license.controller.admin.customer.vo.CustomerRespVO;
import org.agt.module.license.controller.admin.customer.vo.CustomerSaveReqVO; import org.agt.module.license.controller.admin.customer.vo.CustomerSaveReqVO;
import org.agt.module.license.controller.admin.customer.vo.DashboardRespVO; import org.agt.module.license.controller.admin.customer.vo.DashboardRespVO;
import org.agt.module.license.controller.admin.license.vo.ImportRespVO;
import org.agt.module.license.dal.dataobject.customer.CustomerDO; import org.agt.module.license.dal.dataobject.customer.CustomerDO;
import org.agt.module.license.service.customer.CustomerService; import org.agt.module.license.service.customer.CustomerService;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -29,8 +32,10 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.agt.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static org.agt.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -145,4 +150,33 @@ public class CustomerController {
} }
}); });
} }
@GetMapping("/get-import-template")
@Operation(summary = "获得导入客户模板")
public void importTemplate(HttpServletResponse response) throws IOException {
// 手动创建导出 demo
List<CustomerImportRespVO> list = Arrays.asList(
CustomerImportRespVO.builder().name("测试客户").code(2000L).type(1)
.areaNames("北京市 北京市 东城区").contacts("小李")
.build(),
CustomerImportRespVO.builder().name("测试客户2").code(2001L).type(1)
.areaNames("北京市").contacts("小李")
.build()
);
// 输出
ExcelUtils.write(response, "客户导入模板.xlsx", "客户列表", CustomerImportRespVO.class, list);
}
@PostMapping("/import")
@Operation(summary = "导入客户")
@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<CustomerImportRespVO> list = ExcelUtils.read(file, CustomerImportRespVO.class);
return success(customerService.importList(list, updateSupport));
}
} }

View File

@@ -0,0 +1,57 @@
package org.agt.module.license.controller.admin.customer.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 org.agt.framework.excel.core.annotations.DictFormat;
import org.agt.framework.excel.core.convert.DictConvert;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = false) // 设置 chain = false避免导入有问题
public class CustomerImportRespVO {
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@ExcelProperty("客户名称")
private String name;
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000")
@ExcelProperty("客户编号")
private Long code;
@Schema(description = "客户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty(value = "客户类型", converter = DictConvert.class)
@DictFormat("lic_customer_type")
private Integer type;
@Schema(description = "地区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "广东省")
@ExcelProperty("地区")
private String areaNames;
@Schema(description = "联系人", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("联系人")
private String contacts;
@Schema(description = "角色")
@ExcelProperty("角色")
private String role;
@Schema(description = "联系电话")
@ExcelProperty("联系电话")
private String phone;
@Schema(description = "邮箱")
@ExcelProperty("邮箱")
private String email;
@Schema(description = "备注", example = "随便")
@ExcelProperty("备注")
private String remark;
}

View File

@@ -186,7 +186,7 @@ public class LicenseController {
} }
@GetMapping("/get-import-template") @GetMapping("/get-import-template")
@Operation(summary = "获得导入用户模板") @Operation(summary = "获得导入License模板")
public void importTemplate(HttpServletResponse response) throws IOException { public void importTemplate(HttpServletResponse response) throws IOException {
// 手动创建导出 demo // 手动创建导出 demo
List<LicenseImportExcelVO> list = Arrays.asList( List<LicenseImportExcelVO> list = Arrays.asList(
@@ -204,7 +204,7 @@ public class LicenseController {
.build() .build()
); );
// 输出 // 输出
ExcelUtils.write(response, "用户导入模板.xlsx", "用户列表", LicenseImportExcelVO.class, list); ExcelUtils.write(response, "License导入模板.xlsx", "License列表", LicenseImportExcelVO.class, list);
} }
@PostMapping("/import") @PostMapping("/import")

View File

@@ -2,6 +2,7 @@ package org.agt.module.license.controller.admin.project;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@@ -31,8 +32,11 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.agt.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static org.agt.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -128,4 +132,35 @@ public class ProjectController {
public CommonResult<Integer> selectMaxCode() { public CommonResult<Integer> selectMaxCode() {
return success(projectService.selectMaxCode()); return success(projectService.selectMaxCode());
} }
@GetMapping("/get-import-template")
@Operation(summary = "获得导入项目模板")
public void importTemplate(HttpServletResponse response) throws IOException {
// 手动创建导出 demo
List<ProjectImportRespVO> list = Arrays.asList(
ProjectImportRespVO.builder().name("测试项目").serialNo("20002000").startTime(LocalDateTime.now())
.contractCode("111111").status(1).businessOwner("小明").technicalOwnerA("小张")
.businessStatus(1).customerOwner("小丽").envInfo("测试环境")
.build(),
ProjectImportRespVO.builder().name("测试项目2").serialNo("20002001").startTime(LocalDateTime.now())
.contractCode("222222").status(1).businessOwner("小明").technicalOwnerA("小张")
.businessStatus(1).customerOwner("小丽").envInfo("测试环境")
.build()
);
// 输出
ExcelUtils.write(response, "项目导入模板.xlsx", "项目列表", ProjectImportRespVO.class, list);
}
@PostMapping("/import")
@Operation(summary = "导入项目")
@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<ProjectImportRespVO> list = ExcelUtils.read(file, ProjectImportRespVO.class);
return success(projectService.importList(list, updateSupport));
}
} }

View File

@@ -0,0 +1,80 @@
package org.agt.module.license.controller.admin.project.vo;
import com.alibaba.excel.annotation.ExcelProperty;
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 java.time.LocalDateTime;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = false) // 设置 chain = false避免导入有问题
public class ProjectImportRespVO implements VO {
@Schema(description = "项目名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "aa")
@ExcelProperty("项目名称")
private String name;
@Schema(description = "serialNo", example = "随便")
@ExcelProperty("SN")
private String serialNo;
@Schema(description = "项目开始时间")
@ExcelProperty("项目开始时间")
private LocalDateTime startTime;
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1111")
@ExcelProperty("合同编号")
private String contractCode;
@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)
@ExcelProperty("业务负责人")
private String businessOwner;
@Schema(description = "技术负责人1ID", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("技术负责人1")
private String technicalOwnerA;
@Schema(description = "技术负责人2ID")
@ExcelProperty("技术负责人2")
private String technicalOwnerB;
@Schema(description = "技术负责人3ID")
@ExcelProperty("技术负责人3")
private String technicalOwnerC;
@Schema(description = "商务状态", example = "2")
@ExcelProperty(value = "商务状态", converter = DictConvert.class)
@DictFormat("lic_business_status")
private Integer businessStatus;
@Schema(description = "客户对接人ID", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("客户对接人")
private String customerOwner;
@Schema(description = "环境信息")
@ExcelProperty("环境信息")
private String envInfo;
@Schema(description = "项目结束时间")
@ExcelProperty("项目结束时间")
private LocalDateTime endTime;
@Schema(description = "备注", example = "随便")
@ExcelProperty("备注")
private String remark;
}

View File

@@ -26,10 +26,6 @@ public class ProjectRespVO implements VO {
@Trans(type = TransType.SIMPLE, target = CustomerDO.class, fields = "name", ref = "customerName") @Trans(type = TransType.SIMPLE, target = CustomerDO.class, fields = "name", ref = "customerName")
private Long customerId; private Long customerId;
@Schema(description = "所属客户")
@ExcelProperty("所属客户")
private String customerName;
@Schema(description = "项目名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "aa") @Schema(description = "项目名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "aa")
@ExcelProperty("项目名称") @ExcelProperty("项目名称")
private String name; private String name;
@@ -38,23 +34,31 @@ public class ProjectRespVO implements VO {
@ExcelProperty("项目编号") @ExcelProperty("项目编号")
private Long code; private Long code;
@Schema(description = "所属客户")
@ExcelProperty("所属客户")
private String customerName;
@Schema(description = "项目开始时间")
@ExcelProperty("项目开始时间")
private LocalDateTime startTime;
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1111") @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1111")
@ExcelProperty("合同编号") @ExcelProperty("合同编号")
private String contractCode; private String contractCode;
@Schema(description = "商务状态", example = "2") @Schema(description = "serialNo", example = "随便")
@ExcelProperty(value = "商务状态", converter = DictConvert.class) @ExcelProperty("SN")
@DictFormat("lic_business_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 private String serialNo;
private Integer businessStatus;
@Schema(description = "项目状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty(value = "项目状态", converter = DictConvert.class)
@DictFormat("lic_project_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Integer status;
@Schema(description = "业务负责人ID", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "业务负责人ID", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("业务负责人") @ExcelProperty("业务负责人")
private String businessOwner; private String businessOwner;
@Schema(description = "客户对接人ID", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("客户对接人")
private String customerOwner;
@Schema(description = "技术负责人1ID", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "技术负责人1ID", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("技术负责人1") @ExcelProperty("技术负责人1")
private String technicalOwnerA; private String technicalOwnerA;
@@ -67,23 +71,23 @@ public class ProjectRespVO implements VO {
@ExcelProperty("技术负责人3") @ExcelProperty("技术负责人3")
private String technicalOwnerC; private String technicalOwnerC;
@Schema(description = "项目开始时间") @Schema(description = "环境信息")
@ExcelProperty("项目开始时间") @ExcelProperty("环境信息")
private LocalDateTime startTime; private String envInfo;
@Schema(description = "商务状态", example = "2")
@ExcelProperty(value = "商务状态", converter = DictConvert.class)
@DictFormat("lic_business_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Integer businessStatus;
@Schema(description = "客户对接人ID", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("客户对接人")
private String customerOwner;
@Schema(description = "项目结束时间") @Schema(description = "项目结束时间")
@ExcelProperty("项目结束时间") @ExcelProperty("项目结束时间")
private LocalDateTime endTime; private LocalDateTime endTime;
@Schema(description = "项目状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty(value = "项目状态", converter = DictConvert.class)
@DictFormat("lic_project_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private Integer status;
@Schema(description = "环境信息")
@ExcelProperty("环境信息")
private String envInfo;
@Schema(description = "备注", example = "随便") @Schema(description = "备注", example = "随便")
@ExcelProperty("备注") @ExcelProperty("备注")
private String remark; private String remark;
@@ -91,8 +95,4 @@ public class ProjectRespVO implements VO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间") @ExcelProperty("创建时间")
private LocalDateTime createTime; private LocalDateTime createTime;
@Schema(description = "serialNo", example = "随便")
@ExcelProperty("SN")
private String serialNo;
} }

View File

@@ -2,9 +2,11 @@ package org.agt.module.license.service.customer;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.agt.framework.common.pojo.PageResult; import org.agt.framework.common.pojo.PageResult;
import org.agt.module.license.controller.admin.customer.vo.CustomerImportRespVO;
import org.agt.module.license.controller.admin.customer.vo.CustomerPageReqVO; import org.agt.module.license.controller.admin.customer.vo.CustomerPageReqVO;
import org.agt.module.license.controller.admin.customer.vo.CustomerSaveReqVO; import org.agt.module.license.controller.admin.customer.vo.CustomerSaveReqVO;
import org.agt.module.license.controller.admin.customer.vo.DashboardRespVO; import org.agt.module.license.controller.admin.customer.vo.DashboardRespVO;
import org.agt.module.license.controller.admin.license.vo.ImportRespVO;
import org.agt.module.license.dal.dataobject.customer.CustomerDO; import org.agt.module.license.dal.dataobject.customer.CustomerDO;
import java.util.List; import java.util.List;
@@ -87,4 +89,6 @@ public interface CustomerService {
* @return 最大sn号 * @return 最大sn号
*/ */
Integer selectMaxCode(); Integer selectMaxCode();
ImportRespVO importList(List<CustomerImportRespVO> list, Boolean updateSupport);
} }

View File

@@ -1,23 +1,32 @@
package org.agt.module.license.service.customer; package org.agt.module.license.service.customer;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.agt.framework.common.pojo.PageResult; import org.agt.framework.common.pojo.PageResult;
import org.agt.framework.common.util.object.BeanUtils; import org.agt.framework.common.util.object.BeanUtils;
import org.agt.framework.ip.core.utils.AreaUtils;
import org.agt.module.license.controller.admin.customer.vo.CustomerImportRespVO;
import org.agt.module.license.controller.admin.customer.vo.CustomerPageReqVO; import org.agt.module.license.controller.admin.customer.vo.CustomerPageReqVO;
import org.agt.module.license.controller.admin.customer.vo.CustomerSaveReqVO; import org.agt.module.license.controller.admin.customer.vo.CustomerSaveReqVO;
import org.agt.module.license.controller.admin.customer.vo.DashboardRespVO; import org.agt.module.license.controller.admin.customer.vo.DashboardRespVO;
import org.agt.module.license.controller.admin.license.vo.ImportRespVO;
import org.agt.module.license.dal.dataobject.customer.CustomerDO; import org.agt.module.license.dal.dataobject.customer.CustomerDO;
import org.agt.module.license.dal.mysql.customer.CustomerMapper; import org.agt.module.license.dal.mysql.customer.CustomerMapper;
import org.agt.module.license.dal.mysql.license.LicenseMapper; import org.agt.module.license.dal.mysql.license.LicenseMapper;
import org.agt.module.license.dal.mysql.project.ProjectMapper; import org.agt.module.license.dal.mysql.project.ProjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import static org.agt.framework.common.exception.util.ServiceExceptionUtil.exception; import static org.agt.framework.common.exception.util.ServiceExceptionUtil.exception;
import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_CODE_DUPLICATE; import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_CODE_DUPLICATE;
import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_IMPORT_LIST_IS_EMPTY;
import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_NAME_DUPLICATE; import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_NAME_DUPLICATE;
import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS; import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
@@ -30,6 +39,7 @@ import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_NOT_EXIST
@Validated @Validated
public class CustomerServiceImpl implements CustomerService { public class CustomerServiceImpl implements CustomerService {
private static final Logger log = LoggerFactory.getLogger(CustomerServiceImpl.class);
@Resource @Resource
private CustomerMapper customerMapper; private CustomerMapper customerMapper;
@@ -158,4 +168,63 @@ public class CustomerServiceImpl implements CustomerService {
return maxCode == null || maxCode < 2000 ? 2000 : maxCode + 1; return maxCode == null || maxCode < 2000 ? 2000 : maxCode + 1;
} }
@Override
public ImportRespVO importList(List<CustomerImportRespVO> list, Boolean updateSupport) {
if (CollUtil.isEmpty(list)) {
throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY);
}
ImportRespVO respVO = ImportRespVO.builder().creates(new ArrayList<>())
.updates(new ArrayList<>()).failures(new LinkedHashMap<>()).build();
for (CustomerImportRespVO importRespVO : list) {
CustomerDO customerDO = BeanUtils.toBean(importRespVO, CustomerDO.class);
String name = customerDO.getName();
if (StrUtil.isBlank(name)) {
respVO.getFailures().put(name, "客户编号不能为空");
continue;
}
if (StrUtil.isBlank(customerDO.getName())) {
respVO.getFailures().put(name, "客户名称不能为空");
continue;
}
if (customerDO.getType() == null) {
respVO.getFailures().put(name, "客户类型不能为空");
continue;
}
if (StrUtil.isBlank(customerDO.getContacts())) {
respVO.getFailures().put(name, "联系人不能为空");
continue;
}
try {
customerDO.setAreaId(Long.valueOf(AreaUtils.parseArea(importRespVO.getAreaNames(), " ").getId()));
} catch (Exception e) {
log.info("导入地区转换失败:{}", importRespVO.getAreaNames());
}
if (customerDO.getAreaId() == null) {
respVO.getFailures().put(name, "地区不能为空");
continue;
}
CustomerDO customer = customerMapper.selectByCode(customerDO.getCode());
if (customer == null) {
customerMapper.insert(customerDO);
respVO.getCreates().add(name);
continue;
}
if (!updateSupport) {
respVO.getFailures().put(name, "客户编号已存在");
continue;
}
customerDO.setId(customer.getId());
customerMapper.updateById(customerDO);
respVO.getUpdates().add(name);
}
return respVO;
}
} }

View File

@@ -2,6 +2,8 @@ package org.agt.module.license.service.project;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.agt.framework.common.pojo.PageResult; import org.agt.framework.common.pojo.PageResult;
import org.agt.module.license.controller.admin.license.vo.ImportRespVO;
import org.agt.module.license.controller.admin.project.vo.ProjectImportRespVO;
import org.agt.module.license.controller.admin.project.vo.ProjectListReqVO; import org.agt.module.license.controller.admin.project.vo.ProjectListReqVO;
import org.agt.module.license.controller.admin.project.vo.ProjectPageReqVO; 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.ProjectRespVO;
@@ -87,4 +89,6 @@ public interface ProjectService {
* @return 最大sn号 * @return 最大sn号
*/ */
Integer selectMaxCode(); Integer selectMaxCode();
ImportRespVO importList(List<ProjectImportRespVO> list, Boolean updateSupport);
} }

View File

@@ -1,22 +1,34 @@
package org.agt.module.license.service.project; package org.agt.module.license.service.project;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.agt.framework.common.pojo.PageResult; import org.agt.framework.common.pojo.PageResult;
import org.agt.framework.common.util.object.BeanUtils; import org.agt.framework.common.util.object.BeanUtils;
import org.agt.module.license.controller.admin.license.vo.ImportRespVO;
import org.agt.module.license.controller.admin.project.vo.ProjectImportRespVO;
import org.agt.module.license.controller.admin.project.vo.ProjectListReqVO; import org.agt.module.license.controller.admin.project.vo.ProjectListReqVO;
import org.agt.module.license.controller.admin.project.vo.ProjectPageReqVO; 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.ProjectRespVO;
import org.agt.module.license.controller.admin.project.vo.ProjectSaveReqVO; import org.agt.module.license.controller.admin.project.vo.ProjectSaveReqVO;
import org.agt.module.license.dal.dataobject.customer.CustomerDO;
import org.agt.module.license.dal.dataobject.project.ProjectDO; 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.project.ProjectMapper; import org.agt.module.license.dal.mysql.project.ProjectMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import static org.agt.framework.common.exception.util.ServiceExceptionUtil.exception; import static org.agt.framework.common.exception.util.ServiceExceptionUtil.exception;
import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_CODE_DUPLICATE; import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_CODE_DUPLICATE;
import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_IMPORT_LIST_IS_EMPTY;
import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_NAME_DUPLICATE; import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_NAME_DUPLICATE;
import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS; import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS;
@@ -27,11 +39,15 @@ import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class ProjectServiceImpl implements ProjectService { public class ProjectServiceImpl implements ProjectService {
@Resource @Resource
private ProjectMapper projectMapper; private ProjectMapper projectMapper;
@Resource
private CustomerMapper customerMapper;
@Override @Override
public Long createProject(ProjectSaveReqVO createReqVO) { public Long createProject(ProjectSaveReqVO createReqVO) {
// 校验项目名称和编号是否唯一 // 校验项目名称和编号是否唯一
@@ -138,4 +154,98 @@ public class ProjectServiceImpl implements ProjectService {
Integer maxCode = projectMapper.selectMaxCode(); Integer maxCode = projectMapper.selectMaxCode();
return maxCode == null || maxCode < 2000 ? 2000 : maxCode + 1; return maxCode == null || maxCode < 2000 ? 2000 : maxCode + 1;
} }
@Override
public ImportRespVO importList(List<ProjectImportRespVO> list, Boolean updateSupport) {
if (CollUtil.isEmpty(list)) {
throw exception(PROJECT_IMPORT_LIST_IS_EMPTY);
}
ImportRespVO respVO = ImportRespVO.builder().creates(new ArrayList<>())
.updates(new ArrayList<>()).failures(new LinkedHashMap<>()).build();
for (ProjectImportRespVO importRespVO : list) {
String name = importRespVO.getName();
String serialNo = importRespVO.getSerialNo();
if (StrUtil.isBlank(name)) {
respVO.getFailures().put(name, "项目名称不能为空");
continue;
}
if (StrUtil.isBlank(serialNo)) {
respVO.getFailures().put(name, "SN不能为空");
continue;
}
Long customerId = null;
String projectCode = "";
try {
String customerCode = serialNo.substring(0, 4);
projectCode = serialNo.substring(4);
CustomerDO customerDO = customerMapper.selectOne(Wrappers.<CustomerDO>lambdaQuery().eq(CustomerDO::getCode, customerCode));
customerId = customerDO.getId();
} catch (Exception e) {
log.info("导入报错:{}", e.getMessage());
}
if (StrUtil.isBlank(projectCode)) {
respVO.getFailures().put(name, "SN不正确");
continue;
}
if (customerId == null) {
respVO.getFailures().put(name, "所属客户不存在");
continue;
}
if (importRespVO.getStartTime() == null) {
respVO.getFailures().put(name, "项目开始时间不能为空");
continue;
}
if (StrUtil.isBlank(importRespVO.getContractCode())) {
respVO.getFailures().put(name, "合同不能为空");
continue;
}
if (importRespVO.getStatus() == null) {
respVO.getFailures().put(name, "项目状态不能为空");
continue;
}
if (StrUtil.isBlank(importRespVO.getBusinessOwner())) {
respVO.getFailures().put(name, "业务负责人不能为空");
continue;
}
if (StrUtil.isBlank(importRespVO.getTechnicalOwnerA())) {
respVO.getFailures().put(name, "技术负责人1不能为空");
continue;
}
if (importRespVO.getBusinessStatus() == null) {
respVO.getFailures().put(name, "商务状态不能为空");
continue;
}
if (StrUtil.isBlank(importRespVO.getCustomerOwner())) {
respVO.getFailures().put(name, "客户对接人不能为空");
continue;
}
if (StrUtil.isBlank(importRespVO.getEnvInfo())) {
respVO.getFailures().put(name, "环境信息不能为空");
continue;
}
ProjectDO projectDO = BeanUtils.toBean(importRespVO, ProjectDO.class);
projectDO.setCode(projectCode);
projectDO.setCustomerId(customerId);
ProjectDO project = projectMapper.selectByCode(projectDO.getCode());
if (project == null) {
projectMapper.insert(projectDO);
respVO.getCreates().add(name);
continue;
}
if (!updateSupport) {
respVO.getFailures().put(name, "项目编号已存在");
continue;
}
projectDO.setId(project.getId());
projectMapper.updateById(projectDO);
respVO.getUpdates().add(name);
}
return respVO;
}
} }