From 7a4f588f1d590f23058abc93944d1f83afeb8b36 Mon Sep 17 00:00:00 2001 From: caiyuchao Date: Thu, 7 Aug 2025 15:33:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=A2=E6=88=B7=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=92=8C=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../license/enums/ErrorCodeConstants.java | 26 +++-- .../admin/customer/CustomerController.java | 34 ++++++ .../customer/vo/CustomerImportRespVO.java | 57 +++++++++ .../admin/license/LicenseController.java | 4 +- .../admin/project/ProjectController.java | 35 ++++++ .../admin/project/vo/ProjectImportRespVO.java | 80 +++++++++++++ .../admin/project/vo/ProjectRespVO.java | 56 ++++----- .../service/customer/CustomerService.java | 4 + .../service/customer/CustomerServiceImpl.java | 69 +++++++++++ .../service/project/ProjectService.java | 4 + .../service/project/ProjectServiceImpl.java | 110 ++++++++++++++++++ 11 files changed, 437 insertions(+), 42 deletions(-) create mode 100644 agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/customer/vo/CustomerImportRespVO.java create mode 100644 agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/vo/ProjectImportRespVO.java diff --git a/agt-module-license/agt-module-license-api/src/main/java/org/agt/module/license/enums/ErrorCodeConstants.java b/agt-module-license/agt-module-license-api/src/main/java/org/agt/module/license/enums/ErrorCodeConstants.java index 1afcb23..54fc6a3 100644 --- a/agt-module-license/agt-module-license-api/src/main/java/org/agt/module/license/enums/ErrorCodeConstants.java +++ b/agt-module-license/agt-module-license-api/src/main/java/org/agt/module/license/enums/ErrorCodeConstants.java @@ -11,20 +11,22 @@ public interface ErrorCodeConstants { ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_100_001_001, "客户不存在"); ErrorCode CUSTOMER_NAME_DUPLICATE = new ErrorCode(1_100_001_002, "客户名称`{}`已存在"); 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_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_002_002, "License SN`{}`已存在"); - ErrorCode LICENSE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_100_002_003, "导入License数据不能为空!"); + ErrorCode PROJECT_NAME_DUPLICATE = new ErrorCode(1_100_002_002, "项目名称`{}`已存在"); + ErrorCode PROJECT_CODE_DUPLICATE = new ErrorCode(1_100_002_003, "项目编号`{}`已存在"); + ErrorCode PROJECT_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_100_002_004, "导入项目数据不能为空!"); + ErrorCode LICENSE_NOT_EXISTS = new ErrorCode(1_100_003_001, "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_EXITS_CHILDREN = new ErrorCode(1_100_003_002, "存在子评论,无法删除"); - ErrorCode COMMENT_PARENT_NOT_EXITS = new ErrorCode(1_100_003_003,"父级评论不存在"); - ErrorCode COMMENT_PARENT_ERROR = new ErrorCode(1_100_003_004, "不能设置自己为父评论"); - ErrorCode COMMENT_CONTENT_DUPLICATE = new ErrorCode(1_100_003_005, "已经存在该内容的评论"); - ErrorCode COMMENT_PARENT_IS_CHILD = new ErrorCode(1_100_003_006, "不能设置自己的子Comment为父Comment"); + ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1_100_004_001, "评论不存在"); + ErrorCode COMMENT_EXITS_CHILDREN = new ErrorCode(1_100_004_002, "存在子评论,无法删除"); + ErrorCode COMMENT_PARENT_NOT_EXITS = new ErrorCode(1_100_004_003,"父级评论不存在"); + ErrorCode COMMENT_PARENT_ERROR = new ErrorCode(1_100_004_004, "不能设置自己为父评论"); + ErrorCode COMMENT_CONTENT_DUPLICATE = new ErrorCode(1_100_004_005, "已经存在该内容的评论"); + 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, "告警不存在"); } diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/customer/CustomerController.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/customer/CustomerController.java index afa301d..36e2746 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/customer/CustomerController.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/customer/CustomerController.java @@ -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.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; @@ -13,10 +14,12 @@ import org.agt.framework.common.pojo.PageResult; import org.agt.framework.common.util.object.BeanUtils; import org.agt.framework.excel.core.util.ExcelUtils; 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.CustomerRespVO; 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.license.vo.ImportRespVO; import org.agt.module.license.dal.dataobject.customer.CustomerDO; import org.agt.module.license.service.customer.CustomerService; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import java.io.IOException; +import java.util.Arrays; import java.util.List; 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 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 importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { + List list = ExcelUtils.read(file, CustomerImportRespVO.class); + return success(customerService.importList(list, updateSupport)); + } } \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/customer/vo/CustomerImportRespVO.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/customer/vo/CustomerImportRespVO.java new file mode 100644 index 0000000..97ed8b1 --- /dev/null +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/customer/vo/CustomerImportRespVO.java @@ -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; + +} \ No newline at end of file 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 5c41754..8d29fba 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 @@ -186,7 +186,7 @@ public class LicenseController { } @GetMapping("/get-import-template") - @Operation(summary = "获得导入用户模板") + @Operation(summary = "获得导入License模板") public void importTemplate(HttpServletResponse response) throws IOException { // 手动创建导出 demo List list = Arrays.asList( @@ -204,7 +204,7 @@ public class LicenseController { .build() ); // 输出 - ExcelUtils.write(response, "用户导入模板.xlsx", "用户列表", LicenseImportExcelVO.class, list); + ExcelUtils.write(response, "License导入模板.xlsx", "License列表", LicenseImportExcelVO.class, list); } @PostMapping("/import") diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/ProjectController.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/ProjectController.java index 37e1b83..55fc2e0 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/ProjectController.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/ProjectController.java @@ -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.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; @@ -31,8 +32,11 @@ 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.LocalDateTime; +import java.util.Arrays; import java.util.List; import static org.agt.framework.apilog.core.enums.OperateTypeEnum.EXPORT; @@ -128,4 +132,35 @@ public class ProjectController { public CommonResult selectMaxCode() { return success(projectService.selectMaxCode()); } + + @GetMapping("/get-import-template") + @Operation(summary = "获得导入项目模板") + public void importTemplate(HttpServletResponse response) throws IOException { + // 手动创建导出 demo + List 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 importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { + List list = ExcelUtils.read(file, ProjectImportRespVO.class); + return success(projectService.importList(list, updateSupport)); + } } \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/vo/ProjectImportRespVO.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/vo/ProjectImportRespVO.java new file mode 100644 index 0000000..291bbb7 --- /dev/null +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/vo/ProjectImportRespVO.java @@ -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; +} \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/vo/ProjectRespVO.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/vo/ProjectRespVO.java index 70865dc..2bf248e 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/vo/ProjectRespVO.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/controller/admin/project/vo/ProjectRespVO.java @@ -26,10 +26,6 @@ public class ProjectRespVO implements VO { @Trans(type = TransType.SIMPLE, target = CustomerDO.class, fields = "name", ref = "customerName") private Long customerId; - @Schema(description = "所属客户") - @ExcelProperty("所属客户") - private String customerName; - @Schema(description = "项目名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "aa") @ExcelProperty("项目名称") private String name; @@ -38,23 +34,31 @@ public class ProjectRespVO implements VO { @ExcelProperty("项目编号") private Long code; + @Schema(description = "所属客户") + @ExcelProperty("所属客户") + private String customerName; + + @Schema(description = "项目开始时间") + @ExcelProperty("项目开始时间") + private LocalDateTime startTime; + @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") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 - private Integer businessStatus; + @Schema(description = "serialNo", example = "随便") + @ExcelProperty("SN") + private String serialNo; + + @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) @ExcelProperty("业务负责人") private String businessOwner; - @Schema(description = "客户对接人ID", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("客户对接人") - private String customerOwner; - @Schema(description = "技术负责人1ID", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("技术负责人1") private String technicalOwnerA; @@ -67,23 +71,23 @@ public class ProjectRespVO implements VO { @ExcelProperty("技术负责人3") private String technicalOwnerC; - @Schema(description = "项目开始时间") - @ExcelProperty("项目开始时间") - private LocalDateTime startTime; + @Schema(description = "环境信息") + @ExcelProperty("环境信息") + 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 = "项目结束时间") @ExcelProperty("项目结束时间") 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 = "随便") @ExcelProperty("备注") private String remark; @@ -91,8 +95,4 @@ public class ProjectRespVO implements VO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") private LocalDateTime createTime; - - @Schema(description = "serialNo", example = "随便") - @ExcelProperty("SN") - private String serialNo; } \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/customer/CustomerService.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/customer/CustomerService.java index bb4543d..ca7c123 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/customer/CustomerService.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/customer/CustomerService.java @@ -2,9 +2,11 @@ package org.agt.module.license.service.customer; import jakarta.validation.Valid; 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.CustomerSaveReqVO; 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 java.util.List; @@ -87,4 +89,6 @@ public interface CustomerService { * @return 最大sn号 */ Integer selectMaxCode(); + + ImportRespVO importList(List list, Boolean updateSupport); } \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/customer/CustomerServiceImpl.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/customer/CustomerServiceImpl.java index edaf1c5..46c74b9 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/customer/CustomerServiceImpl.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/customer/CustomerServiceImpl.java @@ -1,23 +1,32 @@ package org.agt.module.license.service.customer; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import jakarta.annotation.Resource; import org.agt.framework.common.pojo.PageResult; 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.CustomerSaveReqVO; 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.mysql.customer.CustomerMapper; import org.agt.module.license.dal.mysql.license.LicenseMapper; 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.validation.annotation.Validated; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; 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_IMPORT_LIST_IS_EMPTY; import static org.agt.module.license.enums.ErrorCodeConstants.CUSTOMER_NAME_DUPLICATE; 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 public class CustomerServiceImpl implements CustomerService { + private static final Logger log = LoggerFactory.getLogger(CustomerServiceImpl.class); @Resource private CustomerMapper customerMapper; @@ -158,4 +168,63 @@ public class CustomerServiceImpl implements CustomerService { return maxCode == null || maxCode < 2000 ? 2000 : maxCode + 1; } + @Override + public ImportRespVO importList(List 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; + } + } \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/project/ProjectService.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/project/ProjectService.java index ce72b68..3961974 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/project/ProjectService.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/project/ProjectService.java @@ -2,6 +2,8 @@ package org.agt.module.license.service.project; 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.project.vo.ProjectImportRespVO; 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.ProjectRespVO; @@ -87,4 +89,6 @@ public interface ProjectService { * @return 最大sn号 */ Integer selectMaxCode(); + + ImportRespVO importList(List list, Boolean updateSupport); } \ No newline at end of file diff --git a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/project/ProjectServiceImpl.java b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/project/ProjectServiceImpl.java index 1eee229..5593fea 100644 --- a/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/project/ProjectServiceImpl.java +++ b/agt-module-license/agt-module-license-server/src/main/java/org/agt/module/license/service/project/ProjectServiceImpl.java @@ -1,22 +1,34 @@ package org.agt.module.license.service.project; +import cn.hutool.core.collection.CollUtil; 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 lombok.extern.slf4j.Slf4j; import org.agt.framework.common.pojo.PageResult; 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.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.customer.CustomerDO; 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.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; 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_IMPORT_LIST_IS_EMPTY; import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_NAME_DUPLICATE; 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 @Validated +@Slf4j public class ProjectServiceImpl implements ProjectService { @Resource private ProjectMapper projectMapper; + @Resource + private CustomerMapper customerMapper; + @Override public Long createProject(ProjectSaveReqVO createReqVO) { // 校验项目名称和编号是否唯一 @@ -138,4 +154,98 @@ public class ProjectServiceImpl implements ProjectService { Integer maxCode = projectMapper.selectMaxCode(); return maxCode == null || maxCode < 2000 ? 2000 : maxCode + 1; } + + @Override + public ImportRespVO importList(List 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.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; + } } \ No newline at end of file