2.0.1 版本发布准备

This commit is contained in:
YunaiV 2024-02-28 22:35:25 +08:00
parent 74b5c48fcb
commit d183e75912
42 changed files with 1 additions and 1401 deletions

View File

@ -15,8 +15,8 @@
<module>yudao-spring-boot-starter-redis</module>
<module>yudao-spring-boot-starter-web</module>
<module>yudao-spring-boot-starter-security</module>
<module>yudao-spring-boot-starter-websocket</module>
<module>yudao-spring-boot-starter-file</module>
<module>yudao-spring-boot-starter-monitor</module>
<module>yudao-spring-boot-starter-protection</module>
<module>yudao-spring-boot-starter-job</module>
@ -25,14 +25,9 @@
<module>yudao-spring-boot-starter-excel</module>
<module>yudao-spring-boot-starter-biz-operatelog</module>
<module>yudao-spring-boot-starter-biz-dict</module>
<module>yudao-spring-boot-starter-biz-tenant</module>
<module>yudao-spring-boot-starter-biz-data-permission</module>
<module>yudao-spring-boot-starter-biz-ip</module>
<module>yudao-spring-boot-starter-captcha</module>
<module>yudao-spring-boot-starter-websocket</module>
</modules>
<artifactId>yudao-framework</artifactId>

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-framework</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-spring-boot-starter-biz-dict</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>字典类型、数据</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行 Token 的校验 -->
<version>${revision}</version>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -63,13 +63,6 @@
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
<optional>true</optional> <!-- 设置为 optional只有在 AreaConvert 的时候使用 -->
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yudao-framework</artifactId>
<groupId>cn.iocoder.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-spring-boot-starter-file</artifactId>
<name>${project.artifactId}</name>
<description>文件客户端,支持多种存储器
1. file本地磁盘
2. ftpFTP 服务器
2. sftpSFTP 服务器
4. db数据库
5. s3支持 S3 协议的云存储服务,例如说 MinIO、阿里云、华为云、腾讯云、七牛云等等
</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId> <!-- 解决 ftp 连接 -->
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId> <!-- 解决 sftp 连接 -->
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId> <!-- 文件类型的识别 -->
</dependency>
<!-- 三方云服务相关 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,45 +0,0 @@
package cn.iocoder.yudao.module.crm.enums.business;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* 商机的结束状态枚举
*
* @author lzxhqs
*/
@RequiredArgsConstructor
@Getter
public enum CrmBusinessEndStatusEnum implements IntArrayValuable {
WIN(1, "赢单"),
LOSE(2, "输单"),
INVALID(3, "无效");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmBusinessEndStatusEnum::getStatus).toArray();
/**
* 场景类型
*/
private final Integer status;
/**
* 场景名称
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
public static CrmBusinessEndStatusEnum fromStatus(Integer status) {
return Arrays.stream(values())
.filter(value -> value.getStatus().equals(status))
.findFirst()
.orElse(null);
}
}

View File

@ -1,43 +0,0 @@
package cn.iocoder.yudao.module.crm.enums.receivable;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* CRM 回款方式枚举
*
* @author HUIHUI
*/
@Getter
@AllArgsConstructor
public enum CrmReceivableReturnTypeEnum implements IntArrayValuable {
CHECK(1, "支票"),
CASH(2, "现金"),
POSTAL_REMITTANCE(3, "邮政汇款"),
TELEGRAPHIC_TRANSFER(4, "电汇"),
ONLINE_TRANSFER(5, "网上转账"),
ALIPAY(6, "支付宝"),
WECHAT_PAY(7, "微信支付"),
OTHER(8, "其它");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmReceivableReturnTypeEnum::getType).toArray();
/**
* 类型
*/
private final Integer type;
/**
* 名称
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -1,126 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.business;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - CRM 商机状态")
@RestController
@RequestMapping("/crm/business-status")
@Validated
public class CrmBusinessStatusController {
@Resource
private CrmBusinessStatusService businessStatusTypeService;
@Resource
private AdminUserApi adminUserApi;
@Resource
private DeptApi deptApi;
@PostMapping("/create")
@Operation(summary = "创建商机状态")
@PreAuthorize("@ss.hasPermission('crm:business-status:create')")
public CommonResult<Long> createBusinessStatus(@Valid @RequestBody CrmBusinessStatusSaveReqVO createReqVO) {
return success(businessStatusTypeService.createBusinessStatus(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新商机状态")
@PreAuthorize("@ss.hasPermission('crm:business-status:update')")
public CommonResult<Boolean> updateBusinessStatus(@Valid @RequestBody CrmBusinessStatusSaveReqVO updateReqVO) {
businessStatusTypeService.updateBusinessStatus(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除商机状态")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('crm:business-status:delete')")
public CommonResult<Boolean> deleteBusinessStatusType(@RequestParam("id") Long id) {
businessStatusTypeService.deleteBusinessStatusType(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得商机状态")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:business-status:query')")
public CommonResult<CrmBusinessStatusRespVO> getBusinessStatusType(@RequestParam("id") Long id) {
CrmBusinessStatusTypeDO statusType = businessStatusTypeService.getBusinessStatusType(id);
if (statusType == null) {
return success(null);
}
List<CrmBusinessStatusDO> statuses = businessStatusTypeService.getBusinessStatusListByTypeId(id);
return success(BeanUtils.toBean(statusType, CrmBusinessStatusRespVO.class,
statusTypeVO -> statusTypeVO.setStatuses(BeanUtils.toBean(statuses, CrmBusinessStatusRespVO.Status.class))));
}
@GetMapping("/page")
@Operation(summary = "获得商机状态分页")
@PreAuthorize("@ss.hasPermission('crm:business-status:query')")
public CommonResult<PageResult<CrmBusinessStatusRespVO>> getBusinessStatusPage(@Valid PageParam pageReqVO) {
// 1. 查询数据
PageResult<CrmBusinessStatusTypeDO> pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return success(PageResult.empty(pageResult.getTotal()));
}
// 2. 拼接数据
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSet(pageResult.getList(), statusType -> Long.parseLong(statusType.getCreator())));
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
convertSetByFlatMap(pageResult.getList(), CrmBusinessStatusTypeDO::getDeptIds, Collection::stream));
return success(BeanUtils.toBean(pageResult, CrmBusinessStatusRespVO.class, statusTypeVO -> {
statusTypeVO.setCreator(userMap.get(NumberUtils.parseLong(statusTypeVO.getCreator())).getNickname());
statusTypeVO.setDeptNames(convertList(statusTypeVO.getDeptIds(),
deptId -> deptMap.containsKey(deptId) ? deptMap.get(deptId).getName() : null));
}));
}
@GetMapping("/type-simple-list")
@Operation(summary = "获得商机状态组列表")
public CommonResult<List<CrmBusinessStatusRespVO>> getBusinessStatusTypeSimpleList() {
List<CrmBusinessStatusTypeDO> list = businessStatusTypeService.getBusinessStatusTypeList();
// 过滤掉部门不匹配的
Long deptId = adminUserApi.getUser(getLoginUserId()).getDeptId();
list.removeIf(statusType -> CollUtil.isNotEmpty(statusType.getDeptIds()) && !statusType.getDeptIds().contains(deptId));
return success(BeanUtils.toBean(list, CrmBusinessStatusRespVO.class));
}
@GetMapping("/status-simple-list")
@Operation(summary = "获得商机状态列表")
@Parameter(name = "typeId", description = "商机状态组", required = true, example = "1024")
public CommonResult<List<CrmBusinessStatusRespVO.Status>> getBusinessStatusSimpleList(@RequestParam("typeId") Long typeId) {
List<CrmBusinessStatusDO> list = businessStatusTypeService.getBusinessStatusListByTypeId(typeId);
return success(BeanUtils.toBean(list, CrmBusinessStatusRespVO.Status.class));
}
}

View File

@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - CRM 商机更新状态 Request VO")
@Data
public class CrmBusinessUpdateStatusReqVO {
@Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129")
@NotNull(message = "商机编号不能为空")
private Long id;
@Schema(description = "状态编号", example = "1")
private Long statusId;
@Schema(description = "结束状态", example = "1")
@InEnum(value = CrmBusinessEndStatusEnum.class)
private Integer endStatus;
@AssertTrue(message = "变更状态不正确")
public boolean isStatusValid() {
return statusId != null || endStatus != null;
}
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - CRM 联系人商机 Request VO") // 商机关联联系人用于关联取消关联的操作
@Data
public class CrmContactBusiness2ReqVO {
@Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7638")
@NotNull(message="商机不能为空")
private Long businessId;
@Schema(description = "联系人编号数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "20878")
@NotEmpty(message="联系人数组不能为空")
private List<Long> contactIds;
}

View File

@ -1,44 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contract;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
import cn.iocoder.yudao.module.crm.service.contract.CrmContractConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - CRM 合同配置")
@RestController
@RequestMapping("/crm/contract-config")
@Validated
public class CrmContractConfigController {
@Resource
private CrmContractConfigService contractConfigService;
@GetMapping("/get")
@Operation(summary = "获取合同配置")
@PreAuthorize("@ss.hasPermission('crm:contract-config:query')")
public CommonResult<CrmContractConfigRespVO> getCustomerPoolConfig() {
CrmContractConfigDO config = contractConfigService.getContractConfig();
return success(BeanUtils.toBean(config, CrmContractConfigRespVO.class));
}
@PutMapping("/save")
@Operation(summary = "更新合同配置")
@PreAuthorize("@ss.hasPermission('crm:contract-config:update')")
public CommonResult<Boolean> saveCustomerPoolConfig(@Valid @RequestBody CrmContractConfigSaveReqVO updateReqVO) {
contractConfigService.saveContractConfig(updateReqVO);
return success(true);
}
}

View File

@ -1,16 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - CRM 合同配置 Response VO")
@Data
public class CrmContractConfigRespVO {
@Schema(description = "是否开启提前提醒", example = "true")
private Boolean notifyEnabled;
@Schema(description = "提前提醒天数", example = "2")
private Integer notifyDays;
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config;
import cn.hutool.core.util.BooleanUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.mzt.logapi.starter.annotation.DiffLogField;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.AssertTrue;
import lombok.Data;
import java.util.Objects;
@Schema(description = "管理后台 - CRM 合同配置 Request VO")
@Data
public class CrmContractConfigSaveReqVO {
@Schema(description = "是否开启提前提醒", example = "true")
@DiffLogField(name = "是否开启提前提醒")
private Boolean notifyEnabled;
@Schema(description = "提前提醒天数", example = "2")
@DiffLogField(name = "提前提醒天数")
private Integer notifyDays;
@AssertTrue(message = "提前提醒天数不能为空")
@JsonIgnore
public boolean isNotifyDaysValid() {
if (!BooleanUtil.isTrue(getNotifyEnabled())) {
return true;
}
return Objects.nonNull(getNotifyDays());
}
}

View File

@ -1,45 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - CRM 回款计划新增/修改 Request VO")
@Data
public class CrmReceivablePlanSaveReqVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Long id;
@Schema(description = "客户编号", hidden = true, example = "2")
private Long customerId; // 该字段不通过前端传递而是 contractId 查询出来设置进去
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "合同编号不能为空")
private Long contractId;
@Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "负责人编号不能为空")
private Long ownerUserId;
@Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
@NotNull(message = "计划回款日期不能为空")
private LocalDateTime returnTime;
@Schema(description = "回款方式", example = "1")
private Integer returnType;
@Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
@NotNull(message = "计划回款金额不能为空")
private BigDecimal price;
@Schema(description = "提前几天提醒", example = "1")
private Integer remindDays;
@Schema(description = "备注", example = "备注")
private String remark;
}

View File

@ -1,58 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.crm.enums.receivable.CrmReceivableReturnTypeEnum;
import cn.iocoder.yudao.module.crm.framework.operatelog.core.*;
import com.mzt.logapi.starter.annotation.DiffLogField;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - CRM 回款新增/修改 Request VO")
@Data
public class CrmReceivableSaveReqVO {
@Schema(description = "编号", example = "25787")
private Long id;
@Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
@NotNull(message = "负责人编号不能为空")
private Long ownerUserId;
@Schema(description = "客户编号", example = "2")
@DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
private Long customerId; // 该字段不通过前端传递而是 contractId 查询出来设置进去
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@DiffLogField(name = "合同", function = CrmContractParseFunction.NAME)
@NotNull(message = "合同编号不能为空")
private Long contractId;
@Schema(description = "回款计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@DiffLogField(name = "合同", function = CrmReceivablePlanParseFunction.NAME)
private Long planId;
@Schema(description = "回款方式", example = "2")
@DiffLogField(name = "回款方式", function = CrmReceivableReturnTypeParseFunction.NAME)
@InEnum(CrmReceivableReturnTypeEnum.class)
private Integer returnType;
@Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
@DiffLogField(name = "回款金额")
@NotNull(message = "回款金额不能为空")
private BigDecimal price;
@Schema(description = "回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
@NotNull(message = "回款日期不能为空")
@DiffLogField(name = "回款日期")
private LocalDateTime returnTime;
@Schema(description = "备注", example = "备注")
@DiffLogField(name = "备注")
private String remark;
}

View File

@ -1,9 +0,0 @@
### 合同金额排行榜
GET {{baseUrl}}/crm/statistics-rank/get-contract-price-rank?deptId=100&times[0]=2022-12-12 00:00:00&times[1]=2024-12-12 23:59:59
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}
### 回款金额排行榜
GET {{baseUrl}}/crm/statistics-rank/get-receivable-price-rank?deptId=100&times[0]=2022-12-12 00:00:00&times[1]=2024-12-12 23:59:59
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.module.crm.dal.dataobject.contract;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.*;
import lombok.*;
@TableName("crm_contract_config")
@KeySequence("crm_contract_config_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CrmContractConfigDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 是否开启提前提醒
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Boolean notifyEnabled;
/**
* 提前提醒天数
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Integer notifyDays;
}

View File

@ -1,20 +0,0 @@
package cn.iocoder.yudao.module.crm.dal.mysql.contract;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 合同配置 Mapper
*
* @author Wanwan
*/
@Mapper
public interface CrmContractConfigMapper extends BaseMapperX<CrmContractConfigDO> {
default CrmContractConfigDO selectOne() {
return selectOne(new QueryWrapperX<CrmContractConfigDO>().limitN(1));
}
}

View File

@ -1,18 +0,0 @@
package cn.iocoder.yudao.module.crm.dal.redis;
/**
* CRM Redis Key 枚举类
*
* @author 芋道源码
*/
public interface RedisKeyConstants {
/**
* 序号的缓存
*
* KEY 格式trade_no:{prefix}
* VALUE 数据格式编号自增
*/
String NO = "crm:seq_no:";
}

View File

@ -1,52 +0,0 @@
package cn.iocoder.yudao.module.crm.dal.redis.no;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.module.crm.dal.redis.RedisKeyConstants;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;
import java.time.Duration;
import java.time.LocalDateTime;
/**
* Crm 订单序号的 Redis DAO
*
* @author HUIHUI
*/
@Repository
public class CrmNoRedisDAO {
/**
* 合同 {@link cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO}
*/
public static final String CONTRACT_NO_PREFIX = "HT";
/**
* 回款 {@link cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO}
*/
public static final String RECEIVABLE_PREFIX = "HK";
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* 生成序号使用当前日期格式为 {PREFIX} + yyyyMMdd + 6 位自增
* 例如说QTRK 202109 000001 没有中间空格
*
* @param prefix 前缀
* @return 序号
*/
public String generate(String prefix) {
// 递增序号
String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN);
String key = RedisKeyConstants.NO + noPrefix;
Long no = stringRedisTemplate.opsForValue().increment(key);
// 设置过期时间
stringRedisTemplate.expire(key, Duration.ofDays(1L));
return noPrefix + String.format("%06d", no);
}
}

View File

@ -1,44 +0,0 @@
package cn.iocoder.yudao.module.crm.framework.operatelog.core;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivablePlanService;
import com.mzt.logapi.service.IParseFunction;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* CRM 回款计划的 {@link IParseFunction} 实现类
*
* @author HUIHUI
*/
@Component
@Slf4j
public class CrmReceivablePlanParseFunction implements IParseFunction {
public static final String NAME = "getReceivablePlanServiceById";
@Resource
private CrmReceivablePlanService receivablePlanService;
@Override
public boolean executeBefore() {
return true; // 先转换值后对比
}
@Override
public String functionName() {
return NAME;
}
@Override
public String apply(Object value) {
if (StrUtil.isEmptyIfStr(value)) {
return "";
}
CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(Long.parseLong(value.toString()));
return receivablePlan == null ? "" : receivablePlan.getPeriod().toString();
}
}

View File

@ -1,40 +0,0 @@
package cn.iocoder.yudao.module.crm.framework.operatelog.core;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.dict.util.DictFrameworkUtils;
import com.mzt.logapi.service.IParseFunction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_RECEIVABLE_RETURN_TYPE;
/**
* CRM 回款方式的 {@link IParseFunction} 实现类
*
* @author HUIHUI
*/
@Slf4j
@Component
public class CrmReceivableReturnTypeParseFunction implements IParseFunction {
public static final String NAME = "getReceivableReturnType";
@Override
public boolean executeBefore() {
return true; // 先转换值后对比
}
@Override
public String functionName() {
return NAME;
}
@Override
public String apply(Object value) {
if (StrUtil.isEmptyIfStr(value)) {
return "";
}
return DictFrameworkUtils.getDictDataLabel(CRM_RECEIVABLE_RETURN_TYPE, value.toString());
}
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.crm.framework.web.config;
import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* crm 模块的 web 组件的 Configuration
*
* @author 芋道源码
*/
@Configuration(proxyBeanMethods = false)
public class CrmWebConfiguration {
/**
* crm 模块的 API 分组
*/
@Bean
public GroupedOpenApi crmGroupedOpenApi() {
return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("crm");
}
}

View File

@ -1,4 +0,0 @@
/**
* trade 模块的 web 配置
*/
package cn.iocoder.yudao.module.crm.framework.web;

View File

@ -1,28 +0,0 @@
package cn.iocoder.yudao.module.crm.service.contract;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
import jakarta.validation.Valid;
/**
* 合同配置 Service 接口
*
* @author 芋道源码
*/
public interface CrmContractConfigService {
/**
* 获得合同配置
*
* @return 合同配置
*/
CrmContractConfigDO getContractConfig();
/**
* 保存合同配置
*
* @param saveReqVO 更新信息
*/
void saveContractConfig(@Valid CrmContractConfigSaveReqVO saveReqVO);
}

View File

@ -1,56 +0,0 @@
package cn.iocoder.yudao.module.crm.service.contract;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.config.CrmContractConfigSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractConfigDO;
import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractConfigMapper;
import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.Objects;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
/**
* 合同配置 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class CrmContractConfigServiceImpl implements CrmContractConfigService {
@Resource
private CrmContractConfigMapper contractConfigMapper;
@Override
public CrmContractConfigDO getContractConfig() {
return contractConfigMapper.selectOne();
}
@Override
@LogRecord(type = CRM_CONTRACT_CONFIG_TYPE, subType = CRM_CONTRACT_CONFIG_SUB_TYPE, bizNo = "{{#configId}}",
success = CRM_CONTRACT_CONFIG_SUCCESS)
public void saveContractConfig(CrmContractConfigSaveReqVO saveReqVO) {
// 1. 存在则进行更新
CrmContractConfigDO dbConfig = getContractConfig();
CrmContractConfigDO config = BeanUtils.toBean(saveReqVO, CrmContractConfigDO.class);
if (Objects.nonNull(dbConfig)) {
contractConfigMapper.updateById(config.setId(dbConfig.getId()));
// 记录操作日志上下文
LogRecordContext.putVariable("isConfigUpdate", Boolean.TRUE);
LogRecordContext.putVariable("configId", config.getId());
return;
}
// 2. 不存在则进行插入
contractConfigMapper.insert(config);
// 记录操作日志上下文
LogRecordContext.putVariable("isConfigUpdate", Boolean.FALSE);
LogRecordContext.putVariable("configId", config.getId());
}
}

View File

@ -1,31 +0,0 @@
package cn.iocoder.yudao.module.crm.service.receivable.listener;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent;
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEventListener;
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
/**
* 回款审批的结果的监听器实现类
*
* @author HUIHUI
*/
@Component
public class CrmReceivableResultListener extends BpmProcessInstanceResultEventListener {
@Resource
private CrmReceivableService receivableService;
@Override
public String getProcessDefinitionKey() {
return CrmReceivableServiceImpl.BPM_PROCESS_DEFINITION_KEY;
}
@Override
public void onEvent(BpmProcessInstanceResultEvent event) {
receivableService.updateReceivableAuditStatus(Long.parseLong(event.getBusinessKey()), event.getResult());
}
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.yudao.module.crm.util;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
/**
* CRM 流程工具类
*
* @author HUIHUI
*/
public class CrmAuditStatusUtils {
/**
* BPM 审批结果转换
*
* @param bpmResult BPM 审批结果
*/
public static Integer convertBpmResultToAuditStatus(Integer bpmResult) {
Integer auditStatus = BpmProcessInstanceResultEnum.APPROVE.getResult().equals(bpmResult) ? CrmAuditStatusEnum.APPROVE.getStatus()
: BpmProcessInstanceResultEnum.REJECT.getResult().equals(bpmResult) ? CrmAuditStatusEnum.REJECT.getStatus()
: BpmProcessInstanceResultEnum.CANCEL.getResult().equals(bpmResult) ? BpmProcessInstanceResultEnum.CANCEL.getResult() : null;
Assert.notNull(auditStatus, "BPM 审批结果({}) 转换失败", bpmResult);
return auditStatus;
}
}

View File

@ -1,69 +0,0 @@
package cn.iocoder.yudao.module.erp.controller.admin.statistics;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSummaryRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseTimeSummaryRespVO;
import cn.iocoder.yudao.module.erp.service.statistics.ErpPurchaseStatisticsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import static cn.hutool.core.date.DatePattern.NORM_MONTH_PATTERN;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - ERP 采购统计")
@RestController
@RequestMapping("/erp/purchase-statistics")
@Validated
public class ErpPurchaseStatisticsController {
@Resource
private ErpPurchaseStatisticsService purchaseStatisticsService;
@GetMapping("/summary")
@Operation(summary = "获得采购统计")
@PreAuthorize("@ss.hasPermission('erp:statistics:query')")
public CommonResult<ErpPurchaseSummaryRespVO> getPurchaseSummary() {
LocalDateTime today = LocalDateTimeUtils.getToday();
LocalDateTime yesterday = LocalDateTimeUtils.getYesterday();
LocalDateTime month = LocalDateTimeUtils.getMonth();
LocalDateTime year = LocalDateTimeUtils.getYear();
ErpPurchaseSummaryRespVO summary = new ErpPurchaseSummaryRespVO()
.setTodayPrice(purchaseStatisticsService.getPurchasePrice(today, null))
.setYesterdayPrice(purchaseStatisticsService.getPurchasePrice(yesterday, today))
.setMonthPrice(purchaseStatisticsService.getPurchasePrice(month, null))
.setYearPrice(purchaseStatisticsService.getPurchasePrice(year, null));
return success(summary);
}
@GetMapping("/time-summary")
@Operation(summary = "获得采购时间段统计")
@Parameter(name = "count", description = "时间段数量", example = "6")
@PreAuthorize("@ss.hasPermission('erp:statistics:query')")
public CommonResult<List<ErpPurchaseTimeSummaryRespVO>> getPurchaseTimeSummary(
@RequestParam(value = "count", defaultValue = "6") Integer count) {
List<ErpPurchaseTimeSummaryRespVO> summaryList = new ArrayList<>();
for (int i = count - 1; i >= 0; i--) {
LocalDateTime startTime = LocalDateTimeUtils.beginOfMonth(LocalDateTime.now().minusMonths(i));
LocalDateTime endTime = LocalDateTimeUtils.endOfMonth(startTime);
summaryList.add(new ErpPurchaseTimeSummaryRespVO()
.setTime(LocalDateTimeUtil.format(startTime, NORM_MONTH_PATTERN))
.setPrice(purchaseStatisticsService.getPurchasePrice(startTime, endTime)));
}
return success(summaryList);
}
}

View File

@ -1,11 +0,0 @@
### 请求 /erp/sale-statistics/summary 接口 => 成功
GET {{baseUrl}}/erp/sale-statistics/summary
Content-Type: application/json
tenant-id: {{adminTenentId}}
Authorization: Bearer {{token}}
### 请求 /erp/sale-statistics/time-summary 接口 => 成功
GET {{baseUrl}}/erp/sale-statistics/time-summary
Content-Type: application/json
tenant-id: {{adminTenentId}}
Authorization: Bearer {{token}}

View File

@ -1,69 +0,0 @@
package cn.iocoder.yudao.module.erp.controller.admin.statistics;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.sale.ErpSaleSummaryRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.sale.ErpSaleTimeSummaryRespVO;
import cn.iocoder.yudao.module.erp.service.statistics.ErpSaleStatisticsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import static cn.hutool.core.date.DatePattern.NORM_MONTH_PATTERN;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - ERP 销售统计")
@RestController
@RequestMapping("/erp/sale-statistics")
@Validated
public class ErpSaleStatisticsController {
@Resource
private ErpSaleStatisticsService saleStatisticsService;
@GetMapping("/summary")
@Operation(summary = "获得销售统计")
@PreAuthorize("@ss.hasPermission('erp:statistics:query')")
public CommonResult<ErpSaleSummaryRespVO> getSaleSummary() {
LocalDateTime today = LocalDateTimeUtils.getToday();
LocalDateTime yesterday = LocalDateTimeUtils.getYesterday();
LocalDateTime month = LocalDateTimeUtils.getMonth();
LocalDateTime year = LocalDateTimeUtils.getYear();
ErpSaleSummaryRespVO summary = new ErpSaleSummaryRespVO()
.setTodayPrice(saleStatisticsService.getSalePrice(today, null))
.setYesterdayPrice(saleStatisticsService.getSalePrice(yesterday, today))
.setMonthPrice(saleStatisticsService.getSalePrice(month, null))
.setYearPrice(saleStatisticsService.getSalePrice(year, null));
return success(summary);
}
@GetMapping("/time-summary")
@Operation(summary = "获得销售时间段统计")
@Parameter(name = "count", description = "时间段数量", example = "6")
@PreAuthorize("@ss.hasPermission('erp:statistics:query')")
public CommonResult<List<ErpSaleTimeSummaryRespVO>> getSaleTimeSummary(
@RequestParam(value = "count", defaultValue = "6") Integer count) {
List<ErpSaleTimeSummaryRespVO> summaryList = new ArrayList<>();
for (int i = count - 1; i >= 0; i--) {
LocalDateTime startTime = LocalDateTimeUtils.beginOfMonth(LocalDateTime.now().minusMonths(i));
LocalDateTime endTime = LocalDateTimeUtils.endOfMonth(startTime);
summaryList.add(new ErpSaleTimeSummaryRespVO()
.setTime(LocalDateTimeUtil.format(startTime, NORM_MONTH_PATTERN))
.setPrice(saleStatisticsService.getSalePrice(startTime, endTime)));
}
return success(summaryList);
}
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 采购全局统计 Response VO")
@Data
public class ErpPurchaseSummaryRespVO {
@Schema(description = "今日采购金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private BigDecimal todayPrice;
@Schema(description = "昨日采购金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
private BigDecimal yesterdayPrice;
@Schema(description = "本月采购金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private BigDecimal monthPrice;
@Schema(description = "今年采购金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "88888")
private BigDecimal yearPrice;
}

View File

@ -1,18 +0,0 @@
package cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 采购某个时间段的统计 Response VO")
@Data
public class ErpPurchaseTimeSummaryRespVO {
@Schema(description = "时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-03")
private String time;
@Schema(description = "采购金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private BigDecimal price;
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.sale;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 销售全局统计 Response VO")
@Data
public class ErpSaleSummaryRespVO {
@Schema(description = "今日销售金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private BigDecimal todayPrice;
@Schema(description = "昨日销售金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
private BigDecimal yesterdayPrice;
@Schema(description = "本月销售金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private BigDecimal monthPrice;
@Schema(description = "今年销售金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "88888")
private BigDecimal yearPrice;
}

View File

@ -1,18 +0,0 @@
package cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.sale;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 销售某个时间段的统计 Response VO")
@Data
public class ErpSaleTimeSummaryRespVO {
@Schema(description = "时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2022-03")
private String time;
@Schema(description = "销售金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private BigDecimal price;
}

View File

@ -1,20 +0,0 @@
package cn.iocoder.yudao.module.erp.dal.mysql.statistics;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* ERP 采购统计 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ErpPurchaseStatisticsMapper {
BigDecimal getPurchasePrice(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
}

View File

@ -1,20 +0,0 @@
package cn.iocoder.yudao.module.erp.dal.mysql.statistics;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* ERP 销售统计 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ErpSaleStatisticsMapper {
BigDecimal getSalePrice(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.erp.service.statistics;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* ERP 采购统计 Service 接口
*
* @author 芋道源码
*/
public interface ErpPurchaseStatisticsService {
/**
* 获得采购金额
*
* 计算逻辑采购出库的金额 - 采购退货的金额
*
* @param beginTime >= 开始时间
* @param endTime < 结束时间
* @return 采购金额
*/
BigDecimal getPurchasePrice(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.erp.service.statistics;
import cn.iocoder.yudao.module.erp.dal.mysql.statistics.ErpPurchaseStatisticsMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* ERP 采购统计 Service 实现类
*
* @author 芋道源码
*/
@Service
public class ErpPurchaseStatisticsServiceImpl implements ErpPurchaseStatisticsService {
@Resource
private ErpPurchaseStatisticsMapper purchaseStatisticsMapper;
@Override
public BigDecimal getPurchasePrice(LocalDateTime beginTime, LocalDateTime endTime) {
return purchaseStatisticsMapper.getPurchasePrice(beginTime, endTime);
}
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.erp.service.statistics;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* ERP 销售统计 Service 接口
*
* @author 芋道源码
*/
public interface ErpSaleStatisticsService {
/**
* 获得销售金额
*
* 计算逻辑销售出库的金额 - 销售退货的金额
*
* @param beginTime >= 开始时间
* @param endTime < 结束时间
* @return 销售金额
*/
BigDecimal getSalePrice(LocalDateTime beginTime, LocalDateTime endTime);
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.erp.service.statistics;
import cn.iocoder.yudao.module.erp.dal.mysql.statistics.ErpSaleStatisticsMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* ERP 销售统计 Service 实现类
*
* @author 芋道源码
*/
@Service
public class ErpSaleStatisticsServiceImpl implements ErpSaleStatisticsService {
@Resource
private ErpSaleStatisticsMapper saleStatisticsMapper;
@Override
public BigDecimal getSalePrice(LocalDateTime beginTime, LocalDateTime endTime) {
return saleStatisticsMapper.getSalePrice(beginTime, endTime);
}
}

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.erp.dal.mysql.statistics.ErpPurchaseStatisticsMapper">
<select id="getPurchasePrice" resultType="java.math.BigDecimal">
SELECT
(SELECT IFNULL(SUM(total_price), 0)
FROM erp_purchase_in
WHERE in_time >= #{beginTime}
<if test="endTime != null">
AND in_time &lt; #{endTime}
</if>
AND deleted = 0) -
(SELECT IFNULL(SUM(total_price), 0)
FROM erp_purchase_return
WHERE return_time >= #{beginTime}
<if test="endTime != null">
AND return_time &lt; #{endTime}
</if>
AND deleted = 0)
</select>
</mapper>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.erp.dal.mysql.statistics.ErpSaleStatisticsMapper">
<select id="getSalePrice" resultType="java.math.BigDecimal">
SELECT
(SELECT IFNULL(SUM(total_price), 0)
FROM erp_sale_out
WHERE out_time >= #{beginTime}
<if test="endTime != null">
AND out_time &lt; #{endTime}
</if>
AND deleted = 0) -
(SELECT IFNULL(SUM(total_price), 0)
FROM erp_sale_return
WHERE return_time >= #{beginTime}
<if test="endTime != null">
AND return_time &lt; #{endTime}
</if>
AND deleted = 0)
</select>
</mapper>