增加企业信息 提交企业信息修改 增加多公司支持

This commit is contained in:
MerCry 2026-02-08 20:32:01 +08:00
parent 4d0943823f
commit a4a8b468cd
63 changed files with 1120 additions and 670 deletions

View File

@ -1,253 +0,0 @@
# 快速开始指南
## 📋 前置条件
1. Java 8 或更高版本
2. MySQL 5.7 或更高版本
3. Maven 3.x
4. 企业微信账号及相关权限
## 🚀 快速部署步骤
### 第一步:获取企业微信配置参数
#### 1.1 获取企业 ID (corp-id)
1. 登录企业微信管理后台https://work.weixin.qq.com/
2. 进入「我的企业」→「企业信息」
3. 复制「企业 ID」
#### 1.2 获取应用密钥 (app-secret)
1. 在企业微信管理后台,进入「应用管理」
2. 选择或创建一个自建应用
3. 在应用详情页面找到「Secret」
4. 点击「查看」并复制 Secret
**重要**:需要给应用授予以下权限:
- 企业微信文档 API 权限
- 文档读取权限
#### 1.3 获取文档 ID (doc-id)
1. 在企业微信中打开目标表格文档
2. 查看浏览器地址栏的 URL
3. URL 格式:`https://doc.weixin.qq.com/sheet/xxxxx`
4. `xxxxx` 部分就是 doc-id
#### 1.4 获取工作表 ID (sheet-id)
**方法一:通过浏览器开发者工具**
1. 打开企业微信文档
2. 按 F12 打开开发者工具
3. 切换到「Network」标签
4. 在文档中切换工作表
5. 查看网络请求,找到包含 `sheet_id` 的请求参数
**方法二:使用默认值**
- 如果是文档的第一个工作表,可以尝试使用 `sheet_id = "1"`
### 第二步:配置数据库
#### 2.1 创建数据库
```sql
CREATE DATABASE IF NOT EXISTS ruoyi DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
```
#### 2.2 执行表结构脚本
```bash
mysql -u root -p ruoyi < RuoYi-Vue/excel-handle/sql/schema.sql
```
或者在 MySQL 客户端中执行:
```sql
USE ruoyi;
SOURCE /path/to/RuoYi-Vue/excel-handle/sql/schema.sql;
```
### 第三步:配置应用参数
编辑配置文件 `RuoYi-Vue/excel-handle/src/main/resources/application.yml`
```yaml
# 企业微信配置
wecom:
# 企业 ID必填
corp-id: "ww1234567890abcdef" # 替换为你的企业 ID
# 应用密钥(必填)
app-secret: "your_secret_here" # 替换为你的应用 Secret
# 文档 ID必填
doc-id: "your_doc_id_here" # 替换为你的文档 ID
# 工作表 ID必填
sheet-id: "1" # 替换为你的工作表 ID
# 查询范围必填A1 表示法)
range: "A1:AE1000" # 根据实际表格列数和行数调整
# 抓取间隔(可选,默认 60 分钟)
fetch-interval: 60
# 数据库配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/ruoyi?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root # 替换为你的数据库用户名
password: password # 替换为你的数据库密码
```
### 第四步:确认表格格式
确保企业微信表格的列顺序与以下格式一致:
| 列号 | 字段名 | 说明 |
|------|--------|------|
| A | 客户名称 | 必填 |
| B | 描述 | 可选 |
| C | 添加人 | 可选 |
| D | 添加人账号 | 必填 |
| E | 添加人所属部门 | 可选 |
| F | 添加时间 | 格式yyyy-MM-dd |
| G | 来源 | 可选 |
| H | 手机 | 可选 |
| I | 企业 | 可选 |
| J | 邮箱 | 可选 |
| K | 地址 | 可选 |
| L | 职务 | 可选 |
| M | 电话 | 可选 |
| N-AE | 标签组1-18 | 可选 |
**注意**:第一行必须是表头,数据从第二行开始。
### 第五步:编译和运行
#### 5.1 编译项目
```bash
cd RuoYi-Vue
mvn clean package -DskipTests
```
#### 5.2 运行项目
```bash
cd ruoyi-admin/target
java -jar ruoyi-admin.jar
```
或者在 IDE 中直接运行 `RuoYiApplication.java`
### 第六步:验证功能
#### 6.1 查看日志
启动后查看日志,确认定时任务是否正常执行:
```
开始执行企业微信表格数据同步任务
获取企业微信access_token成功
获取企业微信表格数据成功,行数: 100
数据处理统计: 总计 99 条,新数据 99 条,当天已处理跳过 0 条,无效数据 0 条
企业微信表格数据同步任务执行完成
```
#### 6.2 手动触发同步
使用 API 工具(如 Postman或 curl 命令:
```bash
curl -X POST http://localhost:8080/wecom/table/sync
```
#### 6.3 查看服务状态
```bash
curl -X GET http://localhost:8080/wecom/table/status
```
#### 6.4 查询数据库
```sql
-- 查看客户数据
SELECT * FROM customer_data ORDER BY create_time DESC LIMIT 10;
-- 查看处理记录
SELECT * FROM processed_data_record ORDER BY create_time DESC LIMIT 10;
-- 查看统计数据
SELECT * FROM customer_tag_statistics ORDER BY stat_date DESC, tag_count DESC;
```
## 🔧 常见问题
### Q1: 获取 access_token 失败
**错误信息**: `获取企业微信access_token失败: 40013 - invalid corpid`
**解决方法**:
- 检查 `corp-id` 是否正确
- 检查 `app-secret` 是否正确
- 确认应用未被停用
### Q2: 获取表格数据失败
**错误信息**: `获取企业微信表格数据失败: 40003 - invalid openid`
**解决方法**:
- 检查 `doc-id` 是否正确
- 检查 `sheet-id` 是否正确
- 确认应用有文档访问权限
- 确认文档未被删除或移动
### Q3: 数据解析失败
**错误信息**: `转换表格数据失败`
**解决方法**:
- 检查表格列的顺序是否与代码映射一致
- 检查日期格式是否为 `yyyy-MM-dd`
- 检查表格是否有空行或格式异常
### Q4: 定时任务不执行
**解决方法**:
- 检查 Spring Boot 是否启用了定时任务:`@EnableScheduling`
- 查看日志是否有异常信息
- 检查定时任务配置是否正确
### Q5: 数据重复
**解决方法**:
- 检查去重逻辑是否正常工作
- 查看 `processed_data_record` 表是否有记录
- 检查数据的 `customer_name``add_person_account` 是否为空
## 📊 监控和维护
### 日志位置
- 应用日志:`logs/ruoyi-admin.log`
- 错误日志:`logs/ruoyi-admin-error.log`
### 定时任务时间
- 默认:每小时整点执行一次
- 修改:编辑 `WecomTableSyncTask.java` 中的 `@Scheduled` 注解
### 数据清理
系统会自动清理非当天的缓存数据,但数据库中的历史记录会保留。
如需清理历史数据:
```sql
-- 清理 30 天前的处理记录
DELETE FROM processed_data_record WHERE create_time < DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 清理 90 天前的统计数据
DELETE FROM customer_tag_statistics WHERE create_time < DATE_SUB(NOW(), INTERVAL 90 DAY);
```
## 🎯 下一步
1. 根据业务需求调整表格字段映射
2. 自定义标签统计规则(实现 `TagValidator` 接口)
3. 添加数据导出功能
4. 配置告警通知(邮件、企业微信消息等)
5. 优化性能(批量处理、异步处理等)
## 📚 相关文档
- [完整文档](README.md)
- [企业微信 API 文档](https://developer.work.weixin.qq.com/document/)
- [RuoYi 框架文档](http://doc.ruoyi.vip)
## 💡 技术支持
如遇到问题,请:
1. 查看日志文件获取详细错误信息
2. 参考常见问题部分
3. 查阅企业微信 API 文档
4. 提交 Issue 或联系技术支持

View File

@ -13,6 +13,7 @@ import java.io.Serializable;
@TableName("corp_department")
public class CorpDepartment implements Serializable {
private Long id;
private String corpId;
private Long parentid;
private Long orderNo;

View File

@ -0,0 +1,19 @@
package com.ruoyi.excel.wecom.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
@Getter
@Setter
@Data
@TableName("corp_info")
public class CorpInfo implements Serializable {
private Long id;
private String corpId;
private String secret;
private String name;
}

View File

@ -14,6 +14,7 @@ import java.io.Serializable;
@TableName("corp_user")
public class CorpUser implements Serializable {
private Long id;
private String corpId;
private String userid;
private Long departId;
private String departmentIds;

View File

@ -18,6 +18,7 @@ public class CustomerContactData implements Serializable {
/**
* 主键ID
*/
private String corpId;
private Long id;
/**

View File

@ -20,6 +20,8 @@ public class CustomerDataChangeLog implements Serializable {
/**
* 日志主键ID
*/
private String corpId;
@TableId(type = IdType.AUTO)
private Long logId;

View File

@ -22,6 +22,8 @@ public class CustomerExportData implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private String corpId;
/**
* 客户名称
*/

View File

@ -23,6 +23,7 @@ public class CustomerExportDataHistory implements Serializable {
@TableId(type = IdType.AUTO)
private Long historyId;
private String corpId;
/**
* 关联的客户数据IDcustomer_export_data表的主键
*/

View File

@ -22,6 +22,8 @@ public class CustomerStatisticsData implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private String corpId;
private Date curDate;
@ExcelProperty("重要指标")
private String indicatorName;

View File

@ -24,6 +24,7 @@ public class DepartmentStatisticsData implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private String corpId;
/**
* 统计日期
*/

View File

@ -22,6 +22,8 @@ public class WecomTagDomain implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private String corpId;
/**
* 标签ID
*/

View File

@ -22,6 +22,8 @@ public class WecomTagGroupDomain implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private String corpId;
/**
* 标签组ID
*/

View File

@ -1,7 +1,9 @@
package com.ruoyi.excel.wecom.helper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.excel.wecom.domain.*;
import com.ruoyi.excel.wecom.mapper.*;
import com.ruoyi.excel.wecom.model.WecomCustomer;
@ -9,6 +11,7 @@ import com.ruoyi.excel.wecom.model.WecomTagGroup;
import com.ruoyi.excel.wecom.service.CustomerExportService;
import com.ruoyi.excel.wecom.service.WecomContactService;
import com.ruoyi.excel.wecom.service.WecomTagService;
import com.ruoyi.common.utils.CorpContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -40,6 +43,12 @@ import java.util.concurrent.atomic.AtomicInteger;
@Autowired
private DepartmentStatisticsDataMapper departmentStatisticsDataMapper;
@Autowired
private RedisCache redisCache;
@Autowired
private CorpInfoMapper corpInfoMapper;
/**
* 线程池配置 - 用于并行处理客户数据
*/
@ -61,10 +70,13 @@ import java.util.concurrent.atomic.AtomicInteger;
* 注意由于使用多线程移除了 @Transactional 注解事务管理在 handleData 方法中处理
*/
public void handleAllData() throws IOException {
List<CorpInfo> corpInfos = corpInfoMapper.selectCorpInfoList(new CorpInfo());
corpInfos.forEach(item->{
try {
//根据公司信息处理
//暂时不考虑 员工和部门变动情况下的场景 获取所有批量详情接口数
//1.获取所有配置了客户联系功能的员工列表
List<String> followUserList = wecomContactService.getFollowUserList();
List<String> followUserList = wecomContactService.getFollowUserList(item.getCorpId());
int batchSize = 30;
int totalSize = followUserList.size();
@ -79,12 +91,16 @@ import java.util.concurrent.atomic.AtomicInteger;
// 获取当前批次的数据
List<String> batch = followUserList.subList(i, end);
// 提交异步任务
// 提交异步任务需要传递 corpId 到子线程
String finalCorpId = item.getCorpId();
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
processBatch(batch);
processBatch(batch,finalCorpId);
} catch (IOException e) {
throw new RuntimeException("处理批次数据失败: " + e.getMessage(), e);
} finally {
// 清理子线程的上下文
CorpContextHolder.clear();
}
}, executorService);
@ -97,24 +113,34 @@ import java.util.concurrent.atomic.AtomicInteger;
} catch (Exception e) {
throw new IOException("多线程处理客户数据时发生错误: " + e.getMessage(), e);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 清理主线程的上下文
CorpContextHolder.clear();
}
});
}
/**
* 处理单个批次的员工客户数据
* @param batch 员工ID列表
*/
private void processBatch(List<String> batch) throws IOException {
private void processBatch(List<String> batch,String corpId) throws IOException {
List<WecomCustomer> wecomCustomers = new ArrayList<>();
String tmpCursor = null;
do {
tmpCursor = wecomContactService.batchGetCustomerDetails(batch, wecomCustomers, tmpCursor, 100);
tmpCursor = wecomContactService.batchGetCustomerDetails(corpId,batch, wecomCustomers, tmpCursor, 100);
// 处理当前批次的客户数据
customerExportService.handleData(wecomCustomers);
customerExportService.handleData(corpId,wecomCustomers);
wecomCustomers.clear();
} while(tmpCursor != null);
customerExportService.handleData(wecomCustomers);
customerExportService.handleData(corpId,wecomCustomers);
}
/**
@ -136,7 +162,12 @@ import java.util.concurrent.atomic.AtomicInteger;
* 创建所有日期的流量看板数据包含当日统计- 多线程版本
*/
public void createAllReportData() {
List<Date> allDate = customerExportService.getAllDate();
List<CorpInfo> corpInfos = corpInfoMapper.selectCorpInfoList(new CorpInfo());
corpInfos.forEach(item-> {
try {
String corpId = item.getCorpId();
List<Date> allDate = customerExportService.getAllDate(corpId);
// 创建任务列表
List<CompletableFuture<Void>> futures = new ArrayList<>();
@ -145,7 +176,7 @@ import java.util.concurrent.atomic.AtomicInteger;
for (Date date : allDate) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
createReportData(date);
createReportData(corpId,date);
} catch (Exception e) {
throw new RuntimeException("处理日期 " + date + " 的报表数据失败: " + e.getMessage(), e);
}
@ -160,22 +191,31 @@ import java.util.concurrent.atomic.AtomicInteger;
} catch (Exception e) {
throw new RuntimeException("多线程处理流量看板数据时发生错误: " + e.getMessage(), e);
}
} catch (Exception e) {
throw new RuntimeException("多线程处理流量看板数据时发生错误: " + e.getMessage(), e);
}
});
}
/**
* 创建所有部门指标数据 - 多线程版本
*/
public void createAllDepartmentReportData() {
List<Date> allDate = customerExportService.getAllDate();
List<CorpInfo> corpInfos = corpInfoMapper.selectCorpInfoList(new CorpInfo());
corpInfos.forEach(item-> {
try {
// 为每个日期创建异步任务
String finalCorpId = item.getCorpId();
List<Date> allDate = customerExportService.getAllDate(finalCorpId);
// 创建任务列表
List<CompletableFuture<Void>> futures = new ArrayList<>();
// 为每个日期创建异步任务
for (Date date : allDate) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
createDepartmentReportData(date);
createDepartmentReportData(finalCorpId,date);
} catch (Exception e) {
throw new RuntimeException("处理日期 " + date + " 的部门报表数据失败: " + e.getMessage(), e);
}
@ -190,14 +230,18 @@ import java.util.concurrent.atomic.AtomicInteger;
} catch (Exception e) {
throw new RuntimeException("多线程处理部门报表数据时发生错误: " + e.getMessage(), e);
}
} catch (Exception e) {
throw new RuntimeException("多线程处理部门报表数据时发生错误: " + e.getMessage(), e);
}
});
}
/**
* 创建流量看板数据包含当日统计
* @param date 统计日期
*/
public void createReportData(Date date) {
List<CustomerStatisticsData> oneDateData = calculateStatistics(date);
public void createReportData(String corpId,Date date) {
List<CustomerStatisticsData> oneDateData = calculateStatistics(corpId,date);
oneDateData.forEach(item->{
dataMapper.insert(item);
});
@ -205,18 +249,24 @@ import java.util.concurrent.atomic.AtomicInteger;
/**初始化基础数据 如果需要同步 需要删除老数据数据*/
public boolean initData() throws IOException {
List<CorpInfo> corpInfos = corpInfoMapper.selectCorpInfoList(new CorpInfo());
corpInfos.forEach(oneCorp-> {
try {
List<CorpDepartment> departmentList;
Map<Long, String> cacheDepartMap = new HashMap<>();
Map<Long, Long> parentCacheMap = new HashMap<>();
String corpId = oneCorp.getCorpId();
try {
//存入部门id
departmentList = wecomContactService.getDepartmentList(null);
departmentList = wecomContactService.getDepartmentList(corpId,null);
//循环获取部门详情数据
for (CorpDepartment item : departmentList) {
String departmentDetail = null;
departmentDetail = wecomContactService.getDepartmentDetail(item.getId());
departmentDetail = wecomContactService.getDepartmentDetail(corpId,item.getId());
item.setName(departmentDetail);
item.setCorpId(corpId); // 设置企业ID
cacheDepartMap.put(item.getId(), departmentDetail);
parentCacheMap.put(item.getId(), item.getParentid());
//保存部门数据
@ -230,10 +280,11 @@ import java.util.concurrent.atomic.AtomicInteger;
//根据部门id循环获取下面的员工信息
departmentList.forEach(item -> {
try {
List<CorpUser> departmentMemberList = wecomContactService.getDepartmentMemberList(item.getId(), null, null);
List<CorpUser> departmentMemberList = wecomContactService.getDepartmentMemberList(corpId,item.getId(), null, null);
departmentMemberList.forEach(oneUser -> {
oneUser.setDepartId(item.getId());
oneUser.setDepartmentName(getDepartmentFullPath(item.getId(), cacheDepartMap, parentCacheMap));
oneUser.setCorpId(corpId); // 设置企业ID
userMapper.insert(oneUser);
});
} catch (IOException e) {
@ -246,7 +297,7 @@ import java.util.concurrent.atomic.AtomicInteger;
try {
//查询所有标签信息 存储标签信息
List<WecomTagGroup> tagGroupList = wecomContactService.getCorpTagList();
List<WecomTagGroup> tagGroupList = wecomContactService.getCorpTagList(corpId);
// 同步标签库到数据库
wecomTagService.syncCorpTagList(tagGroupList);
@ -255,58 +306,25 @@ import java.util.concurrent.atomic.AtomicInteger;
}
customerExportService.refreshCache();
}catch (Exception e) {
throw new RuntimeException("初始化数据异常");
}
});
return true;
}
/**
* 创建部门报表数据包含当日统计
* @param date 统计日期
*/
public void createDepartmentReportData(Date date) {
List<DepartmentStatisticsData> oneDateData = calculateDepartmentStatistics(date);
public void createDepartmentReportData(String corpId,Date date) {
List<DepartmentStatisticsData> oneDateData = calculateDepartmentStatistics(corpId,date);
oneDateData.forEach(item -> {
departmentStatisticsDataMapper.insert(item);
});
}
/**
* 计算部门历史累计指标
* @param departmentPath 部门路径
* @return 历史累计指标作为一条记录返回
*/
public List<DepartmentStatisticsData> calculateDepartmentHistoricalStatistics(String departmentPath) {
List<DepartmentStatisticsData> results = new ArrayList<>();
// 1. 查询历史总承接数
Map<String, Object> acceptSumMap = departmentStatisticsDataMapper.selectHistoricalAcceptSum(departmentPath);
int historicalAcceptCount = 0;
if (acceptSumMap != null && acceptSumMap.get("total_value") != null) {
historicalAcceptCount = ((BigDecimal) acceptSumMap.get("total_value")).intValue();
}
// 2. 查询历史总成单数
Map<String, Object> orderSumMap = departmentStatisticsDataMapper.selectHistoricalOrderSum(departmentPath);
int historicalOrderCount = 0;
if (orderSumMap != null && orderSumMap.get("total_value") != null) {
historicalOrderCount = ((BigDecimal) orderSumMap.get("total_value")).intValue();
}
// 3. 计算渗透率
BigDecimal penetrationRate = calculateRateBigDecimal(historicalOrderCount, historicalAcceptCount);
// 生成一条历史累计记录
Date now = new Date();
DepartmentStatisticsData vo = new DepartmentStatisticsData();
vo.setStatDate(now);
vo.setDepartmentPath(departmentPath);
vo.setSortNo(0);
results.add(vo);
return results;
}
/**===================================以下为私有方法============================================*/
/**
@ -356,18 +374,19 @@ import java.util.concurrent.atomic.AtomicInteger;
* @param date 目标日期 (格式: yyyy-MM-dd)
* @return 统计结果列表
*/
private List<CustomerStatisticsData> calculateStatistics(Date date) {
private List<CustomerStatisticsData> calculateStatistics(String corpId,Date date) {
// 1. 初始化累加器
StatisticsAccumulator accumulator = new StatisticsAccumulator();
// 2. 分页查询并累加统计
int pageSize = 1000; // 每页1000条
int pageNum = 1;
LambdaQueryWrapper<CustomerExportData> wrapper= new LambdaQueryWrapper<>();
wrapper.eq(CustomerExportData::getCorpId,corpId);
while (true) {
// 分页查询不在SQL层过滤在Java层过滤以保证准确性
Page<CustomerExportData> page = new Page<>(pageNum, pageSize);
Page<CustomerExportData> pageData = customerExportDataMapper.selectPage(page, null);
Page<CustomerExportData> pageData = customerExportDataMapper.selectPage(page, wrapper);
// 处理当前页数据
for (CustomerExportData data : pageData.getRecords()) {
@ -383,7 +402,7 @@ import java.util.concurrent.atomic.AtomicInteger;
}
// 3. 从累加器生成最终结果
return generateStatisticsResults(date,accumulator);
return generateStatisticsResults(corpId,date,accumulator);
}
@ -392,18 +411,19 @@ import java.util.concurrent.atomic.AtomicInteger;
* @param targetDate 目标日期 (格式: yyyy-MM-dd)
* @return 部门统计结果列表
*/
private List<DepartmentStatisticsData> calculateDepartmentStatistics(Date targetDate) {
private List<DepartmentStatisticsData> calculateDepartmentStatistics(String corpId,Date targetDate) {
// 1. 初始化部门累加器
DepartmentStatisticsAccumulator accumulator = new DepartmentStatisticsAccumulator();
// 2. 分页查询并累加统计
int pageSize = 1000;
int pageNum = 1;
LambdaQueryWrapper<CustomerExportData> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CustomerExportData::getCorpId,corpId);
while (true) {
// 分页查询
Page<CustomerExportData> page = new Page<>(pageNum, pageSize);
Page<CustomerExportData> pageData = customerExportDataMapper.selectPage(page, null);
Page<CustomerExportData> pageData = customerExportDataMapper.selectPage(page, wrapper);
// 处理当前页数据
for (CustomerExportData data : pageData.getRecords()) {
@ -439,7 +459,7 @@ import java.util.concurrent.atomic.AtomicInteger;
}
// 3. 从累加器生成最终结果
return generateDepartmentStatisticsResults(accumulator, targetDate);
return generateDepartmentStatisticsResults(corpId,accumulator, targetDate);
}
/**
@ -608,9 +628,11 @@ import java.util.concurrent.atomic.AtomicInteger;
stats.setOrderCount(stats.getOrderCount() + 1);
String orderStatus = data.getTagGroup7();
if (orderStatus != null) {
if (orderStatus.contains("已成交及时单9元+")) {
String[] split = orderStatus.split(",");
String statusInfo = split[split.length - 1];
if (statusInfo.contains("已成交及时单9元+")) {
stats.setTimelyOrderCount(stats.getTimelyOrderCount() + 1);
} else if (orderStatus.contains("已成交非及时单9元+")) {
} else if (statusInfo.contains("已成交非及时单9元+")) {
stats.setNonTimelyOrderCount(stats.getNonTimelyOrderCount() + 1);
}
}
@ -704,7 +726,7 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* 从累加器生成最终统计结果
*/
private List<CustomerStatisticsData> generateStatisticsResults(Date curDate,StatisticsAccumulator accumulator) {
private List<CustomerStatisticsData> generateStatisticsResults(String corpId,Date curDate,StatisticsAccumulator accumulator) {
// 使用 Map 来存储每个指标对应的 CustomerStatisticsData
// key: 指标名称不带组名前缀value: CustomerStatisticsData 对象
Map<String, CustomerStatisticsData> indicatorMap = new LinkedHashMap<>();
@ -716,84 +738,84 @@ import java.util.concurrent.atomic.AtomicInteger;
StatisticsAccumulator.GroupStatistics stats = entry.getValue();
// 21-23. 成本相关需要手工填写
setIndicatorValue(indicatorMap,curDate, "总成本(当日)", groupName, "需手工填写",(10*sortNo++));
setIndicatorValue(indicatorMap,curDate, "单条成本(当日)", groupName, "需手工填写",(10*sortNo++));
setIndicatorValue(indicatorMap,curDate, "成单成本(当日)", groupName, "需手工填写",(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "总成本(当日)", groupName, "需手工填写",(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "单条成本(当日)", groupName, "需手工填写",(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "成单成本(当日)", groupName, "需手工填写",(10*sortNo++));
// 1. 成单数
setIndicatorValue(indicatorMap,curDate, "成单数(当日)", groupName, String.valueOf(stats.getOrderCount()),(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "成单数(当日)", groupName, String.valueOf(stats.getOrderCount()),(10*sortNo++));
// 2. 进粉数
setIndicatorValue(indicatorMap,curDate, "进粉数(当日)", groupName, String.valueOf(stats.getCustomerCount()),(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "进粉数(当日)", groupName, String.valueOf(stats.getCustomerCount()),(10*sortNo++));
// 3. 转化率
String conversionRate = calculateRate(stats.getOrderCount(), stats.getCustomerCount());
setIndicatorValue(indicatorMap,curDate, "转化率(当日)", groupName, conversionRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "转化率(当日)", groupName, conversionRate,(10*sortNo++));
// 4. 及时单占比
String timelyRate = calculateRate(stats.getTimelyOrderCount(), stats.getCustomerCount());
setIndicatorValue(indicatorMap,curDate, "及时单占比(当日)", groupName, timelyRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "及时单占比(当日)", groupName, timelyRate,(10*sortNo++));
// 5. 非及时单占比
String nonTimelyRate = calculateRate(stats.getNonTimelyOrderCount(), stats.getCustomerCount());
setIndicatorValue(indicatorMap,curDate, "非及时单占比(当日)", groupName, nonTimelyRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "非及时单占比(当日)", groupName, nonTimelyRate,(10*sortNo++));
// 6. 客户属性数量
setIndicatorValue(indicatorMap,curDate, "客户属性数量(当日)", groupName, String.valueOf(stats.getTotalCustomerAttr()),(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "客户属性数量(当日)", groupName, String.valueOf(stats.getTotalCustomerAttr()),(10*sortNo++));
// 7. 家长占比
String parentRate = calculateRate(stats.getParentCount(), stats.getTotalCustomerAttr());
setIndicatorValue(indicatorMap,curDate, "家长占比(当日)", groupName, parentRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "家长占比(当日)", groupName, parentRate,(10*sortNo++));
// 8. 学生占比
String studentRate = calculateRate(stats.getStudentCount(), stats.getTotalCustomerAttr());
setIndicatorValue(indicatorMap,curDate, "学生占比(当日)", groupName, studentRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "学生占比(当日)", groupName, studentRate,(10*sortNo++));
// 9. 未知占比
String unknownRate = calculateRate(stats.getUnknownAttrCount(), stats.getTotalCustomerAttr());
setIndicatorValue(indicatorMap,curDate, "未知占比(当日)", groupName, unknownRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "未知占比(当日)", groupName, unknownRate,(10*sortNo++));
// 10. 意向度数量
setIndicatorValue(indicatorMap,curDate, "意向度数量(当日)", groupName, String.valueOf(stats.getTotalIntention()),(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "意向度数量(当日)", groupName, String.valueOf(stats.getTotalIntention()),(10*sortNo++));
// 11. 主动报价占比
String activeQuoteRate = calculateRate(stats.getActiveQuoteCount(), stats.getTotalIntention());
setIndicatorValue(indicatorMap,curDate, "主动报价占比(当日)", groupName, activeQuoteRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "主动报价占比(当日)", groupName, activeQuoteRate,(10*sortNo++));
// 12. 被动报价占比
String passiveQuoteRate = calculateRate(stats.getPassiveQuoteCount(), stats.getTotalIntention());
setIndicatorValue(indicatorMap,curDate, "被动报价占比(当日)", groupName, passiveQuoteRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "被动报价占比(当日)", groupName, passiveQuoteRate,(10*sortNo++));
// 13. 未开口报价占比
String noQuoteRate = calculateRate(stats.getNoQuoteCount(), stats.getTotalIntention());
setIndicatorValue(indicatorMap,curDate, "未开口报价占比(当日)", groupName, noQuoteRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "未开口报价占比(当日)", groupName, noQuoteRate,(10*sortNo++));
// 14. 已删除报价占比
String deletedQuoteRate = calculateRate(stats.getDeletedQuoteCount(), stats.getTotalIntention());
setIndicatorValue(indicatorMap,curDate, "已删除报价占比(当日)", groupName, deletedQuoteRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "已删除报价占比(当日)", groupName, deletedQuoteRate,(10*sortNo++));
// 15. 年级数量
setIndicatorValue(indicatorMap,curDate, "年级数量(当日)", groupName, String.valueOf(stats.getTotalGrade()),(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "年级数量(当日)", groupName, String.valueOf(stats.getTotalGrade()),(10*sortNo++));
// 16. 小学占比
String primaryRate = calculateRate(stats.getPrimaryCount(), stats.getTotalGrade());
setIndicatorValue(indicatorMap,curDate, "小学占比(当日)", groupName, primaryRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "小学占比(当日)", groupName, primaryRate,(10*sortNo++));
// 17. 初中占比
String middleRate = calculateRate(stats.getMiddleCount(), stats.getTotalGrade());
setIndicatorValue(indicatorMap,curDate, "初中占比(当日)", groupName, middleRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "初中占比(当日)", groupName, middleRate,(10*sortNo++));
// 18. 高中占比
String highRate = calculateRate(stats.getHighCount(), stats.getTotalGrade());
setIndicatorValue(indicatorMap,curDate, "高中占比(当日)", groupName, highRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "高中占比(当日)", groupName, highRate,(10*sortNo++));
// 19. 家长出单占比
String parentOrderRate = calculateRate(stats.getParentOrderCount(), stats.getParentCount());
setIndicatorValue(indicatorMap,curDate, "家长出单占比(当日)", groupName, parentOrderRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "家长出单占比(当日)", groupName, parentOrderRate,(10*sortNo++));
// 20. 学生出单占比
String studentOrderRate = calculateRate(stats.getStudentOrderCount(), stats.getStudentCount());
setIndicatorValue(indicatorMap,curDate, "学生出单占比(当日)", groupName, studentOrderRate,(10*sortNo++));
setIndicatorValue(corpId,indicatorMap,curDate, "学生出单占比(当日)", groupName, studentOrderRate,(10*sortNo++));
}
@ -809,7 +831,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* @param groupName 组名
* @param value 指标值
*/
private void setIndicatorValue(Map<String, CustomerStatisticsData> indicatorMap,Date curDate,
private void setIndicatorValue(String corpId,Map<String, CustomerStatisticsData> indicatorMap,Date curDate,
String indicatorName, String groupName, String value,int sortNo) {
// 获取或创建该指标对应的 CustomerStatisticsData 对象
CustomerStatisticsData vo = indicatorMap.computeIfAbsent(indicatorName, k -> {
@ -817,6 +839,7 @@ import java.util.concurrent.atomic.AtomicInteger;
newVo.setIndicatorName(indicatorName);
newVo.setCurDate(curDate);
newVo.setSortNo(sortNo);
newVo.setCorpId(corpId);
return newVo;
});
@ -917,7 +940,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* 从累加器生成最终部门统计结果
* 每一行数据代表一个部门或员工包含所有指标维度
*/
private List<DepartmentStatisticsData> generateDepartmentStatisticsResults(
private List<DepartmentStatisticsData> generateDepartmentStatisticsResults(String corpId,
DepartmentStatisticsAccumulator accumulator, Date statDate) {
List<DepartmentStatisticsData> results = new ArrayList<>();
@ -932,6 +955,7 @@ import java.util.concurrent.atomic.AtomicInteger;
DepartmentStatisticsData vo = new DepartmentStatisticsData();
vo.setStatDate(statDate);
vo.setDepartmentPath(departmentPath);
vo.setCorpId(corpId);
// 设置各项指标
// 1. 总承接数当日

View File

@ -0,0 +1,30 @@
package com.ruoyi.excel.wecom.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.excel.wecom.domain.CorpInfo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 企业信息Mapper接口
*/
@Mapper
public interface CorpInfoMapper extends BaseMapper<CorpInfo> {
/**
* 查询企业信息列表
*
* @param corpInfo 企业信息
* @return 企业信息集合
*/
List<CorpInfo> selectCorpInfoList(CorpInfo corpInfo);
/**
* 根据企业ID查询企业信息
*
* @param corpId 企业ID
* @return 企业信息
*/
CorpInfo selectCorpInfoByCorpId(String corpId);
}

View File

@ -2,7 +2,6 @@ package com.ruoyi.excel.wecom.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.excel.wecom.domain.CorpUser;
import com.ruoyi.excel.wecom.domain.WecomTagDomain;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@ -13,6 +12,6 @@ import java.util.List;
@Mapper
public interface CorpUserMapper extends BaseMapper<CorpUser> {
List<String> selectAllUserIds();
List<String> selectAllUserIds(String corpId);
}

View File

@ -21,7 +21,7 @@ public interface CustomerContactDataMapper extends BaseMapper<CustomerContactDat
* @param statDate 统计日期
* @return 客户联系统计数据列表
*/
List<CustomerContactData> selectByStatDate(Date statDate);
List<CustomerContactData> selectByStatDate(@Param("corpId") String corpId,@Param("statDate")Date statDate);
/**
* 根据成员ID和日期查询客户联系统计数据
@ -30,7 +30,7 @@ public interface CustomerContactDataMapper extends BaseMapper<CustomerContactDat
* @param statDate 统计日期
* @return 客户联系统计数据列表
*/
List<CustomerContactData> selectByUseridAndStatDate(String userid, Date statDate);
List<CustomerContactData> selectByUseridAndStatDate(@Param("corpId")String corpId,@Param("userid")String userid, @Param("statDate")Date statDate);
/**
* 查询客户联系统计数据列表
@ -40,6 +40,7 @@ public interface CustomerContactDataMapper extends BaseMapper<CustomerContactDat
* @return 客户联系统计数据列表
*/
List<CustomerContactData> selectCustomerContactDataList(
@Param("corpId") String corpId,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("userid") String userid
@ -53,6 +54,7 @@ public interface CustomerContactDataMapper extends BaseMapper<CustomerContactDat
* @return 客户联系统计数据VO列表
*/
List<CustomerContactDataVO> selectCustomerContactDataVOList(
@Param("corpId") String corpId,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("userid") String userid

View File

@ -14,7 +14,7 @@ import java.util.List;
*/
@Mapper
public interface CustomerExportDataMapper extends BaseMapper<CustomerExportData> {
List<Date> getDistinctDate();
List<Date> getDistinctDate( @Param("corpId") String corpId);
/**
* 查询客户导出数据列表
@ -24,6 +24,7 @@ public interface CustomerExportDataMapper extends BaseMapper<CustomerExportData>
* @return 客户导出数据列表
*/
List<CustomerExportData> selectCustomerExportDataList(
@Param("corpId") String corpId,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("customerName") String customerName
@ -37,6 +38,7 @@ public interface CustomerExportDataMapper extends BaseMapper<CustomerExportData>
* @return 客户导出数据VO列表
*/
List<CustomerExportDataVO> selectCustomerExportDataVOList(
@Param("corpId") String corpId,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("customerName") String customerName
@ -50,6 +52,7 @@ public interface CustomerExportDataMapper extends BaseMapper<CustomerExportData>
* @return 客户导出数据
*/
CustomerExportData selectByUniqueKey(
@Param("corpId") String corpId,
@Param("customerName") String customerName,
@Param("addUserAccount") String addUserAccount,
@Param("addTime") Date addTime

View File

@ -16,7 +16,7 @@ import java.util.List;
@Mapper
public interface CustomerStatisticsDataMapper extends BaseMapper<CustomerStatisticsData> {
List<CustomerStatisticsVO> selectByDate(Date date);
List<CustomerStatisticsVO> selectByDate(@Param("corpId") String corpId,@Param("date")Date date);
/**
* 查询客户统计数据列表
@ -26,6 +26,7 @@ public interface CustomerStatisticsDataMapper extends BaseMapper<CustomerStatist
* @return 客户统计数据列表
*/
List<CustomerStatisticsData> selectCustomerStatisticsDataList(
@Param("corpId") String corpId,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("indicatorName") String indicatorName
@ -39,6 +40,7 @@ public interface CustomerStatisticsDataMapper extends BaseMapper<CustomerStatist
* @return 客户统计数据VO列表
*/
List<CustomerStatisticsDataVO> selectCustomerStatisticsDataVOList(
@Param("corpId") String corpId,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("indicatorName") String indicatorName

View File

@ -22,7 +22,7 @@ public interface DepartmentStatisticsDataMapper extends BaseMapper<DepartmentSta
* @param date 统计日期
* @return 统计数据列表
*/
List<DepartmentStatisticsData> selectByDate(@Param("date") Date date);
List<DepartmentStatisticsData> selectByDate(@Param("corpId") String corpId,@Param("date") Date date);
/**
* 根据部门路径和日期范围查询统计数据
@ -32,6 +32,7 @@ public interface DepartmentStatisticsDataMapper extends BaseMapper<DepartmentSta
* @return 统计数据列表
*/
List<DepartmentStatisticsData> selectByDepartmentAndDateRange(
@Param("corpId") String corpId,
@Param("departmentPath") String departmentPath,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate
@ -42,14 +43,14 @@ public interface DepartmentStatisticsDataMapper extends BaseMapper<DepartmentSta
* @param departmentPath 部门路径
* @return 累计值
*/
Map<String, Object> selectHistoricalAcceptSum(@Param("departmentPath") String departmentPath);
Map<String, Object> selectHistoricalAcceptSum(@Param("corpId") String corpId,@Param("departmentPath") String departmentPath);
/**
* 查询指定部门的历史累计成单数
* @param departmentPath 部门路径
* @return 累计值
*/
Map<String, Object> selectHistoricalOrderSum(@Param("departmentPath") String departmentPath);
Map<String, Object> selectHistoricalOrderSum(@Param("corpId") String corpId,@Param("departmentPath") String departmentPath);
/**
* 查询部门统计数据列表
@ -59,6 +60,7 @@ public interface DepartmentStatisticsDataMapper extends BaseMapper<DepartmentSta
* @return 部门统计数据列表
*/
List<DepartmentStatisticsData> selectDepartmentStatisticsDataList(
@Param("corpId") String corpId,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("departmentPath") String departmentPath
@ -72,12 +74,13 @@ public interface DepartmentStatisticsDataMapper extends BaseMapper<DepartmentSta
* @return 部门统计数据VO列表
*/
List<DepartmentStatisticsDataVO> selectDepartmentStatisticsDataVOList(
@Param("corpId") String corpId,
@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("departmentPath") String departmentPath
);
Map<String, BigDecimal> getSummary(@Param("startDate") Date startDate,
Map<String, BigDecimal> getSummary(@Param("corpId") String corpId,@Param("startDate") Date startDate,
@Param("endDate") Date endDate,
@Param("departmentPath") String departmentPath);
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.excel.wecom.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.excel.wecom.domain.WecomTagGroupDomain;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 企业微信标签组Mapper
@ -16,6 +17,6 @@ public interface WecomTagGroupMapper extends BaseMapper<WecomTagGroupDomain> {
* @param tagGroupId 标签组ID
* @return 标签组
*/
WecomTagGroupDomain selectByTagGroupId(String tagGroupId);
WecomTagGroupDomain selectByTagGroupId(@Param("corpId") String corpId,@Param("tagGroupId") String tagGroupId);
}

View File

@ -3,6 +3,7 @@ package com.ruoyi.excel.wecom.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.excel.wecom.domain.WecomTagDomain;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 企业微信标签Mapper
@ -16,6 +17,6 @@ public interface WecomTagMapper extends BaseMapper<WecomTagDomain> {
* @param tagId 标签ID
* @return 标签
*/
WecomTagDomain selectByTagId(String tagId);
WecomTagDomain selectByTagId(@Param("corpId") String corpId, @Param("tagId")String tagId);
}

View File

@ -83,8 +83,8 @@ public class CustomerExportService {
System.out.println("缓存初始化完成!");
}
public List<Date> getAllDate() {
return customerExportDataMapper.getDistinctDate();
public List<Date> getAllDate(String corpId) {
return customerExportDataMapper.getDistinctDate(corpId);
}
/**
* 处理客户数据并保存到数据库
@ -96,7 +96,7 @@ public class CustomerExportService {
* @param customerList 客户列表
* @return 处理成功的数量
*/
public int handleData(List<WecomCustomer> customerList) {
public int handleData(String corpId,List<WecomCustomer> customerList) {
if (customerList == null || customerList.isEmpty()) {
System.out.println("客户列表为空,无需处理");
return 0;
@ -114,12 +114,14 @@ public class CustomerExportService {
if (exportData != null) {
// 根据唯一标识客户名称+添加人账号+添加时间查询是否已存在
CustomerExportData existingData = customerExportDataMapper.selectByUniqueKey(
corpId,
exportData.getCustomerName(),
exportData.getAddUserAccount(),
exportData.getAddTime()
);
if (existingData == null) {
exportData.setCorpId(corpId);
// 新增客户
customerExportDataMapper.insert(exportData);

View File

@ -0,0 +1,67 @@
package com.ruoyi.excel.wecom.service;
import com.ruoyi.excel.wecom.domain.CorpInfo;
import java.util.List;
/**
* 企业信息Service接口
*/
public interface ICorpInfoService {
/**
* 查询企业信息列表
*
* @param corpInfo 企业信息
* @return 企业信息集合
*/
List<CorpInfo> selectCorpInfoList(CorpInfo corpInfo);
/**
* 根据企业ID查询企业信息
*
* @param corpId 企业ID
* @return 企业信息
*/
CorpInfo selectCorpInfoByCorpId(String corpId);
/**
* 根据ID查询企业信息
*
* @param id 主键ID
* @return 企业信息
*/
CorpInfo selectCorpInfoById(Long id);
/**
* 新增企业信息
*
* @param corpInfo 企业信息
* @return 结果
*/
int insertCorpInfo(CorpInfo corpInfo);
/**
* 修改企业信息
*
* @param corpInfo 企业信息
* @return 结果
*/
int updateCorpInfo(CorpInfo corpInfo);
/**
* 批量删除企业信息
*
* @param ids 需要删除的企业信息主键集合
* @return 结果
*/
int deleteCorpInfoByIds(Long[] ids);
/**
* 删除企业信息
*
* @param id 企业信息主键
* @return 结果
*/
int deleteCorpInfoById(Long id);
}

View File

@ -18,7 +18,7 @@ public interface ICustomerContactDataService {
* @param userid 成员ID
* @return 客户联系统计数据列表
*/
List<CustomerContactData> selectCustomerContactDataList(Date startDate, Date endDate, String userid);
List<CustomerContactData> selectCustomerContactDataList(String corpId,Date startDate, Date endDate, String userid);
/**
* 查询客户联系统计数据VO列表(用于导出)
@ -27,7 +27,7 @@ public interface ICustomerContactDataService {
* @param userid 成员ID
* @return 客户联系统计数据VO列表
*/
List<CustomerContactDataVO> selectCustomerContactDataVOList(Date startDate, Date endDate, String userid);
List<CustomerContactDataVO> selectCustomerContactDataVOList(String corpId,Date startDate, Date endDate, String userid);
/**
* 根据ID查询客户联系统计数据
@ -36,13 +36,6 @@ public interface ICustomerContactDataService {
*/
CustomerContactData selectCustomerContactDataById(Long id);
/**
* 新增客户联系统计数据
* @param customerContactData 客户联系统计数据
* @return 结果
*/
int insertCustomerContactData(CustomerContactData customerContactData);
/**
* 修改客户联系统计数据
* @param customerContactData 客户联系统计数据

View File

@ -18,7 +18,7 @@ public interface ICustomerExportDataService {
* @param customerName 客户名称
* @return 客户导出数据列表
*/
List<CustomerExportData> selectCustomerExportDataList(Date startDate, Date endDate, String customerName);
List<CustomerExportData> selectCustomerExportDataList(String corpId,Date startDate, Date endDate, String customerName);
/**
* 查询客户导出数据VO列表(用于导出)
@ -27,7 +27,7 @@ public interface ICustomerExportDataService {
* @param customerName 客户名称
* @return 客户导出数据VO列表
*/
List<CustomerExportDataVO> selectCustomerExportDataVOList(Date startDate, Date endDate, String customerName);
List<CustomerExportDataVO> selectCustomerExportDataVOList(String corpId,Date startDate, Date endDate, String customerName);
/**
* 根据ID查询客户导出数据

View File

@ -19,7 +19,7 @@ public interface ICustomerStatisticsDataService {
* @param indicatorName 指标名称
* @return 客户统计数据列表
*/
List<CustomerStatisticsData> selectCustomerStatisticsDataList(Date startDate, Date endDate, String indicatorName);
List<CustomerStatisticsData> selectCustomerStatisticsDataList(String corpId,Date startDate, Date endDate, String indicatorName);
/**
* 查询客户统计数据VO列表(用于导出)
@ -28,7 +28,7 @@ public interface ICustomerStatisticsDataService {
* @param indicatorName 指标名称
* @return 客户统计数据VO列表
*/
List<CustomerStatisticsDataVO> selectCustomerStatisticsDataVOList(Date startDate, Date endDate, String indicatorName);
List<CustomerStatisticsDataVO> selectCustomerStatisticsDataVOList(String corpId,Date startDate, Date endDate, String indicatorName);
/**
* 根据ID查询客户统计数据
@ -58,5 +58,5 @@ public interface ICustomerStatisticsDataService {
*/
int deleteCustomerStatisticsDataByIds(Long[] ids);
int updateCost(Date curDate, BigDecimal totalCost, String titleAttr);
int updateCost(String corpId,Date curDate, BigDecimal totalCost, String titleAttr);
}

View File

@ -20,7 +20,7 @@ public interface IDepartmentStatisticsDataService {
* @param departmentPath 部门路径
* @return 部门统计数据列表
*/
List<DepartmentStatisticsData> selectDepartmentStatisticsDataList(Date startDate, Date endDate, String departmentPath);
List<DepartmentStatisticsData> selectDepartmentStatisticsDataList(String corpId,Date startDate, Date endDate, String departmentPath);
/**
* 查询部门统计数据VO列表(用于导出)
@ -29,7 +29,7 @@ public interface IDepartmentStatisticsDataService {
* @param departmentPath 部门路径
* @return 部门统计数据VO列表
*/
List<DepartmentStatisticsDataVO> selectDepartmentStatisticsDataVOList(Date startDate, Date endDate, String departmentPath);
List<DepartmentStatisticsDataVO> selectDepartmentStatisticsDataVOList(String corpId,Date startDate, Date endDate, String departmentPath);
/**
* 根据ID查询部门统计数据
@ -59,5 +59,5 @@ public interface IDepartmentStatisticsDataService {
*/
int deleteDepartmentStatisticsDataByIds(Long[] ids);
Map<String, BigDecimal> getSummary(Date startDate, Date endDate, String departmentPath);
Map<String, BigDecimal> getSummary(String corpId,Date startDate, Date endDate, String departmentPath);
}

View File

@ -2,6 +2,9 @@ package com.ruoyi.excel.wecom.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.excel.wecom.domain.CorpInfo;
import com.ruoyi.excel.wecom.model.WecomConfig;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
@ -13,6 +16,7 @@ import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* 企业微信基础服务类
@ -20,30 +24,49 @@ import java.io.IOException;
public class WecomBaseService {
private WecomConfig wecomConfig;
/**
* Redis key 前缀wecom_access_token:{corpId}
*/
private static final String ACCESS_TOKEN_KEY_PREFIX = "wecom_access_token:";
public WecomBaseService(WecomConfig wecomConfig) {
this.wecomConfig = wecomConfig;
}
/**
* 获取accessToken
* 获取accessToken根据当前企业上下文动态获取
*
* @return accessToken
* @throws IOException IO异常
*/
public String getAccessToken() throws IOException {
if (!wecomConfig.isAccessTokenExpired()) {
return wecomConfig.getAccessToken();
public String getAccessToken(String corpId) throws IOException {
// 2. Redis 获取缓存的 access_token
RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
String cacheKey = ACCESS_TOKEN_KEY_PREFIX + corpId;
String cachedToken = redisCache.getCacheObject(cacheKey);
if (cachedToken != null && !cachedToken.trim().isEmpty()) {
return cachedToken;
}
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + wecomConfig.getCorpId() + "&corpsecret=" + wecomConfig.getCorpSecret();
// 3. 缓存不存在或已过期从数据库查询企业信息
ICorpInfoService corpInfoService = SpringUtils.getBean(ICorpInfoService.class);
CorpInfo corpInfo = corpInfoService.selectCorpInfoByCorpId(corpId);
if (corpInfo == null) {
throw new RuntimeException("企业信息不存在: " + corpId);
}
// 4. 调用企业微信API获取新的 access_token
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpInfo.getCorpId() + "&corpsecret=" + corpInfo.getSecret();
String response = doGet(url);
JSONObject jsonObject = JSON.parseObject(response);
if (jsonObject.getInteger("errcode") == 0) {
String accessToken = jsonObject.getString("access_token");
int expiresIn = jsonObject.getInteger("expires_in");
wecomConfig.setAccessToken(accessToken);
wecomConfig.setAccessTokenExpireTime(System.currentTimeMillis() + (expiresIn - 60) * 1000);
// 5. access_token 缓存到 Redis提前60秒过期
redisCache.setCacheObject(cacheKey, accessToken, expiresIn - 60, TimeUnit.SECONDS);
return accessToken;
} else {
throw new RuntimeException("获取accessToken失败: " + jsonObject.getString("errmsg"));

View File

@ -31,8 +31,8 @@ public class WecomContactService extends WecomBaseService {
* @return 成员ID列表
* @throws IOException IO异常
*/
public List<String> getFollowUserList() throws IOException {
String accessToken = getAccessToken();
public List<String> getFollowUserList(String corpId) throws IOException {
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_follow_user_list?access_token=" + accessToken;
String response = doGet(url);
JSONObject jsonObject = JSON.parseObject(response);
@ -51,8 +51,8 @@ public class WecomContactService extends WecomBaseService {
* @return 客户外部联系人ID列表
* @throws IOException IO异常
*/
public List<String> getExternalContactList(String userid) throws IOException {
String accessToken = getAccessToken();
public List<String> getExternalContactList(String corpId,String userid) throws IOException {
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list?access_token=" + accessToken + "&userid=" + userid;
String response = doGet(url);
JSONObject jsonObject = JSON.parseObject(response);
@ -70,12 +70,12 @@ public class WecomContactService extends WecomBaseService {
* @return 成员客户映射关系
* @throws IOException IO异常
*/
public List<MemberCustomer> getAllMembersCustomers() throws IOException {
List<String> userList = getFollowUserList();
public List<MemberCustomer> getAllMembersCustomers(String corpId) throws IOException {
List<String> userList = getFollowUserList(corpId);
List<MemberCustomer> result = new ArrayList<>();
for (String userid : userList) {
List<String> customerList = getExternalContactList(userid);
List<String> customerList = getExternalContactList(corpId,userid);
MemberCustomer memberCustomer = new MemberCustomer();
memberCustomer.setUserid(userid);
memberCustomer.setExternalUserids(customerList);
@ -94,13 +94,13 @@ public class WecomContactService extends WecomBaseService {
* @return 客户详情列表
* @throws IOException IO异常
*/
public String batchGetCustomerDetails(List<String> useridList,List<WecomCustomer> finalResult, String cursor, Integer limit) throws IOException {
public String batchGetCustomerDetails(String corpId,List<String> useridList,List<WecomCustomer> finalResult, String cursor, Integer limit) throws IOException {
if (useridList.size() > 100) {
throw new IllegalArgumentException("成员ID列表不能超过100个");
}
System.out.println("获取用户数据****" + cursor);
String accessToken = getAccessToken();
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=" + accessToken;
JSONObject requestBody = new JSONObject();
@ -133,23 +133,10 @@ public class WecomContactService extends WecomBaseService {
}
} else if (jsonObject.containsKey("next_cursor") && StringUtils.isNotEmpty(jsonObject.getString("next_cursor"))) {
nextCursor = jsonObject.getString("next_cursor");
return batchGetCustomerDetails(useridList, finalResult, nextCursor, limit);
return batchGetCustomerDetails(corpId,useridList, finalResult, nextCursor, limit);
} else {
return null;
}
/* // 处理分页
if (jsonObject.containsKey("next_cursor") && StringUtils.isNotEmpty(jsonObject.getString("next_cursor"))) {
String nextCursor = jsonObject.getString("next_cursor");
//如果发现数量已经存储了2000条则先退出 由外部存储
if (finalResult.size() >= 2000) {
return nextCursor;
} else {
return batchGetCustomerDetails(useridList, finalResult, nextCursor, limit);
}
} else {
return null;
}*/
} else {
throw new RuntimeException("批量获取客户详情失败: " + jsonObject.getString("errmsg"));
}
@ -162,14 +149,14 @@ public class WecomContactService extends WecomBaseService {
* @return 客户详情列表
* @throws IOException IO异常
*/
public List<WecomCustomer> batchGetAllCustomerDetails(List<String> useridList) throws IOException {
public List<WecomCustomer> batchGetAllCustomerDetails(String corpId,List<String> useridList) throws IOException {
List<WecomCustomer> allCustomers = new ArrayList<>();
// 分批处理每次最多100个用户
for (int i = 0; i < useridList.size(); i += 100) {
int endIndex = Math.min(i + 100, useridList.size());
List<String> batchUserids = useridList.subList(i, endIndex);
batchGetCustomerDetails(batchUserids, allCustomers,null, 100);
batchGetCustomerDetails(corpId,batchUserids, allCustomers,null, 100);
}
return allCustomers;
@ -182,8 +169,8 @@ public class WecomContactService extends WecomBaseService {
* @return 客户详情
* @throws IOException IO异常
*/
public WecomCustomer getCustomerDetail(String externalUserid) throws IOException {
String accessToken = getAccessToken();
public WecomCustomer getCustomerDetail(String corpId,String externalUserid) throws IOException {
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=" + accessToken + "&external_userid=" + externalUserid;
String response = doGet(url);
JSONObject jsonObject = JSON.parseObject(response);
@ -206,8 +193,8 @@ public class WecomContactService extends WecomBaseService {
* @return 标签库列表
* @throws IOException IO异常
*/
public List<WecomTagGroup> getCorpTagList() throws IOException {
String accessToken = getAccessToken();
public List<WecomTagGroup> getCorpTagList(String corpId) throws IOException {
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?access_token=" + accessToken;
String response = doGet(url);
JSONObject jsonObject = JSON.parseObject(response);
@ -255,8 +242,8 @@ public class WecomContactService extends WecomBaseService {
* @return 子部门ID列表
* @throws IOException IO异常
*/
public List<CorpDepartment> getDepartmentList(Long departmentId) throws IOException {
String accessToken = getAccessToken();
public List<CorpDepartment> getDepartmentList(String corpId,Long departmentId) throws IOException {
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=" + accessToken;
if (departmentId != null) {
url += "&id=" + departmentId;
@ -282,8 +269,8 @@ public class WecomContactService extends WecomBaseService {
* @return 部门详情
* @throws IOException IO异常
*/
public String getDepartmentDetail(Long departmentId) throws IOException {
String accessToken = getAccessToken();
public String getDepartmentDetail(String corpId,Long departmentId) throws IOException {
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token=" + accessToken + "&id=" + departmentId;
String response = doGet(url);
JSONObject jsonObject = JSON.parseObject(response);
@ -310,8 +297,8 @@ public class WecomContactService extends WecomBaseService {
* @return 部门成员详情列表
* @throws IOException IO异常
*/
public List<CorpUser> getDepartmentMemberList(Long departmentId, Integer fetchChild, Integer status) throws IOException {
String accessToken = getAccessToken();
public List<CorpUser> getDepartmentMemberList(String corpId,Long departmentId, Integer fetchChild, Integer status) throws IOException {
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=" + accessToken + "&department_id=" + departmentId;
if (fetchChild != null) {
url += "&fetch_child=" + fetchChild;
@ -354,8 +341,8 @@ public class WecomContactService extends WecomBaseService {
* @return 统计数据
* @throws IOException IO异常
*/
public JSONObject getUserBehaviorData(Long startTime, Long endTime, List<String> useridList) throws IOException {
String accessToken = getAccessToken();
public JSONObject getUserBehaviorData(String corpId,Long startTime, Long endTime, List<String> useridList) throws IOException {
String accessToken = getAccessToken(corpId);
String url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_user_behavior_data?access_token=" + accessToken;
JSONObject requestBody = new JSONObject();
@ -383,7 +370,7 @@ public class WecomContactService extends WecomBaseService {
* @return 统计数据
* @throws IOException IO异常
*/
public JSONObject getDayUserBehaviorData(String date, List<String> useridList) throws IOException {
public JSONObject getDayUserBehaviorData(String corpId,String date, List<String> useridList) throws IOException {
try {
// 解析日期字符串为Date对象
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
@ -404,7 +391,7 @@ public class WecomContactService extends WecomBaseService {
Long endTime = calendar.getTimeInMillis() / 1000;
// 调用获取统计数据的方法
return getUserBehaviorData(startTime, endTime, useridList);
return getUserBehaviorData(corpId,startTime, endTime, useridList);
} catch (java.text.ParseException e) {
throw new RuntimeException("日期格式错误请使用yyyy-MM-dd格式", e);
}

View File

@ -32,7 +32,7 @@ public class WecomStatisticsService {
* @param statisticsData 统计数据
* @return 处理成功的数量
*/
public int handleAndSaveCustomerStatistics(String date, JSONObject statisticsData) {
public int handleAndSaveCustomerStatistics(String corpId,String date, JSONObject statisticsData) {
if (statisticsData == null || !statisticsData.containsKey("behavior_data")) {
return 0;
}
@ -53,7 +53,7 @@ public class WecomStatisticsService {
JSONObject data = behaviorData.getJSONObject("data");
// 处理每个统计指标
successCount += handleStatisticsIndicators(curDate, userid, data);
successCount += handleStatisticsIndicators(corpId,curDate, userid, data);
}
} catch (Exception e) {
e.printStackTrace();
@ -71,49 +71,49 @@ public class WecomStatisticsService {
* @param data 统计数据
* @return 处理成功的数量
*/
private int handleStatisticsIndicators(Date curDate, String userid, JSONObject data) {
private int handleStatisticsIndicators(String corpId,Date curDate, String userid, JSONObject data) {
int successCount = 0;
// 处理各项统计指标
// 这里需要根据实际的指标名称进行映射
// 示例处理新增客户数
if (data.containsKey("new_contact_cnt")) {
CustomerStatisticsData statisticsData = createCustomerStatisticsData(curDate, "新增客户数", userid, data.getInteger("new_contact_cnt"));
CustomerStatisticsData statisticsData = createCustomerStatisticsData(corpId,curDate, "新增客户数", userid, data.getInteger("new_contact_cnt"));
customerStatisticsDataMapper.insert(statisticsData);
successCount++;
}
// 处理聊天次数
if (data.containsKey("chat_cnt")) {
CustomerStatisticsData statisticsData = createCustomerStatisticsData(curDate, "聊天次数", userid, data.getInteger("chat_cnt"));
CustomerStatisticsData statisticsData = createCustomerStatisticsData(corpId,curDate, "聊天次数", userid, data.getInteger("chat_cnt"));
customerStatisticsDataMapper.insert(statisticsData);
successCount++;
}
// 处理发送消息数
if (data.containsKey("msg_cnt")) {
CustomerStatisticsData statisticsData = createCustomerStatisticsData(curDate, "发送消息数", userid, data.getInteger("msg_cnt"));
CustomerStatisticsData statisticsData = createCustomerStatisticsData(corpId,curDate, "发送消息数", userid, data.getInteger("msg_cnt"));
customerStatisticsDataMapper.insert(statisticsData);
successCount++;
}
// 处理语音通话时长
if (data.containsKey("voice_cnt")) {
CustomerStatisticsData statisticsData = createCustomerStatisticsData(curDate, "语音通话时长(秒)", userid, data.getInteger("voice_cnt"));
CustomerStatisticsData statisticsData = createCustomerStatisticsData(corpId,curDate, "语音通话时长(秒)", userid, data.getInteger("voice_cnt"));
customerStatisticsDataMapper.insert(statisticsData);
successCount++;
}
// 处理视频通话时长
if (data.containsKey("video_cnt")) {
CustomerStatisticsData statisticsData = createCustomerStatisticsData(curDate, "视频通话时长(秒)", userid, data.getInteger("video_cnt"));
CustomerStatisticsData statisticsData = createCustomerStatisticsData(corpId,curDate, "视频通话时长(秒)", userid, data.getInteger("video_cnt"));
customerStatisticsDataMapper.insert(statisticsData);
successCount++;
}
// 处理拜访次数
if (data.containsKey("visit_cnt")) {
CustomerStatisticsData statisticsData = createCustomerStatisticsData(curDate, "拜访次数", userid, data.getInteger("visit_cnt"));
CustomerStatisticsData statisticsData = createCustomerStatisticsData(corpId,curDate, "拜访次数", userid, data.getInteger("visit_cnt"));
customerStatisticsDataMapper.insert(statisticsData);
successCount++;
}
@ -130,9 +130,10 @@ public class WecomStatisticsService {
* @param value 指标值
* @return 客户统计数据实体
*/
private CustomerStatisticsData createCustomerStatisticsData(Date curDate, String indicatorName, String userid, Integer value) {
private CustomerStatisticsData createCustomerStatisticsData(String corpId,Date curDate, String indicatorName, String userid, Integer value) {
CustomerStatisticsData statisticsData = new CustomerStatisticsData();
statisticsData.setCurDate(curDate);
statisticsData.setCorpId(corpId);
statisticsData.setIndicatorName(indicatorName);
// 这里需要根据userid映射到对应的部门组
@ -160,8 +161,8 @@ public class WecomStatisticsService {
* @param date 日期
* @return 客户统计数据列表
*/
public List<CustomerStatisticsVO> getCustomerStatisticsByDate(Date date) {
return customerStatisticsDataMapper.selectByDate(date);
public List<CustomerStatisticsVO> getCustomerStatisticsByDate(String corpId,Date date) {
return customerStatisticsDataMapper.selectByDate(corpId,date);
}
/**
@ -170,7 +171,7 @@ public class WecomStatisticsService {
* @param statisticsData 统计数据
* @return 处理成功的数量
*/
public int handleAndSaveCustomerContactData(JSONObject statisticsData) {
public int handleAndSaveCustomerContactData(String corpId,JSONObject statisticsData) {
if (statisticsData == null || !statisticsData.containsKey("behavior_data")) {
return 0;
}
@ -189,7 +190,7 @@ public class WecomStatisticsService {
JSONObject data = behaviorData.getJSONObject("data");
// 处理每个成员的详细统计数据
successCount += handleCustomerContactData(userid, data);
successCount += handleCustomerContactData(corpId,userid, data);
}
} catch (Exception e) {
e.printStackTrace();
@ -206,7 +207,7 @@ public class WecomStatisticsService {
* @param data 统计数据
* @return 处理成功的数量
*/
private int handleCustomerContactData(String userid, JSONObject data) {
private int handleCustomerContactData(String corpId,String userid, JSONObject data) {
int successCount = 0;
// 处理每个统计时间点的数据
@ -217,7 +218,7 @@ public class WecomStatisticsService {
for (int i = 0; i < statDataArray.size(); i++) {
JSONObject statData = statDataArray.getJSONObject(i);
CustomerContactData contactData = createCustomerContactData(userid, statData);
CustomerContactData contactData = createCustomerContactData(corpId,userid, statData);
if (contactData != null) {
customerContactDataMapper.insert(contactData);
successCount++;
@ -234,9 +235,9 @@ public class WecomStatisticsService {
* @param statData 统计数据
* @return 客户联系统计数据实体
*/
private CustomerContactData createCustomerContactData(String userid, JSONObject statData) {
private CustomerContactData createCustomerContactData(String corpId,String userid, JSONObject statData) {
CustomerContactData contactData = new CustomerContactData();
contactData.setCorpId(corpId);
// 设置统计时间戳
if (statData.containsKey("stat_time")) {
contactData.setStatTime(statData.getLong("stat_time"));
@ -292,8 +293,8 @@ public class WecomStatisticsService {
* @param statDate 统计日期
* @return 客户联系统计数据列表
*/
public List<CustomerContactData> getCustomerContactDataByDate(Date statDate) {
return customerContactDataMapper.selectByStatDate(statDate);
public List<CustomerContactData> getCustomerContactDataByDate(String corpId,Date statDate) {
return customerContactDataMapper.selectByStatDate(corpId,statDate);
}
/**
@ -303,7 +304,7 @@ public class WecomStatisticsService {
* @param statDate 统计日期
* @return 客户联系统计数据列表
*/
public List<CustomerContactData> getCustomerContactDataByUseridAndDate(String userid, Date statDate) {
return customerContactDataMapper.selectByUseridAndStatDate(userid, statDate);
public List<CustomerContactData> getCustomerContactDataByUseridAndDate(String corpId,String userid, Date statDate) {
return customerContactDataMapper.selectByUseridAndStatDate(corpId,userid, statDate);
}
}

View File

@ -1,18 +1,17 @@
package com.ruoyi.excel.wecom.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.excel.wecom.domain.WecomTagDomain;
import com.ruoyi.excel.wecom.domain.WecomTagGroupDomain;
import com.ruoyi.excel.wecom.mapper.WecomTagMapper;
import com.ruoyi.excel.wecom.mapper.WecomTagGroupMapper;
import com.ruoyi.excel.wecom.mapper.WecomTagMapper;
import com.ruoyi.excel.wecom.model.WecomTag;
import com.ruoyi.excel.wecom.model.WecomTagGroup;
import com.ruoyi.common.utils.CorpContextHolder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -26,6 +25,8 @@ public class WecomTagService {
private WecomTagGroupMapper wecomTagGroupMapper;
@Autowired
private WecomTagMapper wecomTagMapper;
@Autowired
private RedisCache redisCache;
/**
@ -35,6 +36,13 @@ public class WecomTagService {
* @return 同步结果
*/
public boolean syncCorpTagList(List<WecomTagGroup> tagGroupList) {
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
throw new RuntimeException("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
try {
// 遍历标签组列表
for (WecomTagGroup tagGroup : tagGroupList) {
@ -44,6 +52,7 @@ public class WecomTagService {
groupDomain.setName(tagGroup.getGroupName());
groupDomain.setCreateTime(new Date(tagGroup.getCreateTime() * 1000));
groupDomain.setOrderNo(tagGroup.getOrder());
groupDomain.setCorpId(corpId); // 设置企业ID
wecomTagGroupMapper.insert(groupDomain);
// 保存标签
List<WecomTag> tagList = tagGroup.getTag();
@ -56,6 +65,7 @@ public class WecomTagService {
tagDomain.setOrderNo(tag.getOrder());
tagDomain.setCreateTime(new Date(tag.getCreateTime() * 1000));
tagDomain.setSyncTime(new Date());
tagDomain.setCorpId(corpId); // 设置企业ID
// 插入标签
wecomTagMapper.insert(tagDomain);
@ -66,6 +76,9 @@ public class WecomTagService {
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
// 清理上下文
CorpContextHolder.clear();
}
}

View File

@ -0,0 +1,100 @@
package com.ruoyi.excel.wecom.service.impl;
import com.ruoyi.excel.wecom.domain.CorpInfo;
import com.ruoyi.excel.wecom.mapper.CorpInfoMapper;
import com.ruoyi.excel.wecom.service.ICorpInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 企业信息Service业务层处理
*/
@Service
public class CorpInfoServiceImpl implements ICorpInfoService {
@Autowired
private CorpInfoMapper corpInfoMapper;
/**
* 查询企业信息列表
*
* @param corpInfo 企业信息
* @return 企业信息集合
*/
@Override
public List<CorpInfo> selectCorpInfoList(CorpInfo corpInfo) {
return corpInfoMapper.selectCorpInfoList(corpInfo);
}
/**
* 根据企业ID查询企业信息
*
* @param corpId 企业ID
* @return 企业信息
*/
@Override
public CorpInfo selectCorpInfoByCorpId(String corpId) {
return corpInfoMapper.selectCorpInfoByCorpId(corpId);
}
/**
* 根据ID查询企业信息
*
* @param id 主键ID
* @return 企业信息
*/
@Override
public CorpInfo selectCorpInfoById(Long id) {
return corpInfoMapper.selectById(id);
}
/**
* 新增企业信息
*
* @param corpInfo 企业信息
* @return 结果
*/
@Override
public int insertCorpInfo(CorpInfo corpInfo) {
return corpInfoMapper.insert(corpInfo);
}
/**
* 修改企业信息
*
* @param corpInfo 企业信息
* @return 结果
*/
@Override
public int updateCorpInfo(CorpInfo corpInfo) {
return corpInfoMapper.updateById(corpInfo);
}
/**
* 批量删除企业信息
*
* @param ids 需要删除的企业信息主键集合
* @return 结果
*/
@Override
public int deleteCorpInfoByIds(Long[] ids) {
int count = 0;
for (Long id : ids) {
count += corpInfoMapper.deleteById(id);
}
return count;
}
/**
* 删除企业信息
*
* @param id 企业信息主键
* @return 结果
*/
@Override
public int deleteCorpInfoById(Long id) {
return corpInfoMapper.deleteById(id);
}
}

View File

@ -27,8 +27,8 @@ public class CustomerContactDataServiceImpl implements ICustomerContactDataServi
* @return 客户联系统计数据列表
*/
@Override
public List<CustomerContactData> selectCustomerContactDataList(Date startDate, Date endDate, String userid) {
return customerContactDataMapper.selectCustomerContactDataList(startDate, endDate, userid);
public List<CustomerContactData> selectCustomerContactDataList(String corpId,Date startDate, Date endDate, String userid) {
return customerContactDataMapper.selectCustomerContactDataList(corpId,startDate, endDate, userid);
}
/**
@ -39,8 +39,8 @@ public class CustomerContactDataServiceImpl implements ICustomerContactDataServi
* @return 客户联系统计数据VO列表
*/
@Override
public List<CustomerContactDataVO> selectCustomerContactDataVOList(Date startDate, Date endDate, String userid) {
return customerContactDataMapper.selectCustomerContactDataVOList(startDate, endDate, userid);
public List<CustomerContactDataVO> selectCustomerContactDataVOList(String corpId,Date startDate, Date endDate, String userid) {
return customerContactDataMapper.selectCustomerContactDataVOList(corpId,startDate, endDate, userid);
}
/**
@ -53,15 +53,6 @@ public class CustomerContactDataServiceImpl implements ICustomerContactDataServi
return customerContactDataMapper.selectById(id);
}
/**
* 新增客户联系统计数据
* @param customerContactData 客户联系统计数据
* @return 结果
*/
@Override
public int insertCustomerContactData(CustomerContactData customerContactData) {
return customerContactDataMapper.insert(customerContactData);
}
/**
* 修改客户联系统计数据

View File

@ -27,8 +27,8 @@ public class CustomerExportDataServiceImpl implements ICustomerExportDataService
* @return 客户导出数据列表
*/
@Override
public List<CustomerExportData> selectCustomerExportDataList(Date startDate, Date endDate, String customerName) {
return customerExportDataMapper.selectCustomerExportDataList(startDate, endDate, customerName);
public List<CustomerExportData> selectCustomerExportDataList(String corpId,Date startDate, Date endDate, String customerName) {
return customerExportDataMapper.selectCustomerExportDataList(corpId,startDate, endDate, customerName);
}
/**
@ -39,8 +39,8 @@ public class CustomerExportDataServiceImpl implements ICustomerExportDataService
* @return 客户导出数据VO列表
*/
@Override
public List<CustomerExportDataVO> selectCustomerExportDataVOList(Date startDate, Date endDate, String customerName) {
return customerExportDataMapper.selectCustomerExportDataVOList(startDate, endDate, customerName);
public List<CustomerExportDataVO> selectCustomerExportDataVOList(String corpId,Date startDate, Date endDate, String customerName) {
return customerExportDataMapper.selectCustomerExportDataVOList(corpId,startDate, endDate, customerName);
}
/**

View File

@ -32,8 +32,8 @@ public class CustomerStatisticsDataServiceImpl implements ICustomerStatisticsDat
* @return 客户统计数据列表
*/
@Override
public List<CustomerStatisticsData> selectCustomerStatisticsDataList(Date startDate, Date endDate, String indicatorName) {
return customerStatisticsDataMapper.selectCustomerStatisticsDataList(startDate, endDate, indicatorName);
public List<CustomerStatisticsData> selectCustomerStatisticsDataList(String corpId,Date startDate, Date endDate, String indicatorName) {
return customerStatisticsDataMapper.selectCustomerStatisticsDataList(corpId,startDate, endDate, indicatorName);
}
/**
@ -44,8 +44,8 @@ public class CustomerStatisticsDataServiceImpl implements ICustomerStatisticsDat
* @return 客户统计数据VO列表
*/
@Override
public List<CustomerStatisticsDataVO> selectCustomerStatisticsDataVOList(Date startDate, Date endDate, String indicatorName) {
return customerStatisticsDataMapper.selectCustomerStatisticsDataVOList(startDate, endDate, indicatorName);
public List<CustomerStatisticsDataVO> selectCustomerStatisticsDataVOList(String corpId,Date startDate, Date endDate, String indicatorName) {
return customerStatisticsDataMapper.selectCustomerStatisticsDataVOList(corpId,startDate, endDate, indicatorName);
}
/**
@ -94,7 +94,7 @@ public class CustomerStatisticsDataServiceImpl implements ICustomerStatisticsDat
@Override
@Transactional
public int updateCost(Date curDate, BigDecimal totalCost, String titleAttr) {
public int updateCost(String corpId,Date curDate, BigDecimal totalCost, String titleAttr) {
try {
// 1. 查询该日期的所有记录
LambdaQueryWrapper<CustomerStatisticsData> queryWrapper = new LambdaQueryWrapper<>();

View File

@ -29,8 +29,8 @@ public class DepartmentStatisticsDataServiceImpl implements IDepartmentStatistic
* @return 部门统计数据列表
*/
@Override
public List<DepartmentStatisticsData> selectDepartmentStatisticsDataList(Date startDate, Date endDate, String departmentPath) {
return departmentStatisticsDataMapper.selectDepartmentStatisticsDataList(startDate, endDate, departmentPath);
public List<DepartmentStatisticsData> selectDepartmentStatisticsDataList(String corpId,Date startDate, Date endDate, String departmentPath) {
return departmentStatisticsDataMapper.selectDepartmentStatisticsDataList(corpId,startDate, endDate, departmentPath);
}
/**
@ -41,8 +41,8 @@ public class DepartmentStatisticsDataServiceImpl implements IDepartmentStatistic
* @return 部门统计数据VO列表
*/
@Override
public List<DepartmentStatisticsDataVO> selectDepartmentStatisticsDataVOList(Date startDate, Date endDate, String departmentPath) {
return departmentStatisticsDataMapper.selectDepartmentStatisticsDataVOList(startDate, endDate, departmentPath);
public List<DepartmentStatisticsDataVO> selectDepartmentStatisticsDataVOList(String corpId,Date startDate, Date endDate, String departmentPath) {
return departmentStatisticsDataMapper.selectDepartmentStatisticsDataVOList(corpId,startDate, endDate, departmentPath);
}
/**
@ -90,7 +90,7 @@ public class DepartmentStatisticsDataServiceImpl implements IDepartmentStatistic
}
@Override
public Map<String, BigDecimal> getSummary(Date startDate, Date endDate, String departmentPath) {
return departmentStatisticsDataMapper.getSummary(startDate,endDate,departmentPath);
public Map<String, BigDecimal> getSummary(String corpId,Date startDate, Date endDate, String departmentPath) {
return departmentStatisticsDataMapper.getSummary(corpId,startDate,endDate,departmentPath);
}
}

View File

@ -90,19 +90,16 @@ public class CustomerExportDataVO implements Serializable {
@ExcelProperty("标签组2(公司孵化)")
@Excel(name = "标签组2(公司孵化)")
@ColumnWidth(20)
private String tagGroup2;
@ExcelProperty("标签组3(商务)")
@Excel(name = "标签组3(商务))")
@ColumnWidth(20)
private String tagGroup3;
@ExcelProperty("标签组4(成交日期)")
@Excel(name = "标签组4(成交日期)")
@ColumnWidth(20)
private String tagGroup4;

View File

@ -17,7 +17,7 @@ public class CustomerStatisticsDataVO implements Serializable {
private static final long serialVersionUID = 1L;
@ExcelProperty("统计日期")
@Excel(name ="统计日期")
@Excel(name ="日期",dateFormat = "yyyy-MM-dd")
@DateTimeFormat("yyyy-MM-dd")
@ColumnWidth(20)
private Date curDate;

View File

@ -18,8 +18,8 @@ import java.util.Date;
public class DepartmentStatisticsDataVO implements Serializable {
private static final long serialVersionUID = 1L;
@ExcelProperty("统计日期")
@Excel(name ="统计日期")
@ExcelProperty("日期")
@Excel(name ="日期",dateFormat = "yyyy-MM-dd")
@DateTimeFormat("yyyy-MM-dd")
@ColumnWidth(15)
private Date statDate;
@ -44,9 +44,13 @@ public class DepartmentStatisticsDataVO implements Serializable {
@ColumnWidth(15)
private BigDecimal dailyConversionRate;
@ExcelProperty("及时单占比(当日)")
@Excel(name ="及时单占比(当日)")
@ColumnWidth(15)
private BigDecimal dailyTimelyOrderRatio;
@ExcelProperty("排序号")
@Excel(name ="排序号")
@ColumnWidth(10)
private Integer sortNo;
@ExcelProperty("非及时单占比(当日")
@Excel(name ="非及时单占比(当日")
@ColumnWidth(15)
private BigDecimal dailyNonTimelyOrderRatio;
}

View File

@ -0,0 +1,35 @@
<?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.ruoyi.excel.wecom.mapper.CorpInfoMapper">
<resultMap id="CorpInfoResult" type="com.ruoyi.excel.wecom.domain.CorpInfo">
<id property="id" column="id"/>
<result property="corpId" column="corp_id"/>
<result property="secret" column="secret"/>
<result property="name" column="name"/>
</resultMap>
<!-- 查询企业信息列表 -->
<select id="selectCorpInfoList" parameterType="com.ruoyi.excel.wecom.domain.CorpInfo" resultMap="CorpInfoResult">
SELECT id, corp_id, secret, name
FROM corp_info
<where>
<if test="corpId != null and corpId != ''">
AND corp_id = #{corpId}
</if>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
</where>
ORDER BY id DESC
</select>
<!-- 根据企业ID查询企业信息 -->
<select id="selectCorpInfoByCorpId" parameterType="String" resultMap="CorpInfoResult">
SELECT id, corp_id, secret, name
FROM corp_info
WHERE corp_id = #{corpId}
LIMIT 1
</select>
</mapper>

View File

@ -4,6 +4,6 @@
<select id="selectAllUserIds" resultType="java.lang.String">
select distinct userid from corp_user
select distinct userid from corp_user where corp_id = #{corpId}
</select>
</mapper>

View File

@ -17,6 +17,7 @@
new_contact_cnt
FROM customer_contact_data
<where>
corp_id = #{corpId}
<if test="startDate != null">
AND stat_date &gt;= #{startDate}
</if>
@ -44,6 +45,8 @@
new_contact_cnt as newContactCnt
FROM customer_contact_data
<where>
corp_id = #{corpId}
<if test="startDate != null">
AND stat_date &gt;= #{startDate}
</if>
@ -59,12 +62,12 @@
<!-- 根据日期查询客户联系统计数据 -->
<select id="selectByStatDate" resultType="com.ruoyi.excel.wecom.domain.CustomerContactData">
SELECT * FROM customer_contact_data WHERE stat_date = #{statDate}
SELECT * FROM customer_contact_data WHERE stat_date = #{statDate} and corp_id = #{corpId}
</select>
<!-- 根据成员ID和日期查询客户联系统计数据 -->
<select id="selectByUseridAndStatDate" resultType="com.ruoyi.excel.wecom.domain.CustomerContactData">
SELECT * FROM customer_contact_data WHERE userid = #{userid} AND stat_date = #{statDate}
SELECT * FROM customer_contact_data WHERE userid = #{userid} AND stat_date = #{statDate} and corp_id = #{corpId}
</select>
</mapper>

View File

@ -4,7 +4,7 @@
<select id="getDistinctDate" resultType="java.util.Date">
select distinct add_date from customer_export_data order by add_date
select distinct add_date from customer_export_data where corp_id = #{corpId} order by add_date
</select>
<!-- 查询客户导出数据VO列表(用于导出) -->
@ -44,6 +44,7 @@
tag_group18 as tagGroup18
FROM customer_export_data
<where>
corp_id = #{corpId}
<if test="startDate != null">
AND add_time &gt;= #{startDate}
</if>
@ -92,6 +93,7 @@
tag_group18 as tagGroup18
FROM customer_export_data
<where>
corp_id = #{corpId}
<if test="startDate != null">
AND add_time &gt;= #{startDate}
</if>
@ -109,7 +111,10 @@
<select id="selectByUniqueKey" resultType="com.ruoyi.excel.wecom.domain.CustomerExportData">
SELECT *
FROM customer_export_data
WHERE customer_name = #{customerName}
WHERE
corp_id = #{corpId}
and
customer_name = #{customerName}
AND add_user_account = #{addUserAccount}
AND add_time = #{addTime}
LIMIT 1

View File

@ -6,7 +6,7 @@
<select id="selectByDate" resultType="com.ruoyi.excel.wecom.vo.CustomerStatisticsVO">
select *
from customer_statistics_data
where tag_id = #{tagId}
where tag_id = #{tagId} and corp_id = #{corpId}
</select>
<!-- 查询客户统计数据列表 -->
@ -14,6 +14,7 @@
SELECT *
FROM customer_statistics_data
<where>
corp_id = #{corpId}
<if test="startDate != null">
AND cur_date &gt;= #{startDate}
</if>
@ -33,6 +34,7 @@
*
FROM customer_statistics_data
<where>
corp_id = #{corpId}
<if test="startDate != null">
AND cur_date &gt;= #{startDate}
</if>

View File

@ -6,7 +6,7 @@
<select id="selectByDate" resultType="com.ruoyi.excel.wecom.domain.DepartmentStatisticsData">
SELECT *
FROM department_statistics_data
WHERE stat_date = #{date}
WHERE corp_id = #{corpId} and stat_date = #{date}
ORDER BY department_path, sort_no
</select>
@ -14,7 +14,7 @@
<select id="selectByDepartmentAndDateRange" resultType="com.ruoyi.excel.wecom.domain.DepartmentStatisticsData">
SELECT *
FROM department_statistics_data
WHERE department_path = #{departmentPath}
WHERE corp_id = #{corpId} and department_path = #{departmentPath}
<if test="startDate != null">
AND stat_date &gt;= #{startDate}
</if>
@ -30,7 +30,7 @@
SUM(daily_total_accepted) as total_value,
COUNT(*) as record_count
FROM department_statistics_data
WHERE department_path = #{departmentPath}
WHERE corp_id = #{corpId} and department_path = #{departmentPath}
</select>
<!-- 查询指定部门的历史累计数据(总成单数) -->
@ -39,7 +39,7 @@
SUM(daily_total_orders) as total_value,
COUNT(*) as record_count
FROM department_statistics_data
WHERE department_path = #{departmentPath}
WHERE corp_id = #{corpId} and department_path = #{departmentPath}
</select>
<!-- 查询部门统计数据VO列表(用于导出) -->
@ -55,6 +55,7 @@
sort_no as sortNo
FROM department_statistics_data
<where>
corp_id = #{corpId} and
<if test="startDate != null">
AND stat_date &gt;= #{startDate}
</if>
@ -80,6 +81,7 @@
sort_no as sortNo
FROM department_statistics_data
<where>
corp_id = #{corpId} and
<if test="startDate != null">
AND stat_date &gt;= #{startDate}
</if>
@ -98,6 +100,7 @@
sum(ifnull(daily_total_accepted,0)+ifnull(manager_accepted,0)) as totalIns
from department_statistics_data
<where>
corp_id = #{corpId}
<if test="startDate != null">
AND stat_date &gt;= #{startDate}
</if>

View File

@ -4,10 +4,11 @@
<resultMap id="BaseResultMap" type="com.ruoyi.excel.wecom.domain.WecomTagGroupDomain">
<id column="id" property="id" />
<result column="corp_id" property="corpId" />
<result column="tag_group_id" property="tagGroupId" />
<result column="name" property="name" />
<result column="create_time" property="createTime" />
<result column="order_no" property="order" />
<result column="order_no" property="orderNo" />
<result column="sync_time" property="syncTime" />
</resultMap>
@ -20,7 +21,7 @@
select
<include refid="Base_Column_List" />
from wecom_tag_group
where tag_group_id = #{tagGroupId}
where corp_id = #{corpId} and tag_group_id = #{tagGroupId}
</select>
</mapper>

View File

@ -4,11 +4,12 @@
<resultMap id="BaseResultMap" type="com.ruoyi.excel.wecom.domain.WecomTagDomain">
<id column="id" property="id" />
<result column="corp_id" property="corpId" />
<result column="tag_id" property="tagId" />
<result column="tag_group_id" property="tagGroupId" />
<result column="name" property="name" />
<result column="create_time" property="createTime" />
<result column="order" property="order" />
<result column="order_no" property="orderNo" />
<result column="sync_time" property="syncTime" />
</resultMap>
@ -21,7 +22,7 @@
select
<include refid="Base_Column_List" />
from wecom_tag
where tag_id = #{tagId}
where corp_id = #{corpId} and tag_id = #{tagId}
</select>
</mapper>

View File

@ -0,0 +1,124 @@
package com.ruoyi.web.controller.wocom;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.excel.wecom.domain.CorpInfo;
import com.ruoyi.excel.wecom.service.ICorpInfoService;
import com.ruoyi.common.utils.CorpContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 企业信息Controller
*/
@RestController
@RequestMapping("/wecom/corp")
public class CorpInfoController extends BaseController {
@Autowired
private ICorpInfoService corpInfoService;
/**
* 查询企业信息列表
*/
@PreAuthorize("@ss.hasPermi('wecom:corp:list')")
@GetMapping("/list")
public TableDataInfo list(CorpInfo corpInfo) {
startPage();
List<CorpInfo> list = corpInfoService.selectCorpInfoList(corpInfo);
return getDataTable(list);
}
/**
* 获取企业信息详细信息
*/
@PreAuthorize("@ss.hasPermi('wecom:corp:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(corpInfoService.selectCorpInfoById(id));
}
/**
* 新增企业信息
*/
@PreAuthorize("@ss.hasPermi('wecom:corp:add')")
@Log(title = "企业信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody CorpInfo corpInfo) {
return toAjax(corpInfoService.insertCorpInfo(corpInfo));
}
/**
* 修改企业信息
*/
@PreAuthorize("@ss.hasPermi('wecom:corp:edit')")
@Log(title = "企业信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody CorpInfo corpInfo) {
return toAjax(corpInfoService.updateCorpInfo(corpInfo));
}
/**
* 删除企业信息
*/
@PreAuthorize("@ss.hasPermi('wecom:corp:remove')")
@Log(title = "企业信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(corpInfoService.deleteCorpInfoByIds(ids));
}
/**
* 切换当前使用的企业
*/
@PostMapping("/switch/{corpId}")
public AjaxResult switchCorp(@PathVariable("corpId") String corpId) {
// 1. 验证企业是否存在
CorpInfo corpInfo = corpInfoService.selectCorpInfoByCorpId(corpId);
if (corpInfo == null) {
return error("企业不存在");
}
// 2. 设置当前企业到 Redis
CorpContextHolder.setCurrentCorpId(corpId);
return success("切换企业成功");
}
/**
* 获取当前使用的企业信息
*/
@GetMapping("/current")
public AjaxResult getCurrentCorp() {
try {
// 1. Redis 获取当前企业ID
String corpId = CorpContextHolder.getCurrentCorpId();
// 2. 查询企业信息
CorpInfo corpInfo = corpInfoService.selectCorpInfoByCorpId(corpId);
if (corpInfo == null) {
return error("当前企业不存在,请重新切换");
}
return success(corpInfo);
} catch (RuntimeException e) {
return error(e.getMessage());
}
}
/**
* 清除当前企业上下文
*/
@PostMapping("/clear")
public AjaxResult clearCurrentCorp() {
CorpContextHolder.clear();
return success("清除成功");
}
}

View File

@ -5,6 +5,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.CorpContextHolder;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.excel.wecom.domain.CustomerContactData;
import com.ruoyi.excel.wecom.service.ICustomerContactDataService;
@ -37,8 +38,9 @@ public class CustomerContactDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "userid", required = false) String userid) {
String corpId = CorpContextHolder.getCurrentCorpId();
startPage();
List<CustomerContactData> list = customerContactDataService.selectCustomerContactDataList(startDate, endDate, userid);
List<CustomerContactData> list = customerContactDataService.selectCustomerContactDataList(corpId,startDate, endDate, userid);
return getDataTable(list);
}
@ -52,7 +54,8 @@ public class CustomerContactDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "userid", required = false) String userid) {
List<CustomerContactDataVO> list = customerContactDataService.selectCustomerContactDataVOList(startDate, endDate, userid);
String corpId = CorpContextHolder.getCurrentCorpId();
List<CustomerContactDataVO> list = customerContactDataService.selectCustomerContactDataVOList(corpId,startDate, endDate, userid);
ExcelUtil<CustomerContactDataVO> util = new ExcelUtil<>(CustomerContactDataVO.class);
util.exportExcel(response, list, "客户联系统计数据");
}
@ -66,16 +69,6 @@ public class CustomerContactDataController extends BaseController {
return success(customerContactDataService.selectCustomerContactDataById(id));
}
/**
* 新增客户联系统计数据
*/
@PreAuthorize("@ss.hasPermi('wecom:customerContact:add')")
@Log(title = "客户联系统计数据", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody CustomerContactData customerContactData) {
return toAjax(customerContactDataService.insertCustomerContactData(customerContactData));
}
/**
* 修改客户联系统计数据
*/

View File

@ -4,6 +4,7 @@ import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.CorpContextHolder;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.excel.wecom.domain.CustomerExportData;
import com.ruoyi.excel.wecom.service.ICustomerExportDataService;
@ -36,8 +37,10 @@ public class CustomerExportDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "customerName", required = false) String customerName) {
String corpId = CorpContextHolder.getCurrentCorpId();
startPage();
List<CustomerExportData> list = customerExportDataService.selectCustomerExportDataList(startDate, endDate, customerName);
List<CustomerExportData> list = customerExportDataService.selectCustomerExportDataList(corpId,startDate, endDate, customerName);
return getDataTable(list);
}
@ -51,7 +54,9 @@ public class CustomerExportDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "customerName", required = false) String customerName) {
List<CustomerExportDataVO> list = customerExportDataService.selectCustomerExportDataVOList(startDate, endDate, customerName);
String corpId = CorpContextHolder.getCurrentCorpId();
List<CustomerExportDataVO> list = customerExportDataService.selectCustomerExportDataVOList(corpId,startDate, endDate, customerName);
ExcelUtil<CustomerExportDataVO> util = new ExcelUtil<>(CustomerExportDataVO.class);
util.exportExcel(response, list, "客户统计数据");
}

View File

@ -5,6 +5,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.CorpContextHolder;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.excel.wecom.domain.CustomerStatisticsData;
import com.ruoyi.excel.wecom.service.ICustomerStatisticsDataService;
@ -38,8 +39,10 @@ public class CustomerStatisticsDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "indicatorName", required = false) String indicatorName) {
String corpId = CorpContextHolder.getCurrentCorpId();
startPage();
List<CustomerStatisticsData> list = customerStatisticsDataService.selectCustomerStatisticsDataList(startDate, endDate, indicatorName);
List<CustomerStatisticsData> list = customerStatisticsDataService.selectCustomerStatisticsDataList(corpId,startDate, endDate, indicatorName);
return getDataTable(list);
}
@ -53,7 +56,9 @@ public class CustomerStatisticsDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "indicatorName", required = false) String indicatorName) {
List<CustomerStatisticsDataVO> list = customerStatisticsDataService.selectCustomerStatisticsDataVOList(startDate, endDate, indicatorName);
String corpId = CorpContextHolder.getCurrentCorpId();
List<CustomerStatisticsDataVO> list = customerStatisticsDataService.selectCustomerStatisticsDataVOList(corpId,startDate, endDate, indicatorName);
ExcelUtil<CustomerStatisticsDataVO> util = new ExcelUtil<>(CustomerStatisticsDataVO.class);
util.exportExcel(response, list, "流量看板数据");
}
@ -77,8 +82,8 @@ public class CustomerStatisticsDataController extends BaseController {
public AjaxResult edit(@RequestParam(value = "curDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date curDate,
@RequestParam(value = "totalCost")BigDecimal totalCost,
@RequestParam(value = "attr")String attr) {
return toAjax(customerStatisticsDataService.updateCost(curDate,totalCost,attr));
String corpId = CorpContextHolder.getCurrentCorpId();
return toAjax(customerStatisticsDataService.updateCost(corpId,curDate,totalCost,attr));
}
}

View File

@ -5,6 +5,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.CorpContextHolder;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.excel.wecom.domain.DepartmentStatisticsData;
import com.ruoyi.excel.wecom.service.IDepartmentStatisticsDataService;
@ -40,8 +41,10 @@ public class DepartmentStatisticsDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "departmentPath", required = false) String departmentPath) {
String corpId = CorpContextHolder.getCurrentCorpId();
startPage();
List<DepartmentStatisticsData> list = departmentStatisticsDataService.selectDepartmentStatisticsDataList(startDate, endDate, departmentPath);
List<DepartmentStatisticsData> list = departmentStatisticsDataService.selectDepartmentStatisticsDataList(corpId,startDate, endDate, departmentPath);
return getDataTable(list);
}
@ -55,7 +58,9 @@ public class DepartmentStatisticsDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "departmentPath", required = false) String departmentPath) {
List<DepartmentStatisticsDataVO> list = departmentStatisticsDataService.selectDepartmentStatisticsDataVOList(startDate, endDate, departmentPath);
String corpId = CorpContextHolder.getCurrentCorpId();
List<DepartmentStatisticsDataVO> list = departmentStatisticsDataService.selectDepartmentStatisticsDataVOList(corpId,startDate, endDate, departmentPath);
ExcelUtil<DepartmentStatisticsDataVO> util = new ExcelUtil<>(DepartmentStatisticsDataVO.class);
util.exportExcel(response, list, "销售看板数据");
}
@ -79,8 +84,9 @@ public class DepartmentStatisticsDataController extends BaseController {
@RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(value = "departmentPath", required = false) String departmentPath) {
String corpId = CorpContextHolder.getCurrentCorpId();
Map<String, BigDecimal> map = departmentStatisticsDataService.getSummary(startDate, endDate, departmentPath);
Map<String, BigDecimal> map = departmentStatisticsDataService.getSummary(corpId,startDate, endDate, departmentPath);
BigDecimal totalOrders = map.get("totalOrders");
BigDecimal totalIns = map.get("totalIns");
if(totalOrders == null) {

View File

@ -4,6 +4,8 @@ import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.CorpContextHolder;
import com.ruoyi.excel.wecom.domain.CorpDepartment;
import com.ruoyi.excel.wecom.domain.CorpUser;
import com.ruoyi.excel.wecom.helper.HandleAllData;
@ -13,7 +15,6 @@ import com.ruoyi.excel.wecom.mapper.DepartmentStatisticsDataMapper;
import com.ruoyi.excel.wecom.model.WecomConfig;
import com.ruoyi.excel.wecom.model.WecomCustomer;
import com.ruoyi.excel.wecom.model.WecomTagGroup;
import com.ruoyi.excel.wecom.service.CustomerExportService;
import com.ruoyi.excel.wecom.service.WecomContactService;
import com.ruoyi.excel.wecom.service.WecomTagService;
import com.ruoyi.excel.wecom.vo.CustomerExportDataVO;
@ -43,9 +44,6 @@ public class WecomContactController {
@Autowired
private HandleAllData handleAllData;
@Autowired
private CustomerExportService customerExportService;
@Autowired
private CustomerExportDataMapper customerExportDataMapper;
@ -54,6 +52,9 @@ public class WecomContactController {
@Autowired
private CustomerStatisticsDataMapper customerStatisticsDataMapper;
@Autowired
private RedisCache redisCache;
/**
* 获取配置了客户联系功能的成员列表
*
@ -63,9 +64,11 @@ public class WecomContactController {
@GetMapping("/followUserList")
public AjaxResult getFollowUserList(HttpServletRequest request) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
List<String> userList = contactService.getFollowUserList();
List<String> userList = contactService.getFollowUserList(currentCorpId);
return AjaxResult.success("获取成功", userList);
} catch (IOException e) {
return AjaxResult.error("获取失败: " + e.getMessage());
@ -84,9 +87,11 @@ public class WecomContactController {
@GetMapping("/externalContactList")
public AjaxResult getExternalContactList(HttpServletRequest request, @RequestParam String userid) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
List<String> customerList = contactService.getExternalContactList(userid);
List<String> customerList = contactService.getExternalContactList(currentCorpId,userid);
return AjaxResult.success("获取成功", customerList);
} catch (IOException e) {
return AjaxResult.error("获取失败: " + e.getMessage());
@ -104,9 +109,11 @@ public class WecomContactController {
@GetMapping("/allMembersCustomers")
public AjaxResult getAllMembersCustomers(HttpServletRequest request) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
List<WecomContactService.MemberCustomer> memberCustomerList = contactService.getAllMembersCustomers();
List<WecomContactService.MemberCustomer> memberCustomerList = contactService.getAllMembersCustomers(currentCorpId);
return AjaxResult.success("获取成功", memberCustomerList);
} catch (IOException e) {
return AjaxResult.error("获取失败: " + e.getMessage());
@ -124,11 +131,13 @@ public class WecomContactController {
@PostMapping("/batchCustomerDetails")
public AjaxResult batchGetCustomerDetails(HttpServletRequest request, @RequestBody List<String> useridList) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
// 解析成员ID列表
List<WecomCustomer> customerList = contactService.batchGetAllCustomerDetails(useridList);
List<WecomCustomer> customerList = contactService.batchGetAllCustomerDetails(currentCorpId,useridList);
return AjaxResult.success("获取成功", customerList);
} catch (IOException e) {
@ -148,9 +157,10 @@ public class WecomContactController {
@GetMapping("/customerDetail")
public AjaxResult getCustomerDetail(HttpServletRequest request, @RequestParam String externalUserid) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
WecomCustomer customer = contactService.getCustomerDetail(externalUserid);
WecomCustomer customer = contactService.getCustomerDetail(currentCorpId, externalUserid);
return AjaxResult.success("获取成功", customer);
} catch (IOException e) {
return AjaxResult.error("获取失败: " + e.getMessage());
@ -168,9 +178,11 @@ public class WecomContactController {
@GetMapping("/corpTagList")
public AjaxResult getCorpTagList(HttpServletRequest request) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
List<WecomTagGroup> tagGroupList = contactService.getCorpTagList();
List<WecomTagGroup> tagGroupList = contactService.getCorpTagList(currentCorpId);
// 同步标签库到数据库
boolean syncResult = wecomTagService.syncCorpTagList(tagGroupList);
@ -209,9 +221,11 @@ public class WecomContactController {
@GetMapping("/departmentList")
public AjaxResult getDepartmentList(HttpServletRequest request, @RequestParam(required = false) Long departmentId) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
List<CorpDepartment> deptIdList = contactService.getDepartmentList(departmentId);
List<CorpDepartment> deptIdList = contactService.getDepartmentList(currentCorpId,departmentId);
return AjaxResult.success("获取成功", deptIdList);
} catch (IOException e) {
return AjaxResult.error("获取失败: " + e.getMessage());
@ -230,9 +244,11 @@ public class WecomContactController {
@GetMapping("/departmentDetail")
public AjaxResult getDepartmentDetail(HttpServletRequest request, @RequestParam Long departmentId) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
Object deptDetail = contactService.getDepartmentDetail(departmentId);
Object deptDetail = contactService.getDepartmentDetail(currentCorpId,departmentId);
return AjaxResult.success("获取成功", deptDetail);
} catch (IOException e) {
return AjaxResult.error("获取失败: " + e.getMessage());
@ -255,9 +271,11 @@ public class WecomContactController {
@RequestParam(required = false) Integer fetchChild,
@RequestParam(required = false) Integer status) {
try {
String currentCorpId = CorpContextHolder.getCurrentCorpId();
WecomConfig config = getWecomConfig(request);
WecomContactService contactService = new WecomContactService(config);
List<CorpUser> memberList = contactService.getDepartmentMemberList(departmentId, fetchChild, status);
List<CorpUser> memberList = contactService.getDepartmentMemberList(currentCorpId,departmentId, fetchChild, status);
return AjaxResult.success("获取成功", memberList);
} catch (IOException e) {
return AjaxResult.error("获取失败: " + e.getMessage());
@ -268,32 +286,87 @@ public class WecomContactController {
@GetMapping("/init")
public AjaxResult init(HttpServletRequest request) throws IOException {
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
return AjaxResult.error("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
try {
handleAllData.initData();
return AjaxResult.success();
} finally {
CorpContextHolder.clear();
}
}
@GetMapping("/test")
public AjaxResult test(HttpServletRequest request) throws IOException {
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
return AjaxResult.error("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
try {
handleAllData.handleAllData();
return AjaxResult.success();
} finally {
CorpContextHolder.clear();
}
}
@GetMapping("/createAllReportData")
public AjaxResult createAllReportData(HttpServletRequest request) throws IOException {
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
return AjaxResult.error("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
try {
handleAllData.createAllReportData();
return AjaxResult.success();
} finally {
CorpContextHolder.clear();
}
}
@GetMapping("/createAllDepartmentReportData")
public AjaxResult createAllDepartmentReportData(HttpServletRequest request) throws IOException {
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
return AjaxResult.error("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
try {
handleAllData.createAllDepartmentReportData();
return AjaxResult.success();
} finally {
CorpContextHolder.clear();
}
}
@GetMapping("/createAllDepartmentReportByDate")
public AjaxResult createAllDepartmentReportByDate(@RequestParam(value = "date", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date date) throws IOException {
handleAllData.createDepartmentReportData(date);
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
return AjaxResult.error("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
try {
handleAllData.createDepartmentReportData(corpId,date);
return AjaxResult.success();
} finally {
CorpContextHolder.clear();
}
}
/**
@ -309,6 +382,13 @@ public class WecomContactController {
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
try {
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
throw new RuntimeException("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
@ -320,7 +400,7 @@ public class WecomContactController {
WriteSheet writeSheet = EasyExcel.writerSheet("客户数据").build();
// 分批查询并写入,避免内存溢出
List<CustomerExportDataVO> dataList = customerExportDataMapper.selectCustomerExportDataVOList(startDate, endDate,null);
List<CustomerExportDataVO> dataList = customerExportDataMapper.selectCustomerExportDataVOList(corpId,startDate, endDate,null);
excelWriter.write(dataList, writeSheet);
excelWriter.finish();
@ -333,6 +413,8 @@ public class WecomContactController {
} catch (IOException ioException) {
ioException.printStackTrace();
}
} finally {
CorpContextHolder.clear();
}
}
@ -351,6 +433,13 @@ public class WecomContactController {
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(required = false) String indicatorName) {
try {
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
throw new RuntimeException("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
@ -362,7 +451,7 @@ public class WecomContactController {
WriteSheet writeSheet = EasyExcel.writerSheet("流量看板统计数据").build();
// 分批查询并写入,避免内存溢出
List<CustomerStatisticsDataVO> dataList = customerStatisticsDataMapper.selectCustomerStatisticsDataVOList(
List<CustomerStatisticsDataVO> dataList = customerStatisticsDataMapper.selectCustomerStatisticsDataVOList(corpId,
startDate, endDate, indicatorName);
excelWriter.write(dataList, writeSheet);
excelWriter.finish();
@ -376,6 +465,8 @@ public class WecomContactController {
} catch (IOException ioException) {
ioException.printStackTrace();
}
} finally {
CorpContextHolder.clear();
}
}
@ -394,6 +485,13 @@ public class WecomContactController {
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
@RequestParam(required = false) String departmentPath) {
try {
// Redis 获取当前企业ID并设置到上下文
String corpId = redisCache.getCacheObject("current_corp_id");
if (corpId == null || corpId.trim().isEmpty()) {
throw new RuntimeException("未找到当前企业ID请先切换企业");
}
CorpContextHolder.setCurrentCorpId(corpId);
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
@ -405,7 +503,7 @@ public class WecomContactController {
WriteSheet writeSheet = EasyExcel.writerSheet("部门统计数据").build();
// 分批查询并写入,避免内存溢出
List<DepartmentStatisticsDataVO> dataList = departmentStatisticsDataMapper.selectDepartmentStatisticsDataVOList(
List<DepartmentStatisticsDataVO> dataList = departmentStatisticsDataMapper.selectDepartmentStatisticsDataVOList(corpId,
startDate, endDate, departmentPath);
excelWriter.write(dataList, writeSheet);
excelWriter.finish();
@ -419,6 +517,8 @@ public class WecomContactController {
} catch (IOException ioException) {
ioException.printStackTrace();
}
} finally {
CorpContextHolder.clear();
}
}

View File

@ -2,6 +2,7 @@ package com.ruoyi.web.controller.wocom;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.CorpContextHolder;
import com.ruoyi.excel.wecom.service.WecomContactService;
import com.ruoyi.excel.wecom.service.WecomStatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
@ -33,7 +34,8 @@ public class WecomStatisticsController {
@PostMapping("/customer/{date}")
public AjaxResult getCustomerStatistics(@PathVariable("date") String date, @RequestParam(value = "useridList", required = false) List<String> useridList) {
try {
JSONObject statisticsData = wecomContactService.getDayUserBehaviorData(date, useridList);
String corpId = CorpContextHolder.getCurrentCorpId();
JSONObject statisticsData = wecomContactService.getDayUserBehaviorData(corpId,date, useridList);
return AjaxResult.success("获取联系客户统计数据成功", statisticsData);
} catch (IOException e) {
e.printStackTrace();
@ -51,13 +53,15 @@ public class WecomStatisticsController {
@PostMapping("/customer/{date}/save")
public AjaxResult saveCustomerStatistics(@PathVariable("date") String date, @RequestParam(value = "useridList", required = false) List<String> useridList) {
try {
JSONObject statisticsData = wecomContactService.getDayUserBehaviorData(date, useridList);
String corpId = CorpContextHolder.getCurrentCorpId();
JSONObject statisticsData = wecomContactService.getDayUserBehaviorData(corpId,date, useridList);
// 存储汇总统计数据
int summaryCount = wecomStatisticsService.handleAndSaveCustomerStatistics(date, statisticsData);
int summaryCount = wecomStatisticsService.handleAndSaveCustomerStatistics(corpId,date, statisticsData);
// 存储详细联系统计数据
int contactCount = wecomStatisticsService.handleAndSaveCustomerContactData(statisticsData);
int contactCount = wecomStatisticsService.handleAndSaveCustomerContactData(corpId,statisticsData);
return AjaxResult.success("获取并存储联系客户统计数据成功,共处理 " + summaryCount + " 条汇总数据," + contactCount + " 条详细数据", statisticsData);
} catch (IOException e) {

View File

@ -0,0 +1,83 @@
package com.ruoyi.common.utils;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.spring.SpringUtils;
/**
* 企业上下文持有者
* 用于获取当前用户正在使用的企业ID
*/
public class CorpContextHolder {
/**
* Redis key 前缀current_corp:{userId}
*/
private static final String CURRENT_CORP_KEY_PREFIX = "current_corp:";
/**
* 获取当前用户正在使用的企业ID
*
* @return 企业ID (corpId)
* @throws RuntimeException 如果未设置当前企业
*/
public static String getCurrentCorpId() {
// 1. 获取当前登录用户ID
Long userId = SecurityUtils.getUserId();
// 2. Redis 获取该用户当前使用的企业ID
RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
String key = CURRENT_CORP_KEY_PREFIX + userId;
String corpId = redisCache.getCacheObject(key);
if (corpId == null || corpId.trim().isEmpty()) {
throw new RuntimeException("未设置当前使用的企业,请先切换企业");
}
return corpId;
}
/**
* 设置当前用户正在使用的企业ID
*
* @param corpId 企业ID
*/
public static void setCurrentCorpId(String corpId) {
// 1. 获取当前登录用户ID
Long userId = SecurityUtils.getUserId();
// 2. 将企业ID存入 Redis
RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
String key = CURRENT_CORP_KEY_PREFIX + userId;
redisCache.setCacheObject(key, corpId);
}
/**
* 清除当前用户的企业上下文
*/
public static void clear() {
// 1. 获取当前登录用户ID
Long userId = SecurityUtils.getUserId();
// 2. Redis 删除
RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
String key = CURRENT_CORP_KEY_PREFIX + userId;
redisCache.deleteObject(key);
}
/**
* 检查当前用户是否已设置企业
*
* @return true-已设置false-未设置
*/
public static boolean hasCurrentCorp() {
try {
Long userId = SecurityUtils.getUserId();
RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
String key = CURRENT_CORP_KEY_PREFIX + userId;
String corpId = redisCache.getCacheObject(key);
return corpId != null && !corpId.trim().isEmpty();
} catch (Exception e) {
return false;
}
}
}

View File

@ -1,6 +1,9 @@
package com.ruoyi.framework.config;
import java.util.concurrent.TimeUnit;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.framework.interceptor.CorpContextInterceptor;
import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -11,9 +14,8 @@ import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
import java.util.concurrent.TimeUnit;
/**
* 通用配置
@ -26,6 +28,9 @@ public class ResourcesConfig implements WebMvcConfigurer
@Autowired
private RepeatSubmitInterceptor repeatSubmitInterceptor;
@Autowired
private CorpContextInterceptor corpContextInterceptor;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
@ -45,6 +50,9 @@ public class ResourcesConfig implements WebMvcConfigurer
@Override
public void addInterceptors(InterceptorRegistry registry)
{
// 企业上下文拦截器用于设置当前企业ID到ThreadLocal
registry.addInterceptor(corpContextInterceptor).addPathPatterns("/**");
// 防重复提交拦截器
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
}

View File

@ -0,0 +1,41 @@
package com.ruoyi.framework.interceptor;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.CorpContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 企业上下文拦截器
* 在请求处理前从 Redis 获取当前企业ID并设置到 ThreadLocal
* 在请求处理后清理 ThreadLocal
*/
@Component
public class CorpContextInterceptor implements HandlerInterceptor {
@Autowired
private RedisCache redisCache;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Redis 获取当前企业ID
String corpId = redisCache.getCacheObject("current_corp_id");
// 如果存在企业ID设置到 ThreadLocal
if (corpId != null && !corpId.trim().isEmpty()) {
CorpContextHolder.setCurrentCorpId(corpId);
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 请求完成后清理 ThreadLocal避免内存泄漏
CorpContextHolder.clear();
}
}

View File

@ -1,17 +1,22 @@
package com.ruoyi.quartz.task;
import com.ruoyi.excel.wecom.domain.CorpInfo;
import com.ruoyi.excel.wecom.helper.HandleAllData;
import com.ruoyi.excel.wecom.mapper.CorpInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Component("wecomTask")
public class WeComTask {
@Autowired
private HandleAllData handleAllData;
@Autowired
private CorpInfoMapper corpInfoMapper;
public void initData() throws IOException {
System.out.println("初始化项目数据 包括 部门 人员");
handleAllData.initData();
@ -37,7 +42,10 @@ public class WeComTask {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = simpleDateFormat.format(date);
System.out.println("计算" + dateStr + "流量看板数据");
handleAllData.createReportData(new Date(dateStr));
List<CorpInfo> corpInfos = corpInfoMapper.selectCorpInfoList(new CorpInfo());
corpInfos.forEach(item->{
handleAllData.createReportData(item.getCorpId(),new Date(dateStr));
});
}
public void createCurDateDepartmentReportData() throws IOException {
@ -45,6 +53,9 @@ public class WeComTask {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = simpleDateFormat.format(date);
System.out.println("计算" + dateStr + "销售看板数据");
handleAllData.createDepartmentReportData(new Date(simpleDateFormat.format(date)));
List<CorpInfo> corpInfos = corpInfoMapper.selectCorpInfoList(new CorpInfo());
corpInfos.forEach(item->{
handleAllData.createDepartmentReportData(item.getCorpId(),new Date(dateStr));
});
}
}

Binary file not shown.

View File

@ -12,14 +12,6 @@
<template v-if="device!=='mobile'">
<search id="header-search" class="right-menu-item" />
<el-tooltip content="源码地址" effect="dark" placement="bottom">
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
</el-tooltip>
<el-tooltip content="文档地址" effect="dark" placement="bottom">
<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
</el-tooltip>
<screenfull id="screenfull" class="right-menu-item hover-effect" />
<el-tooltip content="布局大小" effect="dark" placement="bottom">

View File

@ -166,7 +166,7 @@ export default {
handleExport() {
this.download('/wecom/customerExport/export', {
...this.queryParams
}, `客户导出数据_${new Date().getTime()}.xlsx`)
}, `客户列表数据_${new Date().getTime()}.xlsx`)
}
}
}

View File

@ -308,9 +308,11 @@ export default {
},
/** 导出按钮操作 */
handleExport() {
const formattedDate = this.parseTime(new Date(), '{y}-{m}-{d}');
this.download('/wecom/customerStatistics/export', {
...this.queryParams
}, `客户统计数据_${new Date().getTime()}.xlsx`)
}, `流量看板数据_${formattedDate}.xlsx`)
},
/** 处理成本更新 */
handleUpdateCost(date, cost, attr) {

View File

@ -162,11 +162,13 @@ export default {
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 导出按钮操作 */
handleExport() {
const formattedDate = this.parseTime(new Date(), '{y}-{m}-{d}');
this.download('/wecom/departmentStatistics/export', {
...this.queryParams
}, `部门统计数据_${new Date().getTime()}.xlsx`)
}, `销售看板数据_${formattedDate}.xlsx`)
}
}
}