提交 8a23a94c 作者: duanxincheng

纪要生成服务优化

父级 0a34c27f
......@@ -31,6 +31,7 @@
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatis-plus.version>3.3.0</mybatis-plus.version>
</properties>
<dependencyManagement>
<dependencies>
......@@ -246,11 +247,11 @@
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version> <!-- 请使用最新版本 -->
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>2.3.0</version> &lt;!&ndash; 请使用最新版本 &ndash;&gt;-->
<!-- </dependency>-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
......@@ -293,10 +294,11 @@
</dependency>
<!-- Word 文档操作 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.2</version>
</dependency>
......@@ -305,6 +307,12 @@
<artifactId>commonmark</artifactId>
<version>0.17.1</version> <!-- 可升级至最新稳定版 -->
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
......
......@@ -431,17 +431,17 @@ public class TencentMeetingCallbackController {
Thread.sleep(10000);
EmailSender emailSender = new EmailSender();
//response.getRawBody()
boolean mailFlag = emailSender.sendEmailWithAttachment(emailAddress,
targetPath,
"重要文件",
"您好:\n" +
"\n" +
" 附件为您本次会议的会议纪要,烦请下载查看,如需对会议纪要结果进行修改或查看历史会议,可点击下方链接。");
if (mailFlag) {
logger.info("邮件发送成功");
} else {
logger.error("邮件发送失败");
}
// boolean mailFlag = emailSender.sendEmailWithAttachment(emailAddress,
// targetPath,
// "重要文件",
// "您好:\n" +
// "\n" +
// " 附件为您本次会议的会议纪要,烦请下载查看,如需对会议纪要结果进行修改或查看历史会议,可点击下方链接。");
// if (mailFlag) {
// logger.info("邮件发送成功");
// } else {
// logger.error("邮件发送失败");
// }
}
} catch (Exception e) {
logger.error("下载文件时出错: {}", e.getMessage());
......
package com.cmeeting.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@Slf4j
public class ThreadPoolConfig {
@Bean("fileProcessExecutor")
public ThreadPoolTaskExecutor fileProcessExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数 (CPU密集型任务建议核心数+1)
executor.setCorePoolSize(4); // 固定核心线程数,避免动态获取CPU核心数
// 最大线程数
executor.setMaxPoolSize(4);
// 队列容量
executor.setQueueCapacity(1000);
// 线程名前缀
executor.setThreadNamePrefix("file-process-");
// 明确设置所有必要属性
executor.setAllowCoreThreadTimeOut(false); // 核心线程不允许超时
executor.setWaitForTasksToCompleteOnShutdown(true); // 优雅关闭
executor.setAwaitTerminationSeconds(60); // 等待任务完成的最大时间
// 拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化前打印配置检查
log.info("Initializing ThreadPool: core={}, max={}",
executor.getCorePoolSize(),
executor.getMaxPoolSize());
executor.initialize();
return executor;
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package com.cmeeting.controller;
import com.cmeeting.pojo.TencentMeetingUser;
import com.cmeeting.service.TecentMeetingService;
import com.cmeeting.vo.TencentMeetingVO;
import com.tencentcloudapi.wemeet.Client;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -13,32 +14,18 @@ import java.util.List;
import static com.cmeeting.WeComAndTencentMeeting.*;
@RestController
@RequestMapping("/tecent")
@RequestMapping("/tencent")
public class TencentMeetingController {
@Autowired
private TecentMeetingService tecentMeetingService;
@GetMapping("/add")
public void addUsers() throws Exception {
dousers();
public void addUsers() {
tecentMeetingService.doUsers();
}
private void dousers() {
/**
* 腾讯会议通过通讯录获取员工信息
*/
// 1. 构造client客户端
Client client = new Client.Builder()
.withAppId("211153201").withSdkId("28370276340")
.withSecret("BKOMDZVbvh0iT7k6UHsSizAWBCOVDtT6", "3Y1j0mzNp7KChKFJGyaEnZHLobFoAQ8eLwfaMx8nLbtXAerO")
.build();
// 2.获取到全部用户
List<TencentMeetingUser> users = fetchUsersInBatches(client, 3);;
// 3. 检查重名并设置标志
markDuplicateNamesTecent(users);
// 4. 批量插入数据库
tecentMeetingService.batchInsert(users);
@GetMapping("/getMeetingFiles")
public void getMeetingFiles(TencentMeetingVO.TencentMeetingRequest requestVO){
tecentMeetingService.getMeetingFiles(requestVO);
}
}
......@@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.json.JSONObject;
import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
......@@ -33,9 +34,9 @@ import java.util.stream.Collectors;
@RestController
@RequestMapping
public class UnifiedController {
@Autowired
@Resource
private WeComUserMapper weComUserMapper;
@Autowired
@Resource
private TecentMeetingMapper tecentMeetingMapper;
@Autowired
private UserIdMapper userIdMapper;
......@@ -78,7 +79,7 @@ public class UnifiedController {
}
@GetMapping("/insertTid")
public void insertTid() {
public void insertTid(String corpid, String corpsecret) {
List<UserId> users = userIdMapper.getUsers();
List<UserId> usersWithNullTid = new ArrayList<>();
for (UserId user : users) {
......@@ -88,7 +89,7 @@ public class UnifiedController {
}
for (UserId user : usersWithNullTid) {
//获取企业微信token
String weComToken = getWeComToken();
String weComToken = getWeComToken(corpid,corpsecret);
try {
// 3.1 创建会议(传入用户的 wid)
Map<String, String> meetingCodeAndMeetingid = createMeeting(user.getWid(), weComToken);
......@@ -128,8 +129,8 @@ public class UnifiedController {
//todo 待测试
@GetMapping("/sameNameInsertTid")
public void sameNameInsertTid() throws IOException {
String weComToken = getWeComToken();
public void sameNameInsertTid(String corpid, String corpsecret) throws IOException {
String weComToken = getWeComToken(corpid,corpsecret);
List<WeComUser> sameNameUsers = weComUserMapper.getSameName();
List<UserId> userIds = new ArrayList<>();
for (WeComUser user : sameNameUsers) {
......@@ -269,9 +270,11 @@ public class UnifiedController {
*
* @return
*/
public String getWeComToken() {
@GetMapping("/getWeComToken")
public String getWeComToken(String corpid, String corpsecret) {
//获取token
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ww1fd8778458e9f1e8&corpsecret=uFRq9Xi8-dVY90LydXYBhjc91JnnfkPUR6lHDdeJ_fo";
// String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ww1fd8778458e9f1e8&corpsecret=uFRq9Xi8-dVY90LydXYBhjc91JnnfkPUR6lHDdeJ_fo";
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + corpsecret;
String accessToken = "";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
......
......@@ -23,73 +23,13 @@ import static com.cmeeting.WeComAndTencentMeeting.*;
@RestController
@RequestMapping("/wecom")
public class WeComcontroller {
private static final String BASE_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist";
private static final String ACCESS_TOKEN = "wyYAmCbeVIPvj_Gpdd8ixp_td_hPv2OtTU8gpTGSpB7TaftbpNps5fc_JdCRzpgy_tUv-aGueJpRV6XJeYAG-rqkzCfDV-rcpJbqB0LypjvJUtxPeTmPqEtQuCMwH6euGGVaJZXoc33ATrS70U0T4_4WIrATqpsN2Ed2XsNGyN5N6aG8mq6AyLMG9TokVWx1qd2qF1zVTwve6aqRMWHwXg";
//动态获取token
@Autowired
private WeComService weComService;
@GetMapping("/add")
public void addUsers() throws Exception {
dousers();
}
public void dousers() throws Exception {
// 示例:获取部门ID为6的用户列表
int departmentId = 6;
JsonObject result = getUserListByDepartment(departmentId);
// 处理返回结果
if (result.get("errcode").getAsInt() == 0) {
System.out.println("企微获取用户列表成功:");
JsonArray userList = result.getAsJsonArray("userlist");
for (int i = 0; i < userList.size(); i++) {
JsonObject user = userList.get(i).getAsJsonObject();
System.out.println("姓名: " + user.get("name").getAsString() +
", UserID: " + user.get("userid").getAsString());
}
// 2. 转换为WeComUser集合
List<WeComUser> users = convertJsonToWeComUsers(result);
// 3. 检查重名并设置标志
markDuplicateNames(users);
// 4. 批量插入数据库
weComService.batchInsert(users);
}
}
/**
* 根据企业微信部门ID获取用户列表
*
* @param departmentId 部门ID
* @return 包含用户列表的JsonObject
* @throws Exception
*/
public static JsonObject getUserListByDepartment(int departmentId) throws Exception {
String urlStr = BASE_URL + "?access_token=" + ACCESS_TOKEN + "&department_id=" + departmentId;
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// 使用Gson解析JSON响应
Gson gson = new Gson();
return gson.fromJson(response.toString(), JsonObject.class);
} else {
throw new RuntimeException("HTTP GET请求失败,错误码: " + responseCode);
}
weComService.doUsers();
}
......
package com.cmeeting.email;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
public class EmailSender {
// 发件人邮箱配置(建议从配置文件读取,此处写死示例)
private static final String FROM_EMAIL = "binzhai321@163.com";
private static final String AUTH_CODE = "RXbRu3AdrCxX57ib"; // 授权码
private static final String SMTP_HOST = "smtp.163.com";
private static final int SMTP_PORT = 465;
@Value("${email.sender}")
private String SENDER;
@Value("${email.sender.pwd}")
private String EMAIL_PWD;
@Value("${email.smtp.host}")
private String SMTP_HOST;
private static final Integer MAX_RETRY = 3;
/**
* 发送带附件的邮件
* @param toEmail 收件人邮箱
* @param filePath 附件本地路径(如 "C:/test.pdf")
* @param subject 邮件主题(可选,默认值)
* @param text 邮件正文(可选,默认值)
* @return true发送成功,false发送失败
* @param toEmail 收件人
* @param subject 邮件主题
* @param attachmentPath 附件路径
* @param recordFileId 转录文件ID
* @return
*/
public static boolean sendEmailWithAttachment(String toEmail, String filePath,
String subject, String text) {
// 1. 参数校验
if (toEmail == null || toEmail.isEmpty() || filePath == null) {
System.err.println("参数错误:收件人或附件路径为空");
return false;
}
// 2. 设置默认邮件主题和正文
String mailSubject = (subject != null) ? subject : "";
String mailText = (text != null) ? text : "请查收附件。";
// 3. 配置SMTP
public boolean sendEmailWithAttachment(String toEmail, String subject, String attachmentPath, String recordFileId) {
// 邮件服务器配置
Properties props = new Properties();
props.put("mail.smtp.host", SMTP_HOST);
props.put("mail.smtp.port", SMTP_PORT);
props.put("mail.smtp.host", "smtp.office365.com");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.enable", "true");
try {
// 4. 创建会话
Session session = Session.getInstance(props, new Authenticator() {
@Override
// props.put("mail.smtp.port", "465");
// props.put("mail.smtp.ssl.enable", "true"); // 使用SSL
props.put("mail.smtp.port", "587");
props.put("mail.smtp.starttls.enable", "true"); // 使用TLS
// 或者使用SSL
// props.put("mail.smtp.port", "465");
// props.put("mail.smtp.ssl.enable", "true");
// 创建会话
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(FROM_EMAIL, AUTH_CODE);
return new PasswordAuthentication("cmeeting_assistant@cimc.com", "scyou@xih45g6@xih4");
}
});
String body = "您好:\n" +
"\n" +
" 附件为您本次会议的会议纪要,烦请下载查看";
AtomicInteger retryCount = new AtomicInteger(0);
try {
boolean isSent = false;
while (retryCount.intValue() < MAX_RETRY && !isSent){
// 创建邮件消息
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("cmeeting_assistant@cimc.com"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(toEmail));
message.setSubject(subject);
// 5. 构建邮件内容
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(FROM_EMAIL));
message.setRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
message.setSubject(mailSubject);
// 创建消息体部分(正文)
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText(body);
// 6. 添加正文和附件
// 创建多部分消息
Multipart multipart = new MimeMultipart();
// 文本正文
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText(mailText);
multipart.addBodyPart(textPart);
// 添加文本部分
multipart.addBodyPart(messageBodyPart);
// 附件
// 添加附件部分
if (attachmentPath != null && !attachmentPath.isEmpty()) {
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(new File(filePath));
DataSource source = new FileDataSource(attachmentPath);
attachmentPart.setDataHandler(new DataHandler(source));
attachmentPart.setFileName(new File(attachmentPath).getName());
multipart.addBodyPart(attachmentPart);
}
// 设置完整消息内容
message.setContent(multipart);
// 7. 发送邮件
// 发送邮件
Transport.send(message);
System.out.println("邮件发送成功至: " + toEmail);
return true;
} catch (Exception e) {
System.err.println("邮件发送失败: " + e.getMessage());
return false;
log.error("邮件已成功发送: recordFileId->{}", recordFileId);
isSent = true;
}
} catch (MessagingException e) {
//todo 邮件失败记录
// 异常处理
retryCount.getAndIncrement();
if (retryCount.intValue() > MAX_RETRY) {
log.error("邮件发送达到最大重试次数: recordFileId->{}", recordFileId);
throw new RuntimeException(e);
}
/**
* 简化版调用(仅需收件人和附件路径)
*/
public static boolean sendEmailWithAttachment(String toEmail, String filePath) {
return sendEmailWithAttachment(toEmail, filePath, null, null);
// 指数退避
try {
Thread.sleep((long) Math.pow(2, retryCount.intValue()) * 1000);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("邮件发送重试失败", ie);
}
return false;
}
return true;
}
}
\ No newline at end of file
package com.cmeeting.mapper.primary;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cmeeting.pojo.TencentMeetingUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface TecentMeetingMapper {
public interface TecentMeetingMapper extends BaseMapper<TencentMeetingUser> {
void batchInsertUsers(@Param("userList") List<TencentMeetingUser> userList);
List<TencentMeetingUser> getAlluser();
}
package com.cmeeting.mapper.primary;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cmeeting.pojo.WeComUser;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface WeComUserMapper {
public interface WeComUserMapper extends BaseMapper<WeComUser> {
List<WeComUser> getSameName() ;
WeComUser selectById(Integer id);
void insert(WeComUser user);
int insert(WeComUser user);
List<WeComUser> getAlluser();
/**
* 批量插入用户
......
package com.cmeeting.pojo;
import lombok.Data;
@Data
public class TencentMeetingRecord {
/**
* 主键ID
*/
private Integer id;
/**
* 会议id
*/
private String meetingId;
/**
* 用户ID
*/
private String userId;
/**
* 是否是重名用户(1:重名, 0:不重名)
*/
private String isrepeatName;
}
package com.cmeeting.pojo;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import java.io.Serializable;
@Data
public class WeComUser {
public class WeComUser extends Model implements Serializable {
private Integer id;
private String userName;
private String userId;
private String isRepeatName;
private String email;
public WeComUser() {
}
public WeComUser(Integer id, String userName, String userId, String isRepeatName) {
......@@ -24,6 +29,7 @@ public class WeComUser {
", userName='" + userName + '\'' +
", userId='" + userId + '\'' +
", isRepeatName='" + isRepeatName + '\'' +
", email='" + email + '\'' +
'}';
}
}
package com.cmeeting.service;
import com.cmeeting.job.FileProcessTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class FileProcessCallbackHandler {
// 单个任务完成回调
public void onComplete(FileProcessTask task) {
// 可以记录任务状态、发送通知等
log.info("任务处理完成: {}", task.getRecordFileId());
// 更新数据库状态等
// taskRepository.updateStatus(task.getId(), "COMPLETED");
}
// 所有任务完成回调
public void onAllComplete() {
log.info("所有文件处理任务已完成");
// 可以发送全局通知等
}
}
\ No newline at end of file
package com.cmeeting.service;
import com.cmeeting.job.FileProcessTask;
import com.cmeeting.vo.TencentMeetingVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@Service
@Slf4j
public class FileProcessProducer {
@Autowired
private ThreadPoolTaskExecutor fileProcessExecutor;
@Autowired
private FileProcessCallbackHandler callbackHandler;
@Value(value = "${tencent.appId}")
private String tencentAppId;
@Value(value = "${tencent.sdkId}")
private String tencentSdkId;
@Value(value = "${tencent.secretId}")
private String tencentSecretId;
@Value(value = "${tencent.secretKey}")
private String tencentSecretKey;
@Value(value = "${tencent.admin.userId}")
private String tencentAdminUserId;
// 批量提交任务
public void submitBatchTasks(List<TencentMeetingVO.RecordFile> recordFiles, String baseSavePath) {
List<Future<?>> futures = new ArrayList<>();
for (TencentMeetingVO.RecordFile recordFile : recordFiles) {
// 为每个URL创建任务
FileProcessTask task = new FileProcessTask(
recordFile.getRecordFileId(),
recordFile.getMeetingId(),
recordFile.getSubMeetingId(),
"/save/",
Collections.emptyMap(),
tencentAppId,
tencentSdkId,
tencentSecretId,
tencentSecretKey,
tencentAdminUserId
);
// 提交任务到线程池
Future<?> future = fileProcessExecutor.submit(() -> {
task.process();
callbackHandler.onComplete(task); // 回调处理
});
futures.add(future);
}
// 可以添加一个监控线程来检查所有任务完成情况
monitorTaskCompletion(futures);
}
private void monitorTaskCompletion(List<Future<?>> futures) {
new Thread(() -> {
for (Future<?> future : futures) {
try {
future.get(); // 阻塞直到任务完成
} catch (InterruptedException | ExecutionException e) {
log.error("任务执行异常", e);
}
}
callbackHandler.onAllComplete(); // 所有任务完成回调
}).start();
}
}
\ No newline at end of file
package com.cmeeting.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cmeeting.pojo.TencentMeetingUser;
import com.cmeeting.vo.TencentMeetingVO;
import java.util.List;
public interface TecentMeetingService {
public interface TecentMeetingService extends IService<TencentMeetingUser> {
void batchInsert(List<TencentMeetingUser> users);
void doUsers();
List<TencentMeetingVO.RecordFile> getMeetingFiles(TencentMeetingVO.TencentMeetingRequest requestVO);
}
package com.cmeeting.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cmeeting.pojo.WeComUser;
import java.util.List;
public interface WeComService {
public interface WeComService extends IService<WeComUser> {
void batchInsert(List<WeComUser> users);
void doUsers() throws Exception;
String getToken();
}
package com.cmeeting.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmeeting.mapper.primary.WeComUserMapper;
import com.cmeeting.pojo.WeComUser;
import com.cmeeting.service.WeComService;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import static com.cmeeting.WeComAndTencentMeeting.convertJsonToWeComUsers;
import static com.cmeeting.WeComAndTencentMeeting.markDuplicateNames;
@Service
public class WeComServiceImpl implements WeComService {
@Autowired
public class WeComServiceImpl extends ServiceImpl<WeComUserMapper, WeComUser> implements WeComService {
private static final String BASE_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist";
private static final String ACCESS_TOKEN = "z8g0fkzlVBMKrwi67CRwE7gcnGqjOMrTK6LDih06vs1ixpV9BkrVWQJkoF3HFf5a2UrMvTKEBewOo7wPGvVxNjV_ZGOp_dUxTfnCG6kRUK9LKXPlhskGOI3mcI3ZZpGqpPcgjCsE877hh1BYTB_i3t5X_q1tZfv0K636o3a0HyAMf4GlzviCd1vQHfkGf3p15FjnATwDV8ddhMZo8U-_uA";
private static final String CORP_ID = "wx34544d057db97ffd";
private static final String CORP_SECRET = "7YLePWG7rJqkQFnAB4FeylqAXpmu7q5qv_NOeSGNbm0";
@Resource
private WeComUserMapper weComUserMapper;
@Override
public void batchInsert(List<WeComUser> users) {
weComUserMapper.batchInsert(users);
}
@Override
public void doUsers() throws Exception {
// 示例:获取部门ID为6的用户列表
int departmentId = 6;
JsonObject departmentList = getDepartmentList();
JsonObject result = getUserListByDepartment(departmentId);
// 处理返回结果
if (result.get("errcode").getAsInt() == 0) {
System.out.println("企微获取用户列表成功:");
JsonArray userList = result.getAsJsonArray("userlist");
for (int i = 0; i < userList.size(); i++) {
JsonObject user = userList.get(i).getAsJsonObject();
System.out.println("姓名: " + user.get("name").getAsString() +
", UserID: " + user.get("userid").getAsString());
}
// 2. 转换为WeComUser集合
List<WeComUser> users = convertJsonToWeComUsers(result);
// 3. 检查重名并设置标志
markDuplicateNames(users);
// 4. 批量插入数据库
batchInsert(users);
}
}
@Override
public String getToken() {
//获取token
// String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ww1fd8778458e9f1e8&corpsecret=uFRq9Xi8-dVY90LydXYBhjc91JnnfkPUR6lHDdeJ_fo";
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + CORP_ID + "&corpsecret=" + CORP_SECRET;
String accessToken = "";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get()
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
String responseBody = response.body().string();
JSONObject jsonResponse = new JSONObject(responseBody);
accessToken = jsonResponse.getString("access_token");
} else {
throw new RuntimeException("Failed to fetch token. HTTP Code: " + response.code());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return accessToken;
}
/**
* 获取企微部门列表
*
* @return 包含用户列表的JsonObject
* @throws Exception
*/
public JsonObject getDepartmentList() throws Exception {
String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=" + getToken();
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// 使用Gson解析JSON响应
Gson gson = new Gson();
return gson.fromJson(response.toString(), JsonObject.class);
} else {
throw new RuntimeException("HTTP GET请求失败,错误码: " + responseCode);
}
}
/**
* 根据企业微信部门ID获取用户列表
*
* @param departmentId 部门ID
* @return 包含用户列表的JsonObject
* @throws Exception
*/
public JsonObject getUserListByDepartment ( int departmentId) throws Exception {
String urlStr = BASE_URL + "?access_token=" + ACCESS_TOKEN + "&department_id=" + departmentId;
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// 使用Gson解析JSON响应
Gson gson = new Gson();
return gson.fromJson(response.toString(), JsonObject.class);
} else {
throw new RuntimeException("HTTP GET请求失败,错误码: " + responseCode);
}
}
}
// vo/LoginVO.java
package com.cmeeting.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
public class TencentMeetingVO {
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class TencentMeetingRequest{
private Long startTime; //开始结束时间戳
private Long endTime;
private Integer pageSize;
private Integer page;
private String operatorId;
private Integer operatorIdType;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class RecordFile{
private String meetingId;//如果是周期会议,这个id表示主会议
private String subMeetingId;//如果是周期会议,这个id表示子会议
private String recordFileId;
}
}
\ No newline at end of file
......@@ -29,3 +29,22 @@ mybatis.type-aliases-package=com.cmeeting.pojo\
mybatis.configuration.map-underscore-to-camel-case: true
logging.level.com.zaxxer.hikari=INFO
# tencent meeting
# local
tencent.appId=211153201
tencent.sdkId=28370276340
tencent.secretId=BKOMDZVbvh0iT7k6UHsSizAWBCOVDtT6
tencent.secretKey=3Y1j0mzNp7KChKFJGyaEnZHLobFoAQ8eLwfaMx8nLbtXAerO
#tencent.admin.userId=woaJARCQAAJU1EsO73Ww5rn8YHMW6iYA
tencent.admin.userId=woaJARCQAAhkyWGuf8n9InhZsxQstjjA
# prod
#tencent.appId=210468336
#tencent.sdkId=28790143843
#tencent.secretId=0ks7u8cgQ8DGVtlYZeRA9TxZCjvUT3oL
#tencent.secretKey=gQU09rkJjiQfiGcUYdhiKq5Ol6LebXg4w7F7Ol0rwvvdv3Xy
#tencent.admin.userId=woaJARCQAAftcvU6GGoOn66rdSZ4IrOA
email.sender=cmeeting_assistant@cimc.com
email.sender.pwd=scyou@xih45g6@xih4
email.smtp.host=smtp.office365.com
......@@ -14,6 +14,8 @@
#{user.isrepeatName}
)
</foreach>
ON DUPLICATE KEY UPDATE
user_name = VALUES(user_name)
</insert>
<select id="getAlluser" resultType="com.cmeeting.pojo.TencentMeetingUser">
......
......@@ -13,15 +13,18 @@
</insert>
<insert id="batchInsert" parameterType="list">
INSERT INTO user_wecom ( user_name, user_id, isepeat_name)
INSERT INTO user_wecom ( user_name, user_id, isrepeat_name,email)
VALUES
<foreach collection="list" item="user" separator=",">
(
#{user.userName},
#{user.userId},
#{user.isRepeatName}
#{user.isRepeatName},
#{user.email}
)
</foreach>
ON DUPLICATE KEY UPDATE
user_name = VALUES(user_name)
</insert>
<select id="getAlluser" resultType="com.cmeeting.pojo.WeComUser">
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论