From e26bd20a5b121f729cc42e5aa6168806a73f394f Mon Sep 17 00:00:00 2001 From: dhb52 Date: Mon, 16 Oct 2023 23:45:18 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=8F=8Aexcel=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-module-crm/yudao-module-crm-biz/pom.xml | 15 +++++- .../test/resources/application-unit-test.yaml | 50 +++++++++++++++++++ .../src/test/resources/logback.xml | 4 ++ 3 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/test/resources/logback.xml diff --git a/yudao-module-crm/yudao-module-crm-biz/pom.xml b/yudao-module-crm/yudao-module-crm-biz/pom.xml index dc2818da9..5bedf5eac 100644 --- a/yudao-module-crm/yudao-module-crm-biz/pom.xml +++ b/yudao-module-crm/yudao-module-crm-biz/pom.xml @@ -1,6 +1,6 @@ - cn.iocoder.boot @@ -22,6 +22,11 @@ yudao-module-system-api ${revision} + + cn.iocoder.boot + yudao-module-crm-api + ${revision} + @@ -46,6 +51,12 @@ yudao-spring-boot-starter-mybatis + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + cn.iocoder.boot diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml new file mode 100644 index 000000000..767f2526f --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/application-unit-test.yaml @@ -0,0 +1,50 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + +--- #################### 数据库相关配置 #################### + +spring: + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 + +mybatis-plus: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +# Resilience4j 配置项 + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/resources/logback.xml b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/logback.xml new file mode 100644 index 000000000..1d071e479 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/logback.xml @@ -0,0 +1,4 @@ + + + + From eedb528412f5c790250d55663d88689821c52d3a Mon Sep 17 00:00:00 2001 From: dhb52 Date: Mon, 16 Oct 2023 23:53:17 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20CRM/=E5=90=88=E5=90=8C=E7=AE=A1?= =?UTF-8?q?=E7=90=86=20-=20crud?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/crm/enums/ErrorCodeConstants.java | 5 +- .../admin/contact/package-info.java | 4 - .../admin/contract/ContractController.java | 99 +++++++++ .../admin/contract/vo/ContractBaseVO.java | 72 +++++++ .../contract/vo/ContractCreateReqVO.java | 20 ++ .../admin/contract/vo/ContractExcelVO.java | 70 +++++++ .../contract/vo/ContractExportReqVO.java | 37 ++++ .../admin/contract/vo/ContractPageReqVO.java | 42 ++++ .../admin/contract/vo/ContractRespVO.java | 22 ++ .../contract/vo/ContractUpdateReqVO.java | 26 +++ .../crm/convert/contract/ContractConvert.java | 36 ++++ .../dal/dataobject/contract/ContractDO.java | 104 ++++++++++ .../dal/mysql/contract/ContractMapper.java | 45 ++++ .../crm/service/contract/ContractService.java | 75 +++++++ .../service/contract/ContractServiceImpl.java | 90 ++++++++ .../contract/ContractServiceImplTest.java | 195 ++++++++++++++++++ 16 files changed, 937 insertions(+), 5 deletions(-) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/package-info.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/ContractController.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractBaseVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractCreateReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractExcelVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractExportReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractPageReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractRespVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractUpdateReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/ContractDO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/ContractMapper.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractService.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImpl.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImplTest.java diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java index b59eae2bd..532533d6c 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.crm.enums; +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + /** * CRM 错误码枚举类 *

@@ -7,6 +9,7 @@ package cn.iocoder.yudao.module.crm.enums; */ public interface ErrorCodeConstants { - + // ========== 合同管理 1-020-000-000 ========== + ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在"); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/package-info.java deleted file mode 100644 index 9b4afafef..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 联系人 - */ -package cn.iocoder.yudao.module.crm.controller.admin.contact; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/ContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/ContractController.java new file mode 100644 index 000000000..3bc52c038 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/ContractController.java @@ -0,0 +1,99 @@ +package cn.iocoder.yudao.module.crm.controller.admin.contract; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; +import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO; +import cn.iocoder.yudao.module.crm.service.contract.ContractService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; + +@Tag(name = "管理后台 - 合同") +@RestController +@RequestMapping("/crm/contract") +@Validated +public class ContractController { + + @Resource + private ContractService contractService; + + @PostMapping("/create") + @Operation(summary = "创建合同") + @PreAuthorize("@ss.hasPermission('crm:contract:create')") + public CommonResult createContract(@Valid @RequestBody ContractCreateReqVO createReqVO) { + return success(contractService.createContract(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新合同") + @PreAuthorize("@ss.hasPermission('crm:contract:update')") + public CommonResult updateContract(@Valid @RequestBody ContractUpdateReqVO updateReqVO) { + contractService.updateContract(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除合同") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('crm:contract:delete')") + public CommonResult deleteContract(@RequestParam("id") Long id) { + contractService.deleteContract(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得合同") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('crm:contract:query')") + public CommonResult getContract(@RequestParam("id") Long id) { + ContractDO contract = contractService.getContract(id); + return success(ContractConvert.INSTANCE.convert(contract)); + } + + @GetMapping("/list") + @Operation(summary = "获得合同列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") + @PreAuthorize("@ss.hasPermission('crm:contract:query')") + public CommonResult> getContractList(@RequestParam("ids") Collection ids) { + List list = contractService.getContractList(ids); + return success(ContractConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得合同分页") + @PreAuthorize("@ss.hasPermission('crm:contract:query')") + public CommonResult> getContractPage(@Valid ContractPageReqVO pageVO) { + PageResult pageResult = contractService.getContractPage(pageVO); + return success(ContractConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出合同 Excel") + @PreAuthorize("@ss.hasPermission('crm:contract:export')") + @OperateLog(type = EXPORT) + public void exportContractExcel(@Valid ContractExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = contractService.getContractList(exportReqVO); + // 导出 Excel + List datas = ContractConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "合同.xls", "数据", ContractExcelVO.class, datas); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractBaseVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractBaseVO.java new file mode 100644 index 000000000..ad43604a1 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractBaseVO.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * 合同 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class ContractBaseVO { + + @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") + @NotNull(message = "合同名称不能为空") + private String name; + + @Schema(description = "客户编号", example = "18336") + private Long customerId; + + @Schema(description = "商机编号", example = "10864") + private Long businessId; + + @Schema(description = "工作流编号", example = "1043") + private Long processInstanceId; + + @Schema(description = "下单日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime orderDate; + + @Schema(description = "负责人的用户编号", example = "17144") + private Long ownerUserId; + + @Schema(description = "合同编号") + private String no; + + @Schema(description = "开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime startTime; + + @Schema(description = "结束时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime endTime; + + @Schema(description = "合同金额", example = "5617") + private Integer price; + + @Schema(description = "整单折扣") + private Integer discountPercent; + + @Schema(description = "产品总金额", example = "19510") + private Integer productPrice; + + @Schema(description = "联系人编号", example = "18546") + private Long contactId; + + @Schema(description = "公司签约人", example = "14036") + private Long signUserId; + + @Schema(description = "最后跟进时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime contactLastTime; + + @Schema(description = "备注", example = "你猜") + private String remark; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractCreateReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractCreateReqVO.java new file mode 100644 index 000000000..38c95d23f --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractCreateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 合同创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ContractCreateReqVO extends ContractBaseVO { + + @Schema(description = "只读权限的用户编号数组") + private String roUserIds; + + @Schema(description = "读写权限的用户编号数组") + private String rwUserIds; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractExcelVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractExcelVO.java new file mode 100644 index 000000000..895ac821a --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractExcelVO.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 合同 Excel VO + * + * @author dhb52 + */ +@Data +public class ContractExcelVO { + + @ExcelProperty("合同编号") + private Long id; + + @ExcelProperty("合同名称") + private String name; + + @ExcelProperty("客户编号") + private Long customerId; + + @ExcelProperty("商机编号") + private Long businessId; + + @ExcelProperty("工作流编号") + private Long processInstanceId; + + @ExcelProperty("下单日期") + private LocalDateTime orderDate; + + @ExcelProperty("负责人的用户编号") + private Long ownerUserId; + + @ExcelProperty("合同编号") + private String no; + + @ExcelProperty("开始时间") + private LocalDateTime startTime; + + @ExcelProperty("结束时间") + private LocalDateTime endTime; + + @ExcelProperty("合同金额") + private Integer price; + + @ExcelProperty("整单折扣") + private Integer discountPercent; + + @ExcelProperty("产品总金额") + private Integer productPrice; + + @ExcelProperty("联系人编号") + private Long contactId; + + @ExcelProperty("公司签约人") + private Long signUserId; + + @ExcelProperty("最后跟进时间") + private LocalDateTime contactLastTime; + + @ExcelProperty("备注") + private String remark; + + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractExportReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractExportReqVO.java new file mode 100644 index 000000000..8de3b4c1b --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractExportReqVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 合同 Excel 导出 Request VO,参数和 ContractPageReqVO 是一致的") +@Data +public class ContractExportReqVO { + + @Schema(description = "合同名称", example = "王五") + private String name; + + @Schema(description = "客户编号", example = "18336") + private Long customerId; + + @Schema(description = "商机编号", example = "10864") + private Long businessId; + + @Schema(description = "下单日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] orderDate; + + @Schema(description = "合同编号") + private String no; + + @Schema(description = "整单折扣") + private Integer discountPercent; + + @Schema(description = "产品总金额", example = "19510") + private Integer productPrice; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractPageReqVO.java new file mode 100644 index 000000000..01562be1b --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractPageReqVO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 合同分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ContractPageReqVO extends PageParam { + + @Schema(description = "合同名称", example = "王五") + private String name; + + @Schema(description = "客户编号", example = "18336") + private Long customerId; + + @Schema(description = "商机编号", example = "10864") + private Long businessId; + + @Schema(description = "下单日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] orderDate; + + @Schema(description = "合同编号") + private String no; + + @Schema(description = "整单折扣") + private Integer discountPercent; + + @Schema(description = "产品总金额", example = "19510") + private Integer productPrice; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractRespVO.java new file mode 100644 index 000000000..a0ab1d248 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 合同 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ContractRespVO extends ContractBaseVO { + + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + private Long id; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractUpdateReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractUpdateReqVO.java new file mode 100644 index 000000000..f38ac7677 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/ContractUpdateReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 合同更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ContractUpdateReqVO extends ContractBaseVO { + + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + @NotNull(message = "合同编号不能为空") + private Long id; + + @Schema(description = "只读权限的用户编号数组") + private String roUserIds; + + @Schema(description = "读写权限的用户编号数组") + private String rwUserIds; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java new file mode 100644 index 000000000..906dd7562 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.crm.convert.contract; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractCreateReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractExcelVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractRespVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractUpdateReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 合同 Convert + * + * @author dhb52 + */ +@Mapper +public interface ContractConvert { + + ContractConvert INSTANCE = Mappers.getMapper(ContractConvert.class); + + ContractDO convert(ContractCreateReqVO bean); + + ContractDO convert(ContractUpdateReqVO bean); + + ContractRespVO convert(ContractDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/ContractDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/ContractDO.java new file mode 100644 index 000000000..8caa4d2cb --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/ContractDO.java @@ -0,0 +1,104 @@ +package cn.iocoder.yudao.module.crm.dal.dataobject.contract; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.time.LocalDateTime; + +/** + * 合同 DO + * + * @author dhb52 + */ +@TableName("crm_contract") +@KeySequence("crm_contract_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ContractDO extends BaseDO { + + /** + * 合同编号 + */ + @TableId + private Long id; + /** + * 合同名称 + */ + private String name; + /** + * 客户编号 + */ + private Long customerId; + /** + * 商机编号 + */ + private Long businessId; + /** + * 工作流编号 + */ + private Long processInstanceId; + /** + * 下单日期 + */ + private LocalDateTime orderDate; + /** + * 负责人的用户编号 + */ + private Long ownerUserId; + /** + * 合同编号 + */ + private String no; + /** + * 开始时间 + */ + private LocalDateTime startTime; + /** + * 结束时间 + */ + private LocalDateTime endTime; + /** + * 合同金额 + */ + private Integer price; + /** + * 整单折扣 + */ + private Integer discountPercent; + /** + * 产品总金额 + */ + private Integer productPrice; + /** + * 只读权限的用户编号数组 + */ + private String roUserIds; + /** + * 读写权限的用户编号数组 + */ + private String rwUserIds; + /** + * 联系人编号 + */ + private Long contactId; + /** + * 公司签约人 + */ + private Long signUserId; + /** + * 最后跟进时间 + */ + private LocalDateTime contactLastTime; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/ContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/ContractMapper.java new file mode 100644 index 000000000..47337518b --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/ContractMapper.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.crm.dal.mysql.contract; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractExportReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractPageReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 合同 Mapper + * + * @author dhb52 + */ +@Mapper +public interface ContractMapper extends BaseMapperX { + + default PageResult selectPage(ContractPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(ContractDO::getName, reqVO.getName()) + .eqIfPresent(ContractDO::getCustomerId, reqVO.getCustomerId()) + .eqIfPresent(ContractDO::getBusinessId, reqVO.getBusinessId()) + .betweenIfPresent(ContractDO::getOrderDate, reqVO.getOrderDate()) + .eqIfPresent(ContractDO::getNo, reqVO.getNo()) + .eqIfPresent(ContractDO::getDiscountPercent, reqVO.getDiscountPercent()) + .eqIfPresent(ContractDO::getProductPrice, reqVO.getProductPrice()) + .orderByDesc(ContractDO::getId)); + } + + default List selectList(ContractExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(ContractDO::getName, reqVO.getName()) + .eqIfPresent(ContractDO::getCustomerId, reqVO.getCustomerId()) + .eqIfPresent(ContractDO::getBusinessId, reqVO.getBusinessId()) + .betweenIfPresent(ContractDO::getOrderDate, reqVO.getOrderDate()) + .eqIfPresent(ContractDO::getNo, reqVO.getNo()) + .eqIfPresent(ContractDO::getDiscountPercent, reqVO.getDiscountPercent()) + .eqIfPresent(ContractDO::getProductPrice, reqVO.getProductPrice()) + .orderByDesc(ContractDO::getId)); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractService.java new file mode 100644 index 000000000..6d6c9fe9f --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractService.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.crm.service.contract; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractCreateReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractExportReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractUpdateReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + +/** + * 合同 Service 接口 + * + * @author dhb52 + */ +public interface ContractService { + + /** + * 创建合同 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createContract(@Valid ContractCreateReqVO createReqVO); + + /** + * 更新合同 + * + * @param updateReqVO 更新信息 + */ + void updateContract(@Valid ContractUpdateReqVO updateReqVO); + + /** + * 删除合同 + * + * @param id 编号 + */ + void deleteContract(Long id); + + /** + * 获得合同 + * + * @param id 编号 + * @return 合同 + */ + ContractDO getContract(Long id); + + /** + * 获得合同列表 + * + * @param ids 编号 + * @return 合同列表 + */ + List getContractList(Collection ids); + + /** + * 获得合同分页 + * + * @param pageReqVO 分页查询 + * @return 合同分页 + */ + PageResult getContractPage(ContractPageReqVO pageReqVO); + + /** + * 获得合同列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 合同列表 + */ + List getContractList(ContractExportReqVO exportReqVO); + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImpl.java new file mode 100644 index 000000000..e840626b9 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImpl.java @@ -0,0 +1,90 @@ +package cn.iocoder.yudao.module.crm.service.contract; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractCreateReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractExportReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractUpdateReqVO; +import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO; +import cn.iocoder.yudao.module.crm.dal.mysql.contract.ContractMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTRACT_NOT_EXISTS; + +/** + * 合同 Service 实现类 + * + * @author dhb52 + */ +@Service +@Validated +public class ContractServiceImpl implements ContractService { + + @Resource + private ContractMapper contractMapper; + + @Override + public Long createContract(ContractCreateReqVO createReqVO) { + // 插入 + ContractDO contract = ContractConvert.INSTANCE.convert(createReqVO); + contractMapper.insert(contract); + // 返回 + return contract.getId(); + } + + @Override + public void updateContract(ContractUpdateReqVO updateReqVO) { + // 校验存在 + validateContractExists(updateReqVO.getId()); + // 更新 + ContractDO updateObj = ContractConvert.INSTANCE.convert(updateReqVO); + contractMapper.updateById(updateObj); + } + + @Override + public void deleteContract(Long id) { + // 校验存在 + validateContractExists(id); + // 删除 + contractMapper.deleteById(id); + } + + private void validateContractExists(Long id) { + if (contractMapper.selectById(id) == null) { + throw exception(CONTRACT_NOT_EXISTS); + } + } + + @Override + public ContractDO getContract(Long id) { + return contractMapper.selectById(id); + } + + @Override + public List getContractList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return ListUtil.empty(); + } + return contractMapper.selectBatchIds(ids); + } + + @Override + public PageResult getContractPage(ContractPageReqVO pageReqVO) { + return contractMapper.selectPage(pageReqVO); + } + + @Override + public List getContractList(ContractExportReqVO exportReqVO) { + return contractMapper.selectList(exportReqVO); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImplTest.java b/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImplTest.java new file mode 100644 index 000000000..f9cbe3a38 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImplTest.java @@ -0,0 +1,195 @@ +package cn.iocoder.yudao.module.crm.service.contract; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractCreateReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractExportReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.ContractUpdateReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO; +import cn.iocoder.yudao.module.crm.dal.mysql.contract.ContractMapper; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTRACT_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link ContractServiceImpl} 的单元测试类 + * + * @author dhb52 + */ +@Import(ContractServiceImpl.class) +public class ContractServiceImplTest extends BaseDbUnitTest { + + @Resource + private ContractServiceImpl contractService; + + @Resource + private ContractMapper contractMapper; + + @Test + public void testCreateContract_success() { + // 准备参数 + ContractCreateReqVO reqVO = randomPojo(ContractCreateReqVO.class); + + // 调用 + Long contractId = contractService.createContract(reqVO); + // 断言 + assertNotNull(contractId); + // 校验记录的属性是否正确 + ContractDO contract = contractMapper.selectById(contractId); + assertPojoEquals(reqVO, contract); + } + + @Test + public void testUpdateContract_success() { + // mock 数据 + ContractDO dbContract = randomPojo(ContractDO.class); + contractMapper.insert(dbContract);// @Sql: 先插入出一条存在的数据 + // 准备参数 + ContractUpdateReqVO reqVO = randomPojo(ContractUpdateReqVO.class, o -> { + o.setId(dbContract.getId()); // 设置更新的 ID + }); + + // 调用 + contractService.updateContract(reqVO); + // 校验是否更新正确 + ContractDO contract = contractMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, contract); + } + + @Test + public void testUpdateContract_notExists() { + // 准备参数 + ContractUpdateReqVO reqVO = randomPojo(ContractUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> contractService.updateContract(reqVO), CONTRACT_NOT_EXISTS); + } + + @Test + public void testDeleteContract_success() { + // mock 数据 + ContractDO dbContract = randomPojo(ContractDO.class); + contractMapper.insert(dbContract);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbContract.getId(); + + // 调用 + contractService.deleteContract(id); + // 校验数据不存在了 + assertNull(contractMapper.selectById(id)); + } + + @Test + public void testDeleteContract_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> contractService.deleteContract(id), CONTRACT_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetContractPage() { + // mock 数据 + ContractDO dbContract = randomPojo(ContractDO.class, o -> { // 等会查询到 + o.setName(null); + o.setCustomerId(null); + o.setBusinessId(null); + o.setOrderDate(null); + o.setNo(null); + o.setDiscountPercent(null); + o.setProductPrice(null); + }); + contractMapper.insert(dbContract); + // 测试 name 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setName(null))); + // 测试 customerId 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setCustomerId(null))); + // 测试 businessId 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setBusinessId(null))); + // 测试 orderDate 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setOrderDate(null))); + // 测试 no 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setNo(null))); + // 测试 discountPercent 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setDiscountPercent(null))); + // 测试 productPrice 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setProductPrice(null))); + // 准备参数 + ContractPageReqVO reqVO = new ContractPageReqVO(); + reqVO.setName(null); + reqVO.setCustomerId(null); + reqVO.setBusinessId(null); + reqVO.setOrderDate(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setNo(null); + reqVO.setDiscountPercent(null); + reqVO.setProductPrice(null); + + // 调用 + PageResult pageResult = contractService.getContractPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbContract, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetContractList() { + // mock 数据 + ContractDO dbContract = randomPojo(ContractDO.class, o -> { // 等会查询到 + o.setName("合同名称"); + o.setCustomerId(null); + o.setBusinessId(null); + o.setOrderDate(null); + o.setNo(null); + o.setDiscountPercent(null); + o.setProductPrice(null); + }); + contractMapper.insert(dbContract); + // 测试 name 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setName(null))); + // 测试 customerId 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setCustomerId(null))); + // 测试 businessId 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setBusinessId(null))); + // 测试 orderDate 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setOrderDate(null))); + // 测试 no 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setNo(null))); + // 测试 discountPercent 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setDiscountPercent(null))); + // 测试 productPrice 不匹配 + contractMapper.insert(cloneIgnoreId(dbContract, o -> o.setProductPrice(null))); + // 准备参数 + ContractExportReqVO reqVO = new ContractExportReqVO(); + reqVO.setName(null); + reqVO.setCustomerId(null); + reqVO.setBusinessId(null); + reqVO.setOrderDate(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); + reqVO.setNo(null); + reqVO.setDiscountPercent(null); + reqVO.setProductPrice(null); + + // 调用 + List list = contractService.getContractList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbContract, list.get(0)); + } + +} From 164be5732b4c022b61d42403019c899f8ecb2fbe Mon Sep 17 00:00:00 2001 From: dhb52 Date: Mon, 16 Oct 2023 23:53:27 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20CRM/=E5=90=88=E5=90=8C=E7=AE=A1?= =?UTF-8?q?=E7=90=86=20-=20SQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/crm.sql | 39 ++++++++++++ sql/mysql/crm_menu.sql | 63 +++++++++++++++++++ .../src/test/resources/sql/clean.sql | 1 + .../src/test/resources/sql/create_tables.sql | 27 ++++++++ 4 files changed, 130 insertions(+) create mode 100644 sql/mysql/crm.sql create mode 100644 sql/mysql/crm_menu.sql create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/test/resources/sql/clean.sql create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/test/resources/sql/create_tables.sql diff --git a/sql/mysql/crm.sql b/sql/mysql/crm.sql new file mode 100644 index 000000000..eeb2d12ac --- /dev/null +++ b/sql/mysql/crm.sql @@ -0,0 +1,39 @@ +SET NAMES utf8mb4; + +-- ---------------------------- +-- 合同表 +-- ---------------------------- +DROP TABLE IF EXISTS `crm_contract`; +CREATE TABLE `crm_contract` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号,主键自增', + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '合同名称', + `customer_id` bigint DEFAULT NULL COMMENT '客户编号', + `business_id` bigint DEFAULT NULL COMMENT '商机编号', + `process_instance_id` bigint DEFAULT NULL COMMENT '工作流编号', + `order_date` datetime DEFAULT NULL COMMENT '下单日期', + `owner_user_id` bigint DEFAULT NULL COMMENT '负责人的用户编号', + `no` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '合同编号', + `start_time` datetime DEFAULT NULL COMMENT '开始时间', + `end_time` datetime DEFAULT NULL COMMENT '结束时间', + `price` int DEFAULT NULL COMMENT '合同金额', + `discount_percent` int DEFAULT NULL COMMENT '整单折扣', + `product_price` int DEFAULT NULL COMMENT '产品总金额', + `ro_user_ids` varchar(4096) DEFAULT NULL COMMENT '只读权限的用户编号数组', + `rw_user_ids` varchar(4096) DEFAULT NULL COMMENT '读写权限的用户编号数组', + `contact_id` bigint DEFAULT NULL COMMENT '联系人编号', + `sign_user_id` bigint DEFAULT NULL COMMENT '公司签约人', + `contact_last_time` datetime DEFAULT NULL COMMENT '最后跟进时间', + + -- 通用字段 + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '备注', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB + CHARACTER SET = utf8mb4 + COLLATE = utf8mb4_unicode_ci COMMENT ='合同表'; diff --git a/sql/mysql/crm_menu.sql b/sql/mysql/crm_menu.sql new file mode 100644 index 000000000..83e5ae29d --- /dev/null +++ b/sql/mysql/crm_menu.sql @@ -0,0 +1,63 @@ +-- ---------------------------- +-- 合同菜单 +-- ---------------------------- + +-- 菜单 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status, component_name +) +VALUES ( + '合同管理', '', 2, 0, 1254, + 'contract', '', 'crm/contract/index', 0, 'Contract' +); + +-- 按钮父菜单ID +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 +SELECT @parentId := LAST_INSERT_ID(); + +-- 按钮 SQL +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '合同查询', 'crm:contract:query', 3, 1, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '合同创建', 'crm:contract:create', 3, 2, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '合同更新', 'crm:contract:update', 3, 3, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '合同删除', 'crm:contract:delete', 3, 4, @parentId, + '', '', '', 0 +); +INSERT INTO system_menu( + name, permission, type, sort, parent_id, + path, icon, component, status +) +VALUES ( + '合同导出', 'crm:contract:export', 3, 5, @parentId, + '', '', '', 0 +); + +-- ---------------------------- +-- ...菜单 +-- ---------------------------- \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/resources/sql/clean.sql b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/sql/clean.sql new file mode 100644 index 000000000..c45d2602e --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/sql/clean.sql @@ -0,0 +1 @@ +DELETE FROM "crm_contract"; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/resources/sql/create_tables.sql b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/sql/create_tables.sql new file mode 100644 index 000000000..c25a80e44 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/test/resources/sql/create_tables.sql @@ -0,0 +1,27 @@ +CREATE TABLE IF NOT EXISTS "crm_contract" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "name" varchar NOT NULL, + "customer_id" bigint, + "business_id" bigint, + "process_instance_id" bigint, + "order_date" varchar, + "owner_user_id" bigint, + "no" varchar, + "start_time" varchar, + "end_time" varchar, + "price" int, + "discount_percent" int, + "product_price" int, + "ro_user_ids" varchar, + "rw_user_ids" varchar, + "contact_id" bigint, + "sign_user_id" bigint, + "contact_last_time" varchar, + "remark" varchar, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") + ) COMMENT '合同表'; \ No newline at end of file