Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -16,6 +16,8 @@ import okhttp3.*;
|
|||||||
import com.srs.common.core.domain.AjaxResult; // ✅ RuoYi 的返回结果类
|
import com.srs.common.core.domain.AjaxResult; // ✅ RuoYi 的返回结果类
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.ResponseBody;
|
import okhttp3.ResponseBody;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -44,44 +46,54 @@ public class AiChatController extends BaseController {
|
|||||||
* Dify API的访问密钥
|
* Dify API的访问密钥
|
||||||
* 用于身份验证,授权访问Dify服务
|
* 用于身份验证,授权访问Dify服务
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_API_KEY = "app-2wjqcYI9n6igHTVHdH8qXlnh";
|
private static final String DIFY_API_KEY = "app-BfPtBZDNBuHOS9K1PaZrxQYE";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify API的URL地址
|
* Dify API的URL地址
|
||||||
* 用于发送聊天消息请求到Dify服务
|
* 用于发送聊天消息请求到Dify服务
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private static final String DIFY_API_URL = "http://47.112.118.149:8100/v1/chat-messages";
|
private static final String DIFY_API_URL = "http://172.16.129.101/v1:6100/v1/chat-messages";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify反馈API的基础URL
|
* Dify反馈API的基础URL
|
||||||
* 用于提交消息反馈(点赞、点踩等)
|
* 用于提交消息反馈(点赞、点踩等)
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_FEEDBACK_BASE_URL = "http://47.112.118.149:8100/v1/messages";
|
private static final String DIFY_FEEDBACK_BASE_URL = "http://172.16.129.101/v1:6100/v1/messages";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify获取反馈API的基础URL
|
* Dify获取反馈API的基础URL
|
||||||
* 用于获取消息反馈(点赞、点踩等)
|
* 用于获取消息反馈(点赞、点踩等)
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_API_FEEDBACK_URL = "http://47.112.118.149:8100/v1/app/feedbacks?page=";
|
private static final String DIFY_API_FEEDBACK_URL = "http://172.16.129.101/v1:6100/v1/app/feedbacks?page=";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify消息历史记录API的基础URL
|
* Dify消息历史记录API的基础URL
|
||||||
* 用于获取消息历史记录
|
* 用于获取消息历史记录
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_API_HISTORY_URL = "http://47.112.118.149:8100/v1/messages";
|
private static final String DIFY_API_HISTORY_URL = "http://172.16.129.101/v1:6100/v1/messages";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify会话API的基础URL
|
* Dify会话API的基础URL
|
||||||
* 用于获取会话列表
|
* 用于获取会话列表
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_CONVERSATIONS_URL = "http://47.112.118.149:8100/v1/conversations";
|
private static final String DIFY_CONVERSATIONS_URL = "http://172.16.129.101/v1:6100/v1/conversations";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dify文件上传API的URL地址
|
* Dify文件上传API的URL地址
|
||||||
* 用于上传文件到Dify服务,支持图文多模态理解
|
* 用于上传文件到Dify服务,支持图文多模态理解
|
||||||
*/
|
*/
|
||||||
private static final String DIFY_FILES_URL = "http://47.112.118.149:8100/v1/files/upload";
|
private static final String DIFY_FILES_URL = "http://172.16.129.101/v1:6100/v1/files/upload";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis中会话ID的key前缀
|
||||||
|
*/
|
||||||
|
private static final String CONVERSATION_ID_CACHE_PREFIX = "dify:conversation:id:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis中会话ID的过期时间(小时)
|
||||||
|
*/
|
||||||
|
private static final int CONVERSATION_ID_CACHE_EXPIRE_HOURS = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP客户端实例
|
* HTTP客户端实例
|
||||||
@@ -93,6 +105,13 @@ public class AiChatController extends BaseController {
|
|||||||
.writeTimeout(Duration.ofSeconds(12)) // 写超时
|
.writeTimeout(Duration.ofSeconds(12)) // 写超时
|
||||||
.retryOnConnectionFailure(true)
|
.retryOnConnectionFailure(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis模板,用于缓存会话ID
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
/** 为本次请求设置 “总超时”(含连接/读写),避免无限挂起 */
|
/** 为本次请求设置 “总超时”(含连接/读写),避免无限挂起 */
|
||||||
private Response execWithTimeouts(Request req, int callSecs, int readSecs, int writeSecs) throws IOException {
|
private Response execWithTimeouts(Request req, int callSecs, int readSecs, int writeSecs) throws IOException {
|
||||||
OkHttpClient shortClient = client.newBuilder()
|
OkHttpClient shortClient = client.newBuilder()
|
||||||
@@ -173,7 +192,8 @@ public class AiChatController extends BaseController {
|
|||||||
* @param currentUsername
|
* @param currentUsername
|
||||||
* @throws IOException 当网络请求或IO操作失败时抛出
|
* @throws IOException 当网络请求或IO操作失败时抛出
|
||||||
*/
|
*/
|
||||||
private void sendToDifyAndStream(Map<String, Object> requestData, SseEmitter emitter, String currentUsername) throws IOException {
|
private void sendToDifyAndStream(Map<String, Object> requestData, SseEmitter emitter, String currentUsername)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
// 构建请求体参数
|
// 构建请求体参数
|
||||||
Map<String, Object> bodyMap = new HashMap<>();
|
Map<String, Object> bodyMap = new HashMap<>();
|
||||||
@@ -258,7 +278,8 @@ public class AiChatController extends BaseController {
|
|||||||
try (BufferedReader reader = new BufferedReader(httpResponse.body().charStream())) {
|
try (BufferedReader reader = new BufferedReader(httpResponse.body().charStream())) {
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
if (line.isEmpty() || !line.startsWith("data:")) continue;
|
if (line.isEmpty() || !line.startsWith("data:"))
|
||||||
|
continue;
|
||||||
String jsonData = line.substring(5).trim();
|
String jsonData = line.substring(5).trim();
|
||||||
if ("[DONE]".equals(jsonData)) {
|
if ("[DONE]".equals(jsonData)) {
|
||||||
break;
|
break;
|
||||||
@@ -313,7 +334,8 @@ public class AiChatController extends BaseController {
|
|||||||
* @return 统一响应结果
|
* @return 统一响应结果
|
||||||
*/
|
*/
|
||||||
@PostMapping("/feedback")
|
@PostMapping("/feedback")
|
||||||
public AjaxResult submitFeedback(@org.springframework.web.bind.annotation.RequestBody Map<String, Object> feedbackData) {
|
public AjaxResult submitFeedback(
|
||||||
|
@org.springframework.web.bind.annotation.RequestBody Map<String, Object> feedbackData) {
|
||||||
// 校验必要字段
|
// 校验必要字段
|
||||||
String messageId = (String) feedbackData.get("message_id");
|
String messageId = (String) feedbackData.get("message_id");
|
||||||
if (messageId == null || messageId.trim().isEmpty()) {
|
if (messageId == null || messageId.trim().isEmpty()) {
|
||||||
@@ -357,8 +379,7 @@ public class AiChatController extends BaseController {
|
|||||||
String jsonBody = mapper.writeValueAsString(bodyMap);
|
String jsonBody = mapper.writeValueAsString(bodyMap);
|
||||||
okhttp3.RequestBody body = okhttp3.RequestBody.create(
|
okhttp3.RequestBody body = okhttp3.RequestBody.create(
|
||||||
MediaType.get("application/json; charset=utf-8"),
|
MediaType.get("application/json; charset=utf-8"),
|
||||||
jsonBody
|
jsonBody);
|
||||||
);
|
|
||||||
|
|
||||||
// 调用 Dify API
|
// 调用 Dify API
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
@@ -431,12 +452,19 @@ public class AiChatController extends BaseController {
|
|||||||
|
|
||||||
// 提取反馈信息
|
// 提取反馈信息
|
||||||
feedbackItem.put("id", feedbackNode.has("id") ? feedbackNode.get("id").asText() : null);
|
feedbackItem.put("id", feedbackNode.has("id") ? feedbackNode.get("id").asText() : null);
|
||||||
feedbackItem.put("message_id", feedbackNode.has("message_id") ? feedbackNode.get("message_id").asText() : null);
|
feedbackItem.put("message_id",
|
||||||
feedbackItem.put("rating", feedbackNode.has("rating") ? feedbackNode.get("rating").asText() : null);
|
feedbackNode.has("message_id") ? feedbackNode.get("message_id").asText() : null);
|
||||||
feedbackItem.put("content", feedbackNode.has("content") ? feedbackNode.get("content").asText() : null);
|
feedbackItem.put("rating",
|
||||||
feedbackItem.put("created_at", feedbackNode.has("created_at") ? feedbackNode.get("created_at").asLong() : null);
|
feedbackNode.has("rating") ? feedbackNode.get("rating").asText() : null);
|
||||||
feedbackItem.put("app_id", feedbackNode.has("app_id") ? feedbackNode.get("app_id").asText() : null);
|
feedbackItem.put("content",
|
||||||
feedbackItem.put("conversation_id", feedbackNode.has("conversation_id") ? feedbackNode.get("conversation_id").asText() : null);
|
feedbackNode.has("content") ? feedbackNode.get("content").asText() : null);
|
||||||
|
feedbackItem.put("created_at",
|
||||||
|
feedbackNode.has("created_at") ? feedbackNode.get("created_at").asLong() : null);
|
||||||
|
feedbackItem.put("app_id",
|
||||||
|
feedbackNode.has("app_id") ? feedbackNode.get("app_id").asText() : null);
|
||||||
|
feedbackItem.put("conversation_id",
|
||||||
|
feedbackNode.has("conversation_id") ? feedbackNode.get("conversation_id").asText()
|
||||||
|
: null);
|
||||||
|
|
||||||
feedbackList.add(feedbackItem);
|
feedbackList.add(feedbackItem);
|
||||||
}
|
}
|
||||||
@@ -481,14 +509,24 @@ public class AiChatController extends BaseController {
|
|||||||
@RequestParam(defaultValue = "-updated_at") String sortBy) {
|
@RequestParam(defaultValue = "-updated_at") String sortBy) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 首先尝试从Redis缓存中获取会话ID
|
||||||
|
String conversationId = getCachedConversationId(user);
|
||||||
|
|
||||||
|
// 如果Redis缓存中没有会话ID,则使用原来的方法获取
|
||||||
|
if (conversationId == null) {
|
||||||
List<ConversationDTO> conversations = getConversations(user);
|
List<ConversationDTO> conversations = getConversations(user);
|
||||||
|
|
||||||
if (conversations == null || conversations.isEmpty()) {
|
if (conversations == null || conversations.isEmpty()) {
|
||||||
return AjaxResult.error("暂无会话记录");
|
return AjaxResult.error("暂无会话记录");
|
||||||
}
|
}
|
||||||
|
|
||||||
String conversation_id = conversations.get(0).getId();
|
conversationId = conversations.get(0).getId();
|
||||||
Map<String, Object> result = getConversationHistoryMessages(conversation_id, user, firstId, limit);
|
|
||||||
|
// 将获取到的会话ID缓存到Redis中
|
||||||
|
cacheConversationId(user, conversationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> result = getConversationHistoryMessages(conversationId, user, firstId, limit);
|
||||||
|
|
||||||
AjaxResult successResult = success(result);
|
AjaxResult successResult = success(result);
|
||||||
return successResult;
|
return successResult;
|
||||||
@@ -509,14 +547,25 @@ public class AiChatController extends BaseController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String user = SecurityUtils.getLoginUser().getUsername();
|
String user = SecurityUtils.getLoginUser().getUsername();
|
||||||
|
|
||||||
|
// 首先尝试从Redis缓存中获取会话ID
|
||||||
|
String conversationId = getCachedConversationId(user);
|
||||||
|
|
||||||
|
// 如果Redis缓存中没有会话ID,则使用原来的方法获取
|
||||||
|
if (conversationId == null) {
|
||||||
List<ConversationDTO> conversations = getConversations(user);
|
List<ConversationDTO> conversations = getConversations(user);
|
||||||
|
|
||||||
if (conversations == null || conversations.isEmpty()) {
|
if (conversations == null || conversations.isEmpty()) {
|
||||||
return AjaxResult.error("暂无会话记录");
|
return AjaxResult.error("暂无会话记录");
|
||||||
}
|
}
|
||||||
|
|
||||||
String conversation_id = conversations.get(0).getId();
|
conversationId = conversations.get(0).getId();
|
||||||
Map<String, Object> result = getConversationHistoryMessages(conversation_id, user, firstId, limit);
|
|
||||||
|
// 将获取到的会话ID缓存到Redis中
|
||||||
|
cacheConversationId(user, conversationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> result = getConversationHistoryMessages(conversationId, user, firstId, limit);
|
||||||
|
|
||||||
AjaxResult successResult = success(result);
|
AjaxResult successResult = success(result);
|
||||||
return successResult;
|
return successResult;
|
||||||
@@ -529,11 +578,67 @@ public class AiChatController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从Redis缓存中获取用户的会话ID
|
||||||
|
*
|
||||||
|
* @param user 用户名
|
||||||
|
* @return 会话ID,如果不存在则返回null
|
||||||
|
*/
|
||||||
|
private String getCachedConversationId(String user) {
|
||||||
|
try {
|
||||||
|
// 参数校验
|
||||||
|
if (user == null || user.trim().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = user.trim();
|
||||||
|
String cacheKey = CONVERSATION_ID_CACHE_PREFIX + user;
|
||||||
|
|
||||||
|
// 从Redis中获取会话ID
|
||||||
|
String conversationId = stringRedisTemplate.opsForValue().get(cacheKey);
|
||||||
|
|
||||||
|
return conversationId;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将会话ID与用户绑定并存储到Redis中
|
||||||
|
*
|
||||||
|
* @param user 用户名
|
||||||
|
* @param conversationId 会话ID
|
||||||
|
*/
|
||||||
|
private void cacheConversationId(String user, String conversationId) {
|
||||||
|
try {
|
||||||
|
// 参数校验
|
||||||
|
if (user == null || user.trim().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conversationId == null || conversationId.trim().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user = user.trim();
|
||||||
|
conversationId = conversationId.trim();
|
||||||
|
|
||||||
|
// 将用户与会话ID绑定存储到Redis中
|
||||||
|
String cacheKey = CONVERSATION_ID_CACHE_PREFIX + user;
|
||||||
|
stringRedisTemplate.opsForValue().set(
|
||||||
|
cacheKey,
|
||||||
|
conversationId,
|
||||||
|
Duration.ofHours(CONVERSATION_ID_CACHE_EXPIRE_HOURS));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("绑定会话ID时发生错误: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 获取会话列表
|
* 获取会话列表
|
||||||
* */
|
*/
|
||||||
public List<ConversationDTO> getConversations(String user, String lastId, int limit, String sortBy) throws IOException {
|
public List<ConversationDTO> getConversations(String user, String lastId, int limit, String sortBy)
|
||||||
|
throws IOException {
|
||||||
// 构建带查询参数的 URL
|
// 构建带查询参数的 URL
|
||||||
HttpUrl.Builder urlBuilder = HttpUrl.parse(DIFY_CONVERSATIONS_URL).newBuilder();
|
HttpUrl.Builder urlBuilder = HttpUrl.parse(DIFY_CONVERSATIONS_URL).newBuilder();
|
||||||
urlBuilder.addQueryParameter("user", user);
|
urlBuilder.addQueryParameter("user", user);
|
||||||
@@ -558,7 +663,6 @@ public class AiChatController extends BaseController {
|
|||||||
|
|
||||||
// 读取响应体
|
// 读取响应体
|
||||||
String responseBodyString = response.body().string();
|
String responseBodyString = response.body().string();
|
||||||
System.out.println("Raw Response: " + responseBodyString); // 打印原始数据
|
|
||||||
JsonNode rootNode = mapper.readTree(responseBodyString);
|
JsonNode rootNode = mapper.readTree(responseBodyString);
|
||||||
|
|
||||||
// 提取 data 数组
|
// 提取 data 数组
|
||||||
@@ -599,8 +703,7 @@ public class AiChatController extends BaseController {
|
|||||||
return getConversations(user, null, limit, sortBy);
|
return getConversations(user, null, limit, sortBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取历史消息
|
||||||
//获取历史消息
|
|
||||||
private Map<String, Object> getConversationHistoryMessages(
|
private Map<String, Object> getConversationHistoryMessages(
|
||||||
String conversationId,
|
String conversationId,
|
||||||
String user,
|
String user,
|
||||||
@@ -688,11 +791,6 @@ public class AiChatController extends BaseController {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传接口
|
* 文件上传接口
|
||||||
* <p>
|
* <p>
|
||||||
@@ -718,7 +816,7 @@ public class AiChatController extends BaseController {
|
|||||||
.setType(MultipartBody.FORM)
|
.setType(MultipartBody.FORM)
|
||||||
.addFormDataPart("user", user)
|
.addFormDataPart("user", user)
|
||||||
.addFormDataPart("file", file.getOriginalFilename(),
|
.addFormDataPart("file", file.getOriginalFilename(),
|
||||||
RequestBody.create(MediaType.parse("application/octet-stream"),file.getBytes()))
|
RequestBody.create(MediaType.parse("application/octet-stream"), file.getBytes()))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 构建请求
|
// 构建请求
|
||||||
|
|||||||
@@ -495,13 +495,51 @@
|
|||||||
union
|
union
|
||||||
select concat('knzz-',count(a.id)) as `all`
|
select concat('knzz-',count(a.id)) as `all`
|
||||||
from knzz_tufa_apply as a
|
from knzz_tufa_apply as a
|
||||||
where a.apply_status = 1
|
where a.apply_status = 3
|
||||||
/*宁博 6、困难资助-国家励志奖学金-学工审核代办*/
|
/*宁博 6、困难资助-国家励志奖学金-学工审核代办*/
|
||||||
union
|
union
|
||||||
select concat('knzzgl-',count(a.id)) as `all`
|
select concat('knzzgl-',count(a.id)) as `all`
|
||||||
from knzz_gl_apply as a
|
from knzz_gl_apply as a
|
||||||
left join view_stu_info as b on a.stu_no = b.stu_no
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
where a.apply_status = 1
|
where a.apply_status = 3
|
||||||
|
-- 陈冠元 困难资助-自治区人民政府奖学金-学工审核代办
|
||||||
|
union
|
||||||
|
select concat('knzzzzq-',count(a.id)) as `all`
|
||||||
|
from knzz_zzq_apply as a
|
||||||
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
|
where a.apply_status = 3
|
||||||
|
-- 邵政文-(日常事务-学生证补办-辅导员审核-学工审核)
|
||||||
|
union
|
||||||
|
select concat('xszb-',count(a.id)) as `all`
|
||||||
|
from rt_stu_id_reissue as a
|
||||||
|
where a.inspection_progress = 1
|
||||||
|
-- 邵政文-(日常事务-在校证明申请-辅导员审核-学工审核)
|
||||||
|
union
|
||||||
|
select concat('zxzm-',count(a.id)) as `all`
|
||||||
|
from rt_stu_at_school as a
|
||||||
|
where a.xgstatus = 0 or a.xgstatus is null
|
||||||
|
/*庞世斌 4、学生奖惩-先进班集体-学工审核代办*/
|
||||||
|
union
|
||||||
|
select concat('xjbjt-',count(a.id)) as `all`
|
||||||
|
from cph_new_good_class_apply as a
|
||||||
|
WHERE a.apply_status = 3
|
||||||
|
<!-- 知无涯 "中职升高职" 学校终审 -->
|
||||||
|
union
|
||||||
|
select concat('zsg-',count(a.id)) as `all`
|
||||||
|
from knzz_zsg_apply as a
|
||||||
|
where a.apply_status = 3
|
||||||
|
# 宁博-辅导员管理--成果绩效----待办 (第3步:科室复核 和 第4步:学工处长终审)
|
||||||
|
union
|
||||||
|
select concat('cg-',count(a.check_id)) as `all`
|
||||||
|
from sys_teacher_achievementcheck as a
|
||||||
|
left join sys_user as b on a.teacher_id = b.user_name
|
||||||
|
where a.check_status in (3, 4)
|
||||||
|
-- 陈冠元 辅导员业绩考核-科室复核待办-学工处长审核待办
|
||||||
|
union
|
||||||
|
select concat('yj-',count(a.id)) as `all`
|
||||||
|
from sys_teacher_kpi_filling as a
|
||||||
|
left join sys_user as b on a.job_number = b.user_name
|
||||||
|
where a.role_audit in (3, 4)
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="countStuUnDo" resultType="String" parameterType="String">
|
<select id="countStuUnDo" resultType="String" parameterType="String">
|
||||||
@@ -533,6 +571,7 @@
|
|||||||
select concat('knzz-',count(a.id)) as `all`
|
select concat('knzz-',count(a.id)) as `all`
|
||||||
from knzz_tufa_apply as a
|
from knzz_tufa_apply as a
|
||||||
where a.apply_status = 6 and a.stu_no = #{stuNo}
|
where a.apply_status = 6 and a.stu_no = #{stuNo}
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
@@ -585,13 +624,51 @@
|
|||||||
select concat('knzz-',count(a.id)) as `all`
|
select concat('knzz-',count(a.id)) as `all`
|
||||||
from knzz_tufa_apply as a
|
from knzz_tufa_apply as a
|
||||||
left join view_stu_info as b on a.stu_no = b.stu_no
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
where a.apply_status = 1 and b.dept_id = #{id}
|
where a.apply_status = 2 and b.dept_id = #{id}
|
||||||
/*宁博 6、困难资助-国家励志奖学金-学务审核代办*/
|
/*宁博 6、困难资助-国家励志奖学金-学务审核代办*/
|
||||||
union
|
union
|
||||||
select concat('knzzgl-',count(a.id)) as `all`
|
select concat('knzzgl-',count(a.id)) as `all`
|
||||||
from knzz_gl_apply as a
|
from knzz_gl_apply as a
|
||||||
left join view_stu_info as b on a.stu_no = b.stu_no
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
where a.apply_status = 1 and b.dept_id = #{id}
|
where a.apply_status = 2 and b.dept_id = #{id}
|
||||||
|
-- 陈冠元 困难资助-自治区人民政府奖学金-学校审核代办
|
||||||
|
union
|
||||||
|
select concat('knzzzzq-',count(a.id)) as `all`
|
||||||
|
from knzz_zzq_apply as a
|
||||||
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
|
where a.apply_status = 2 and b.dept_id = #{id}
|
||||||
|
/*庞世斌 4、学生奖惩-先进班集体-学务审核代办*/
|
||||||
|
union
|
||||||
|
select concat('xjbjt-',count(a.id)) as `all`
|
||||||
|
from cph_new_good_class_apply as a
|
||||||
|
left join srs_class as c on a.class_id = c.class_id
|
||||||
|
left join srs_majors as e on c.major_id = e.major_id
|
||||||
|
left join sys_dept as f on e.college_id = f.dept_id
|
||||||
|
WHERE a.apply_status = 2 and f.dept_id = #{id}
|
||||||
|
<!-- 知无涯"中职升高职" 学务审核 -->
|
||||||
|
union
|
||||||
|
select concat('zsg-',count(a.id)) as `all`
|
||||||
|
from knzz_zsg_apply as a
|
||||||
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
|
where a.apply_status = 2 and b.dept_id = #{id}
|
||||||
|
<!-- 知无涯"铺导员综合绩效" (第1步:学务初审) -->
|
||||||
|
union
|
||||||
|
select concat('jx-',count(a.id)) as `all`
|
||||||
|
from sys_performance as a
|
||||||
|
left join sys_user as b on a.credit_pass = b.user_name
|
||||||
|
where a.xwstatus IS NULL and b.dept_id = #{id}
|
||||||
|
# 宁博-辅导员管理--成果绩效----(第1步:学务初审)
|
||||||
|
union
|
||||||
|
select concat('cg-',count(a.check_id)) as `all`
|
||||||
|
from sys_teacher_achievementcheck as a
|
||||||
|
left join sys_user as b on a.teacher_id = b.user_name
|
||||||
|
where a.check_status = 1 and b.dept_id = #{id}
|
||||||
|
-- 陈冠元 辅导员业绩考核-学务审核待办
|
||||||
|
union
|
||||||
|
select concat('yj-',count(a.id)) as `all`
|
||||||
|
from sys_teacher_kpi_filling as a
|
||||||
|
left join sys_user as b on a.job_number = b.user_name
|
||||||
|
where a.role_audit = 1 and b.dept_id = #{id}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="countFdyUnDo" resultType="String" parameterType="String">
|
<select id="countFdyUnDo" resultType="String" parameterType="String">
|
||||||
@@ -662,6 +739,48 @@
|
|||||||
from knzz_gl_apply as a
|
from knzz_gl_apply as a
|
||||||
left join view_stu_info as b on a.stu_no = b.stu_no
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
where a.apply_status = 1 and b.t_no = #{tNo}
|
where a.apply_status = 1 and b.t_no = #{tNo}
|
||||||
|
-- 陈冠元 困难资助-自治区人民政府奖学金-辅导员审核代办
|
||||||
|
union
|
||||||
|
select concat('knzzzzq-',count(a.id)) as `all`
|
||||||
|
from knzz_zzq_apply as a
|
||||||
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
|
where a.apply_status = 1 and b.t_no = #{tNo}
|
||||||
|
-- 邵政文-(日常事务-学生证补办-辅导员审核-学工审核)
|
||||||
|
union
|
||||||
|
select concat('xszb-',count(a.id)) as `all`
|
||||||
|
from rt_stu_id_reissue as a
|
||||||
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
|
where b.t_no = #{tNo} and a.inspection_progress = 0
|
||||||
|
-- 邵政文-(日常事务-在校证明申请-辅导员审核-学工审核)
|
||||||
|
union
|
||||||
|
select concat('zxzm-',count(a.id)) as `all`
|
||||||
|
from rt_stu_at_school as a
|
||||||
|
left join view_stu_info as d on a.student_id = d.stu_no
|
||||||
|
where d.t_no = #{tNo} and (a.status = 0 or a.status is null)
|
||||||
|
/* 庞世斌 学生奖惩-先进班集体-辅导员审核代办*/
|
||||||
|
union
|
||||||
|
select concat('xjbjt-',count(a.id)) as `all`
|
||||||
|
from cph_new_good_class_apply as a
|
||||||
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
|
WHERE b.t_no = #{tNo} and a.apply_status = 1
|
||||||
|
/*庞世斌 3、综合素质-综合素质申请审核代办*/
|
||||||
|
union
|
||||||
|
select concat('zhsz-',count(a.id)) as `all`
|
||||||
|
from cph_audit_details a
|
||||||
|
left join view_stu_info as b on a.submitter_id = b.stu_id
|
||||||
|
WHERE status_code = 1 and t_no=#{tNo}
|
||||||
|
<!-- 知无涯"中职升高职" 辅导员审核 -->
|
||||||
|
union
|
||||||
|
select concat('zsg-',count(a.id)) as `all`
|
||||||
|
from knzz_zsg_apply as a
|
||||||
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
|
where a.apply_status = 1 and b.t_no = #{tNo}
|
||||||
|
<!--知无涯 "铺导员综合绩效" 待办 (第3步:科室复核 和 第4步:学工处长终审) -->
|
||||||
|
union
|
||||||
|
select concat('jx-',count(a.id)) as `all`
|
||||||
|
from sys_performance as a
|
||||||
|
where (a.shstatus IS NOT NULL and a.ksstatus IS NULL) -- 科室复核待办
|
||||||
|
or (a.ksstatus IS NOT NULL and a.xgstatus IS NULL) -- 学工处长待办
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
@@ -691,7 +810,143 @@
|
|||||||
from knzz_tufa_apply as a
|
from knzz_tufa_apply as a
|
||||||
left join view_stu_info as b on a.stu_no = b.stu_no
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
where a.apply_status = 1 and b.dept_id = #{id}
|
where a.apply_status = 1 and b.dept_id = #{id}
|
||||||
|
<!-- 知无涯"书记综合绩效" 待办 (第2步:书记审核) -->
|
||||||
|
union
|
||||||
|
select concat('jx-',count(a.id)) as `all`
|
||||||
|
from sys_performance as a
|
||||||
|
left join sys_user as b on a.credit_pass = b.user_name
|
||||||
|
where a.xwstatus IS NOT NULL and a.shstatus IS NULL and b.dept_id = #{id}
|
||||||
|
# 宁博-辅导员管理--成果绩效----待办 (第2步:书记审核)
|
||||||
|
union
|
||||||
|
select concat('cg-',count(a.check_id)) as `all`
|
||||||
|
from sys_teacher_achievementcheck as a
|
||||||
|
left join sys_user as b on a.teacher_id = b.user_name
|
||||||
|
where a.check_status = 2 and b.dept_id = #{id}
|
||||||
|
-- 陈冠元 辅导员业绩考核-学院书记待办
|
||||||
|
union
|
||||||
|
select concat('yj-',count(a.id)) as `all`
|
||||||
|
from sys_teacher_kpi_filling as a
|
||||||
|
left join sys_user as b on a.job_number = b.user_name
|
||||||
|
where a.role_audit = 2 and b.dept_id = #{id}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
========================================================================================================================
|
||||||
|
开发与维护文档 (Development & Maintenance Document)
|
||||||
|
========================================================================================================================
|
||||||
|
最后更新: 2025-08-19
|
||||||
|
负责人: 知无涯
|
||||||
|
|
||||||
|
模块概述:
|
||||||
|
本 XML 文件是整个学工系统的核心组件之一,其主要功能是为系统首页(工作台)提供各个角色的“待办事项”数量统计。
|
||||||
|
它并非传统的CRUD映射文件,而是通过一系列复杂的 `UNION` 查询,从不同的业务表中汇总统计数据。
|
||||||
|
|
||||||
|
|
||||||
|
核心设计模式:
|
||||||
|
1. 角色分离:文件通过不同的 `<select>` 标签(id 以 `count...UnDo` 命名)来为不同的系统角色提供独立的待办统计逻辑。
|
||||||
|
2. 联合查询(UNION):每个角色的待办数量都是通过 `UNION` 连接多个 `SELECT COUNT(...)` 语句来实现的。
|
||||||
|
3. 键值对格式:每个 `SELECT` 语句都使用 `CONCAT('prefix-', COUNT(...))` 的格式返回一个字符串,例如 'jx-5'。
|
||||||
|
- 'prefix-' (例如 'jx-'):这是待办事项的唯一标识符(Key)。
|
||||||
|
- COUNT(...) (例如 5):这是该事项的待办数量(Value)。
|
||||||
|
前端会根据这个 'prefix' 来匹配并更新界面上对应待办事项的数量。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
角色与待办事项详解:
|
||||||
|
|
||||||
|
1. <select id="countJwcUnDo"> - 学工/校级管理员 (Jwc)
|
||||||
|
- 职责:负责各项业务的最终审批环节。
|
||||||
|
- 数据范围:全校范围,无部门或个人过滤。
|
||||||
|
- 包含待办项:
|
||||||
|
- `good-`, `lake-`, `biye-`: 评优/毕业生,状态为3 (待校级审核)。
|
||||||
|
- `dms-`: 宿舍,状态为2 (待校级审核)。
|
||||||
|
- `kn-`, `zx-`: 困难认定/助学金,进入最终步骤。
|
||||||
|
- `knzz-`, `knzzgl-`, `knzzzzq-`: 各类困难资助,状态为3 (待校级终审)。
|
||||||
|
- `xszb-`, `zxzm-`: 学生证补办/在校证明,进入校级审核环节。
|
||||||
|
- `xjbjt-`: 先进班集体,状态为3 (待校级审核)。
|
||||||
|
- `zsg-`: 中职升高职,状态为3 (待校级终审)。
|
||||||
|
|
||||||
|
2. <select id="countXwUnDo"> - 学务/院系管理员 (Xw)
|
||||||
|
- 职责:负责各项业务的院系级审批(第二级)。
|
||||||
|
- 数据范围:按当前登录用户的院系ID (`dept_id`) 过滤。
|
||||||
|
- 包含待办项:
|
||||||
|
- 常规业务 (`good-`, `biye-`, `dms-`, `kn-`, `zx-`等):状态均为流程的第二步。
|
||||||
|
- `zsg-`: 中职升高职,状态为2 (待院系审核)。
|
||||||
|
- `jx-`: 辅导员综合绩效,状态为 `xwstatus IS NULL` (流程第一步)。
|
||||||
|
|
||||||
|
3. <select id="countSjUnDo"> - 书记/院系领导 (Sj)
|
||||||
|
- 职责:负责院系内的特殊和高级别审批。
|
||||||
|
- 数据范围:按当前登录用户的院系ID (`dept_id`) 过滤。
|
||||||
|
- 包含待办项:
|
||||||
|
- `sj-`: 学生违纪处分,状态为3。
|
||||||
|
- `knzz-`: 困难资助,状态为1 (可代办辅导员的待办)。
|
||||||
|
- `jx-`: 辅导员综合绩效,状态为 `xwstatus IS NOT NULL and shstatus IS NULL` (流程第二步)。
|
||||||
|
|
||||||
|
4. <select id="countFdyUnDo"> - 辅导员/指导老师 (Fdy)
|
||||||
|
- 职责:这是一个综合性角色,处理多项职责的待办。
|
||||||
|
- 数据范围:主要按辅导员/教师工号 (`t_no`) 过滤。
|
||||||
|
- 包含待办项:
|
||||||
|
- 常规初审 (`good-`, `biye-`, `dms-`, `kn-`, `zx-`等):状态均为流程的第一步。
|
||||||
|
- 勤工助学 (`qgzxgw-`, `qgzxgzjl-`): 作为“指导老师”,按 `zdls_no` 过滤。
|
||||||
|
- `zsg-`: 中职升高职,状态为1 (流程第一步)。
|
||||||
|
- `jx-`: 辅导员综合绩效,这是一个特例。此处的待办是为内嵌在此角色中的“科室复核”和“学工处长”岗准备的,
|
||||||
|
查询条件是 `(shstatus IS NOT NULL and ksstatus IS NULL) or (ksstatus IS NOT NULL and xgstatus IS NULL)`,
|
||||||
|
它聚合了绩效审批的第三步和第四步。
|
||||||
|
|
||||||
|
5. <select id="countStuUnDo"> - 学生 (Stu)
|
||||||
|
- 职责:处理被驳回或需要本人操作的申请。
|
||||||
|
- 数据范围:按当前登录学生的学号 (`stuNo`) 过滤。
|
||||||
|
- 包含待办项:主要是各项业务被驳回的状态,例如 `apply_status = 6`。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
如何新增一个待办事项 (示例:为辅导员添加“新增奖学金”待办)
|
||||||
|
|
||||||
|
1. **确定角色和审批环节**:
|
||||||
|
- 角色:辅导员。
|
||||||
|
- 环节:初审。
|
||||||
|
- 因此,我们需要修改 `<select id="countFdyUnDo">`。
|
||||||
|
|
||||||
|
2. **确定业务逻辑**:
|
||||||
|
- 业务表:`new_scholarship_apply`。
|
||||||
|
- 状态字段:`status`。
|
||||||
|
- 待办状态值:`1` (代表“待初审”)。
|
||||||
|
- 过滤方式:按辅导员教师工号 `t_no` 过滤。
|
||||||
|
|
||||||
|
3. **选择一个唯一的前缀 (Prefix)**:
|
||||||
|
- 我们选择 `xsjxj-` (“新式奖学金”的拼音首字母)。
|
||||||
|
|
||||||
|
4. **编写并添加SQL代码**:
|
||||||
|
- 在 `<select id="countFdyUnDo">` 的最后一个 `union` 之后,添加以下代码块:
|
||||||
|
```xml
|
||||||
|
union
|
||||||
|
select concat('xsjxj-',count(a.id)) as `all`
|
||||||
|
from new_scholarship_apply as a
|
||||||
|
left join view_stu_info as b on a.stu_no = b.stu_no
|
||||||
|
where a.status = 1 and b.t_no = #{tNo}
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **同步更新前端代码**:
|
||||||
|
- 在前端定义辅导员 `taskList` 的地方,添加一个新的对象:
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
label: "辅导员·新增奖学金审核",
|
||||||
|
name: "xsjxj", // 必须与后端的 'xsjxj-' 匹配
|
||||||
|
value: 0,
|
||||||
|
url: "/scholarship/new/fdy-audit" // 跳转到对应的审核页面
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
注意事项与最佳实践:
|
||||||
|
|
||||||
|
- **保持一致性**:新增业务时,尽量遵循现有的状态码约定(如1=待初审, 2=待院审, 3=待校审, 6=驳回)。
|
||||||
|
- **注释是关键**:添加任何新的 `union` 查询时,请务必在前面加上清晰的注释,说明其业务目的和开发者。
|
||||||
|
- **前端同步**:后端添加的任何新前缀,都必须在前端有对应的 `name` 才能显示出来。
|
||||||
|
- **性能考虑**:`UNION` 的性能开销会随着子查询的增多而增加。虽然目前性能良好,但未来应避免无限制地增加。
|
||||||
|
- **逻辑严谨**:在编写 `WHERE` 条件时,要特别注意审批链的流转,确保上级审批的待办条件正确承接了下级的“已通过”状态。
|
||||||
|
========================================================================================================================
|
||||||
|
-->
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -1,42 +1,69 @@
|
|||||||
package com.srs.flowable.listener.disciplinary;
|
package com.srs.flowable.listener.disciplinary;
|
||||||
|
|
||||||
|
|
||||||
|
import com.srs.common.core.domain.AjaxResult;
|
||||||
|
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 com.srs.flowable.mapper.LeaveMapper;
|
import com.srs.flowable.mapper.LeaveMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.flowable.engine.delegate.ExecutionListener;
|
import org.flowable.engine.delegate.ExecutionListener;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据辅导员的部门id,查询该部门的学无干事人员
|
* 根据辅导员的部门id,查询该部门的学无干事人员
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|
||||||
public class XWGSListener implements ExecutionListener {
|
public class XWGSListener 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.class);
|
||||||
|
|
||||||
Long deptId = (Long) delegateExecution.getVariable("deptId");
|
Long deptId = (Long) delegateExecution.getVariable("deptId");
|
||||||
|
|
||||||
if (deptId != null) {
|
if (deptId != null) {
|
||||||
|
// 步骤 1: 获取审批人的系统ID (userId) 知无涯
|
||||||
Long userId = disciplinaryMapper.getApprovalByDeptIdAndRoleKey(deptId, "stumanger");
|
Long userId = disciplinaryMapper.getApprovalByDeptIdAndRoleKey(deptId, "stumanger");
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
|
// 将审批人ID设置到流程变量中,供后续任务节点使用
|
||||||
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='/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("该学院学务干事审批人员未设置");
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("未找到部门相关信息");
|
throw new RuntimeException("未找到部门相关信息");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ public interface DisciplinaryMapper {
|
|||||||
*/
|
*/
|
||||||
Long getApprovalByDeptIdAndRoleKey(@Param("deptId") Long deptId,@Param("roleKey") String roleKey);
|
Long getApprovalByDeptIdAndRoleKey(@Param("deptId") Long deptId,@Param("roleKey") String roleKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 知无涯 新增:根据用户ID查询用户名 (用于企业微信通知)
|
||||||
|
* @param userId 系统内部的用户ID
|
||||||
|
* @return 用户的username
|
||||||
|
*/
|
||||||
|
String getUserNameByUserId(@Param("userId") Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据rolekey获取该角色的用户信息,审批
|
* 根据rolekey获取该角色的用户信息,审批
|
||||||
* @param roleKey
|
* @param roleKey
|
||||||
@@ -23,6 +30,7 @@ public interface DisciplinaryMapper {
|
|||||||
*/
|
*/
|
||||||
List<Long> getApprovalByRoleKey(String roleKey);
|
List<Long> getApprovalByRoleKey(String roleKey);
|
||||||
|
|
||||||
|
|
||||||
int updateRtStuDisciplinaryApplication(StuDisciplinaryApplication rtStuDisciplinaryApplication);
|
int updateRtStuDisciplinaryApplication(StuDisciplinaryApplication rtStuDisciplinaryApplication);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -101,5 +101,10 @@
|
|||||||
WHERE c.role_key=#{roleKey}
|
WHERE c.role_key=#{roleKey}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!--知无涯 新增: 根据用户ID查询用户名的SQL实现 -->
|
||||||
|
<select id="getUserNameByUserId" resultType="java.lang.String">
|
||||||
|
SELECT user_name FROM sys_user WHERE user_id = #{userId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user