Skip to content

Commit

Permalink
Merge branch 'master-jdk21' of https://gitee.com/zhijiantianya/yudao-…
Browse files Browse the repository at this point in the history
…cloud

# Conflicts:
#	pom.xml
#	yudao-dependencies/pom.xml
#	yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
#	yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java
  • Loading branch information
YunaiV committed Feb 17, 2024
2 parents 3a25879 + 0e55c4d commit 8b4b4fc
Show file tree
Hide file tree
Showing 524 changed files with 37,566 additions and 95 deletions.
Binary file added .image/common/erp-feature.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@
* 数据报表
* 商城系统
* 微信公众号
* ERP 系统
* CRM 系统

> 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。
>
Expand Down Expand Up @@ -230,6 +232,12 @@
| 🚀 | 会员分组 | 对会员进行分组,用于用户画像、内容推送等运营手段 |
| 🚀 | 积分签到 | 回馈给签到、消费等行为的积分,会员可订单抵现、积分兑换等途径消耗 |

### ERP 系统

![功能图](/.image/common/erp-feature.png)

演示地址:<https://doc.iocoder.cn/erp-preview/>

## 🐨 技术栈

### 微服务
Expand Down
216 changes: 191 additions & 25 deletions sql/mysql/ruoyi-vue-pro.sql

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,16 @@ public static <T, V extends Comparable<? super V>> V getMinValue(List<T> from, F

public static <T, V extends Comparable<? super V>> V getSumValue(List<T> from, Function<T, V> valueFunc,
BinaryOperator<V> accumulator) {
return getSumValue(from, valueFunc, accumulator, null);
}

public static <T, V extends Comparable<? super V>> V getSumValue(Collection<T> from, Function<T, V> valueFunc,
BinaryOperator<V> accumulator, V defaultValue) {
if (CollUtil.isEmpty(from)) {
return null;
return defaultValue;
}
assert from.size() > 0; // 断言,避免告警
return from.stream().map(valueFunc).reduce(accumulator).get();
assert !from.isEmpty(); // 断言,避免告警
return from.stream().map(valueFunc).filter(Objects::nonNull).reduce(accumulator).orElse(defaultValue);
}

public static <T> void addIfNotNull(Collection<T> coll, T item) {
Expand All @@ -302,8 +307,12 @@ public static <T> void addIfNotNull(Collection<T> coll, T item) {
coll.add(item);
}

public static <T> Collection<T> singleton(T deptId) {
return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
public static <T> Collection<T> singleton(T obj) {
return obj == null ? Collections.emptyList() : Collections.singleton(obj);
}

public static <T> List<T> newArrayList(List<List<T>> list) {
return list.stream().flatMap(Collection::stream).collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
*/
public class MoneyUtils {

/**
* 金额的小数位数
*/
private static final int PRICE_SCALE = 2;

/**
* 百分比对应的 BigDecimal 对象
*/
public static final BigDecimal PERCENT_100 = BigDecimal.valueOf(100);

/**
* 计算百分比金额,四舍五入
*
Expand All @@ -35,6 +45,22 @@ public static Integer calculateRatePriceFloor(Integer price, Double rate) {
return calculateRatePrice(price, rate, 0, RoundingMode.FLOOR).intValue();
}

/**
* 计算百分比金额
*
* @param price 金额(单位分)
* @param count 数量
* @param percent 折扣(单位分),列如 60.2%,则传入 6020
* @return 商品总价
*/
public static Integer calculator(Integer price, Integer count, Integer percent) {
price = price * count;
if (percent == null) {
return price;
}
return MoneyUtils.calculateRatePriceFloor(price, (double) (percent / 100));
}

/**
* 计算百分比金额
*
Expand Down Expand Up @@ -70,4 +96,36 @@ public static String fenToYuanStr(int fen) {
return new Money(0, fen).toString();
}

/**
* 金额相乘,默认进行四舍五入
*
* 位数:{@link #PRICE_SCALE}
*
* @param price 金额
* @param count 数量
* @return 金额相乘结果
*/
public static BigDecimal priceMultiply(BigDecimal price, BigDecimal count) {
if (price == null || count == null) {
return null;
}
return price.multiply(count).setScale(PRICE_SCALE, RoundingMode.HALF_UP);
}

/**
* 金额相乘(百分比),默认进行四舍五入
*
* 位数:{@link #PRICE_SCALE}
*
* @param price 金额
* @param percent 百分比
* @return 金额相乘结果
*/
public static BigDecimal priceMultiplyPercent(BigDecimal price, BigDecimal percent) {
if (price == null || percent == null) {
return null;
}
return price.multiply(percent).divide(PERCENT_100, PRICE_SCALE, RoundingMode.HALF_UP);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package cn.iocoder.yudao.framework.common.util.number;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;

import java.math.BigDecimal;

/**
* 数字的工具类,补全 {@link cn.hutool.core.util.NumberUtil} 的功能
*
Expand Down Expand Up @@ -37,4 +40,21 @@ public static double getDistance(double lat1, double lng1, double lat2, double l
return distance;
}

/**
* 提供精确的乘法运算
*
* 和 hutool {@link NumberUtil#mul(BigDecimal...)} 的差别是,如果存在 null,则返回 null
*
* @param values 多个被乘值
* @return 积
*/
public static BigDecimal mul(BigDecimal... values) {
for (BigDecimal value : values) {
if (value == null) {
return null;
}
}
return NumberUtil.mul(values);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cn.iocoder.yudao.framework.file.core.client;

import cn.iocoder.yudao.framework.file.core.client.s3.FilePresignedUrlRespDTO;

/**
* 文件客户端
*
Expand All @@ -18,11 +20,11 @@ public interface FileClient {
* 上传文件
*
* @param content 文件流
* @param path 相对路径
* @param path 相对路径
* @return 完整路径,即 HTTP 访问地址
* @throws Exception 上传文件时,抛出 Exception 异常
*/
String upload(byte[] content, String path, String type) throws Exception;
String upload(byte[] content, String path, String type) throws Exception;

/**
* 删除文件
Expand All @@ -40,4 +42,14 @@ public interface FileClient {
*/
byte[] getContent(String path) throws Exception;

/**
* 获得文件预签名地址
*
* @param path 相对路径
* @return 文件预签名地址
*/
default FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception {
throw new UnsupportedOperationException("不支持的操作");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cn.iocoder.yudao.framework.file.core.client.s3;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* 文件预签名地址 Response DTO
*
* @author owen
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FilePresignedUrlRespDTO {

/**
* 文件上传 URL(用于上传)
*
* 例如说:
*/
private String uploadUrl;

/**
* 文件 URL(用于读取、下载等)
*/
private String url;

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import cn.hutool.http.HttpUtil;
import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
import io.minio.*;
import io.minio.http.Method;

import java.io.ByteArrayInputStream;
import java.util.concurrent.TimeUnit;

import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_ALIYUN;
import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_TENCENT;
Expand Down Expand Up @@ -117,4 +119,16 @@ public byte[] getContent(String path) throws Exception {
return IoUtil.readBytes(response);
}

@Override
public FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception {
String uploadUrl = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.PUT)
.bucket(config.getBucket())
.object(path)
.expiry(10, TimeUnit.MINUTES) // 过期时间(秒数)取值范围:1 秒 ~ 7 天
.build()
);
return new FilePresignedUrlRespDTO(uploadUrl, config.getDomain() + "/" + path);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public QueryWrapperX<T> limitN(int n) {
switch (SqlConstants.DB_TYPE) {
case ORACLE:
case ORACLE_12C:
super.eq("ROWNUM", n);
super.le("ROWNUM", n);
break;
case SQL_SERVER:
case SQL_SERVER2005:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public void run(ApplicationArguments args) {
System.out.println("[微信公众号 yudao-module-mp 教程][参考 https://cloud.iocoder.cn/mp/build/ 开启]");
// 商城系统
System.out.println("[商城系统 yudao-module-mall 教程][参考 https://cloud.iocoder.cn/mall/build/ 开启]");
// ERP 系统
System.out.println("[ERP 系统 yudao-module-erp - 已禁用][参考 https://doc.iocoder.cn/erp/build/ 开启]");
// 支付平台
System.out.println("[支付系统 yudao-module-pay - 已禁用][参考 https://doc.iocoder.cn/pay/build/ 开启]");
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,13 @@ private CommonResult<?> handleTableNotExists(Throwable ex) {
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]");
}
// 5. 支付平台
// 5. ERP 系统
if (message.contains("erp_")) {
log.error("[ERP 系统 yudao-module-erp - 表结构未导入][参考 https://doc.iocoder.cn/erp/build/ 开启]");
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
"[ERP 系统 yudao-module-erp - 表结构未导入][参考 https://doc.iocoder.cn/erp/build/ 开启]");
}
// 6. 支付平台
if (message.contains("pay_")) {
log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]");
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public void run(ApplicationArguments args) {
System.out.println("[微信公众号 yudao-module-mp 教程][参考 https://cloud.iocoder.cn/mp/build/ 开启]");
// 商城系统
System.out.println("[商城系统 yudao-module-mall 教程][参考 https://cloud.iocoder.cn/mall/build/ 开启]");
// ERP 系统
System.out.println("[ERP 系统 yudao-module-erp - 已禁用][参考 https://doc.iocoder.cn/erp/build/ 开启]");
// 支付平台
System.out.println("[支付系统 yudao-module-pay - 已禁用][参考 https://doc.iocoder.cn/pay/build/ 开启]");
});
Expand Down
22 changes: 18 additions & 4 deletions yudao-gateway/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,20 @@ spring:
- Path=/admin-api/statistics/**
filters:
- RewritePath=/admin-api/statistics/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
- id: statistics-app-api # 路由的编号
uri: grayLb://statistics-server
## erp-server 服务
- id: erp-admin-api # 路由的编号
uri: grayLb://erp-server
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/admin-api/erp/**
filters:
- RewritePath=/admin-api/erp/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
## crm-server 服务
- id: crm-admin-api # 路由的编号
uri: grayLb://crm-server
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/app-api/statistics/**
- Path=/admin-api/crm/**
filters:
- RewritePath=/app-api/statistics/v3/api-docs, /v3/api-docs
- RewritePath=/admin-api/crm/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
x-forwarded:
prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀

Expand Down Expand Up @@ -182,6 +190,12 @@ knife4j:
- name: statistics-server
service-name: statistics-server
url: /admin-api/statistics/v3/api-docs
- name: erp-server
service-name: erp-server
url: /admin-api/erp/v3/api-docs
- name: crm-server
service-name: crm-server
url: /admin-api/crm/v3/api-docs

--- #################### 芋道相关配置 ####################

Expand Down
25 changes: 25 additions & 0 deletions yudao-module-crm/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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.cloud</groupId>
<artifactId>yudao</artifactId>
<version>${revision}</version>
</parent>
<modules>
<module>yudao-module-crm-api</module>
<module>yudao-module-crm-biz</module>
</modules>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-crm</artifactId>
<packaging>pom</packaging>

<name>${project.artifactId}</name>
<description>
crm 包下,客户关系管理(Customer Relationship Management)。
例如说:客户、联系人、商机、合同、回款等等
商业智能 BI 模块,包括:报表、图表、数据大屏等等
</description>

</project>
Loading

0 comments on commit 8b4b4fc

Please sign in to comment.