提交 9c63e432 作者: 洪东保

cmeeting独立部署:

 1. 删除与其他服务相关无用代码
 2. 新增cimc服务配置
父级 c38ab7e6
package com.cmeeting;
import com.azure.core.credential.TokenRequestContext;
import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import okhttp3.*;
import java.io.IOException;
public class GraphApiWithOkHttp {
static String CLIENT_ID = "d65aa91b-05f4-42b2-902f-4d82ea5a2b93";
static String TENANT_ID = "74cc8acf-aacc-4514-9bbb-dc27ce3096bb"; // or "common" for multi-tenant apps
static String CLIENT_SECRET = "~N98Q~83v6dViQFIofwr0fRn4J5VEZ2tvwOz.bPX";
private static final String USER_EMAIL = "biinizhai321@outlook.com"; // 发送邮件的用户
public static void main(String[] args) throws IOException {
/**中集:
* c06fe7cf-2a89-4099-9805-ce03031938f8
* wsu8Q~GxYxPLf2akioQZDRG8NR1EzCAHIAQRVc6u
* 18653b3e-03c7-499e-8baf-42ef06a814ef
*/
ClientSecretCredential credential = new ClientSecretCredentialBuilder()
.clientId(CLIENT_ID)
.clientSecret(CLIENT_SECRET)
.tenantId(TENANT_ID)
.build();
// 1. 获取 Access Token
String token = credential.getToken(
new TokenRequestContext()
.addScopes("https://graph.microsoft.com/.default"))
.block().getToken();
System.out.println("获取到的令牌: " + token);
String token1 ="EwBYBMl6BAAUBKgm8k1UswUNwklmy2v7U/S+1fEAAUa0jd3QNQBdqTy9ZwEaLPqqapU5zHFRz4XvGqbI7jN7x01mEvBtCSFgYtNiSOEb5s1UwLxl6HwlHFqfJsqDsoCicvnlqCWjsaR/4wPZgXxd+pBhHRSPl+tJcSzz2NJB+dy81wHcSaU4bRxCIgoU7MtrW2ak9DhGisnK4/vxHkzxuIjHe9IDOZBzwzAtTZhycWRoAtuQrC1iu/kuKGJaU9noNjsOwfHUaXRz68g6niSdPT8P6zOa2vlOHjhXh478ms1PhqKeTkS+nkTurT2Gc5qRJviICiiAlK4BlxV70tOA6xEtl2ApXOrfFr+rlv4pASmPewtbdkTHnpP3H0R9L0kQZgAAEF4HO14XaFxPCdIqniVBvSkgA75wLsTuUZragTXGu71SV7ccLi26nZ+9KZlulf8dAlj/NEdheqtdEHb+BOLknQoXFEJ0UNj6PLkczzHfV3Yr5zlXJICwb3yI9vrFTUCb555ux/P904vXCY900UNgX81gBIYJQIJtOCURDAcHWtxyWvfNlkr17fKgnX5KdDyec6JK9tgzPi62LlqhDcoR/W/4MTCZhfJRlZgdYkI52pQSbDJItR6W7xfZguXPgKRHVcZJTzlybtOW0kbrfv96CKrryKzGeRjZyEcov1U3VjAoBUllgi3+LdIFK86aojMuBP+v5PvRq81qZS2q5roIRJD5zydu1selrpwhrZjm2nupDxHGjvfj2TVZJlz1zGYsVYrSRz2+st+2UbZagR1fbPRX2GilTfDyN05HV//LrfdrddbffMImxY2M8D9iQZFSjBYSFa20S9Vs9/yj08M9ljwiJifHGjX2o/arR63SWe3pbga26EC+j8JaBemhAhPsu91xW4o7+j/xEUadXR2NDbuogMq+MeINKe3PqAAFeTva1ZWZF5p3oGVIQKL4pcQFA9xEwopoN+vSeHDuAOvTFQ/4PukxicJdFTiaZquGeQMF0sLFvLdddpvS3Xaf17fPxjMUlMGcjYQ8gK5XG5wzjR8Up4MZZyX3xiK/hccGOp5pwi8WAN5cVmTKZOSXTkHUGEQT4rcGUYTPduHYMjjrVpzffpnmqfO92VA7a7fuYqXKp3NPikv17s6PTVr6b4+24AP8u3MEhDHU2YjaMuFR3jBUYLxtm443Gn58MC7oYrmQIVN2VYJrxADgStqpE+3nUCyKajmF0q5U+LUI1cCYnOKgmAkrpN71qlB9GeQLLQDJytG2sg64NG/h3CN1SseudSYtmqM3XUURSsztB9dNL7xmHQAcEBYMVjec5N5jHLhIs48rxAqI/WAJ/2RFKWgJIeCUJ8v4oQYEI9lAlWgReVhrjcNxRsbuVDFFwU7cTSeY9bJzxSX5kWJ8TXr/Q/SELEViUVCz10Cw/sOtm4urke538R4yXlR1wfMk3S86xlOfc3HJ6Iz7hi1h2fovWA9T1ceFWQM=";
// 2. 使用 OkHttp 发送邮件
sendEmail(token);
}
// 使用 Graph API 发送邮件
private static void sendEmail(String accessToken) throws IOException {
OkHttpClient client = new OkHttpClient();
// 构建邮件内容 (JSON 格式)
String emailJson = "{\n" +
" \"message\": {\n" +
" \"subject\": \"Test Email\",\n" +
" \"body\": {\n" +
" \"contentType\": \"Text\",\n" +
" \"content\": \"This is a test email.\"\n" +
" },\n" +
" \"toRecipients\": [\n" +
" {\n" +
" \"emailAddress\": {\n" +
" \"address\": \"binzhai321@outlook.com\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
// 构建请求
Request request = new Request.Builder()
.url("https://graph.microsoft.com/v1.0/users/" + USER_EMAIL + "/sendMail")
.post(RequestBody.create(MediaType.parse("application/json"), emailJson))
.addHeader("authorization", "Bearer " + accessToken)
.addHeader("Content-Type", "application/json")
.build();
// 发送请求
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
System.out.println("Email sent successfully!");
} else {
System.err.println("Failed to send email: " + response.code() + " - " + response.message());
System.err.println(response.body().string()); // 打印错误详情
}
}
}
}
//package com.cmeeting;
//
//import com.alibaba.fastjson2.JSON;
//import com.cmeeting.email.EmailSender;
//import com.cmeeting.mapper.tertiary.AuthMapper;
//import com.cmeeting.mapper.primary.UserIdMapper;
//import com.cmeeting.mapper.tertiary.SysUserSyncMapper;
//import com.cmeeting.pojo.CoreModulePermissions;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import com.tencentcloudapi.wemeet.Client;
//import com.tencentcloudapi.wemeet.core.authenticator.AuthenticatorBuilder;
//import com.tencentcloudapi.wemeet.core.authenticator.JWTAuthenticator;
//import com.tencentcloudapi.wemeet.core.exception.ClientException;
//import com.tencentcloudapi.wemeet.core.exception.ServiceException;
//import com.tencentcloudapi.wemeet.core.xhttp.ApiResponse;
//import com.tencentcloudapi.wemeet.service.meeting_control.api.MeetingControlApi;
//import com.tencentcloudapi.wemeet.service.meeting_control.model.V1RealControlMeetingsMeetingIdAsrPutRequest;
//import com.tencentcloudapi.wemeet.service.meetings.api.MeetingsApi;
//import com.util.meeting.MeetingMinutesGenerator;
//import org.apache.commons.lang3.StringUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//import org.springframework.http.ResponseEntity;
//import org.springframework.http.HttpStatus;
//
//import javax.crypto.Cipher;
//import javax.crypto.spec.IvParameterSpec;
//import javax.crypto.spec.SecretKeySpec;
//import java.io.IOException;
//import java.math.BigInteger;
//import java.security.MessageDigest;
//import java.security.SecureRandom;
//import java.util.*;
//import java.net.URLDecoder;
//import java.nio.charset.StandardCharsets;
//import java.util.Base64;
//import java.util.stream.Collectors;
//
//@RestController
//@RequestMapping
//public class TencentMeetingCallbackController {
// private static final Logger logger = LoggerFactory.getLogger(TencentMeetingCallbackController.class);
// /**
// * *
// * * 配置参数 - 从配置文件或环境变量获取
// * * 用于校验腾讯会议的事件订阅
// */
//
//
// //tencent.meeting.token
// private final String token = "Jo6X4sZKhPFknSdBH8o6gXVOb";
// //tencent.meeting.aesKey
// private final String encodingAESKey = "AhES8VLIoktG4KGPqgKz6uUMtvs67JZWCuStmogMAwr";
//
// // 1.构造 client 客户端(jwt 鉴权需要配置 appId sdkId secretID 和 secretKey)
// Client client = new Client.Builder()
// .withAppId("211153201").withSdkId("28370276340")
// .withSecret("BKOMDZVbvh0iT7k6UHsSizAWBCOVDtT6", "3Y1j0mzNp7KChKFJGyaEnZHLobFoAQ8eLwfaMx8nLbtXAerO")
// .build();
// @Autowired
// private UserIdMapper userIdMapper;
// @Autowired
// private AuthMapper authMapper;
// @Autowired
// private SysUserSyncMapper sysUserSysMapper;
//
// //处理GET请求 - URL验证
// @GetMapping
// public ResponseEntity<String> verifyUrl(
// @RequestParam("check_str") String checkStr,
// @RequestHeader("timestamp") String timestamp,
// @RequestHeader("nonce") String nonce,
// @RequestHeader("signature") String signature) {
//
// try {
// // 1. URL解码
// checkStr = URLDecoder.decode(checkStr, StandardCharsets.UTF_8.name());
//
// // 2. 验证签名
// if (!verifySignature(token, timestamp, nonce, checkStr, signature)) {
// return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Signature verification failed");
// }
//
// // 3. 解密check_str
// String decryptedStr = decryptData(checkStr);
//
// // 4. 返回明文(不能加引号或换行符)
// return ResponseEntity.ok(decryptedStr);
//
// } catch (Exception e) {
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
// .body("Error: " + e.getMessage());
// }
// }
//
// //处理POST请求 -事件回调
// @PostMapping(consumes = "application/json")
//
// public ResponseEntity<String> handleEvent(
// @RequestBody Map<String, String> requestBody,
// @RequestHeader("timestamp") String timestamp,
// @RequestHeader("nonce") String nonce,
// @RequestHeader("signature") String signature) {
//
// try {
// // 1. 获取data字段
// String encryptedData = requestBody.get("data");
// if (encryptedData == null) {
// return ResponseEntity.badRequest().body("Missing data field");
// }
//
// // 2. 验证签名
// if (!verifySignature(token, timestamp, nonce, encryptedData, signature)) {
// return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Signature verification failed");
// }
//
// // 3. 解密data
// String decryptedData = decryptData(encryptedData);
// logger.info("Decrypted event data: {}", decryptedData);
// try {
// ObjectMapper objectMapper = new ObjectMapper();
// JsonNode rootNode = objectMapper.readTree(decryptedData);
// JsonNode firstPayload = rootNode.path("payload").get(0);
// String userId = firstPayload.path("operator").path("userid").asText();
// // 通过腾讯的userid查询到企业微信的userid
// String wid = userIdMapper.getWidByTid(userId);
// logger.info("该用户的工号id:{},", wid);
// // 调用admin的find接口查询用户信息包括用户的部门id路径
// String userDeptPath = "";
//// sysUserMapper.getUserDeptPath(wid);
// logger.info("该用户的部门路径:{},", userDeptPath);
// List<String> deptPath = null;
// if (userDeptPath != null && !userDeptPath.isEmpty()) {
// // 使用split方法分割字符串,并过滤掉空字符串
// deptPath = Arrays.stream(userDeptPath.split("/"))
// .filter(s -> !s.isEmpty())
// .collect(Collectors.toList());
// }
// logger.info("分割后的部门路径列表:{}", deptPath);
// //通过智能体id查询该id下的部门和用户
// String targetId = "1815393211829587968";//职能体id
// String tenantId = "1806976109082972160";//租户id
// List<CoreModulePermissions> auths = authMapper.getAuthByTargetId(targetId, tenantId);
// // 创建两个集合分别存储type=0(部门)和type=1(员工)的数据
// List<CoreModulePermissions> type0List = new ArrayList<>();
// List<CoreModulePermissions> type1List = new ArrayList<>();
//
// for (CoreModulePermissions auth : auths) {
// if (auth.getType() == 0) {
// type0List.add(auth);
// } else if (auth.getType() == 1) {
// type1List.add(auth);
// }
// // 如果type为null或其他值,这里会被忽略
// }
// // 检查权限
// boolean hasPermission = false;
// // 1. 先检查员工是否在type1List中
// for (CoreModulePermissions empAuth : type1List) {
// if (wid.equals(empAuth.getRelId())) {
// hasPermission = true;
// logger.info("员工{}在直接授权列表中", wid);
// break;
// }
// }
// // 2. 如果员工不在直接授权列表中,检查部门权限
// if (!hasPermission && !deptPath.isEmpty()) {
// for (CoreModulePermissions deptAuth : type0List) {
// if (deptPath.contains(deptAuth.getRelId())) {
// hasPermission = true;
// logger.info("员工{}通过部门{}获得权限", wid, deptAuth.getRelId());
// break;
// }
// }
// }
// if (hasPermission) {
// processEvent(decryptedData);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// // 5. 返回成功响应(必须严格匹配)
// return ResponseEntity.ok("successfully received callback");
// } catch (Exception e) {
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
// .body("Error: " + e.getMessage());
// }
// }
//
//
// //验证签名(SHA1)
//
//
// private boolean verifySignature(String token, String timestamp, String nonce,
// String data, String receivedSignature) throws Exception {
// // 1. 按字典序排序
// String[] arr = new String[]{token, timestamp, nonce, data};
// Arrays.sort(arr);
//
// // 2. 拼接字符串
// String combined = String.join("", arr);
//
// // 3. SHA1加密
// MessageDigest md = MessageDigest.getInstance("SHA-1");
// byte[] digest = md.digest(combined.getBytes(StandardCharsets.UTF_8));
//
// // 4. 转换为16进制字符串
// StringBuilder hexStr = new StringBuilder();
// for (byte b : digest) {
// String hex = Integer.toHexString(b & 0xFF);
// if (hex.length() == 1) {
// hexStr.append('0');
// }
// hexStr.append(hex);
// }
//
// // 5. 比较签名
// return hexStr.toString().equals(receivedSignature);
// }
//
// //AES解密数据
// private String decryptData(String encryptedData) throws Exception {
// // 1. Base64解码
// byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
//
// // 2. 处理AES密钥
// byte[] aesKeyBytes = Base64.getDecoder().decode(encodingAESKey + "=");
// byte[] ivBytes = Arrays.copyOfRange(aesKeyBytes, 0, 16);
//
// // 3. 初始化Cipher
// SecretKeySpec keySpec = new SecretKeySpec(aesKeyBytes, "AES");
// IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
//
// // 4. 解密
// byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
//
// // 5. 处理PKCS5Padding补位
// int pad = decryptedBytes[decryptedBytes.length - 1];
// if (pad < 1 || pad > 32) {
// pad = 0;
// }
//
// return new String(
// Arrays.copyOfRange(decryptedBytes, 0, decryptedBytes.length - pad),
// StandardCharsets.UTF_8
// );
// }
//
// // 类成员变量记录已处理的事件
// private final Set<String> startProcessedEvents = Collections.synchronizedSet(new HashSet<>());
// private final Set<String> sendProcessedEvents = Collections.synchronizedSet(new HashSet<>());
//
// //处理事件业务逻辑
// private void processEvent(String decryptedData) {
// // 这里可以解析JSON并处理具体业务
// // 示例: 打印事件数据
// logger.info("这是获取到的会议信息:");
// logger.info("Processing event: {}", decryptedData);
// String json = decryptedData;
// try {
// ObjectMapper mapper = new ObjectMapper();
//
// // 解析JSON
// java.util.Map<String, Object> jsonMap = mapper.readValue(json, java.util.Map.class);
//
// // 1. 提取 event
// String event = (String) jsonMap.get("event");
// // 获取payload数组
// java.util.List<java.util.Map<String, Object>> payload = (java.util.List<java.util.Map<String, Object>>) jsonMap.get("payload");
// java.util.Map<String, Object> firstPayload = payload.get(0);
// // 获取meeting_info信息
// java.util.Map<String, Object> meetingInfo = (java.util.Map<String, Object>) firstPayload.get("meeting_info");
// String meetingId = (String) meetingInfo.get("meeting_id");
// Map<String, Object> operator = (Map<String, Object>) firstPayload.get("operator");
// String operatorUserId = (String) operator.get("userid");
// String instanceIdStr = (String) operator.get("instance_id");
// Integer instanceId = Integer.parseInt(instanceIdStr);
//
// //判断事件是否为开始会议
// if ("meeting.started".equals(event)) {
//
// try {
// // 生成唯一事件ID(使用事件类型+会议ID+时间戳)
// String eventId = meetingId;
// // 检查是否已处理
// if (startProcessedEvents.contains(eventId)) {
// //System.out.println("忽略已处理事件: " + eventId);
// logger.info("忽略已处理事件: {}", eventId);
// return;
// }
// // 记录已处理事件
// startProcessedEvents.add(eventId);
//
// // 原有处理逻辑...
// } catch (Exception e) {
// e.printStackTrace();
// }
// //开启语音转写功能
// //System.out.println("开启会议语音转写");
// logger.info("开启会议语音转写");
// ObjectMapper jsonMapper = new ObjectMapper();
// ObjectNode jsonBody = jsonMapper.createObjectNode()
// .put("operator_id", operatorUserId)
// .put("operator_id_type", 1)
// .put("instance_id", instanceId) // 自动识别为数字类型
// .put("is_open", true)
// .put("open_asr_view", 0);
// String BODY_JSON = mapper.writeValueAsString(jsonBody);
// V1RealControlMeetingsMeetingIdAsrPutRequest body = JSON.parseObject(BODY_JSON, V1RealControlMeetingsMeetingIdAsrPutRequest.class);
//
// // 2.构造请求参数
// MeetingControlApi.ApiV1RealControlMeetingsMeetingIdAsrPutRequest request =
// new MeetingControlApi.ApiV1RealControlMeetingsMeetingIdAsrPutRequest.Builder(meetingId)
// .body(body).build();
// // 3.构造 JWT 鉴权器
// // 随机数
// BigInteger nonce = BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt()));
// // 当前时间戳
// String timestamp = String.valueOf(System.currentTimeMillis() / 1000L);
// AuthenticatorBuilder<JWTAuthenticator> authenticatorBuilder =
// new JWTAuthenticator.Builder().nonce(nonce).timestamp(timestamp);
// try {
// MeetingControlApi.ApiV1RealControlMeetingsMeetingIdAsrPutResponse response =
// client.meeting_control().v1RealControlMeetingsMeetingIdAsrPut(request, authenticatorBuilder);
// // response from `v1RealControlMeetingsMeetingIdAsrPut`: V1RealControlMeetingsMeetingIdAsrPut200Response
// logger.info("Response from `MeetingControlApi.v1RealControlMeetingsMeetingIdAsrPut`: \nheader: {}\n{}",
// response.getHeader(), response.getData());
// } catch (ClientException e) {
// logger.error("Error when calling `MeetingControlApi.v1RealControlMeetingsMeetingIdAsrPut`", e);
// throw new RuntimeException(e);
// } catch (ServiceException e) {
// logger.error("Error when calling `MeetingControlApi.v1RealControlMeetingsMeetingIdAsrPut`", e);
// logger.error("Full HTTP response: {}", new String(e.getApiResp().getRawBody()));
// throw new RuntimeException(e);
// }
// } else if ("meeting.end".equals(event)) {
//
// try {
// // 生成唯一事件ID(使用事件类型+会议ID+时间戳)
// String eventId = meetingId;
// // 检查是否已处理
// if (sendProcessedEvents.contains(eventId)) {
// logger.info("忽略已处理事件: {}", eventId);
// return;
// }
// // 记录已处理事件
// sendProcessedEvents.add(eventId);
//
// // 原有处理逻辑...
// } catch (Exception e) {
// e.printStackTrace();
// }
// logger.info("operatorId: {}", operatorUserId);
// logger.info("meetingId: {}", meetingId);
// // 2.构造请求参数
// MeetingsApi.ApiV1AsrDetailsGetRequest request =
// new MeetingsApi.ApiV1AsrDetailsGetRequest.Builder()
// .operatorIdType("1")
// .operatorId(operatorUserId)
// .meetingId(meetingId)
// .fileType("1")
// .build();
// // 3.构造 JWT 鉴权器
// // 随机数
// BigInteger nonce = BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt()));
// // 当前时间戳
// String timestamp = String.valueOf(System.currentTimeMillis() / 1000L);
// AuthenticatorBuilder<JWTAuthenticator> authenticatorBuilder =
// new JWTAuthenticator.Builder().nonce(nonce).timestamp(timestamp);
// // 4.发送对应的请求
// try {
// ApiResponse response =
// client.meetings().v1AsrDetailsGet(request, authenticatorBuilder);
// logger.info("Response from `MeetingsApi.v1AsrDetailsGet`: \nheader: {}\n{}",
// response.getHeader(), response.getRawBody());
// String rawBodyString = new String(response.getRawBody(), StandardCharsets.UTF_8);
// logger.info("Raw Body (string): {}", rawBodyString);
// try {
// // 解析JSON获取下载URL
// com.fasterxml.jackson.databind.ObjectMapper resultmapper = new com.fasterxml.jackson.databind.ObjectMapper();
// java.util.Map<String, Object> result = resultmapper.readValue(rawBodyString, java.util.Map.class);
// String downloadUrl = ((java.util.List<String>) result.get("download_url")).get(0);
// // 设置保存路径为D盘根目录
// String savePath = "D:/" + meetingId + ".docx";
// String targetPath = "D:/" + meetingId + "纪要" + ".docx";
// // 下载文件
// logger.info("开始下载文件到: {}", savePath);
// try (java.io.BufferedInputStream in = new java.io.BufferedInputStream(new java.net.URL(downloadUrl).openStream());
// java.io.FileOutputStream fileOutputStream = new java.io.FileOutputStream(savePath)) {
// byte[] dataBuffer = new byte[1024];
// int bytesRead;
// while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
// fileOutputStream.write(dataBuffer, 0, bytesRead);
// }
// logger.info("文件下载完成,已保存到 {}", savePath);
// //将文件传送给大模型处理
// try {
// boolean success = MeetingMinutesGenerator.generateMinutesFromWord(
// savePath,
// targetPath,
// "AKIAXFAXF62IWJXGLVEE.LnKInaahcMZG9zLsGMH3nTLOw3S3lK5Vcu0+ifnO",
// "https://bedrock.chatbot.cn/llm/sse-invoke"
// );
//
// if (success) {
// logger.info("会议纪要生成成功!");
// }
// } catch (IOException e) {
// logger.error("错误: {}", e.getMessage());
// }
// //使用邮箱发送邮件
// // 1.获得主持人的腾讯会议userid
// // 2.根据获得的腾讯会议userid获得员工的企业微信userid
// // 3.根据企业微信userid查询员工表获得员工邮箱
// String tid = operatorUserId;
// String wid = userIdMapper.getWidByTid(tid);
// String tenantId = "1806976109082972160";
// String emailAddress = sysUserSysMapper.getCompanyEmail(wid, tenantId);
// if (StringUtils.isEmpty(emailAddress)) {
// logger.info("用户:{}", wid, "没有企业邮箱");
// return;
// }
// Thread.sleep(10000);
// EmailSender emailSender = new EmailSender();
// //response.getRawBody()
//// boolean mailFlag = emailSender.sendEmailWithAttachment(emailAddress,
//// targetPath,
//// "重要文件",
//// "您好:\n" +
//// "\n" +
//// " 附件为您本次会议的会议纪要,烦请下载查看,如需对会议纪要结果进行修改或查看历史会议,可点击下方链接。");
//// if (mailFlag) {
//// logger.info("邮件发送成功");
//// } else {
//// logger.error("邮件发送失败");
//// }
// }
// } catch (Exception e) {
// logger.error("下载文件时出错: {}", e.getMessage());
// e.printStackTrace();
// }
// } catch (ClientException e) {
// logger.error("Error when calling `MeetingsApi.v1AsrDetailsGet`", e);
// throw new RuntimeException(e);
// } catch (ServiceException e) {
// logger.error("Error when calling `MeetingsApi.v1AsrDetailsGet`", e);
// logger.error("Full HTTP response: {}", new String(e.getApiResp().getRawBody()));
// throw new RuntimeException(e);
// }
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
//
//}
//package com.cmeeting;
//
//import com.cmeeting.pojo.TencentMeetingUser;
//import com.cmeeting.pojo.WeComUser;
//import com.google.gson.Gson;
//import com.google.gson.JsonArray;
//import com.google.gson.JsonElement;
//import com.google.gson.JsonObject;
//
//import java.io.BufferedReader;
//import java.io.InputStreamReader;
//import java.net.HttpURLConnection;
//import java.net.URL;
//
//import com.tencentcloudapi.wemeet.Client;
//import com.tencentcloudapi.wemeet.core.authenticator.AuthenticatorBuilder;
//import com.tencentcloudapi.wemeet.core.authenticator.JWTAuthenticator;
//import com.tencentcloudapi.wemeet.core.exception.ClientException;
//import com.tencentcloudapi.wemeet.core.exception.ServiceException;
//import com.tencentcloudapi.wemeet.service.user_manager.api.UserManagerApi;
//import com.tencentcloudapi.wemeet.service.user_manager.model.V1UsersListGet200Response;
//import com.tencentcloudapi.wemeet.service.user_manager.model.V1UsersListGet200ResponseUsersInner;
//import org.springframework.stereotype.Service;
//
//import java.math.BigInteger;
//import java.security.SecureRandom;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//@Service
//public class WeComAndTencentMeeting {
// 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";
// public static void main(String[] args) {
// try {
// // 示例:获取部门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());
// }
// } else {
// System.out.println("企微获取用户列表失败: " + result.get("errmsg").getAsString());
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// /**
// * 腾讯会议通过通讯录获取员工信息
// */
// // 1. 构造client客户端
// Client client = new Client.Builder()
// .withAppId("211153201").withSdkId("28370276340")
// .withSecret("BKOMDZVbvh0iT7k6UHsSizAWBCOVDtT6", "3Y1j0mzNp7KChKFJGyaEnZHLobFoAQ8eLwfaMx8nLbtXAerO")
// .build();
//
// // 2. 开始循环获取用户列表
// fetchUsersInBatches(client, 3);
// }
// /**
// * 将企业微信返回的JSON转换为WeComUser列表
// */
// public static List<WeComUser> convertJsonToWeComUsers(JsonObject json) {
// List<WeComUser> users = new ArrayList<>();
//
// if (json.has("userlist") && json.get("userlist").isJsonArray()) {
// JsonArray userList = json.getAsJsonArray("userlist");
// Gson gson = new Gson();
//
// for (JsonElement element : userList) {
// JsonObject userJson = element.getAsJsonObject();
// WeComUser user = new WeComUser();
//
// // 根据企业微信API实际返回字段调整
// user.setUserId(userJson.get("userid").getAsString());
// user.setUserName(userJson.get("name").getAsString());
//
// // 其他字段设置...
// users.add(user);
// }
// }
//
// return users;
// }
//
// /**
// * 标记企业微信重名用户
// */
// public static void markDuplicateNames(List<WeComUser> users) {
// // 按姓名分组,统计每个名字出现的次数
// Map<String, Long> nameCountMap = users.stream()
// .collect(Collectors.groupingBy(WeComUser::getUserName, Collectors.counting()));
//
// // 设置是否重名标志
// users.forEach(user -> {
// if (nameCountMap.get(user.getUserName()) > 1) {
// user.setIsRepeatName("1"); // 重名
// } else {
// user.setIsRepeatName("0"); // 不重名
// }
// });
// }
//
// /**
// * 标记企业微信重名用户
// */
// public static void markDuplicateNamesTecent(List<TencentMeetingUser> users) {
// // 按姓名分组,统计每个名字出现的次数
// Map<String, Long> nameCountMap = users.stream()
// .collect(Collectors.groupingBy(TencentMeetingUser::getUserName, Collectors.counting()));
//
// // 设置是否重名标志
// users.forEach(user -> {
// if (nameCountMap.get(user.getUserName()) > 1) {
// user.setIsrepeatName("1"); // 重名
// } else {
// user.setIsrepeatName("0"); // 不重名
// }
// });
// }
//
// /**
// * 根据企业微信部门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);
// }
// }
//
// /**
// * 腾讯会议获取员工信息
// */
// /**
// * 分批次获取用户列表
// *
// * @param client 客户端实例
// * @param pageSize 每页大小
// * @return
// */
// public static List<TencentMeetingUser> fetchUsersInBatches(Client client, int pageSize) {
// int currentPage = 1;
// boolean hasMore = true;
// int totalUsers = 0;
// List<TencentMeetingUser> userList = new ArrayList<>(); // 创建集合存储用户数据
//
// while (hasMore) {
// try {
// // 1. 构造请求参数
// UserManagerApi.ApiV1UsersListGetRequest request =
// new UserManagerApi.ApiV1UsersListGetRequest.Builder()
// .page(String.valueOf(currentPage))
// .pageSize(String.valueOf(pageSize))
// .operatorId("woaJARCQAAJU1EsO73Ww5rn8YHMW6iYA")
// .operatorIdType("1")
// .build();
//
// // 2. 构造JWT鉴权器
// BigInteger nonce = BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt()));
// String timestamp = String.valueOf(System.currentTimeMillis() / 1000L);
// AuthenticatorBuilder<JWTAuthenticator> authenticatorBuilder =
// new JWTAuthenticator.Builder().nonce(nonce).timestamp(timestamp);
//
// // 3. 发送请求
// UserManagerApi.ApiV1UsersListGetResponse response =
// client.user_manager().v1UsersListGet(request, authenticatorBuilder);
//
// // 4. 处理响应并转换为TencentMeetingUser对象
// V1UsersListGet200Response responseData = response.getData();
// List<V1UsersListGet200ResponseUsersInner> users = responseData.getUsers();
// int currentSize = users.size();
// totalUsers += currentSize;
//
// System.out.printf("第 %d 页,获取到 %d 个用户:\n", currentPage, currentSize);
//
// for (V1UsersListGet200ResponseUsersInner user : users) {
// // 创建TencentMeetingUser对象并设置属性
// TencentMeetingUser meetingUser = new TencentMeetingUser();
// meetingUser.setUserId(user.getUserid());
// meetingUser.setUserName(user.getUsername());
// meetingUser.setIsrepeatName("0"); // 默认设为不重名,可根据实际业务调整
//
// userList.add(meetingUser); // 添加到集合
// System.out.printf("用户ID: %s, 用户名: %s\n", user.getUserid(), user.getUsername());
// }
//
// // 5. 检查是否还有更多数据
// if (currentSize == 0 || currentSize < pageSize) {
// hasMore = false;
// System.out.printf("\n所有用户获取完成,共获取 %d 个用户\n", totalUsers);
// } else {
// currentPage++;
// }
//
// } catch (ClientException e) {
// System.out.printf("客户端错误: %s\n", e);
// throw new RuntimeException(e);
// } catch (ServiceException e) {
// System.out.printf("服务端错误: %s\n", e);
// System.out.printf("完整响应: %s\n", new String(e.getApiResp().getRawBody()));
// throw new RuntimeException(e);
// }
// }
//
// return userList; // 返回用户集合
//
// }
//}
...@@ -72,15 +72,6 @@ public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticat ...@@ -72,15 +72,6 @@ public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticat
"AbstractUserDetailsAuthenticationProvider.badCredentials", "AbstractUserDetailsAuthenticationProvider.badCredentials",
"Bad credentials")); "Bad credentials"));
} }
String presentedPassword = authentication.getCredentials().toString();
// 密码验证在login接口做过了
// if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
// logger.debug("Authentication failed: password does not match stored value");
// throw new BadCredentialsException(messages.getMessage(
// "AbstractUserDetailsAuthenticationProvider.badCredentials",
// "Bad credentials"));
// }
} }
protected void doAfterPropertiesSet() { protected void doAfterPropertiesSet() {
......
package com.cmeeting.ad.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @author liuzhenmeng
* @date 2024/2/4 17:05
*/
@Data
@Component
@ConfigurationProperties(prefix = "robot.custom")
public class CustomWhiteConfigProperties {
/**
* 接口白名单
*/
private List<String> whiteTables = new ArrayList<>();
}
...@@ -41,16 +41,8 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -41,16 +41,8 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired @Autowired
private RobotJwtAuthenticationTokenFilter robotJwtAuthenticationTokenFilter; private RobotJwtAuthenticationTokenFilter robotJwtAuthenticationTokenFilter;
@Autowired @Autowired
private CustomWhiteConfigProperties customWhiteConfigProperties;
@Autowired
private CustomUserDetailsService customUserDetailsService; private CustomUserDetailsService customUserDetailsService;
@Autowired
private RobotWhiteConfigProperties configProperties;
/** /**
* 解决 无法直接注入 AuthenticationManager * 解决 无法直接注入 AuthenticationManager
* *
...@@ -87,11 +79,6 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -87,11 +79,6 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter {
*/ */
@Override @Override
protected void configure(HttpSecurity httpSecurity) throws Exception { protected void configure(HttpSecurity httpSecurity) throws Exception {
List<String> whiteTables = configProperties.getWhiteTables();
String[] api = ArrayUtil.toArray(whiteTables, String.class);
List<String> customWhiteTables = customWhiteConfigProperties.getWhiteTables();
String[] customApi = ArrayUtil.toArray(customWhiteTables, String.class);
httpSecurity httpSecurity
// 由于使用的是JWT,我们这里不需要csrf // 由于使用的是JWT,我们这里不需要csrf
.csrf().disable() .csrf().disable()
...@@ -100,8 +87,8 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -100,8 +87,8 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter {
// 过滤请求 // 过滤请求
.authorizeRequests() .authorizeRequests()
// 对于登录login 图标 要允许匿名访问 // 对于登录login 图标 要允许匿名访问
.antMatchers(customApi).access("@robotJwtCustomTokenFilter.checkToken(request)") // .antMatchers(customApi).access("@robotJwtCustomTokenFilter.checkToken(request)")
.antMatchers(api).anonymous() // .antMatchers(api).anonymous()
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css",
"/**/*.js", "/**/*.map") "/**/*.js", "/**/*.map")
.permitAll() .permitAll()
......
package com.cmeeting.ad.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @author 张伟
* @date 2021/2/2 17:47
*/
@Data
@Component
@ConfigurationProperties(prefix = "robot.white")
public class RobotWhiteConfigProperties {
/**
* 接口白名单
*/
private List<String> whiteTables = new ArrayList<>();
private List<String> whiteSignUrls = new ArrayList<>();
}
package com.cmeeting.ad.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 租户平台设置关联表(RelPlatformSettingTenant)实体类
*
* @author makejava
* @since 2023-06-12 10:03:26
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("rel_platform_setting_tenant")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RelPlatformSettingTenant implements Serializable {
private static final long serialVersionUID = -89908876679147553L;
private String id;
private String tenantId;
/**
* 菜单id
*/
private String platformSettingId;
private Integer isDel;
private Date createTime;
private String createUser;
private Date updateTime;
private String updateUser;
}
...@@ -48,7 +48,6 @@ public class RobotSecurityUser implements UserDetails { ...@@ -48,7 +48,6 @@ public class RobotSecurityUser implements UserDetails {
@JsonIgnore @JsonIgnore
private Collection<? extends GrantedAuthority> authorities; private Collection<? extends GrantedAuthority> authorities;
private SysPlatformSetting sysPlatformSetting;
private String nick; private String nick;
private String picture; private String picture;
......
package com.cmeeting.ad.entity;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* @author: 王长伟
*/
@Getter
@Setter
public class RoleTree implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> tenantCenter = new ArrayList<>();
private List<String> interactCenter = new ArrayList<>();
private List<String> knowledgeCenter = new ArrayList<>();
private List<String> llmCenter = new ArrayList<>();
private List<String> statisticsCenter = new ArrayList<>();
private List<String> securityCenter = new ArrayList<>();
private List<String> robotCenter = new ArrayList<>();
private List<String> staffCenter = new ArrayList<>();
private List<String> processCenter = new ArrayList<>();
}
package com.cmeeting.ad.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* <p>
* 菜单权限表
* </p>
*
* @author robot
* @since 2019-04-21
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_menu")
public class SysMenu extends Model<SysMenu> {
private static final long serialVersionUID = 1L;
/**
* 菜单ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Integer id;
/**
* 菜单名称
*/
private String name;
/**
* 菜单权限标识
*/
private String perms;
/**
* 前端path / 即跳转路由
*/
private String path;
/**
* 菜单组件
*/
private String component;
/**
* 父菜单ID
*/
private Integer parentId;
/**
* 图标
*/
private String icon;
/**
* 是否为外链
*/
private Boolean isAdmin;
/**
* 排序
*/
private Integer sort;
/**
* 菜单类型 (类型 1:目录 2:菜单 3:按钮)
*/
private Integer type;
/**
* 所属大功能模块
*/
private String parentSystem;
/**
* 在租户菜单是否展示 新增
*/
private Integer isShow;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@TableField(fill = FieldFill.INSERT)
@TableLogic
private Integer isDel;
/**
* 非数据库字段
* 父菜单名称
*/
@TableField(exist = false)
private String parentName;
/**
* 非数据库字段
* 菜单等级
*/
@TableField(exist = false)
private Integer level;
/**
* 非数据库字段
* 子菜单
*/
@TableField(exist = false)
private List<SysMenu> children;
@TableField(exist = false)
private String parentPath;
@TableField(exist = false)
private String key;
@TableField(exist = false)
private String title;
public String getTitle() {
return name;
}
@Override
public boolean equals(Object o) {
return Objects.hash(id) == o.hashCode();
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
package com.cmeeting.ad.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 平台设置表(SysPlatformSetting)实体类
*
* @author makejava
* @since 2023-06-12 11:43:45
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sys_platform_setting")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SysPlatformSetting implements Serializable {
private static final long serialVersionUID = -86441288874834748L;
/**
* 主键id
*/
private String id;
/**
* 是否使用机器人 0:false 1:true, 默认为1
*/
private Integer robot;
/**
* 是否使用数字人 0:false 1:true, 默认为1
*/
private Integer digitalPerson;
/**
* 是否使用客服系统 0:false 1:true ,默认为1
*/
private Integer moduleKefu;
/**
* 是否使用大语言模型 0:false 1:true ,默认为1
*/
private Integer largeLanguage;
/**
* 是否使用工单系统 0:false 1:true , 默认为1
*/
private Integer moduleTicket;
/**
* 是否使用问答知识点 0:false 1:true, 默认为1
*/
private Integer qaKnowledge;
/**
* 是否使用知识导图 0:false 1:true, 默认为1
*/
private Integer atlasKnowledge;
/**
* 是否使用多轮对话 0:false 1:true ,默认为1
*/
private Integer dialogKnowledge;
/**
* 是否使用文档知识点 0:false 1:true , 默认为1
*/
private Integer docKnowledge;
/**
* logo登录标签地址
*/
private String loginLogoUrl;
/**
* logo首页标签地址
*/
private String indexLogoUrl;
/**
* 背景图片地址
*/
private String backgroundUrl;
/**
* 推广图片地址
*/
private String advertiseUrl;
/**
* 底部信息
*/
private String bottomInfo;
/**
* 创建时间;创建时间
*/
private Date createTime;
/**
* 更新时间;更新时间
*/
private Date updateTime;
/**
* 创建人;创建人id
*/
private String createUser;
/**
* 更新人;更新人id
*/
private String updateUser;
/**
* 删除标识;0正常,1删除,默认为0
*/
private Integer isDel;
private Integer isAdmin;
private String agreement;
}
package com.cmeeting.ad.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 租户表
* </p>
*
* @author robot
* @since 2019-08-10
*/
@Getter
@Setter
public class SysTenant implements Serializable {
/**
* 租户id
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
private String kefuId;
/**
* 租户名称
*/
private String name;
/**
* 删除标记
*/
@TableField(fill = FieldFill.INSERT)
@TableLogic
private Boolean isDel;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private String createUser;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateUser;
/**
* 有效期
*/
private String validity;
/**
* 0纯网页 11企业微信第三方应用 12企业微信自建 21钉钉第三方应用 22钉钉自建 3 teams
*/
// private Integer tenantType;
/**
* 启用状态(0: 启用, 1: 禁用)
*/
private String status;
/**
* 备注
*/
private String remarks;
/**
* 机器人数量
*/
private Integer robotNums;
/**
* 知识点数量上限
*/
private Integer qaNums;
private Integer atlasNums;
private Integer dialogNums;
private Integer docNums;
private Integer formNums;
private Integer userNums;
private Integer regulatorsNums;
/**
* 知创建租户的系统用户名称
*/
private String userName;
/**
* 语言
*/
private String language;
@TableField(exist = false)
private Boolean expired;
}
package com.cmeeting.ad.service.impl; package com.cmeeting.ad.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.cmeeting.ad.entity.RobotSecurityUser; import com.cmeeting.ad.entity.RobotSecurityUser;
import com.cmeeting.ad.entity.SysUserSync;
import com.cmeeting.ad.service.CustomUserDetailsService; import com.cmeeting.ad.service.CustomUserDetailsService;
import com.cmeeting.constant.UserAdminRouteConstant;
import com.cmeeting.constant.UserTypeConstant; import com.cmeeting.constant.UserTypeConstant;
import com.cmeeting.util.HttpClientUtils; import com.cmeeting.service.SysUserSyncService;
import com.cmeeting.util.UserAdminConfig;
import com.cmeeting.util.UserAdminTokenUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
...@@ -24,7 +21,7 @@ import javax.annotation.Resource; ...@@ -24,7 +21,7 @@ import javax.annotation.Resource;
@Service @Service
public class DetailsServiceImpl implements CustomUserDetailsService { public class DetailsServiceImpl implements CustomUserDetailsService {
@Resource @Resource
private UserAdminConfig userAdminConfig; private SysUserSyncService sysUserSyncService;
/** /**
* @return 用户基本信息 * @return 用户基本信息
...@@ -34,14 +31,11 @@ public class DetailsServiceImpl implements CustomUserDetailsService { ...@@ -34,14 +31,11 @@ public class DetailsServiceImpl implements CustomUserDetailsService {
public UserDetails loadUser(String uid, String tenantId, String role) { public UserDetails loadUser(String uid, String tenantId, String role) {
RobotSecurityUser user = new RobotSecurityUser(); RobotSecurityUser user = new RobotSecurityUser();
user.setUserType(UserTypeConstant.SYNC); user.setUserType(UserTypeConstant.SYNC);
String url = userAdminConfig.getUserAdminDomain() + UserAdminRouteConstant.SyncUser.INFO + "?id=" + uid + "&tenantId=" + tenantId; SysUserSync one = sysUserSyncService.getById(uid);
JSONObject jsonObject = HttpClientUtils.httpGet(url, UserAdminTokenUtil.getUserAdminToken()); user.setId(one.getUserId());
JSONObject data = jsonObject.getJSONObject("data"); user.setUserId(Long.valueOf(one.getUserId()));
user.setId(data.getString("userId")); user.setUsername(one.getName());
user.setUserId(Long.valueOf(data.getString("userId"))); user.setNick(one.getName());
user.setUsername(data.getString("name"));
user.setNick(data.getString("nickName"));
user.setTenantId(data.getString("tenantId"));
user.setRole(role); user.setRole(role);
return user; return user;
} }
......
...@@ -3,20 +3,19 @@ package com.cmeeting.ad.service.impl; ...@@ -3,20 +3,19 @@ package com.cmeeting.ad.service.impl;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cmeeting.ad.entity.*; import com.cmeeting.ad.entity.RobotSecurityUser;
import com.cmeeting.ad.util.SecurityUtil; import com.cmeeting.ad.entity.SysUserSync;
import com.cmeeting.ad.service.ILdapService;
import com.cmeeting.ad.service.UserService;
import com.cmeeting.ad.util.JwtUtil;
import com.cmeeting.ad.vo.ApplicationUserVO;
import com.cmeeting.ad.vo.UserVo; import com.cmeeting.ad.vo.UserVo;
import com.cmeeting.constant.RecordTemplateConstant; import com.cmeeting.constant.RecordTemplateConstant;
import com.cmeeting.exception.RobotBaseException; import com.cmeeting.exception.RobotBaseException;
import com.cmeeting.mapper.primary.AuthMapper; import com.cmeeting.mapper.primary.AuthMapper;
import com.cmeeting.ad.service.ILdapService;
import com.cmeeting.ad.service.UserService;
import com.cmeeting.ad.util.JwtUtil;
import com.cmeeting.constant.UserAdminRouteConstant;
import com.cmeeting.mapper.primary.SysUserSyncMapper; import com.cmeeting.mapper.primary.SysUserSyncMapper;
import com.cmeeting.pojo.CoreModulePermissions; import com.cmeeting.pojo.CoreModulePermissions;
import com.cmeeting.util.*; import com.cmeeting.util.*;
import com.cmeeting.ad.vo.ApplicationUserVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
...@@ -28,8 +27,14 @@ import org.springframework.stereotype.Service; ...@@ -28,8 +27,14 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.*; import java.time.Duration;
import java.util.*; import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
......
...@@ -10,7 +10,6 @@ import lombok.extern.slf4j.Slf4j; ...@@ -10,7 +10,6 @@ import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
......
...@@ -11,40 +11,15 @@ public interface CimcConstants { ...@@ -11,40 +11,15 @@ public interface CimcConstants {
String GET_TEST_POSITION = "https://apipoc1.cimc.com/env-101/por-101/hrapi/hrms/cimc_org_position_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM"; String GET_TEST_POSITION = "https://apipoc1.cimc.com/env-101/por-101/hrapi/hrms/cimc_org_position_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM";
//获取员工标准信息 //获取员工标准信息
String GET_TEST_EMPLOYEE = "https://apipoc1.cimc.com/env-101/por-101/hrapi/hrms/cimc_lbr_employee_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_include_dismission=1&p_page_num=PAGE_NUM"; String GET_TEST_EMPLOYEE = "https://apipoc1.cimc.com/env-101/por-101/hrapi/hrms/cimc_lbr_employee_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_include_dismission=1&p_page_num=PAGE_NUM";
//获取IWORK获取访问token
String GET_TEST_TOKEN = "https://apipoc1.cimc.com/env-101/por-101/hrapi/iWorkapi/v1/token?apikey=API_KEY";
String TEST_IWORK_LOGIN = "https://apipoc1.cimc.com/env-101/por-101/hrapi/iWorkapi/ticket/TICKET?access_token=TOKEN&apikey=API_KEY";
//2. API地址(集团本地节点-生产)
String GET_ORGANIZATION = "https://cchqapi.cimc.com/por-11/hrapi/hrms/cimc_org_unit_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM";
String GET_POSITION = "https://cchqapi.cimc.com/por-11/hrapi/hrms/cimc_org_position_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM";
String GET_EMPLOYEE = "https://cchqapi.cimc.com/por-11/hrapi/hrms/cimc_lbr_employee_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM";
String GET_TOKEN = "https://cchqapi.cimc.com/por-11/hrapi/iWorkapi/v1/token?apikey=API_KEY";
String IWORK_LOGIN = "https://cchqapi.cimc.com/por-11/hrapi/iWorkapi/ticket/TICKET?access_token=TOKEN&apikey=API_KEY";
//3. API地址(AWS节点-生产) //3. API地址(AWS节点-生产)
String GET_AWS_ORGANIZATION = "https://awsapi.cimc.cn/env-101/por-10/hrapi/hrms/cimc_org_unit_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM"; String GET_AWS_ORGANIZATION = "https://awsapi.cimc.cn/env-101/por-10/hrapi/hrms/cimc_org_unit_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM";
String GET_AWS_POSITION = "https://awsapi.cimc.cn/env-101/por-10/hrapi/hrms/cimc_org_position_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM"; String GET_AWS_POSITION = "https://awsapi.cimc.cn/env-101/por-10/hrapi/hrms/cimc_org_position_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM";
String GET_AWS_EMPLOYEE = "https://awsapi.cimc.cn/env-101/por-10/hrapi/hrms/cimc_lbr_employee_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM"; String GET_AWS_EMPLOYEE = "https://awsapi.cimc.cn/env-101/por-10/hrapi/hrms/cimc_lbr_employee_wbs_standard.service?p_user=USER&p_password=PASSWORD&apikey=API_KEY&p_page_num=PAGE_NUM";
String GET_AWS_TOKEN = "https://awsapi.cimc.cn/env-101/por-10/hrapi/iWorkapi/v1/token?apikey=API_KEY";
String AWS_IWORK_LOGIN = "https://awsapi.cimc.cn/env-101/por-10/hrapi/iWorkapi/ticket/TICKET?access_token=TOKEN&apikey=API_KEY";
//门户登录
String POST_TEST_LOGIN = "https://apipoc1.cimc.com/env-101/por-101/cimcoatest/test/APIUserService"; //参数 apikey systemid token
String POST_LOGIN = "https://awsapi.cimc.cn/env-101/por-10/cimcoaprd/oa_prd/APIUserService";
String BPM_POST_FORM_TEST = "https://apipoc1.cimc.com/env-101/por-101/ekp/bpm/addReview";
String BPM_POST_FORM_PROD = "https://awsapi.cimc.cn/env-101/por-10/ekp/bpm/addReview";
String ALTER_USER = "USER"; String ALTER_USER = "USER";
String ALTER_PASSWORD = "PASSWORD"; String ALTER_PASSWORD = "PASSWORD";
String ALTER_API_KEY = "API_KEY"; String ALTER_API_KEY = "API_KEY";
String ALTER_DISMISSION = "DISMISSION";
String ALTER_PAGE_NUM = "PAGE_NUM"; String ALTER_PAGE_NUM = "PAGE_NUM";
String ALTER_TOKEN = "TOKEN";
String ALTER_TICKET = "TICKET";
String EMPTY = "";
} }
package com.cmeeting.constant; //package com.cmeeting.constant;
//
/** ///**
* 用户系统功能接口 // * 用户系统功能接口
* // *
* @author hong // * @author hong
*/ // */
public interface UserAdminRouteConstant { //public interface UserAdminRouteConstant {
String ACCESS_TOKEN = "/chatbot/getAccessToken"; // String ACCESS_TOKEN = "/chatbot/getAccessToken";
/** // /**
* 自建用户 // * 自建用户
*/ // */
interface SysUser { // interface SysUser {
/** // /**
* 分类查询接口 // * 分类查询接口
*/ // */
String CATEGORY_TREE = "/chatbot/user/category/tree"; // String CATEGORY_TREE = "/chatbot/user/category/tree";
//
/** // /**
* 创建系统自建用户分类 // * 创建系统自建用户分类
*/ // */
String ADD_CATEGORY = "/chatbot/user/category/add"; // String ADD_CATEGORY = "/chatbot/user/category/add";
//
/** // /**
* 编辑用户分类 // * 编辑用户分类
*/ // */
String EDIT_CATEGORY = "/chatbot/user/category/edit"; // String EDIT_CATEGORY = "/chatbot/user/category/edit";
/** // /**
* 删除用户分类 // * 删除用户分类
*/ // */
String DELETE_CATEGORY = "/chatbot/user/category/remove"; // String DELETE_CATEGORY = "/chatbot/user/category/remove";
/** // /**
* 查询用户列表 // * 查询用户列表
*/ // */
String UPDATE_PASS = "/chatbot/user/updatePass"; // String UPDATE_PASS = "/chatbot/user/updatePass";
String LIST = "/chatbot/user/list"; // String LIST = "/chatbot/user/list";
/** // /**
* 创建用户 // * 创建用户
*/ // */
String ADD = "/chatbot/user/add"; // String ADD = "/chatbot/user/add";
String COUNT = "/chatbot/user/count"; // String COUNT = "/chatbot/user/count";
/** // /**
* 更新用户 // * 更新用户
*/ // */
String EDIT = "/chatbot/user/edit"; // String EDIT = "/chatbot/user/edit";
/** // /**
* 删除用户 // * 删除用户
*/ // */
String DELETE = "/chatbot/user/delete"; // String DELETE = "/chatbot/user/delete";
/** // /**
* 批量删除用户 // * 批量删除用户
*/ // */
String BATCH_DELETE = "/chatbot/user/deleteBatchIds"; // String BATCH_DELETE = "/chatbot/user/deleteBatchIds";
/** // /**
* 用户详情 // * 用户详情
*/ // */
String INFO = "/chatbot/user/info"; // String INFO = "/chatbot/user/info";
/** // /**
* 根据条件查询所有三类用户 // * 根据条件查询所有三类用户
*/ // */
String FIND = "/chatbot/user/find"; // String FIND = "/chatbot/user/find";
String FIND_TENANT_ID = "/chatbot/user/findTenantIdByUserId"; // String FIND_TENANT_ID = "/chatbot/user/findTenantIdByUserId";
String FIND_BY_UID = "/chatbot/user/findByUid"; // String FIND_BY_UID = "/chatbot/user/findByUid";
String FIND_USER_BY_UID = "/chatbot/user/findUserByUid"; // String FIND_USER_BY_UID = "/chatbot/user/findUserByUid";
String FIND_NAME = "/chatbot/user/findName"; //根据用户和分类ID查询对应name // String FIND_NAME = "/chatbot/user/findName"; //根据用户和分类ID查询对应name
String FIND_ADMIN_NAME = "/chatbot/user/findAdminName"; //超管查询根据用户和分类ID查询对应name、checked // String FIND_ADMIN_NAME = "/chatbot/user/findAdminName"; //超管查询根据用户和分类ID查询对应name、checked
String FIND_SHARE_NAME = "/chatbot/user/findShareName"; //超管查询根据用户和分类ID查询对应name、checked // String FIND_SHARE_NAME = "/chatbot/user/findShareName"; //超管查询根据用户和分类ID查询对应name、checked
String INIT = "/chatbot/user/init"; // 创建租户的时候 初始化用户系统 Get请求 参数:tenantId, applicationId // String INIT = "/chatbot/user/init"; // 创建租户的时候 初始化用户系统 Get请求 参数:tenantId, applicationId
//
String PUSH = "/chatbot/user/push"; // String PUSH = "/chatbot/user/push";
String EXPORT = "/chatbot/user/export"; // String EXPORT = "/chatbot/user/export";
} // }
//
/** // /**
* 同步用户 // * 同步用户
*/ // */
interface SyncUser { // interface SyncUser {
String CATEGORY_TREE = "/chatbot/user/sync/category/tree"; // 查询分类 // String CATEGORY_TREE = "/chatbot/user/sync/category/tree"; // 查询分类
String LIST = "/chatbot/user/sync/list"; //查询用户 // String LIST = "/chatbot/user/sync/list"; //查询用户
String FIELD_INFO = "/chatbot/user/sync/field/info"; //查询属性 // String FIELD_INFO = "/chatbot/user/sync/field/info"; //查询属性
String FIELD_UPDATE = "/chatbot/user/sync/field/update"; //更新属性值 // String FIELD_UPDATE = "/chatbot/user/sync/field/update"; //更新属性值
// String ADD = "/chatbot/user/sync/add"; //新增 //// String ADD = "/chatbot/user/sync/add"; //新增
String TREE = "/chatbot/user/sync/tree"; //用户查询 // String TREE = "/chatbot/user/sync/tree"; //用户查询
String INFO = "/chatbot/user/sync/info"; //用户详情 // String INFO = "/chatbot/user/sync/info"; //用户详情
String PUSH = "/chatbot/user/sync/push"; //用户同步 // String PUSH = "/chatbot/user/sync/push"; //用户同步
String ZHONGJI_PUSH = "/chatbot/user/sync/zhongji_push"; //用户同步-中集同步接口 // String ZHONGJI_PUSH = "/chatbot/user/sync/zhongji_push"; //用户同步-中集同步接口
String INIT_TEMP_TABLE = "/chatbot/user/sync/initTempTable"; //初始化临时表 // String INIT_TEMP_TABLE = "/chatbot/user/sync/initTempTable"; //初始化临时表
String HANDEL_PTAH = "/chatbot/user/sync/category/handelPath"; //用户同步后处理分类 // String HANDEL_PTAH = "/chatbot/user/sync/category/handelPath"; //用户同步后处理分类
String COMMIT_OR_ROLLBACK = "/chatbot/user/sync/commitOrRollback"; //用户同步后处理分类 // String COMMIT_OR_ROLLBACK = "/chatbot/user/sync/commitOrRollback"; //用户同步后处理分类
String REMOVE = "/chatbot/user/sync/field/remove"; //属性删除 // String REMOVE = "/chatbot/user/sync/field/remove"; //属性删除
String MOVE = "/chatbot/user/sync/field/move"; //用户同步 // String MOVE = "/chatbot/user/sync/field/move"; //用户同步
String INIT = "/chatbot/user/sync/init"; //用户同步 // String INIT = "/chatbot/user/sync/init"; //用户同步
String DEPART = "/chatbot/user/sync/getAllDeptByUserId"; //用户部门 // String DEPART = "/chatbot/user/sync/getAllDeptByUserId"; //用户部门
//
String TRUNCATE = "/chatbot/user/sync/truncate"; //用户部门 // String TRUNCATE = "/chatbot/user/sync/truncate"; //用户部门
//
String ALL_CHILDREN = "/chatbot/user/sync/children"; //查询部门下所有子部门id以及用户id // String ALL_CHILDREN = "/chatbot/user/sync/children"; //查询部门下所有子部门id以及用户id
String BATCH_DELETE = "/chatbot/user/sync/batchDelete"; //用户部门 // String BATCH_DELETE = "/chatbot/user/sync/batchDelete"; //用户部门
String FIND_DEPT_NAME = "/chatbot/user/sync/getAllDeptByUserId";//查询部门全路径//用户同步 // String FIND_DEPT_NAME = "/chatbot/user/sync/getAllDeptByUserId";//查询部门全路径//用户同步
//
String ADMIN_LIST = "/chatbot/user/sync/adminList"; //超管同步用户授权给租户查询 // String ADMIN_LIST = "/chatbot/user/sync/adminList"; //超管同步用户授权给租户查询
String AUTH_LIST = "/chatbot/user/sync/authList"; //超管同步用户已授权用户/部门查询 // String AUTH_LIST = "/chatbot/user/sync/authList"; //超管同步用户已授权用户/部门查询
String AUTH = "/chatbot/user/sync/auth"; //超管同步用户已授权用户/部门查询 // String AUTH = "/chatbot/user/sync/auth"; //超管同步用户已授权用户/部门查询
String REMOVE_AUTH = "/chatbot/user/sync/removeAuth"; //超管同步用户已授权用户/部门查询 // String REMOVE_AUTH = "/chatbot/user/sync/removeAuth"; //超管同步用户已授权用户/部门查询
String SHARE_TREE = "/chatbot/shareUser/tree"; //超管分享的部门查询 // String SHARE_TREE = "/chatbot/shareUser/tree"; //超管分享的部门查询
String SHARE_LIST = "/chatbot/shareUser/list"; //超管分享的用户查询 // String SHARE_LIST = "/chatbot/shareUser/list"; //超管分享的用户查询
//
} // }
//
/** // /**
* 应用用户 // * 应用用户
*/ // */
interface ApplicationUser { // interface ApplicationUser {
String ADD_CATEGORY = "/chatbot/user/application/category/add"; // 新增分类 // String ADD_CATEGORY = "/chatbot/user/application/category/add"; // 新增分类
String EDIT_CATEGORY = "/chatbot/user/application/category/edit"; // 编辑分类 // String EDIT_CATEGORY = "/chatbot/user/application/category/edit"; // 编辑分类
String CATEGORY_TREE = "/chatbot/user/application/category/tree"; // 查询分类 // String CATEGORY_TREE = "/chatbot/user/application/category/tree"; // 查询分类
String DELETE_CATEGORY = "/chatbot/user/application/category/remove"; // 删除分类 // String DELETE_CATEGORY = "/chatbot/user/application/category/remove"; // 删除分类
String ADD = "/chatbot/user/application/add"; // 新增用户 // String ADD = "/chatbot/user/application/add"; // 新增用户
String EDIT = "/chatbot/user/application/edit"; // 编辑用户信息 // String EDIT = "/chatbot/user/application/edit"; // 编辑用户信息
String BATCH_EDIT = "/chatbot/user/application/batchEdit"; // 编辑用户信息 // String BATCH_EDIT = "/chatbot/user/application/batchEdit"; // 编辑用户信息
String BATCH_DELETE = "/chatbot/user/application/batchDelete"; // 编辑用户信息 // String BATCH_DELETE = "/chatbot/user/application/batchDelete"; // 编辑用户信息
//
String DELETE = "/chatbot/user/application/delete"; // 删除用户 // String DELETE = "/chatbot/user/application/delete"; // 删除用户
String LIST = "/chatbot/user/application/list"; // 用户列表 // String LIST = "/chatbot/user/application/list"; // 用户列表
String INFO = "/chatbot/user/application/info"; // 用户详情 // String INFO = "/chatbot/user/application/info"; // 用户详情
} // }
interface Report{ // interface Report{
String COUNT = "/chatbot/report/user/count"; // 应用用户+系统用户 总计和新增 // String COUNT = "/chatbot/report/user/count"; // 应用用户+系统用户 总计和新增
} // }
//
//
} //}
...@@ -9,7 +9,6 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -9,7 +9,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.Date; import java.util.Date;
......
...@@ -358,7 +358,13 @@ public class CmeetingJob { ...@@ -358,7 +358,13 @@ public class CmeetingJob {
*/ */
@Scheduled(cron = "0 0 6 * * ? ") @Scheduled(cron = "0 0 6 * * ? ")
public void pullAllDate() { public void pullAllDate() {
if (isDev) {
return;
}
log.info("同步用户开始");
long l = System.currentTimeMillis();
cimcService.pullCimcData(); cimcService.pullCimcData();
log.info("同步用户结束,耗时: {}ms", System.currentTimeMillis() - l);
} }
......
...@@ -4,15 +4,12 @@ import cn.chatbot.meeting.LLMConfig; ...@@ -4,15 +4,12 @@ import cn.chatbot.meeting.LLMConfig;
import cn.chatbot.meeting.LLMResult; import cn.chatbot.meeting.LLMResult;
import cn.chatbot.meeting.MeetingProcess; import cn.chatbot.meeting.MeetingProcess;
import cn.chatbot.openai.completion.chat.ChatCompletionRequest; import cn.chatbot.openai.completion.chat.ChatCompletionRequest;
import cn.chatbot.openai.completion.chat.ChatMessage;
import cn.chatbot.openai.completion.chat.ChatMessageRole;
import cn.chatbot.openai.completion.chat.Message; import cn.chatbot.openai.completion.chat.Message;
import cn.chatbot.openai.service.LLMService; import cn.chatbot.openai.service.LLMService;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
...@@ -20,9 +17,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; ...@@ -20,9 +17,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cmeeting.constant.KnowledgePlatformRouteConstant; import com.cmeeting.constant.KnowledgePlatformRouteConstant;
import com.cmeeting.constant.MeetingState; import com.cmeeting.constant.MeetingState;
import com.cmeeting.constant.RecordTemplateConstant;
import com.cmeeting.dto.DocResultDto; import com.cmeeting.dto.DocResultDto;
import com.cmeeting.dto.MeetTypeDto;
import com.cmeeting.dto.UserDTO; import com.cmeeting.dto.UserDTO;
import com.cmeeting.email.EmailSender; import com.cmeeting.email.EmailSender;
import com.cmeeting.exception.RobotBaseException; import com.cmeeting.exception.RobotBaseException;
...@@ -41,14 +36,8 @@ import com.deepoove.poi.XWPFTemplate; ...@@ -41,14 +36,8 @@ import com.deepoove.poi.XWPFTemplate;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.tencentcloudapi.wemeet.Client; import com.tencentcloudapi.wemeet.service.meetings.model.V1MeetingsMeetingIdParticipantsGet200Response;
import com.tencentcloudapi.wemeet.core.authenticator.AuthenticatorBuilder; import com.tencentcloudapi.wemeet.service.meetings.model.V1MeetingsMeetingIdParticipantsGet200ResponseParticipantsInner;
import com.tencentcloudapi.wemeet.core.authenticator.JWTAuthenticator;
import com.tencentcloudapi.wemeet.service.meetings.api.MeetingsApi;
import com.tencentcloudapi.wemeet.service.meetings.model.*;
import com.tencentcloudapi.wemeet.service.records.api.RecordsApi;
import com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200Response;
import com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200ResponseAiMeetingTranscriptsInner;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -64,10 +53,8 @@ import org.springframework.util.CollectionUtils; ...@@ -64,10 +53,8 @@ import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.*; import java.io.*;
import java.math.BigInteger;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
...@@ -321,42 +308,6 @@ public class FileProcessTask { ...@@ -321,42 +308,6 @@ public class FileProcessTask {
log.info("线程结束, 耗时: {} ms", System.currentTimeMillis() - l); log.info("线程结束, 耗时: {} ms", System.currentTimeMillis() - l);
} }
private byte[] downloadFile(String url) {
// 实现文件下载逻辑
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
try {
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
return response.body().bytes();
} catch (Exception e) {
throw new RuntimeException("下载文件失败", e);
}
}
private String getRecordTextContent(byte[] fileData) {
// 定义文件路径和文件名
String fullPath = savePath + (System.currentTimeMillis() / 1000L) + ".docx";
// 将字节内容写入本地文件
try (FileOutputStream fos = new FileOutputStream(fullPath)) {
fos.write(fileData);
log.info("DOCX transcript saved to: {}", fullPath);
} catch (IOException e) {
log.error("Error saving DOCX transcript to file: {}", e.getMessage(), e);
}
XWPFDocument document;
try {
FileInputStream fis = new FileInputStream(fullPath);
document = new XWPFDocument(fis);
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
XWPFWordExtractor extractor = new XWPFWordExtractor(document);
String textContent = extractor.getText();
log.info("DOCX content as string:\n{}", textContent);
return textContent;
}
/** /**
* 提供会议转录文件和会议主题,判断会议类型 * 提供会议转录文件和会议主题,判断会议类型
* *
...@@ -426,10 +377,6 @@ public class FileProcessTask { ...@@ -426,10 +377,6 @@ public class FileProcessTask {
return type; return type;
} }
private String formatMessage(String pattern, Object... args) {
return MessageFormat.format(pattern, args);
}
/** /**
* 大模型生成纪要xml * 大模型生成纪要xml
* *
...@@ -621,35 +568,6 @@ public class FileProcessTask { ...@@ -621,35 +568,6 @@ public class FileProcessTask {
); );
} }
private String convertXmlToJSON(String xml) {
String json;
try {
XmlMapper xmlMapper = new XmlMapper();
JsonNode rootNode = xmlMapper.readTree(xml.getBytes());
// 正确获取节点和属性的方式
List<Map> list = new ArrayList<>();
Iterator<String> iterator = rootNode.fieldNames();
while (iterator.hasNext()) {
String tagName = iterator.next();
JsonNode subNode = rootNode.path(tagName);
String displayName = subNode.path("label").asText();
String content = subNode.path("").asText();
list.add(new HashMap() {{
put("key", tagName + "/" + displayName);
put("value", content);
}});
}
// 构建JSON对象
ObjectMapper jsonMapper = new ObjectMapper();
json = jsonMapper.writeValueAsString(list);
} catch (IOException e) {
log.error(e.getMessage());
throw new RuntimeException(e.getMessage());
}
return json;
}
private String call_llm(String apiAddr, String model, String token, List<Message> messages, int maxTokens) { private String call_llm(String apiAddr, String model, String token, List<Message> messages, int maxTokens) {
LLMService service = new LLMService(token, apiAddr); LLMService service = new LLMService(token, apiAddr);
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
...@@ -736,7 +654,7 @@ public class FileProcessTask { ...@@ -736,7 +654,7 @@ public class FileProcessTask {
MeetingInfoMapper meetingInfoMapper, MinioUtils minioUtils, RedisUtils redisUtils, EmailSender emailSender, MeetingInfoMapper meetingInfoMapper, MinioUtils minioUtils, RedisUtils redisUtils, EmailSender emailSender,
MeetingRecordTemplateMapper meetingRecordTemplateMapper, MeetingRecordTemplateService meetingRecordTemplateService, MeetTypeService meetTypeService, UserIdMapper userIdMapper, MeetingRecordTemplateMapper meetingRecordTemplateMapper, MeetingRecordTemplateService meetingRecordTemplateService, MeetTypeService meetTypeService, UserIdMapper userIdMapper,
String llmApiAddr, Boolean finalRetry, ProcessLogService processLogService, List<UserDTO.TemplateAuthorizedUserDTO> authorizedUsers, Map<String, String> tidWidRelations, String llmApiAddr, Boolean finalRetry, ProcessLogService processLogService, List<UserDTO.TemplateAuthorizedUserDTO> authorizedUsers, Map<String, String> tidWidRelations,
UserAdminConfig userAdminConfig, String adminToken, String applicationId, String fileDownloadPath, String permTenantId, UserAdminConfig userAdminConfig, String applicationId, String fileDownloadPath, String permTenantId,
String aesKey) { String aesKey) {
this.recordFileIdList = recordFileIdList; this.recordFileIdList = recordFileIdList;
this.savePath = savePath; this.savePath = savePath;
...@@ -757,7 +675,6 @@ public class FileProcessTask { ...@@ -757,7 +675,6 @@ public class FileProcessTask {
this.authorizedUsers = authorizedUsers; this.authorizedUsers = authorizedUsers;
this.tidWidRelations = tidWidRelations; this.tidWidRelations = tidWidRelations;
this.userAdminConfig = userAdminConfig; this.userAdminConfig = userAdminConfig;
this.adminToken = adminToken;
this.applicationId = applicationId; this.applicationId = applicationId;
this.fileDownloadPath = fileDownloadPath; this.fileDownloadPath = fileDownloadPath;
this.permTenantId = permTenantId; this.permTenantId = permTenantId;
......
...@@ -15,7 +15,6 @@ public class ProcessLogServiceImpl extends ServiceImpl<ProcessLogMapper, Process ...@@ -15,7 +15,6 @@ public class ProcessLogServiceImpl extends ServiceImpl<ProcessLogMapper, Process
@Override @Override
public boolean log(String meetingId, String subMeetingId, String message) { public boolean log(String meetingId, String subMeetingId, String message) {
ProcessLog processLog = ProcessLog.builder().meetingId(meetingId).subMeetingId(subMeetingId).message(message).operateTime(LocalDateTime.now()).build(); ProcessLog processLog = ProcessLog.builder().meetingId(meetingId).subMeetingId(subMeetingId).message(message).operateTime(LocalDateTime.now()).build();
boolean save = save(processLog); return save(processLog);
return save;
} }
} }
...@@ -9,5 +9,11 @@ import java.util.List; ...@@ -9,5 +9,11 @@ import java.util.List;
@Mapper @Mapper
public interface AuthMapper { public interface AuthMapper {
/**
* 智能体权限查询
* @param targetId
* @param tenantId
* @return
*/
List<CoreModulePermissions> getAuthByTargetId(@Param("targetId") String targetId, @Param("tenantId") String tenantId); List<CoreModulePermissions> getAuthByTargetId(@Param("targetId") String targetId, @Param("tenantId") String tenantId);
} }
//package com.cmeeting.mapper.secondary;
//
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.cmeeting.pojo.ShareUser;
//import org.apache.ibatis.annotations.Param;
//
//import java.util.List;
//
///**
// * (ShareUser)表数据库访问层
// *
// * @author makejava
// * @since 2025-01-16 14:50:16
// */
//public interface ShareUserMapper extends BaseMapper<ShareUser> {
//
//}
...@@ -2,7 +2,6 @@ package com.cmeeting.mapper.primary; ...@@ -2,7 +2,6 @@ package com.cmeeting.mapper.primary;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cmeeting.pojo.TencentMeetingUser; import com.cmeeting.pojo.TencentMeetingUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
......
package com.cmeeting.pojo; package com.cmeeting.pojo;
import lombok.AllArgsConstructor; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.NoArgsConstructor; import lombok.*;
import lombok.experimental.Accessors;
import java.util.Date; import java.util.Date;
...@@ -14,6 +15,11 @@ import java.util.Date; ...@@ -14,6 +15,11 @@ import java.util.Date;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("core_module_permissions")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CoreModulePermissions { public class CoreModulePermissions {
/** /**
* 主键ID * 主键ID
......
package com.cmeeting.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* (ShareUser)实体类
*
* @author makejava
* @since 2025-01-16 14:50:14
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("share_user")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ShareUser implements Serializable {
private static final long serialVersionUID = -15064516326494187L;
/**
* 单个用户id或者分类id
*/
private String relId;
/**
* 0 分类 1用户
*/
private Integer type;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 0-正常,1-删除
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
private boolean isDel;
/**
* 用户创建人
*/
private String createUser;
/**
* 更新者
*/
private String updateUser;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date updateTime;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date createTime;
/**
* 租户id
*/
private String tenantId;
}
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;
}
// pojo/User.java
package com.cmeeting.pojo;
import lombok.Data;
@Data
public class User {
private Long id;
private String username;
private String password;
private String salt;
// 其他字段...
public User() {
}
public User(Long id, String username, String password, String salt) {
this.id = id;
this.username = username;
this.password = password;
this.salt = salt;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", salt='" + salt + '\'' +
'}';
}
}
\ No newline at end of file
package com.cmeeting.pojo;
import lombok.Data;
@Data
public class UserCompany {
private Integer id; // 对应表中的 `id`
private String userName; // 对应表中的 `user_name`
private String phone; // 对应表中的 `phone`
private String email; // 对应表中的 `emaill`(注意拼写修正为 email)
private String address; // 对应表中的 `address`
private String userId; // 对应表中的 `user_id`
// 无参构造方法
public UserCompany() {
}
// 全参构造方法
public UserCompany(Integer id, String userName, String phone, String email, String address, String userId) {
this.id = id;
this.userName = userName;
this.phone = phone;
this.email = email;
this.address = address;
this.userId = userId;
}
@Override
public String toString() {
return "UserCompany{" +
"id=" + id +
", userName='" + userName + '\'' +
", phone='" + phone + '\'' +
", email='" + email + '\'' +
", address='" + address + '\'' +
", userId='" + userId + '\'' +
'}';
}
}
\ No newline at end of file
...@@ -8,11 +8,9 @@ import com.cmeeting.log.service.ProcessLogService; ...@@ -8,11 +8,9 @@ import com.cmeeting.log.service.ProcessLogService;
import com.cmeeting.mapper.primary.MeetingInfoMapper; import com.cmeeting.mapper.primary.MeetingInfoMapper;
import com.cmeeting.mapper.primary.MeetingRecordTemplateMapper; import com.cmeeting.mapper.primary.MeetingRecordTemplateMapper;
import com.cmeeting.mapper.primary.UserIdMapper; import com.cmeeting.mapper.primary.UserIdMapper;
import com.cmeeting.pojo.UserId;
import com.cmeeting.util.MinioUtils; import com.cmeeting.util.MinioUtils;
import com.cmeeting.util.RedisUtils; import com.cmeeting.util.RedisUtils;
import com.cmeeting.util.UserAdminConfig; import com.cmeeting.util.UserAdminConfig;
import com.cmeeting.util.UserAdminTokenUtil;
import com.cmeeting.vo.TencentMeetingVO; import com.cmeeting.vo.TencentMeetingVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -83,7 +81,6 @@ public class FileProcessProducer { ...@@ -83,7 +81,6 @@ public class FileProcessProducer {
*/ */
public void submitBatchTasks(List<TencentMeetingVO.RecordFile> recordFiles, List<UserDTO.TemplateAuthorizedUserDTO> authorizedUsers, Map<String, String> tidWidRelations, Boolean finalRetry) { public void submitBatchTasks(List<TencentMeetingVO.RecordFile> recordFiles, List<UserDTO.TemplateAuthorizedUserDTO> authorizedUsers, Map<String, String> tidWidRelations, Boolean finalRetry) {
List<Future<?>> futures = new ArrayList<>(); List<Future<?>> futures = new ArrayList<>();
String adminToken = UserAdminTokenUtil.getUserAdminToken();
log.info("待处理会议数量: {}", recordFiles.size()); log.info("待处理会议数量: {}", recordFiles.size());
for (TencentMeetingVO.RecordFile recordFile : recordFiles) { for (TencentMeetingVO.RecordFile recordFile : recordFiles) {
// 为每个URL创建任务 // 为每个URL创建任务
...@@ -107,7 +104,6 @@ public class FileProcessProducer { ...@@ -107,7 +104,6 @@ public class FileProcessProducer {
authorizedUsers, authorizedUsers,
tidWidRelations, tidWidRelations,
userAdminConfig, userAdminConfig,
adminToken,
applicationId, applicationId,
fileDownloadPath, fileDownloadPath,
permTenantId, permTenantId,
......
...@@ -21,17 +21,13 @@ import java.util.List; ...@@ -21,17 +21,13 @@ import java.util.List;
@Slf4j @Slf4j
@Component @Component
public class CimcUtil implements CimcConstants { public class CimcUtil implements CimcConstants {
@Value("${cimc.loginApiKey-test}")
public String loginApiKey = "faBqIHbXOtDIbguxJ7F55QhL04jIRekJ";//生产 Jj8UONm74FRxOSMnlIN95pVVUJf5Nn2D 测试 faBqIHbXOtDIbguxJ7F55QhL04jIRekJ
@Value("${cimc.loginApiKey-prod}")
public String prodLoginApiKey = "Jj8UONm74FRxOSMnlIN95pVVUJf5Nn2D";//生产 Jj8UONm74FRxOSMnlIN95pVVUJf5Nn2D 测试 faBqIHbXOtDIbguxJ7F55QhL04jIRekJ
@Value("${cimc.username}") @Value("${cimc.username}")
public String username; public String username;
@Value("${cimc.password}") @Value("${cimc.password}")
public String password; public String password;
@Value("${cimc.apiKey}") @Value("${cimc.apiKey}")
public String apiKey;//同步apiKey public String apiKey;
@Value("${cimc.userinfo-environment}") @Value("${cimc.userinfo-environment}")
public String userInfoEnvironment; public String userInfoEnvironment;
......
package com.cmeeting.util;
import com.alibaba.fastjson.JSONObject;
import com.cmeeting.constant.UserAdminRouteConstant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* @author a
*/
@Component
public class UserAdminTokenUtil {
@Resource
private RedisUtils redisUtils;
@Resource
private UserAdminConfig userAdminConfig;
@Value("${userAdmin.appId}")
private String appId;
@Value("${userAdmin.secret}")
private String secret;
private String getAccessToken() {
String key = "user_admin_token_" + appId;
Object o = redisUtils.get(key);
if (o != null) {
return o.toString();
}
String url = userAdminConfig.getUserAdminDomain() + UserAdminRouteConstant.ACCESS_TOKEN;
JSONObject body = new JSONObject();
body.put("appId", appId);
body.put("secret", secret);
JSONObject object = HttpClientUtils.httpPost(url, body, null);
if (object != null && object.getInteger("code") == 0) {
String data = object.getString("data");
redisUtils.set(key, data, 7000);
return data;
} else {
throw new RuntimeException("获取accessToken失败");
}
}
private static UserAdminTokenUtil util;
@PostConstruct
public void init() {
util = this;
}
public static String getUserAdminToken() {
return util.getAccessToken();
}
}
...@@ -146,12 +146,8 @@ userAdmin: ...@@ -146,12 +146,8 @@ userAdmin:
jwt: jwt:
header: Authorization header: Authorization
customHeader: 'Custom-Auth-Token'
applicationId: 'Application-Id'
tokenHead: 'Bearer ' tokenHead: 'Bearer '
openingUp-header: 'aigc-open-auth-token'
expireTime: 36000 expireTime: 36000
customExpireTime: 36000 # 5天
permission: permission:
applicationId: ${PERMISSION_APPLiCATION_ID} applicationId: ${PERMISSION_APPLiCATION_ID}
...@@ -178,3 +174,10 @@ statistics: ...@@ -178,3 +174,10 @@ statistics:
toEmails: toEmails:
- user: - user:
email: hongdongbao@chatbot.cn email: hongdongbao@chatbot.cn
# 同步组织架构信息用 HR账号密码
cimc:
username: cimc_AIGC
password: 4A6BEB75A7017F4BC4D381C2CBB0E6FB
apiKey: Jj8UONm74FRxOSMnlIN95pVVUJf5Nn2D
userinfo-environment: test
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论