Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -42,48 +42,50 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
@RequestMapping("/aitutor/aichat")
|
@RequestMapping("/aitutor/aichat")
|
||||||
public class AiChatController extends BaseController {
|
public class AiChatController extends BaseController {
|
||||||
|
|
||||||
|
// private static final String DIFY_BASE_URL = "http://172.16.129.101:6100";
|
||||||
|
private static final String DIFY_BASE_URL = "http://47.112.118.149:8100";
|
||||||
/**
|
/**
|
||||||
* Dify API的访问密钥
|
* Dify API的访问密钥
|
||||||
* 用于身份验证,授权访问Dify服务
|
* 用于身份验证,授权访问Dify服务
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_API_KEY = "app-BfPtBZDNBuHOS9K1PaZrxQYE";
|
// private static final String DIFY_API_KEY = "app-BfPtBZDNBuHOS9K1PaZrxQYE";
|
||||||
|
private static final String DIFY_API_KEY = "app-2wjqcYI9n6igHTVHdH8qXlnh";
|
||||||
/**
|
/**
|
||||||
* Dify API的URL地址
|
* Dify API的URL地址
|
||||||
* 用于发送聊天消息请求到Dify服务
|
* 用于发送聊天消息请求到Dify服务
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private static final String DIFY_API_URL = "http://172.16.129.101/v1:6100/v1/chat-messages";
|
private static final String DIFY_API_URL = DIFY_BASE_URL+"/v1/chat-messages";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify反馈API的基础URL
|
* Dify反馈API的基础URL
|
||||||
* 用于提交消息反馈(点赞、点踩等)
|
* 用于提交消息反馈(点赞、点踩等)
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_FEEDBACK_BASE_URL = "http://172.16.129.101/v1:6100/v1/messages";
|
private static final String DIFY_FEEDBACK_BASE_URL = DIFY_BASE_URL+"/v1/messages";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify获取反馈API的基础URL
|
* Dify获取反馈API的基础URL
|
||||||
* 用于获取消息反馈(点赞、点踩等)
|
* 用于获取消息反馈(点赞、点踩等)
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_API_FEEDBACK_URL = "http://172.16.129.101/v1:6100/v1/app/feedbacks?page=";
|
private static final String DIFY_API_FEEDBACK_URL = DIFY_BASE_URL+"/v1/app/feedbacks?page=";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify消息历史记录API的基础URL
|
* Dify消息历史记录API的基础URL
|
||||||
* 用于获取消息历史记录
|
* 用于获取消息历史记录
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_API_HISTORY_URL = "http://172.16.129.101/v1:6100/v1/messages";
|
private static final String DIFY_API_HISTORY_URL = DIFY_BASE_URL+"/v1/messages";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify会话API的基础URL
|
* Dify会话API的基础URL
|
||||||
* 用于获取会话列表
|
* 用于获取会话列表
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_CONVERSATIONS_URL = "http://172.16.129.101/v1:6100/v1/conversations";
|
private static final String DIFY_CONVERSATIONS_URL = DIFY_BASE_URL+"/v1/conversations";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify文件上传API的URL地址
|
* Dify文件上传API的URL地址
|
||||||
* 用于上传文件到Dify服务,支持图文多模态理解
|
* 用于上传文件到Dify服务,支持图文多模态理解
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_FILES_URL = "http://172.16.129.101/v1:6100/v1/files/upload";
|
private static final String DIFY_FILES_URL = DIFY_BASE_URL+"/v1/files/upload";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redis中会话ID的key前缀
|
* Redis中会话ID的key前缀
|
||||||
@@ -532,7 +534,7 @@ public class AiChatController extends BaseController {
|
|||||||
return successResult;
|
return successResult;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return AjaxResult.error("网络请求失败,请稍后重试");
|
return AjaxResult.error("网络请求失败,请稍后重试getMessagesToAdmin");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return AjaxResult.error("请求处理失败: " + e.getMessage());
|
return AjaxResult.error("请求处理失败: " + e.getMessage());
|
||||||
@@ -571,7 +573,7 @@ public class AiChatController extends BaseController {
|
|||||||
return successResult;
|
return successResult;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return AjaxResult.error("网络请求失败,请稍后重试");
|
return AjaxResult.error("网络请求失败,请稍后重试getMessagesToUser");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return AjaxResult.error("请求处理失败: " + e.getMessage());
|
return AjaxResult.error("请求处理失败: " + e.getMessage());
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ public class WeChatUtil {
|
|||||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
|
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
|
||||||
|
|
||||||
JSONObject msg = new JSONObject();
|
JSONObject msg = new JSONObject();
|
||||||
msg.put("touser", toUser);
|
msg.put("touser", "2023429229");
|
||||||
msg.put("msgtype", "text");
|
msg.put("msgtype", "text");
|
||||||
msg.put("agentid", weChatConfig.getAgentId());
|
msg.put("agentid", weChatConfig.getAgentId());
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.srs.flowable.listener.disciplinary;
|
package com.srs.flowable.listener.disciplinary;
|
||||||
|
|
||||||
|
import com.srs.common.utils.WeChatUtil;
|
||||||
import com.srs.common.utils.spring.SpringUtils;
|
import com.srs.common.utils.spring.SpringUtils;
|
||||||
import com.srs.flowable.mapper.DisciplinaryMapper;
|
import com.srs.flowable.mapper.DisciplinaryMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -14,9 +15,10 @@ import org.springframework.stereotype.Component;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class EJXYSJListener implements ExecutionListener {
|
public class EJXYSJListener implements ExecutionListener {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notify(DelegateExecution delegateExecution) {
|
public void notify(DelegateExecution delegateExecution) {
|
||||||
DisciplinaryMapper disciplinaryMapper = (DisciplinaryMapper)SpringUtils.getBean("disciplinaryMapper");
|
DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean("disciplinaryMapper");
|
||||||
|
|
||||||
Long deptId = (Long) delegateExecution.getVariable("deptId");
|
Long deptId = (Long) delegateExecution.getVariable("deptId");
|
||||||
|
|
||||||
@@ -24,7 +26,29 @@ public class EJXYSJListener implements ExecutionListener {
|
|||||||
if (userId!=null){
|
if (userId!=null){
|
||||||
delegateExecution.setVariable("approval", userId);
|
delegateExecution.setVariable("approval", userId);
|
||||||
// todo 企业微信推送消息
|
// todo 企业微信推送消息
|
||||||
|
// --- 企业微信推送消息模块 ---
|
||||||
|
try {
|
||||||
|
// 步骤 2: 【关键】使用 userId 查询对应的企业微信账号 (userName)
|
||||||
|
String userName = disciplinaryMapper.getUserNameByUserId(userId);
|
||||||
|
|
||||||
|
// 步骤 3: 检查 userName 是否存在
|
||||||
|
if (userName != null && !userName.isEmpty()) {
|
||||||
|
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||||
|
|
||||||
|
// 构造包含超链接的消息内容
|
||||||
|
String content = "您有一条新的学生违纪审批任务待处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||||
|
|
||||||
|
// 步骤 4: 【关键】使用 userName 作为接收人发送消息
|
||||||
|
weChatUtil.sendTextMessage(userName, content);
|
||||||
|
log.info("已成功向二级学院书记(userName:{})发送企业微信审批通知。", userName);
|
||||||
|
} else {
|
||||||
|
// 如果找不到userName,记录警告日志,但流程继续
|
||||||
|
log.warn("找到了二级学院书记审批人(userId:{}),但其对应的企业微信账号(userName)为空,无法发送通知。", userId);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 保证即使通知失败,流程也能继续
|
||||||
|
log.error("向二级学院书记(userId:{})发送企业微信通知时出现异常。流程将继续。错误详情: {}", userId, e.getMessage(), e);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
throw new RuntimeException("该二级学院书记审批人未配置");
|
throw new RuntimeException("该二级学院书记审批人未配置");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,5 @@ public class StuInfoListener implements ExecutionListener {
|
|||||||
log.info("学生信息:{}",stuId);
|
log.info("学生信息:{}",stuId);
|
||||||
delegateExecution.setVariable("approval",stuId);
|
delegateExecution.setVariable("approval",stuId);
|
||||||
// todo 企业微信推送消息
|
// todo 企业微信推送消息
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.srs.flowable.listener.disciplinary;
|
||||||
|
|
||||||
|
import com.srs.common.utils.WeChatUtil;
|
||||||
|
import com.srs.common.utils.spring.SpringUtils;
|
||||||
|
import com.srs.flowable.mapper.DisciplinaryMapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.flowable.engine.delegate.ExecutionListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生教育管理科审核节点的执行监听器。
|
||||||
|
* 向“学生教育管理科”角色发送企业微信通知。
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class XSJYGLKListener implements ExecutionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(DelegateExecution delegateExecution) {
|
||||||
|
DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean(DisciplinaryMapper.class);
|
||||||
|
|
||||||
|
// 1. 【核心】定义“学生教育管理科”xsjyglksh
|
||||||
|
final String TARGET_ROLE_KEY = "xsjyglksh";
|
||||||
|
log.info("流程实例 [{}]: 准备向角色 '{}' 发送通知。", delegateExecution.getProcessInstanceId(), TARGET_ROLE_KEY);
|
||||||
|
|
||||||
|
// 2. 根据这个固定的角色Key,查询该角色的所有成员ID(即使只有一个)。
|
||||||
|
List<Long> userIdList = disciplinaryMapper.getApprovalByRoleKey(TARGET_ROLE_KEY);
|
||||||
|
|
||||||
|
// 3. 检查是否找到了成员。
|
||||||
|
if (userIdList == null || userIdList.isEmpty()) {
|
||||||
|
log.error("根据角色Key '{}' 未找到任何用户,无法发送通知。", TARGET_ROLE_KEY);
|
||||||
|
return; // 中止执行,不抛出异常以免中断流程
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 发送企业微信通知。
|
||||||
|
// (我们的批量发送逻辑即使只有一个用户也能完美处理)
|
||||||
|
try {
|
||||||
|
// 批量查询userName (即使只有一个ID,这个方法也能正常工作)
|
||||||
|
List<String> userNameList = disciplinaryMapper.getUserNamesByUserIdList(userIdList);
|
||||||
|
|
||||||
|
if (!userNameList.isEmpty()) {
|
||||||
|
// 将列表拼接成 "username1|username2|..." 的格式
|
||||||
|
String toUser = String.join("|", userNameList);
|
||||||
|
|
||||||
|
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||||
|
String content = "您有一条新的学生违纪审批任务待处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||||
|
|
||||||
|
weChatUtil.sendTextMessage(toUser, content);
|
||||||
|
log.info("已成功向角色 '{}' 的成员发送通知。接收人: {}", TARGET_ROLE_KEY, toUser);
|
||||||
|
} else {
|
||||||
|
log.warn("角色 '{}' 中找到了 {} 个用户,但无人配置企业微信账号,未发送任何通知。", TARGET_ROLE_KEY, userIdList.size());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("向角色 '{}' 发送企业微信通知时出现异常。流程将继续。错误详情: {}", TARGET_ROLE_KEY, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,7 +45,7 @@ public class XWGSListener implements ExecutionListener {
|
|||||||
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||||
|
|
||||||
// 构造包含超链接的消息内容
|
// 构造包含超链接的消息内容
|
||||||
String content = "您有一条新的学生违纪审批任务待处理,<a href='/pages/Approval/index'>请点击前往处理</a>。";
|
String content = "您有一条新的学生违纪审批任务待处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||||
|
|
||||||
// 步骤 4: 使用 userName 作为接收人发送消息
|
// 步骤 4: 使用 userName 作为接收人发送消息
|
||||||
weChatUtil.sendTextMessage(userName, content);
|
weChatUtil.sendTextMessage(userName, content);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.srs.flowable.listener.disciplinary;
|
package com.srs.flowable.listener.disciplinary;
|
||||||
|
|
||||||
|
import com.srs.common.utils.WeChatUtil;
|
||||||
import com.srs.common.utils.spring.SpringUtils;
|
import com.srs.common.utils.spring.SpringUtils;
|
||||||
import com.srs.flowable.mapper.DisciplinaryMapper;
|
import com.srs.flowable.mapper.DisciplinaryMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -18,15 +19,36 @@ public class XYWJCLWYHListener implements ExecutionListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notify(DelegateExecution delegateExecution) {
|
public void notify(DelegateExecution delegateExecution) {
|
||||||
DisciplinaryMapper disciplinaryMapper = (DisciplinaryMapper)SpringUtils.getBean("disciplinaryMapper");
|
DisciplinaryMapper disciplinaryMapper = SpringUtils.getBean("disciplinaryMapper");
|
||||||
List<Long> xywjclwyh = disciplinaryMapper.getApprovalByRoleKey("xywjclwyh");
|
// 步骤 1: 根据角色Key获取审批人ID列表 (第1次DB查询)
|
||||||
if (xywjclwyh.size() == 0){
|
List<Long> userIdList = disciplinaryMapper.getApprovalByRoleKey("xywjclwyh");
|
||||||
|
if (userIdList == null || userIdList.isEmpty()){
|
||||||
log.error("未找到角色相关信息");
|
log.error("未找到角色相关信息");
|
||||||
throw new RuntimeException("学院违纪处理委员会审批人员未设置");
|
throw new RuntimeException("学院违纪处理委员会审批人员未设置");
|
||||||
}else{
|
}else{
|
||||||
delegateExecution.setVariable("userList",xywjclwyh);
|
delegateExecution.setVariable("userList",userIdList);
|
||||||
// todo 企业微信推送消息
|
// todo 企业微信推送消息
|
||||||
|
// --- 企业微信推送消息模块 ---
|
||||||
|
try {
|
||||||
|
// 步骤 2: 一次性批量查询所有有效的userName (第2次DB查询,性能最优)
|
||||||
|
List<String> userNameList = disciplinaryMapper.getUserNamesByUserIdList(userIdList);
|
||||||
|
|
||||||
|
if (!userNameList.isEmpty()) {
|
||||||
|
// 步骤 3: 将 userName 列表用 "|" 连接成一个字符串
|
||||||
|
String toUser = String.join("|", userNameList);
|
||||||
|
|
||||||
|
WeChatUtil weChatUtil = SpringUtils.getBean(WeChatUtil.class);
|
||||||
|
String content = "您有一条新的学生违纪审批任务待处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||||
|
|
||||||
|
weChatUtil.sendTextMessage(toUser, content);
|
||||||
|
log.info("已成功向学院违纪处理委员会发送群组通知。接收人: {}", toUser);
|
||||||
|
} else {
|
||||||
|
log.warn("角色 'xywjclwyh' 存在审批人,但无人配置企业微信账号,未发送任何通知。");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 保证即使通知失败,流程也能继续
|
||||||
|
log.error("向学院违纪处理委员会发送企业微信通知时出现异常。流程将继续。错误详情: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ public interface DisciplinaryMapper {
|
|||||||
* @return 用户的username
|
* @return 用户的username
|
||||||
*/
|
*/
|
||||||
String getUserNameByUserId(@Param("userId") Long userId);
|
String getUserNameByUserId(@Param("userId") Long userId);
|
||||||
|
/**
|
||||||
|
* 知无涯新增:根据用户ID列表批量查询用户名列表
|
||||||
|
* @param userIdList 用户ID列表
|
||||||
|
* @return 用户的username列表
|
||||||
|
*/
|
||||||
|
List<String> getUserNamesByUserIdList(@Param("userIdList") List<Long> userIdList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据rolekey获取该角色的用户信息,审批
|
* 根据rolekey获取该角色的用户信息,审批
|
||||||
|
|||||||
@@ -106,5 +106,15 @@
|
|||||||
SELECT user_name FROM sys_user WHERE user_id = #{userId}
|
SELECT user_name FROM sys_user WHERE user_id = #{userId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 知无涯 新增:批量查询用户名的SQL实现 -->
|
||||||
|
<select id="getUserNamesByUserIdList" resultType="java.lang.String">
|
||||||
|
SELECT user_name FROM sys_user
|
||||||
|
WHERE user_id IN
|
||||||
|
<foreach item="userId" collection="userIdList" open="(" separator="," close=")">
|
||||||
|
#{userId}
|
||||||
|
</foreach>
|
||||||
|
AND user_name IS NOT NULL AND user_name != ''
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ public class RtStuDisciplinaryApplicationServiceImpl extends ServiceImpl<RtStuDi
|
|||||||
|
|
||||||
// todo 企业微信推送消息
|
// todo 企业微信推送消息
|
||||||
|
|
||||||
AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById("flow_n27gxm4k:7:257682", variables);
|
AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById("flow_n27gxm4k:8:610039", variables);
|
||||||
String code = ajaxResult.get("code").toString();
|
String code = ajaxResult.get("code").toString();
|
||||||
if (code.equals("200")) {
|
if (code.equals("200")) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user