22 Commits

Author SHA1 Message Date
king
5b25cb3766 计算销售报表-增加计算字段 本月毛利率,本年毛利率,上年毛利率,本月销售金额占比,本年销售金额占比,上年销售金额占比,本月毛利额占比,本年毛利额占比,上年毛利额占比,销售金额增长率,毛利额增长率,毛利变动 2026-03-12 10:28:04 +08:00
king
66028bf17a 计算销售报表-增加计算字段 本月毛利率,本年毛利率,上年毛利率,本月销售金额占比,本年销售金额占比,上年销售金额占比,本月毛利额占比,本年毛利额占比,上年毛利额占比,销售金额增长率,毛利额增长率,毛利变动 2026-03-12 10:26:12 +08:00
king
ebf54b4ecf 计算销售报表-调整计算逻辑,增加计算字段 2026-03-11 17:11:25 +08:00
king
8f22732f04 计算销售报表 2026-03-11 14:41:55 +08:00
king
e230587f66 计算销售报表 2026-03-11 14:41:51 +08:00
king
3fb081217f 计算销售报表 2026-03-11 14:38:51 +08:00
king
e882dd280e Merge remote-tracking branch 'origin/master' 2026-03-11 09:13:38 +08:00
king
7fc21dcc9b SQL调整 金额已万为单位 2026-03-11 09:07:54 +08:00
chy
eca53d5424 添加单点登录接口和退出接口 2026-03-11 00:23:07 +08:00
chy
f9d4b08495 Merge remote-tracking branch 'origin/master' 2026-03-11 00:01:49 +08:00
chy
32627270d1 添加单点登录接口和退出接口 2026-03-11 00:01:32 +08:00
king
affe6bfed5 分组SQL调整 2026-03-10 16:52:34 +08:00
king
8523b80eb3 分组SQL调整 2026-03-10 15:38:16 +08:00
king
b6a6ad88e7 分组SQL调整 2026-03-10 15:04:48 +08:00
king
3c1274c3d6 Merge branch 'master' into dev_js_20260309 2026-03-10 14:37:07 +08:00
king
b021d2ef01 删除打印 2026-03-10 14:36:06 +08:00
2fa40c266f Merge pull request '实现前置增强逻辑,再实现“综合销售情况表” 动态分组逻辑' (#25) from dev_js_20260309 into master
Reviewed-on: #25
2026-03-10 14:32:51 +08:00
chy
56cb31c616 根据tokne获取用户信息 2026-03-10 14:23:28 +08:00
king
1c9d3b831c 实现前置增强逻辑,再实现“综合销售情况表” 动态分组逻辑 2026-03-10 14:13:57 +08:00
chy
de1774b2d3 修改配置文件 2026-03-10 11:13:56 +08:00
chy
43e66ea9c6 根据ticket获取用户信息 2026-03-10 11:09:46 +08:00
f494611789 Merge pull request '销售明细表定时任务' (#24) from liug into master
Reviewed-on: #24
2026-03-06 23:01:12 +08:00
27 changed files with 895 additions and 40 deletions

View File

@@ -9,43 +9,33 @@ spring:
datasource:
master:
# MYSQL数据库 主库,业务库
# url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://192.168.126.128:33306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
username: root
password: root
lideeyunji: # 从库,框架库
# url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://192.168.126.128:33306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: root
slave: # 日志库单独
lazy: true # 开启懒加载,保证启动速度
# url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://192.168.126.128:33306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: root
oracle_gryybi: # 报表平台 oracle
driver-class-name: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@//192.168.1.247:1521/gryy?oracle.jdbc.defaultNChar=true&oracle.jdbc.convertNcharLiterals=true
username: GRYYBI
password: xxb147258367
# driver-class-name: oracle.jdbc.OracleDriver
driver-class-name: oracle.jdbc.driver.OracleDriver
erp_bi_data: # 报表平台 mysql
# url: jdbc:mysql://127.0.0.1:3306/erp_bi_data?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://192.168.126.128:33306/erp_bi_data?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/erp_bi_data?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: root
# redis:
# host: 127.0.0.1 # 地址
# port: 6379 # 端口
# database: 2 # 数据库索引
# password: lidee@123 # 密码,建议生产环境开启
redis:
host: 192.168.126.128 # 地址
host: 127.0.0.1 # 地址
port: 6379 # 端口
database: 2 # 数据库索引
password: 123456 # 密码,建议生产环境开启
password: lidee@123 # 密码,建议生产环境开启
--- #################### 地代码平台相关配置 ####################

View File

@@ -9,16 +9,26 @@ spring:
datasource:
master:
# MYSQL数据库 主库,业务库
url: jdbc:mysql://127.0.0.1:3306/gr_repoort?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
username: root
password: gryy@8888
lideeyunji: # 从库,框架库
url: jdbc:mysql://127.0.0.1:3306/gr_repoort?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: gryy@8888
slave: # 日志库单独
lazy: true # 开启懒加载,保证启动速度
url: jdbc:mysql://127.0.0.1:3306/gr_repoort?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
url: jdbc:mysql://127.0.0.1:3306/gr_report?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: gryy@8888
oracle_gryybi: # 报表平台 oracle
url: jdbc:oracle:thin:@//192.168.1.247:1521/gryy?oracle.jdbc.defaultNChar=true&oracle.jdbc.convertNcharLiterals=true
username: GRYYBI
password: xxb147258367
# driver-class-name: oracle.jdbc.OracleDriver
driver-class-name: oracle.jdbc.driver.OracleDriver
erp_bi_data: # 报表平台 mysql
url: jdbc:mysql://127.0.0.1:3306/erp_bi_data?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: gryy@8888
redis:

View File

@@ -2,8 +2,8 @@ spring:
application:
name: lideeyunji-server
profiles:
active: local # 读取配置
#active: prod # 读取配置
# active: local # 读取配置
active: prod # 读取配置
main:
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。

View File

@@ -78,5 +78,10 @@
<artifactId>lidee-service-infra-api</artifactId>
<version>${lidee.version}</version>
</dependency>
<dependency>
<groupId>com.oracle.database.nls</groupId>
<artifactId>orai18n</artifactId>
<version>21.1.0.0</version>
</dependency>
</dependencies>
</project>

View File

@@ -13,6 +13,7 @@ import com.lideeyunji.core.framework.config.aspect.enhancereport.model.EnhanceRe
import com.lideeyunji.core.framework.config.aspect.enhancereport.model.EnhanceReportParam;
import com.lideeyunji.core.framework.config.aspect.enhancereport.plugin.ReportAfterAdvicePlugin;
import com.lideeyunji.core.framework.config.aspect.enhancereport.plugin.ReportBaseAdvicePlugin;
import com.lideeyunji.core.framework.config.aspect.enhancereport.plugin.ReportBeforeAdvicePlugin;
import com.lideeyunji.core.framework.config.aspect.enhancereport.plugin.ReportPluginManager;
import com.lideeyunji.core.framework.entity.ReportEntity;
import com.lideeyunji.core.framework.service.IReportService;
@@ -25,6 +26,7 @@ import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@@ -113,6 +115,31 @@ public class LideeYunJiReportEnhance extends LideeYunJiBaseEnhance {
}
@Before("@annotation(lideeyunJiReportEnhance)")
public void before(JoinPoint joinPoint, LideeyunJiReportEnhance lideeyunJiReportEnhance) throws Throwable {
//获取参数
BuildEnhanceReportContext buildEnhanceContext = this.getContextAndPlugins(joinPoint);
if (FuncBase.isEmpty(buildEnhanceContext)) {//没有增强
return ;
}
//增强列表
String javaClass = buildEnhanceContext.getJavaClass();
if (Func.isEmpty(javaClass)) {//无增强
return ;
}
//有增强,但是增强不是报表增强,直接返回原值
ReportBaseAdvicePlugin plugin = ReportPluginManager.getPlugin(javaClass);
if (!(plugin instanceof ReportBeforeAdvicePlugin)) {
return ;
}
EnhanceReportContext context = buildEnhanceContext.getContext();
//执行增强
ReportPluginManager.executePlugin(javaClass, context);
}
private BuildEnhanceReportContext getContextAndPlugins(JoinPoint joinPoint) {
Map<String, Object> paramMap = super.getJoinPointParam(joinPoint);

View File

@@ -0,0 +1,9 @@
package com.lideeyunji.core.framework.config.aspect.enhancereport.plugin;
/**
* 报表统计 前置增强(报表统计专属)
*/
public interface ReportBeforeAdvicePlugin extends ReportBaseAdvicePlugin {
}

View File

@@ -0,0 +1,34 @@
package com.lideeyunji.core.framework.config.job;
import com.lideeyunji.core.framework.service.IGrBiSaAggService;
import com.lideeyunji.tool.framework.common.constant.lideeYunJiBaseConstant;
import com.lideeyunji.tool.framework.quartz.core.handler.JobHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 计算销售报表
* erp_bi_data.GR_BI_PUB_GOODS
* erp_bi_data.GR_BI_PUB_SALEZONE
* erp_bi_data.GR_BI_PUB_PROVINCE
* erp_bi_data.GR_BI_PUB_SALETYPE
* erp_bi_data.GR_BI_PUB_DOSAGE
* erp_bi_data.GR_BI_PUB_CUSTOM
* erp_bi_data.GR_BI_PUB_SALER
* --> mysql erp_bi_data.yunji_gr_bi_sa_agg
*/
@Slf4j
@Component("generateSalesReportJob")
public class GenerateSalesReportJob implements JobHandler {
@Resource
private IGrBiSaAggService grBiSaAggService;
public String execute(String param) {
log.info("*********** 开始生成销售报表 ************");
grBiSaAggService.generateSalesReportJob(lideeYunJiBaseConstant.DS_ERP_BI_DATA);
log.info("*********** 生成销售报表完成 ************");
return "*********** 生成销售报表完成 ************";
}
}

View File

@@ -13,8 +13,8 @@ import org.springframework.stereotype.Component;
* 同步销售明细表
* oracle gryybi GR_BI_SA_SETDTL --> mysql erp_bi_data GR_BI_SA_SETDTL
*/
@Component
@Slf4j
@Component("SaSetdtlSyncJob")
public class SaSetdtlSyncJob implements JobHandler {
@Autowired

View File

@@ -60,9 +60,6 @@ public class anyToGrBiSasetdtl implements JobHandler {
while (rs.next()) {
//写入到数据中台表
System.out.println(rs.getString("SASETTLEDTLID"));
}

View File

@@ -0,0 +1,158 @@
package com.lideeyunji.core.framework.enhance.example.report.xtsy;
import com.lideeyunji.core.framework.config.aspect.enhancereport.model.EnhanceReportContext;
import com.lideeyunji.core.framework.config.aspect.enhancereport.plugin.ReportBeforeAdvicePlugin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 报表-系统首页-单表
*/
@Slf4j
@Component("zhxsqkLineReportEnhance")
public class zhxsqkLineReportEnhance implements ReportBeforeAdvicePlugin {
@Override
public void execute(EnhanceReportContext enhanceContext) {
log.info("进入=======>zhxsqkLineReportEnhance=======>execute");
Map<String, Object> params = enhanceContext.getParam().getParams();
if (params.containsKey("Group by")) {
List<String> groupFieldList = Arrays.asList(params.get("Group by").toString().split(","));
StringBuilder executePluginSql = new StringBuilder();
executePluginSql.append(" SELECT \n");
if (groupFieldList.contains("customname")) { //客户名称
executePluginSql.append(" tbl_lgbsa.CUSTOMID, \n");
executePluginSql.append(" tbl_lgbsa.CUSTOMNAME, \n");
}
if (groupFieldList.contains("useyear")) { //年
executePluginSql.append(" tbl_lgbsa.USEYEAR, \n");
}
if (groupFieldList.contains("usemonth")) { //月
executePluginSql.append(" tbl_lgbsa.USEMONTH, \n");
}
if (groupFieldList.contains("zonename")) { //业务区域
executePluginSql.append(" tbl_lgbsa.ZONEID, \n");
executePluginSql.append(" tbl_lgbsa.ZONENAME, \n");
}
if (groupFieldList.contains("saletypename")) { //销售类型
executePluginSql.append(" tbl_lgbsa.SALETYPEID, \n");
executePluginSql.append(" tbl_lgbsa.SALETYPENAME, \n");
}
if (groupFieldList.contains("salername")) { //业务员
executePluginSql.append(" tbl_lgbsa.SALERID, \n");
executePluginSql.append(" tbl_lgbsa.SALERNAME, \n");
}
if (groupFieldList.contains("dosagename")) { //剂型
executePluginSql.append(" tbl_lgbsa.DOSAGEID, \n");
executePluginSql.append(" tbl_lgbsa.DOSAGENAME, \n");
}
executePluginSql.append(" MAX(CONCAT(USEYEAR, LPAD(USEMONTH, 2, '0'))) as ny, \n"); //年月
executePluginSql.append(" GROUP_CONCAT(DISTINCT tbl_lgbsa.PROVINCEID ORDER BY tbl_lgbsa.PROVINCEID SEPARATOR ',') as PROVINCEID, \n"); //行政区域ID
executePluginSql.append(" GROUP_CONCAT(DISTINCT tbl_lgbsa.PROVINCENAME ORDER BY tbl_lgbsa.PROVINCEID SEPARATOR ',') as PROVINCENAME, \n"); //行政区域名称
executePluginSql.append(" SUM(tbl_lgbsa.MONTHSAQTY) as MONTHSAQTY, \n"); //本月销量
executePluginSql.append(" CONCAT(ROUND((SELECT SUM(MONTHSAQTY) FROM yunji_gr_bi_sa_agg)/100000000 ,2), '亿') AS monthsaqty_s, \n");
executePluginSql.append(" CONCAT(ROUND((SELECT SUM(THISSAQTY) FROM yunji_gr_bi_sa_agg)/100000000 ,2), '亿') AS thissaqty_s, \n");
executePluginSql.append(" CONCAT(ROUND((SELECT SUM(LASTSAQTY) FROM yunji_gr_bi_sa_agg)/100000000 ,2), '亿') AS lastsaqty_s, \n");
executePluginSql.append(" -- 原本带CAST的字段简化写法CONCAT会自动转为字符串 \n");
executePluginSql.append(" CONCAT(ROUND((SELECT SUM(MONTHSAMONEY) FROM yunji_gr_bi_sa_agg)/100000000 ,2), '亿') AS monthsamoney_s, \n");
executePluginSql.append(" CONCAT(ROUND((SELECT SUM(THISSAMONEY) FROM yunji_gr_bi_sa_agg)/100000000,2), '亿') AS thissamoney_s, \n");
executePluginSql.append(" CONCAT(ROUND((SELECT SUM(LASTSAMONEY) FROM yunji_gr_bi_sa_agg)/100000000,2), '亿') AS lastsamoney_s, \n");
executePluginSql.append(" SUM(tbl_lgbsa.THISSAQTY) as THISSAQTY, \n"); //本年销量
executePluginSql.append(" SUM(tbl_lgbsa.LASTSAQTY) as LASTSAQTY, \n"); //上年销量
executePluginSql.append(" -- 数量同比(原有) \n");
executePluginSql.append(" CASE \n");
executePluginSql.append(" WHEN (CASE WHEN sum(tbl_lgbsa.LASTSAQTY) = 0 THEN IF(sum(tbl_lgbsa.THISSAQTY) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISSAQTY) - sum(tbl_lgbsa.LASTSAQTY)) / sum(tbl_lgbsa.LASTSAQTY) * 100 END) > 0 THEN \n");
executePluginSql.append(" CONCAT('🟢 ', ROUND((CASE WHEN sum(tbl_lgbsa.LASTSAQTY) = 0 THEN IF(sum(tbl_lgbsa.THISSAQTY) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISSAQTY) - sum(tbl_lgbsa.LASTSAQTY)) / sum(tbl_lgbsa.LASTSAQTY) * 100 END), 2), '%') \n");
executePluginSql.append(" WHEN (CASE WHEN sum(tbl_lgbsa.LASTSAQTY) = 0 THEN IF(sum(tbl_lgbsa.THISSAQTY) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISSAQTY) - sum(tbl_lgbsa.LASTSAQTY)) / sum(tbl_lgbsa.LASTSAQTY) * 100 END) < 0 THEN \n");
executePluginSql.append(" CONCAT('🔴 ', ROUND((CASE WHEN sum(tbl_lgbsa.LASTSAQTY) = 0 THEN IF(sum(tbl_lgbsa.THISSAQTY) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISSAQTY) - sum(tbl_lgbsa.LASTSAQTY)) / sum(tbl_lgbsa.LASTSAQTY) * 100 END), 2), '%') \n");
executePluginSql.append(" ELSE '0.00%' \n");
executePluginSql.append(" END AS saqty_yoy, \n");
executePluginSql.append(" CONCAT(ROUND(SUM(tbl_lgbsa.MONTHSAMONEY) / 10000, 2), '万') as MONTHSAMONEY, \n"); //本月销售金额(元)
executePluginSql.append(" CONCAT(ROUND(SUM(tbl_lgbsa.THISSAMONEY) / 10000, 2), '万') as THISSAMONEY, \n"); //本年销售金额(元)
executePluginSql.append(" CONCAT(ROUND(SUM(tbl_lgbsa.LASTSAMONEY) / 10000, 2), '万') as LASTSAMONEY, \n"); //上年销售金额(元)
executePluginSql.append(" -- 销售金额同比(原有新增) \n");
executePluginSql.append(" CASE \n");
executePluginSql.append(" WHEN (CASE WHEN sum(tbl_lgbsa.LASTSAMONEY) = 0 THEN IF(sum(tbl_lgbsa.THISSAMONEY) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISSAMONEY) - sum(tbl_lgbsa.LASTSAMONEY)) / sum(tbl_lgbsa.LASTSAMONEY) * 100 END) > 0 THEN \n");
executePluginSql.append(" CONCAT('🟢 ', ROUND((CASE WHEN sum(tbl_lgbsa.LASTSAMONEY) = 0 THEN IF(sum(tbl_lgbsa.THISSAMONEY) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISSAMONEY) - sum(tbl_lgbsa.LASTSAMONEY)) / sum(tbl_lgbsa.LASTSAMONEY) * 100 END), 2), '%') \n");
executePluginSql.append(" WHEN (CASE WHEN sum(tbl_lgbsa.LASTSAMONEY) = 0 THEN IF(sum(tbl_lgbsa.THISSAMONEY) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISSAMONEY) - sum(tbl_lgbsa.LASTSAMONEY)) / sum(tbl_lgbsa.LASTSAMONEY) * 100 END) < 0 THEN \n");
executePluginSql.append(" CONCAT('🔴 ', ROUND((CASE WHEN sum(tbl_lgbsa.LASTSAMONEY) = 0 THEN IF(sum(tbl_lgbsa.THISSAMONEY) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISSAMONEY) - sum(tbl_lgbsa.LASTSAMONEY)) / sum(tbl_lgbsa.LASTSAMONEY) * 100 END), 2), '%') \n");
executePluginSql.append(" ELSE '0.00%' \n");
executePluginSql.append(" END AS samoney_yoy, \n"); //销售收入同比
executePluginSql.append(" CONCAT(ROUND(SUM(tbl_lgbsa.MONTHPROFIT) / 10000, 2), '万') as MONTHPROFIT, \n"); //本月毛利额(元)
executePluginSql.append(" CONCAT(ROUND(SUM(tbl_lgbsa.THISPROFIT) / 10000, 2), '万') as THISPROFIT, \n"); //本年毛利额(元)
executePluginSql.append(" CONCAT(ROUND(SUM(tbl_lgbsa.LASTPROFIT) / 10000, 2), '万') as LASTPROFIT, \n"); //上年毛利额(元)
executePluginSql.append(" -- 新增:毛利同比 \n");
executePluginSql.append(" CASE \n");
executePluginSql.append(" -- 正数红色圆点emoji + 数值 + % \n");
executePluginSql.append(" WHEN (CASE WHEN sum(tbl_lgbsa.LASTPROFIT) = 0 THEN IF(sum(tbl_lgbsa.THISPROFIT) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISPROFIT) - sum(tbl_lgbsa.LASTPROFIT)) / sum(tbl_lgbsa.LASTPROFIT) * 100 END) > 0 THEN \n");
executePluginSql.append(" CONCAT('🟢 ', ROUND((CASE WHEN sum(tbl_lgbsa.LASTPROFIT) = 0 THEN IF(sum(tbl_lgbsa.THISPROFIT) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISPROFIT) - sum(tbl_lgbsa.LASTPROFIT)) / sum(tbl_lgbsa.LASTPROFIT) * 100 END), 2), '%') \n");
executePluginSql.append(" -- 负数绿色圆点emoji + 数值 + % \n");
executePluginSql.append(" WHEN (CASE WHEN sum(tbl_lgbsa.LASTPROFIT) = 0 THEN IF(sum(tbl_lgbsa.THISPROFIT) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISPROFIT) - sum(tbl_lgbsa.LASTPROFIT)) / sum(tbl_lgbsa.LASTPROFIT) * 100 END) < 0 THEN \n");
executePluginSql.append(" CONCAT('🔴 ', ROUND((CASE WHEN sum(tbl_lgbsa.LASTPROFIT) = 0 THEN IF(sum(tbl_lgbsa.THISPROFIT) > 0, 100, 0) \n");
executePluginSql.append(" ELSE (sum(tbl_lgbsa.THISPROFIT) - sum(tbl_lgbsa.LASTPROFIT)) / sum(tbl_lgbsa.LASTPROFIT) * 100 END), 2), '%') \n");
executePluginSql.append(" -- 0值直接显示 \n");
executePluginSql.append(" ELSE '0.00%' \n");
executePluginSql.append(" END AS profit_yoy, \n"); //毛利同比
executePluginSql.append(" CONCAT(ROUND(SUM(tbl_lgbsa.MONTHCOST) / 10000, 2), '万') as MONTHCOST, \n"); //本月销售成本(元)
executePluginSql.append(" ROUND(avg(tbl_lgbsa.PROFITCHANGE), 2) as PROFITCHANGE, \n"); //毛利变动(元)
executePluginSql.append(" ROUND(avg(tbl_lgbsa.PROFITGROWTH), 2) as PROFITGROWTH, \n"); //毛利额增长率
executePluginSql.append(" ROUND(avg(tbl_lgbsa.THISPROFITRATE), 2) as THISPROFITRATE, \n"); //本年毛利率
executePluginSql.append(" ROUND(avg(tbl_lgbsa.SAMONEYGROWTH), 2) as SAMONEYGROWTH, \n"); //销售金额增长率
executePluginSql.append(" ROUND(avg(tbl_lgbsa.LASTPROFITSHARE) * 100, 2) as LASTPROFITSHARE, \n"); //上年毛利额占比
executePluginSql.append(" CONCAT(ROUND(avg(tbl_lgbsa.THISPROFITSHARE) * 100, 2), '%') AS THISPROFITSHARE, \n"); //本年毛利额占比
executePluginSql.append(" CONCAT(ROUND(avg(tbl_lgbsa.MONTHPROFITSHARE) * 100, 2), '%') AS MONTHPROFITSHARE, \n"); //本月毛利额占比
executePluginSql.append(" CONCAT(ROUND(avg(tbl_lgbsa.LASTSAMONEYSHARE) * 100, 2), '%') AS LASTSAMONEYSHARE, \n"); //上年销售金额占比
executePluginSql.append(" CONCAT(ROUND(avg(tbl_lgbsa.THISSAMONEYSHARE) * 100, 2), '%') AS THISSAMONEYSHARE, \n"); //本年销售金额占比
executePluginSql.append(" CONCAT(ROUND(avg(tbl_lgbsa.MONTHSAMONEYSHARE) * 100, 2), '%') AS MONTHSAMONEYSHARE \n"); //本月销售金额占比
executePluginSql.append(" FROM \n");
executePluginSql.append(" yunji_gr_bi_sa_agg tbl_lgbsa \n");
executePluginSql.append(" GROUP BY \n");
if (groupFieldList.contains("customname")) {
executePluginSql.append(" tbl_lgbsa.CUSTOMID,");
executePluginSql.append(" tbl_lgbsa.CUSTOMNAME,");
}
if (groupFieldList.contains("useyear")) {
executePluginSql.append(" tbl_lgbsa.USEYEAR,");
}
if (groupFieldList.contains("usemonth")) {
executePluginSql.append(" tbl_lgbsa.USEMONTH,");
}
if (groupFieldList.contains("zonename")) {
executePluginSql.append(" tbl_lgbsa.ZONEID,");
executePluginSql.append(" tbl_lgbsa.ZONENAME,");
}
if (groupFieldList.contains("saletypename")) {
executePluginSql.append(" tbl_lgbsa.SALETYPEID,");
executePluginSql.append(" tbl_lgbsa.SALETYPENAME,");
}
if (groupFieldList.contains("salername")) {
executePluginSql.append(" tbl_lgbsa.SALERID,");
executePluginSql.append(" tbl_lgbsa.SALERNAME,");
}
if (groupFieldList.contains("dosagename")) {
executePluginSql.append(" tbl_lgbsa.DOSAGEID,");
executePluginSql.append(" tbl_lgbsa.DOSAGENAME,");
}
executePluginSql.deleteCharAt(executePluginSql.length() - 1);
params.put("executePluginSql", executePluginSql.toString());
// params.remove("Group by"); // 原有的逻辑注释了,这里也注释
}
}
}

View File

@@ -0,0 +1,21 @@
package com.lideeyunji.core.framework.enhance.example.report.xtsy;
import com.lideeyunji.core.framework.config.aspect.enhancereport.model.EnhanceReportContext;
import com.lideeyunji.core.framework.config.aspect.enhancereport.plugin.ReportBeforeAdvicePlugin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 报表-系统首页-单表
*/
@Slf4j
@Component("zhxsqkPlugin")
public class zhxsqkPlugin implements ReportBeforeAdvicePlugin {
@Override
public void execute(EnhanceReportContext enhanceContext) {
}
}

View File

@@ -0,0 +1,142 @@
package com.lideeyunji.core.framework.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
@TableName("yunji_gr_bi_sa_agg")
@Data
@EqualsAndHashCode
public class GrBiSaAgg implements Serializable {
private final static long serialVersionUID = 1L;
@TableId(value = "ID", type = IdType.INPUT)
private Integer id;
@TableField(value = "USEYEAR")
private Integer useYear;
@TableField(value = "USEMONTH")
private Integer useMonth;
@TableField(value = "ZONEID")
private String zoneId;
@TableField(value = "ZONENAME")
private String zoneName;
@TableField(value = "SALETYPEID")
private String saleTypeId;
@TableField(value = "SALETYPENAME")
private String saleTypeName;
@TableField(value = "CUSTOMID")
private String customId;
@TableField(value = "CUSTOMNAME")
private String customName;
@TableField(value = "DOSAGEID")
private String dosageId;
@TableField(value = "DOSAGENAME")
private String dosageName;
@TableField(value = "GOODSNAME")
private String goodsName;
@TableField(value = "GOODSID")
private String goodsId;
@TableField(value = "PROVINCEID")
private String provinceId;
@TableField(value = "PROVINCENAME")
private String provinceName;
@TableField(value = "SALERID")
private String salerId;
@TableField(value = "SALERNAME")
private String salerName;
@TableField(value = "MONTHSAQTY")
private String monthSaqty;
@TableField(value = "THISSAQTY")
private String thisSaqty;
@TableField(value = "LASTSAQTY")
private String lastSaqty;
@TableField(value = "MONTHSAMONEY")
private String monthSaMoney;
@TableField(value = "THISSAMONEY")
private String thisSaMoney;
@TableField(value = "LASTSAMONEY")
private String lastSaMoney;
@TableField(value = "MONTHPROFIT")
private String monthProfit;
@TableField(value = "THISPROFIT")
private String thisProfit;
@TableField(value = "LASTPROFIT")
private String lastProfit;
@TableField(value = "MONTHCOST")
private String monthCost;
@TableField(value = "THISCOST")
private String thisCost;
@TableField(value = "LASTCOST")
private String lastCost;
@TableField(value = "MONTHPROFITRATE")
private String monthProfitRate;
@TableField(value = "THISPROFITRATE")
private String thisProfitRate;
@TableField(value = "LASTPROFITRATE")
private String lastProfitRate;
@TableField(value = "MONTHSAMONEYSHARE")
private String monthSaMoneyShare;
@TableField(value = "THISSAMONEYSHARE")
private String thisSaMoneyShare;
@TableField(value = "LASTSAMONEYSHARE")
private String lastSaMoneyShare;
@TableField(value = "MONTHPROFITSHARE")
private String monthProfitShare;
@TableField(value = "THISPROFITSHARE")
private String thisProfitShare;
@TableField(value = "LASTPROFITSHARE")
private String lastProfitShare;
@TableField(value = "SAMONEYGROWTH")
private String saMoneyGrowth;
@TableField(value = "PROFITGROWTH")
private String profitGrowth;
@TableField(value = "PROFITCHANGE")
private String profitChange;
}

View File

@@ -0,0 +1,31 @@
package com.lideeyunji.core.framework.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lideeyunji.core.framework.entity.GrBiSaAgg;
import com.lideeyunji.tool.framework.common.constant.lideeYunJiBaseConstant;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@DS(lideeYunJiBaseConstant.DS_ERP_BI_DATA)
public interface GrBiSaAggMapper extends BaseMapper<GrBiSaAgg> {
List<GrBiSaAgg> generateSalesReport(@Param("pastYearMonth") Integer pastYearMonth,
@Param("currentYearMonth") Integer currentYearMonth);
int deleteSalesReport(@Param("pastYearMonth") Integer pastYearMonth,
@Param("currentYearMonth") Integer currentYearMonth);
void updateThisData();
void updateLastData();
void updateComplexCalculate1();
void updateComplexCalculate2();
void updateComplexCalculate3();
void updateComplexCalculate4();
void updateComplexCalculate5();
}

View File

@@ -0,0 +1,12 @@
package com.lideeyunji.core.framework.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lideeyunji.core.framework.entity.GrBiSaAgg;
import org.apache.ibatis.annotations.Param;
public interface IGrBiSaAggService extends IService<GrBiSaAgg> {
//同步销售明细表
void generateSalesReportJob(@Param("dataSourceType") String dataSourceType);
}

View File

@@ -1054,8 +1054,14 @@ public class FrameServiceImpl implements IFrameService {
if (Func.isEmpty(dataSourceConfigModel) || Func.isEmpty(dataSourceConfigModel.getExecuteSql())) {
return null;
}
//直接执行数据源
queryWrapper.setTableSql(dataSourceConfigModel.getExecuteSql());
//默认从参数中取,参数中的是前置中塞的
Object sqlObj = params.get("executePluginSql");
if(sqlObj != null){
queryWrapper.setTableSql(sqlObj.toString());
}else{
//直接执行数据源
queryWrapper.setTableSql(dataSourceConfigModel.getExecuteSql());
}
//处理占位符参数
Func.replaceParam(dataSourceConfigModel.getExecuteSql(), params, null, lideeYunJiAdapter);

View File

@@ -0,0 +1,90 @@
package com.lideeyunji.core.framework.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lideeyunji.core.framework.entity.GrBiSaAgg;
import com.lideeyunji.core.framework.mapper.GrBiSaAggMapper;
import com.lideeyunji.core.framework.service.IGrBiSaAggService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
@Slf4j
@Service
public class GrBiSaAggServiceImpl extends ServiceImpl<GrBiSaAggMapper, GrBiSaAgg> implements IGrBiSaAggService {
/**
* 计算销售报表
*/
@Override
@Transactional
@DS(value = "#dataSourceType")
public void generateSalesReportJob(@Param("dataSourceType") String dataSourceType) {
//获取本地mysql数据库中表中UPDATE_TIME最新的数据
LambdaQueryWrapper<GrBiSaAgg> queryWrapper = new LambdaQueryWrapper<GrBiSaAgg>().orderByDesc(GrBiSaAgg::getUseYear, GrBiSaAgg::getUseMonth).last("LIMIT 1");
GrBiSaAgg grBiSaAgg = this.baseMapper.selectOne(queryWrapper);
int lastUserYear = 2022;
int lastUserMonth = 1;
if(grBiSaAgg != null){
lastUserYear = grBiSaAgg.getUseYear();
lastUserMonth = grBiSaAgg.getUseMonth();
}
// 获取当前时间的年和月
LocalDateTime now = LocalDateTime.now();
int currentYear = now.getYear();
int currentMonth = now.getMonthValue();
// 获取三个月前的时间和年月
LocalDateTime threeMonthsAgo = now.minusMonths(3);
int pastYear = threeMonthsAgo.getYear();
int pastMonth = threeMonthsAgo.getMonthValue();
log.info("最后更新的年月:{}年{}月", lastUserYear, lastUserMonth);
log.info("当前:{}年{}月", currentYear, currentMonth);
log.info("三个月前:{}年{}月", pastYear, pastMonth);
if (lastUserYear < pastYear || (lastUserYear == pastYear && lastUserMonth < pastMonth)) {
pastYear = lastUserYear;
pastMonth = lastUserMonth;
}
log.info("开始时间:{}年{}月, 结束时间:{}年{}月", pastYear, pastMonth, currentYear, currentMonth);
// 获取三个月前的数据
List<GrBiSaAgg> grBiSaSetdtlList = this.baseMapper.generateSalesReport(pastYear * 100 + pastMonth, currentYear * 100 + currentMonth);
if (CollUtil.isEmpty(grBiSaSetdtlList)) {
return;
}
//保存数据
removeAndSaveBatch(pastYear, pastMonth, currentYear, currentMonth, grBiSaSetdtlList);
this.baseMapper.updateThisData();
this.baseMapper.updateLastData();
this.baseMapper.updateComplexCalculate1();
this.baseMapper.updateComplexCalculate2();
this.baseMapper.updateComplexCalculate3();
this.baseMapper.updateComplexCalculate4();
this.baseMapper.updateComplexCalculate5();
}
//批量新增
public void removeAndSaveBatch(Integer pastYear, Integer pastMonth, Integer currentYear, Integer currentMonth, List<GrBiSaAgg> grBiSaSetdtlList) {
int reNum = this.baseMapper.deleteSalesReport(pastYear * 100 + pastMonth, currentYear * 100 + currentMonth);
log.info("删除数量:{}", reNum);
int result = 0;
for (GrBiSaAgg grBiSaSetdtl : grBiSaSetdtlList) {
int re = this.baseMapper.insert(grBiSaSetdtl);
if (re < 1) {
throw new RuntimeException("批量新增异常");
}
result += re;
}
}
}

View File

@@ -1147,10 +1147,10 @@ public class Func extends FuncBase {
});
}
}
if(params.containsKey("Group by")){
String[] str=params.get("Group by").toString().split(",");
wrapper.groupByColumns(str);
}
// if(params.containsKey("Group by")){
// String[] str=params.get("Group by").toString().split(",");
// wrapper.groupByColumns(str);
// }
}

View File

@@ -0,0 +1,258 @@
<?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="com.lideeyunji.core.framework.mapper.GrBiSaAggMapper">
<select id="generateSalesReport" resultType="com.lideeyunji.core.framework.entity.GrBiSaAgg">
select a.USEYEAR,
a.USEMONTH,
goods.goodsid as GOODSID,
goods.GOODSNAME,
sales.SALEZONEID as ZONEID,
sales.SALEZONENAME as ZONENAME,
province.PROVINCEID,
province.PROVINCENAME,
salestype.SALETYPEID,
salestype.SALETYPENAME,
dosage.DOSAGEID,
dosage.DOSAGENAME,
custom.CUSTOMID,
custom.CUSTOMNAME,
saler.SALERID,
saler.SALERNAME,
a.`本月销量` as MONTHSAQTY,
a.`含税销售额` as MONTHSAMONEY,
a.`销售成本` as MONTHCOST,
a.`毛利额` as MONTHPROFIT
from erp_bi_data.GR_BI_PUB_GOODS as goods
inner join erp_bi_data.GR_BI_PUB_SALEZONE as sales
inner join erp_bi_data.GR_BI_PUB_PROVINCE as province
inner join erp_bi_data.GR_BI_PUB_SALETYPE as salestype
inner join erp_bi_data.GR_BI_PUB_DOSAGE as dosage
inner join erp_bi_data.GR_BI_PUB_CUSTOM as custom
INNER join erp_bi_data.GR_BI_PUB_SALER as saler
left join
(SELECT USEYEAR,
USEMONTH,
SALEZONEID,
SALEZONENAME,
PROVINCEID,
PROVINCENAME,
SALETYPE,
SALETYPENAME,
CUSTOMNAME,
SALERNAME,
DOSAGENAME,
goodsid,
GOODSNAME,
GOODSTYPE,
sum(SAQTY) as 本月销量,
DOSAGEID,
CUSTOMID,
SALERID,
round(SUM(SAMONEY), 2) 除税销售额,
round(sum(SAMONEYTX), 2) 含税销售额,
round(sum(COST), 2) 销售成本,
round(sum(PROFIT), 2) 毛利额
FROM GR_BI_SA_SETDTL
where USESTATUS = 2
GROUP BY SALETYPE, SALEZONEID, SALEZONENAME, PROVINCEID, PROVINCENAME, SALETYPE, SALETYPENAME, CUSTOMID,
CUSTOMNAME, SALERID, SALERNAME, DOSAGEID, DOSAGENAME, GOODSID, GOODSNAME, GOODSTYPE, USEYEAR,
USEMONTH) a
on a.goodsid = goods.goodsid and a.SALEZONEID = sales.SALEZONEID and a.PROVINCEID = province.PROVINCEID
and salestype.SALETYPEID = a.SALETYPE and dosage.DOSAGEID = a.DOSAGEID and
custom.CUSTOMID = a.CUSTOMID and saler.SALERID = a.SALERID
<where>
a.USEYEAR is not NULL
and (a.USEYEAR * 100 + a.USEMONTH) BETWEEN #{pastYearMonth} AND #{currentYearMonth}
</where>
order by a.USEYEAR, a.USEMONTH
</select>
<delete id="deleteSalesReport">
delete from yunji_gr_bi_sa_agg
where (USEYEAR * 100 + USEMONTH) BETWEEN #{pastYearMonth} AND #{currentYearMonth}
</delete>
<update id="updateThisData">
UPDATE yunji_gr_bi_sa_agg a
LEFT JOIN (
SELECT
USEYEAR,
GOODSID,
ZONEID,
PROVINCEID,
SALETYPEID,
DOSAGEID,
CUSTOMID,
SALERID,
SUM( MONTHSAQTY ) AS THISSAQTY,
SUM( MONTHSAMONEY ) AS THISSAMONEY,
SUM( MONTHCOST) as THISCOST,
SUM( MONTHPROFIT ) AS THISPROFIT
FROM
yunji_gr_bi_sa_agg
GROUP BY
USEYEAR,
GOODSID,
ZONEID,
PROVINCEID,
SALETYPEID,
DOSAGEID,
CUSTOMID,
SALERID
) b ON b.USEYEAR = a.USEYEAR
AND b.GOODSID = a.GOODSID
AND b.ZONEID = a.ZONEID
AND b.PROVINCEID = a.PROVINCEID
AND b.SALETYPEID = a.SALETYPEID
AND b.DOSAGEID = a.DOSAGEID
AND b.CUSTOMID = a.CUSTOMID
AND b.SALERID = a.SALERID
SET a.THISSAQTY = COALESCE ( b.THISSAQTY, 0 ),
a.THISSAMONEY = COALESCE ( b.THISSAMONEY, 0 ),
a.THISCOST = COALESCE ( b.THISCOST, 0 ),
a.THISPROFIT = COALESCE ( b.THISPROFIT, 0 );
</update>
<update id="updateLastData">
UPDATE yunji_gr_bi_sa_agg a
LEFT JOIN (
SELECT
USEYEAR,
GOODSID,
ZONEID,
PROVINCEID,
SALETYPEID,
DOSAGEID,
CUSTOMID,
SALERID,
SUM( MONTHSAQTY ) AS LASTSAQTY,
SUM( MONTHSAMONEY ) AS LASTSAMONEY,
SUM( MONTHCOST) as LASTCOST,
SUM( MONTHPROFIT ) AS LASTPROFIT
FROM
yunji_gr_bi_sa_agg
GROUP BY
USEYEAR,
GOODSID,
ZONEID,
PROVINCEID,
SALETYPEID,
DOSAGEID,
CUSTOMID,
SALERID
) b ON b.USEYEAR = a.USEYEAR-1
AND b.GOODSID = a.GOODSID
AND b.ZONEID = a.ZONEID
AND b.PROVINCEID = a.PROVINCEID
AND b.SALETYPEID = a.SALETYPEID
AND b.DOSAGEID = a.DOSAGEID
AND b.CUSTOMID = a.CUSTOMID
AND b.SALERID = a.SALERID
SET a.LASTSAQTY = COALESCE ( b.LASTSAQTY, 0 ),
a.LASTSAMONEY = COALESCE ( b.LASTSAMONEY, 0 ),
a.LASTCOST = COALESCE ( b.LASTCOST, 0 ),
a.LASTPROFIT = COALESCE ( b.LASTPROFIT, 0 );
</update>
<update id="updateComplexCalculate1">
-- 本月毛利率 MONTHPROFITRATE 本月销售毛利/本月销售收入×100%
-- 本年毛利率 THISPROFITRATE 本年销售毛利/本年销售收入×100%
-- 上年毛利率 LASTPROFITRATE 上年销售毛利/上年销售收入×100%
UPDATE yunji_gr_bi_sa_agg
SET
MONTHPROFITRATE = CASE WHEN MONTHSAMONEY = 0 or MONTHSAMONEY is null THEN
100 ELSE MONTHPROFIT/ MONTHSAMONEY * 100 END,
THISPROFITRATE = CASE WHEN THISSAMONEY = 0 or THISSAMONEY is null THEN
100 ELSE THISPROFIT/ THISSAMONEY * 100 END,
LASTPROFITRATE =CASE WHEN LASTSAMONEY = 0 or LASTSAMONEY is null THEN
100 ELSE LASTPROFIT/ LASTSAMONEY * 100 END;
</update>
<update id="updateComplexCalculate2">
-- 本月销售金额占比 MONTHSAMONEYSHARE 当前行本月销售额/本月销售额总和*100%
-- 本月毛利额占比 MONTHPROFITSHARE 当前行本月毛利额/本月毛利额总和*100%
UPDATE yunji_gr_bi_sa_agg a
LEFT JOIN (
SELECT
USEYEAR,
USEMONTH,
SUM( MONTHSAMONEY ) AS MONTHSAMONEY_SUM,
SUM(MONTHPROFIT) AS MONTHPROFIT_SUM
FROM
yunji_gr_bi_sa_agg
GROUP BY
USEYEAR,
USEMONTH
) b ON b.USEYEAR = a.USEYEAR
AND b.USEMONTH = a.USEMONTH
SET a.MONTHSAMONEYSHARE = COALESCE (ROUND( a.MONTHSAMONEY/b.MONTHSAMONEY_SUM * 100, 2), 0 ),
a.MONTHPROFITSHARE = COALESCE (ROUND( a.MONTHPROFIT/b.MONTHPROFIT_SUM * 100, 2), 0 );
</update>
<update id="updateComplexCalculate3">
-- 本年销售金额占比 THISSAMONEYSHARE当前行本年销售额/本年销售额总和*100%
-- 本年毛利额占比 THISPROFITSHARE 当前行本年毛利额/本年毛利额总和*100%
UPDATE yunji_gr_bi_sa_agg a
LEFT JOIN (
SELECT
USEYEAR,
SUM( THISSAMONEY ) AS THISSAMONEY_SUM,
SUM( THISPROFIT ) AS THISPROFIT_SUM
FROM
yunji_gr_bi_sa_agg
GROUP BY
USEYEAR
) b ON b.USEYEAR = a.USEYEAR
SET a.THISSAMONEYSHARE = COALESCE (ROUND( a.THISSAMONEY/b.THISSAMONEY_SUM * 100, 2), 0 ),
a.THISPROFITSHARE = COALESCE (ROUND( a.THISPROFIT/b.THISPROFIT_SUM * 100, 2), 0 );
</update>
<update id="updateComplexCalculate4">
-- 上年销售金额占比 LASTSAMONEYSHARE 当前行上年销售额/上年销售额总和*100%
-- 上年毛利额占比 LASTPROFITSHARE 当前行上年毛利额/上年毛利额总和*100%
UPDATE yunji_gr_bi_sa_agg a
LEFT JOIN (
SELECT
USEYEAR,
SUM(LASTSAMONEY) AS LASTSAMONEY_SUM,
SUM(LASTPROFIT) AS LASTPROFIT_SUM
FROM
yunji_gr_bi_sa_agg
GROUP BY
USEYEAR,
USEMONTH
) b ON b.USEYEAR = a.USEYEAR
SET a.LASTSAMONEYSHARE = COALESCE (ROUND( CASE WHEN LASTSAMONEY_SUM = 0 or LASTSAMONEY_SUM is null THEN 1 ELSE a.LASTSAMONEY/b.LASTSAMONEY_SUM * 100 END, 2), 0 ),
a.LASTPROFITSHARE = COALESCE (ROUND( CASE WHEN LASTPROFIT_SUM = 0 or LASTPROFIT_SUM is null THEN 1 ELSE a.LASTPROFIT/b.LASTPROFIT_SUM * 100 END, 2), 0 );
</update>
<update id="updateComplexCalculate5">
-- 销售金额增长率 SAMONEYGROWTH (本年销售额-上年销售额)÷上年销售额×100%
-- 毛利额增长率 PROFITGROWTH (本年毛利额 - 上年毛利额) / 上年毛利额 × 100%
-- 毛利变动 PROFITCHANGE 本年毛利额 - 上年毛利额
UPDATE yunji_gr_bi_sa_agg
SET
SAMONEYGROWTH = CASE
WHEN ( LASTSAMONEY = 0 OR LASTSAMONEY IS NULL )
AND THISSAMONEY IS NOT NULL THEN
100
WHEN THISPROFIT IS NULL THEN
0 ELSE ( THISSAMONEY - LASTSAMONEY )/ LASTSAMONEY * 100
END,
PROFITGROWTH = CASE
WHEN ( LASTPROFIT = 0 OR LASTPROFIT IS NULL )
AND THISPROFIT IS NOT NULL THEN
100
WHEN THISPROFIT IS NULL THEN
0 ELSE ( THISPROFIT - LASTPROFIT )/ LASTPROFIT * 100
END,
PROFITCHANGE = ( THISPROFIT - LASTPROFIT);
</update>
</mapper>

View File

@@ -97,6 +97,11 @@
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java-sms</artifactId>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.4.11</version>
</dependency>
<dependency>
<groupId>com.lideeyunji</groupId>
<artifactId>lidee-module-api</artifactId>

View File

@@ -6,7 +6,6 @@ import cn.hutool.core.util.StrUtil;
import com.lideeyunji.service.system.config.convert.auth.AuthConvert;
import com.lideeyunji.service.system.constant.ErrorCodeConstants;
import com.lideeyunji.service.system.controller.vo.auth.*;
import com.lideeyunji.service.system.controller.vo.auth.*;
import com.lideeyunji.service.system.controller.vo.user.user.UserRespVO;
import com.lideeyunji.service.system.entity.AdminUserDO;
import com.lideeyunji.service.system.entity.MenuDO;
@@ -23,7 +22,6 @@ import com.lideeyunji.tool.framework.operatelog.core.annotations.OperateLog;
import com.lideeyunji.tool.framework.security.config.SecurityProperties;
import com.lideeyunji.tool.framework.security.core.util.SecurityFrameworkUtils;
import com.lideeyunji.tool.framework.tenant.core.context.TenantContextHolder;
import com.lideeyunji.service.system.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
@@ -87,6 +85,15 @@ public class AuthController {
return success(true);
}
@PostMapping("/logout-client")
@PermitAll
@Operation(tags = "授权管理",summary = "登出系统")
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
public CommonResult<Boolean> logoutClient(@RequestParam("refreshToken") String refreshToken) {
logoutService(refreshToken);
return success(true);
}
@PostMapping("/switch-login")
@Operation(tags = "授权管理",summary = "切换部门登录")
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
@@ -165,8 +172,10 @@ public class AuthController {
@Operation(tags = "根据token获取用户信息",summary = "根据token获取用户信息")
@Parameter(name = "refreshToken", description = "根据token获取用户信息", required = true)
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
public CommonResult<AuthLoginRespVO> getUerInfo(@RequestParam("refreshToken") String refreshToken) {
return success(authService.refreshToken(refreshToken));
public CommonResult<AdminUserDO> getUerInfo(@RequestParam("refreshToken") String refreshToken) {
CommonResult<AdminUserDO> result = CommonResult.success(authService.getTokenTouserInfo(refreshToken));
return result;
}
@GetMapping("/get-permission-info")
@@ -293,7 +302,23 @@ public class AuthController {
authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
}
//清空个人信息
String userRedisKey="JEE_LOW_CODE:USER:"+loginUserId+":*";
String userRedisKey="LIDEE_LOW_CODE:USER:"+loginUserId+":*";
Set<String> keys = stringRedisTemplate.keys(userRedisKey);
if(keys!=null && keys.size()>0){
keys.forEach(key->{
stringRedisTemplate.delete(key);
});
}
}
private void logoutService(String token){
AdminUserDO user = authService.getTokenTouserInfo(token);
Long loginUserId = user.getId();
if (StrUtil.isNotBlank(token)) {
authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
}
//清空个人信息
String userRedisKey="LIDEE_LOW_CODE:USER:"+loginUserId+":*";
Set<String> keys = stringRedisTemplate.keys(userRedisKey);
if(keys!=null && keys.size()>0){
keys.forEach(key->{

View File

@@ -73,7 +73,7 @@ public class OAuth2ClientController {
@GetMapping("/myPage")
@Operation(tags = "OAuth2.0管理",summary = "获得用户角色下 OAuth2 客户端分页")
@PreAuthorize("@ss.hasPermission('system:oauth2-client:query')")
// @PreAuthorize("@ss.hasPermission('system:oauth2-client:query')")
public CommonResult<PageResult<OAuth2ClientRespVO>> getMyPage(@Valid OAuth2ClientPageReqVO pageVO) {
PageResult<OAuth2ClientDO> pageResult = oAuth2ClientService.getMyPage(pageVO);
return success(BeanUtils.toBean(pageResult, OAuth2ClientRespVO.class));

View File

@@ -78,4 +78,6 @@ public interface IAdminAuthService {
*/
AuthLoginRespVO refreshToken(String refreshToken);
AdminUserDO getTokenTouserInfo(String refreshToken);
}

View File

@@ -1,5 +1,6 @@
package com.lideeyunji.service.system.service;
import com.lideeyunji.service.system.entity.AdminUserDO;
import com.lideeyunji.tool.framework.common.pojo.PageResult;
import com.lideeyunji.service.system.controller.vo.oauth2.token.OAuth2AccessTokenPageReqVO;
import com.lideeyunji.service.system.entity.OAuth2AccessTokenDO;
@@ -41,6 +42,10 @@ public interface IOAuth2TokenService {
*/
OAuth2AccessTokenDO refreshAccessToken(String refreshToken, String clientId);
AdminUserDO getTokenTouserInfo(String refreshToken);
/**
* 获得访问令牌
*

View File

@@ -362,6 +362,15 @@ public class AdminAuthServiceImpl implements IAdminAuthService {
return AuthConvert.INSTANCE.convert(accessTokenDO);
}
@Override
public AdminUserDO getTokenTouserInfo(String refreshToken) {
AdminUserDO user= oauth2TokenService.getTokenTouserInfo(refreshToken);
return user;
}
@Override
public void logout(String token, Integer logType) {
// 删除访问令牌

View File

@@ -100,7 +100,7 @@ public class LideeYunJiPermissionServiceImpl implements ILideeYunJiPermissionSer
}
//根据角色id来判断我是否是开发者如果有开发者则说明直接可以访问
boolean devUserFlag=false;
String isDevUserRedisKey="JEE_LOW_CODE:USER:"+userId+":DEVUSER";
String isDevUserRedisKey="LIDEE_LOW_CODE:USER:"+userId+":DEVUSER";
if(!stringRedisTemplate.hasKey(isDevUserRedisKey)){//没有数据,则查询获取 TODO 优化
//所有菜单列表
Set<Long> menuIdList = permissionService.getRoleMenuListByRoleId(roleIds);

View File

@@ -61,6 +61,7 @@ public class OAuth2TokenServiceImpl implements IOAuth2TokenService {
@Lazy // 懒加载,避免循环依赖
private IAdminUserService adminUserService;
@Override
public OAuth2AccessTokenDO createAccessToken(Long userId, Long lastLoginDeptId, Long lastLoginRoleId, Integer userType, String clientId, List<String> scopes) {
return createAccessToken(userId, lastLoginDeptId, lastLoginRoleId, userType, clientId, scopes,false);
@@ -77,6 +78,18 @@ public class OAuth2TokenServiceImpl implements IOAuth2TokenService {
}
@Override
public AdminUserDO getTokenTouserInfo(String refreshToken ) {
// 获得用户基本信息
OAuth2AccessTokenDO accessTokenDO= oauth2AccessTokenMapper.selectByAccessToken(refreshToken);
AdminUserDO user = adminUserService.getUser(accessTokenDO.getUserId());
user.setPassword("");
user.setEmail("");
return user;
}
@Override
public OAuth2AccessTokenDO refreshAccessToken(String refreshToken, String clientId) {
boolean supAdmin = SecurityFrameworkUtils.isSupAdmin();
@@ -110,6 +123,12 @@ public class OAuth2TokenServiceImpl implements IOAuth2TokenService {
return createOAuth2AccessToken(refreshTokenDO, clientDO, supAdmin);
}
@Override
public OAuth2AccessTokenDO getAccessToken(String accessToken) {
// 优先从 Redis 中获取

View File

@@ -9,7 +9,7 @@ package com.lideeyunji.tool.framework.yunji.constant;
public interface lideeRedisConstants {
//低代码
String lideeyunji_PREFIX = "JEE_LOW_CODE:";
String lideeyunji_PREFIX = "LIDEE_LOW_CODE:";
//js增强加锁
String ENHANCE_JS_LOCK = "LOCK_JS:%s";