diff --git a/pom.xml b/pom.xml index 5be727c..0e4315f 100644 --- a/pom.xml +++ b/pom.xml @@ -10,10 +10,10 @@ 8.0.28 2.3.1 2.0.8 - 1.5.8 + 1.5.13 1.25.0 1.6.2 - 3.8.1 + 3.18.0 4.0.0 1.15.3 2.5.1 @@ -57,7 +57,7 @@ 4.35.37.ALL - + javax.xml jaxrpc @@ -102,6 +102,12 @@ io.minio minio 8.2.2 + + + com.google.guava + guava + + javax.activation @@ -138,6 +144,17 @@ org.nutz nutzboot-core ${nutzboot.version} + + + org.yaml + snakeyaml + + + + + org.yaml + snakeyaml + 2.0 org.nutz @@ -233,6 +250,18 @@ net.unicon.cas cas-client-autoconfig-support 2.3.0-GA + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter + 2.6.15 + compile @@ -319,12 +348,18 @@ com.fasterxml.jackson.core jackson-databind - 2.8.1 + 2.9.4 com.fasterxml.uuid java-uuid-generator 3.1.3 + + + log4j + log4j + + @@ -376,8 +411,18 @@ slf4j-api org.slf4j + + com.google.guava + guava + + + com.google.guava + guava + 32.0.1-jre + compile + com.github.xiaoymin knife4j-openapi2-spring-boot-starter diff --git a/src/main/java/com/budwk/app/base/sms/SmsService.java b/src/main/java/com/budwk/app/base/sms/SmsService.java index df7cd4d..4281afe 100644 --- a/src/main/java/com/budwk/app/base/sms/SmsService.java +++ b/src/main/java/com/budwk/app/base/sms/SmsService.java @@ -2,38 +2,138 @@ package com.budwk.app.base.sms; import java.util.List; +/** + * 短信/消息发送服务接口 + * 保持参数直观可见,调用者无需查看实体类即可知晓参数含义 + */ public interface SmsService { - /** - * 单发 - * @param loginName 工号 - * @param content 内容 - */ - void send(String loginName, String content); + /** + * 单发普通消息(无标题) + * @param loginName 接收人工号(必填) + * @param content 消息内容(必填) + * @return + */ + void sendSingleMessage(String loginName, String content); - /** - * 单发 - * @param loginName 工号 - * @param title 标题 - * @param content 内容 - */ - void send(String loginName, String title, String content); + /** + * 单发普通消息(带标题) + * @param loginName 接收人工号(必填) + * @param title 消息标题(可选,可为null) + * @param content 消息内容(必填) + * @return + */ + void sendSingleMessage(String loginName, String title, String content); - /** - * 单发 - * @param loginName 工号 - * @param title 标题 - * @param content 内容 - * @param link 链接 - */ - void send(String loginName, String title, String content, String link); + /** + * 单发文本卡片消息 + * @param loginName 接收人工号(必填) + * @param content 卡片内容(必填) + * @param pcUrl PC端跳转链接(必填) + * @param mobileUrl 移动端跳转链接(必填) + * @return + */ + void sendSingleTextCard(String loginName, String content, String pcUrl, String mobileUrl); - /** - * 群发 多人接收内容相同时使用该方法 - * @param loginNames 工号 - * @param title 标题 - * @param content 内容 - * @param link 链接 - */ - void massSend(List loginNames, String title, String content, String link); + /** + * 单发文本卡片消息(带标题) + * @param loginName 接收人工号(必填) + * @param title 卡片标题(可选,可为null) + * @param content 卡片内容(必填) + * @param pcUrl PC端跳转链接(必填) + * @param mobileUrl 移动端跳转链接(必填) + * @return + */ + void sendSingleTextCard(String loginName, String title, String content, String pcUrl, String mobileUrl); + + /** + * 单发图文卡片消息 + * @param loginName 接收人工号(必填) + * @param content 卡片内容(必填) + * @param pcUrl PC端跳转链接(必填) + * @param mobileUrl 移动端跳转链接(必填) + * @param picUrl 图片链接(必填) + * @return + */ + void sendSinglePicTextCard(String loginName, String content, String pcUrl, String mobileUrl, String picUrl); + + /** + * 单发图文卡片消息(带标题) + * @param loginName 接收人工号(必填) + * @param title 卡片标题(可选,可为null) + * @param content 卡片内容(必填) + * @param pcUrl PC端跳转链接(必填) + * @param mobileUrl 移动端跳转链接(必填) + * @param picUrl 图片链接(必填) + * @return + */ + void sendSinglePicTextCard(String loginName, String title, String content, String pcUrl, String mobileUrl, String picUrl); + + /** + * 群发普通消息(多人接收相同内容) + * @param loginNames 接收人工号列表(必填,不能为空列表) + * @param content 消息内容(必填) + * @return void + */ + void massSendMessage(List loginNames, String content); + + /** + * 群发普通消息(多人接收相同内容) + * @param loginNames 接收人工号列表(必填,不能为空列表) + * @param title 消息标题(可选,可为null) + * @param content 消息内容(必填) + * @return void + */ + void massSendMessage(List loginNames, String title, String content); + + /** + * 群发短信文本卡片消息 + * @param loginNames 接收人工号列表(必填,不能为空列表) + * @param content 卡片内容(必填) + * @param pcUrl PC端跳转链接(必填) + * @param mobileUrl 移动端跳转链接(必填) + * @return + */ + void massSendTextCard(List loginNames, String content, String pcUrl, String mobileUrl); + + /** + * 群发短信文本卡片消息 + * @param loginNames 接收人工号列表(必填,不能为空列表) + * @param title 卡片标题(可选,可为null) + * @param content 卡片内容(必填) + * @param pcUrl PC端跳转链接(必填) + * @param mobileUrl 移动端跳转链接(必填) + * @return + */ + void massSendTextCard(List loginNames, String title, String content, String pcUrl, String mobileUrl); + + /** + * 群发图文卡片消息 + * @param loginNames 接收人工号列表(必填,不能为空列表) + * @param content 卡片内容(必填) + * @param pcUrl PC端跳转链接(必填) + * @param mobileUrl 移动端跳转链接(必填) + * @param picUrl 图片链接(必填) + * @return + */ + void massSendPicTextCard(List loginNames, String content, String pcUrl, String mobileUrl, String picUrl); + + /** + * 群发图文卡片消息 + * @param loginNames 接收人工号列表(必填,不能为空列表) + * @param title 卡片标题(可选,可为null) + * @param content 卡片内容(必填) + * @param pcUrl PC端跳转链接(必填) + * @param mobileUrl 移动端跳转链接(必填) + * @param picUrl 图片链接(必填) + * @return + */ + void massSendPicTextCard(List loginNames, String title, String content, String pcUrl, String mobileUrl, String picUrl); + + /** + * 消息撤回 + * @param msgId 消息Id + * @return + */ + void recallMsg(String msgId); } diff --git a/src/main/java/com/budwk/app/base/sms/impl/jshvc/SmsJshvcServiceImpl.java b/src/main/java/com/budwk/app/base/sms/impl/jshvc/SmsJshvcServiceImpl.java index 338f6a1..f30ae47 100644 --- a/src/main/java/com/budwk/app/base/sms/impl/jshvc/SmsJshvcServiceImpl.java +++ b/src/main/java/com/budwk/app/base/sms/impl/jshvc/SmsJshvcServiceImpl.java @@ -1,21 +1,23 @@ package com.budwk.app.base.sms.impl.jshvc; -import cn.hutool.core.util.StrUtil; -import cn.hutool.crypto.digest.DigestUtil; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import com.budwk.app.base.sms.SmsService; -import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.todo.platform.TodoPlatformConfig; +import com.wisedu.casp.sdk.api.mc.ReceiverDto; +import com.wisedu.casp.sdk.api.mc.SendMsgRequest; +import com.wisedu.casp.sdk.api.mc.SendMsgResponse; +import com.wisedu.casp.sdk.api.mc.constants.MsgType_Constants; +import com.wisedu.casp.sdk.api.mc.constants.SendType_Constants; +import com.wisedu.casp.sdk.api.mc.constants.WxSendType_Constants; +import com.wisedu.casp.sdk.api.mc.recallMsg.RecallMsgRequest; +import com.wisedu.casp.sdk.api.mc.recallMsg.RecallMsgResponse; +import com.wisedu.casp.sdk.core.Client; +import com.wisedu.casp.sdk.core.DefaultClient; import lombok.extern.slf4j.Slf4j; -import org.nutz.integration.jedis.RedisService; -import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.json.Json; import org.nutz.lang.Lang; -import org.nutz.lang.util.NutMap; import java.util.List; -import java.util.Map; /** * @ClassName SmsJshvcServiceImpl @@ -28,128 +30,144 @@ import java.util.Map; @IocBean public class SmsJshvcServiceImpl implements SmsService { - private static final String APPID = "1430576717768122368"; - private static final String APP_SECRET = "19A0ACB03FBQHL4R4XQD"; - private static final String TOKEN_URL = "https://gateway.jshvc.edu.cn/token/gateway/accessToken"; - private static final String MSG_URL = "https://gateway.jshvc.edu.cn/mp/restful/v2/message/send"; - private static final String REDIS_KEY_MSG_ACCESS_TOKEN = "msg:token:"; - - @Inject - private RedisService redisService; - @Override - public void send(String loginName, String content) { - send(loginName, "智慧工会", content); + public void sendSingleMessage(String loginName, String content) { + this.sendSingleMessage(loginName, "智慧工会", content); } @Override - public void send(String loginName, String title, String content) { - send(loginName, "智慧工会", content, null); + public void sendSingleMessage(String loginName, String title, String content) { + this.massSendMessage(List.of(loginName), title, content); } @Override - public void send(String loginName, String title, String content, String link) { - Map paramMap = Map.of("userId", loginName); - doSend(title, content, List.of(paramMap), link); + public void sendSingleTextCard(String loginName, String content, String pcUrl, String mobileUrl) { + this.sendSingleTextCard(loginName, "智慧工会", content, pcUrl, mobileUrl); } @Override - public void massSend(List loginNames, String title, String content, String link) { - List> receivers = loginNames.stream() - .map(name -> Map.of("userId", name)) - .toList(); - doSend(title, content, receivers, link); + public void sendSingleTextCard(String loginName, String title, String content, String pcUrl, String mobileUrl) { + this.massSendTextCard(List.of(loginName), title, content, pcUrl, mobileUrl); } - /** - * sign: 请求签名:(accessToken + 第一个receivers 的userID )的32位小写的MD5加密值,其中如果相应部分没有则忽略 - * msgType: 0: 普通消息(默认) 1: 必读消息 2: 验证码(为验证码时消息一定不入收件箱) - * expiredTime: 当msgType 为1必读消息 ,该字段为必填字段 格式:yyyy-MM-dd HH:mm:ss - * sendType: 1.只发送PC门户 2.只发送移动校园 3.邮件 4.短信 5.微信企业号 6.钉钉企业内部应用工作通知 7.微信服务号 8.welink - * wxSendType: 当发送类型为5时此字段才会生效:text(文本消息)、textcard(文本卡片)、nes(图文卡片,如果图文,则qyWeChatImgUrl必填)、button(按钮卡片详见示例),不传默认为text - * receiverType: 1:用户 2:用户组 3:部门,默认为1 - * - * @param title - * @param content - * @param receivers - */ - private void doSend(String title, String content, List> receivers, String link) { + @Override + public void sendSinglePicTextCard(String loginName, String content, String pcUrl, String mobileUrl, String picUrl) { + this.sendSinglePicTextCard(loginName, "智慧工会", content, pcUrl, mobileUrl, picUrl); + } - if(!SecurityUtil.getUserLoginname().equals("superadmin")) { - return; + @Override + public void sendSinglePicTextCard(String loginName, String title, String content, String pcUrl, String mobileUrl, String picUrl) { + this.massSendPicTextCard(List.of(loginName), title, content, pcUrl, mobileUrl, picUrl); + } + + @Override + public void massSendMessage(List loginNames, String content) { + this.massSendMessage(loginNames, "智慧工会", content); + } + + @Override + public void massSendMessage(List loginNames, String title, String content) { + List list = loginNames.stream().map(loginName -> { + ReceiverDto receiverDto = new ReceiverDto(); + receiverDto.setUserId(loginName); + return receiverDto; + }).toList(); + this.doSend(WxSendType_Constants.TEXT, list, title, content, null, null, null); + } + + @Override + public void massSendTextCard(List loginNames, String content, String pcUrl, String mobileUrl) { + this.massSendTextCard(loginNames, "智慧工会", content, pcUrl, mobileUrl); + } + + @Override + public void massSendTextCard(List loginNames, String title, String content, String pcUrl, String mobileUrl) { + List list = loginNames.stream().map(loginName -> { + ReceiverDto receiverDto = new ReceiverDto(); + receiverDto.setUserId(loginName); + return receiverDto; + }).toList(); + this.doSend(WxSendType_Constants.TEXT_CARD, list, title, content, pcUrl, mobileUrl, null); + } + + @Override + public void massSendPicTextCard(List loginNames, String content, String pcUrl, String mobileUrl, String picUrl) { + this.massSendPicTextCard(loginNames, "智慧工会", content, pcUrl, mobileUrl, picUrl); + } + + @Override + public void massSendPicTextCard(List loginNames, String title, String content, String pcUrl, String mobileUrl, String picUrl) { + List list = loginNames.stream().map(loginName -> { + ReceiverDto receiverDto = new ReceiverDto(); + receiverDto.setUserId(loginName); + return receiverDto; + }).toList(); + this.doSend(WxSendType_Constants.NEWS, list, title, content, pcUrl, mobileUrl, picUrl); + } + + @Override + public void recallMsg(String msgId) { + try { + Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_BASE_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); + RecallMsgRequest request = new RecallMsgRequest(); + request.setMsgId(msgId); + + log.info("撤回企业微信消息,请求参数:{}", Json.toJson(request)); + RecallMsgResponse response = client.execute(request); + log.info("撤回企业微信消息,接口响应数据:{}", Json.toJson(response)); + } catch (Exception e) { + log.error("撤回企业微信消息失败", e); } + } + + private void doSend(String sendType, + List receivers, + String title, + String content, + String pcUrl, + String mobileUrl, + String picUrl) { if (Lang.isEmpty(receivers)) { log.error("send fail by receivers is null"); return; } - - // 获取token - String accessToken = buildAccessToken(); - // 获取第一个接收人的userID - String firstUserId = receivers.get(0).get("userId"); - // md5小写加密生成签名 - String sign = DigestUtil.md5Hex(accessToken + firstUserId); - - NutMap paramsMap = new NutMap(); - paramsMap.put("sign", sign); - paramsMap.put("msgType", "0"); - paramsMap.put("subject", title); - paramsMap.put("content", content); - paramsMap.put("sendType", "5"); - paramsMap.put("receivers", receivers); - if (StrUtil.isBlank(link)) { - paramsMap.put("wxSendType", "text"); - } else { - paramsMap.put("wxSendType", "textcard"); - paramsMap.put("mobileUrl", link); - // 这是图文卡片,后面用到再对接吧 - // paramsMap.put("qyWeChatImgUrl", ""); - } - - log.debug("send params: {}", Json.toJson(paramsMap)); - - HttpRequest request = HttpRequest.post(MSG_URL) - .header("appId", APPID) - .header("accessToken", accessToken) - .body(Json.toJson(paramsMap)); - try { - HttpResponse response = request.execute(); - log.info("send response body: {}", response.body()); + // 创建客户端 + Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_BASE_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); + SendMsgRequest request = new SendMsgRequest(); + request.setSubject(title); + request.setContent(content); + request.setMsgType(MsgType_Constants.COMMON); + request.setSendType(SendType_Constants.WECHAT_ENTERPRISE); + request.setWxSendType(sendType); + request.setReceivers(receivers); - NutMap bodyMap = Json.fromJson(NutMap.class, response.body()); - if (bodyMap.getInt("status") == 200) { - log.info("send success code: {}, msg: {}", bodyMap.getInt("status"), bodyMap.getString("msg")); + if (WxSendType_Constants.TEXT_CARD.equals(sendType)) { + request.setPcUrl(pcUrl); + request.setMobileUrl(mobileUrl); + request.setUrlDesc("查看详情"); + } + if (WxSendType_Constants.NEWS.equals(sendType)) { + request.setPcUrl(pcUrl); + request.setMobileUrl(mobileUrl); + request.setUrlDesc("查看详情"); + request.setQyWeChatImgUrl(picUrl); + } + + log.info("发送企业微信通知,请求参数:{}", Json.toJson(request)); + SendMsgResponse response = client.execute(request); + log.info("发送企业微信通知,接口响应数据:{}", Json.toJson(response)); + + if (response.isSuccess() && response.getStatus() == 200) { + // TODO 消息Id,后面可以存着,撤回要用到 + String msgId = response.getMsgId(); + log.info("发送企业微信通知成功: {}, msg: {}", response.getStatus(), response.getMsg()); } else { - log.error("send error code: {}, msg: {}", bodyMap.getInt("status"), bodyMap.getString("msg")); + log.info("发送企业微信通知失败:{}", response.getMsg()); } } catch (Exception e) { - log.error("Failed to send: {}", e.getMessage(), e); + log.error("发送企业微信通知失败", e); } } - - private String buildAccessToken() { - String token = redisService.get(REDIS_KEY_MSG_ACCESS_TOKEN); - if (StrUtil.isNotBlank(token)) { - return token; - } - HttpRequest request = HttpRequest.get(TOKEN_URL); - request.header("appId", APPID); - request.header("appSecret", APP_SECRET); - - HttpResponse response = request.execute(); - - log.info("accessToken response: {}", Json.toJson(response.body())); - - NutMap bodyMap = Json.fromJson(NutMap.class, response.body()); - if (bodyMap.getInt("errcode") == 0) { - log.info("accessToken status: {}", bodyMap.getInt("errorcode")); - redisService.setex(REDIS_KEY_MSG_ACCESS_TOKEN, 60 * 120, bodyMap.getString("data")); - return bodyMap.getString("data"); - } else { - log.error("accessToken status: {}", bodyMap.getInt("errorcode")); - } - return ""; - } } diff --git a/src/main/java/com/budwk/app/flow/controller/FlowTodoCenterController.java b/src/main/java/com/budwk/app/flow/controller/FlowTodoCenterController.java index 59138a8..11fcd5a 100644 --- a/src/main/java/com/budwk/app/flow/controller/FlowTodoCenterController.java +++ b/src/main/java/com/budwk/app/flow/controller/FlowTodoCenterController.java @@ -117,6 +117,7 @@ public class FlowTodoCenterController { if (StrUtil.isNotBlank(searchKeyword)) { cnd.where().andLike("ins.variable ->> '$.instanceName'", searchKeyword); } + cnd.and("t.taskName", "!=", "startTask"); cnd.desc("t.createdAt"); sql.setCondition(cnd); Pagination pagination = sysUserService.listPageMap(pageNumber, pageSize, sql); diff --git a/src/main/java/com/budwk/app/flow/listenter/ProcessTaskStartEventListener.java b/src/main/java/com/budwk/app/flow/listenter/ProcessTaskStartEventListener.java index 4291d95..68ac77e 100644 --- a/src/main/java/com/budwk/app/flow/listenter/ProcessTaskStartEventListener.java +++ b/src/main/java/com/budwk/app/flow/listenter/ProcessTaskStartEventListener.java @@ -1,6 +1,7 @@ package com.budwk.app.flow.listenter; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; import com.budwk.app.flow.constant.FlowConst; import com.budwk.app.flow.engine.event.ProcessEvent; import com.budwk.app.flow.engine.event.ProcessEventListener; @@ -9,6 +10,8 @@ import com.budwk.app.flow.entity.ProcessTask; import com.budwk.app.flow.entity.ProcessTaskActor; import com.budwk.app.flow.enums.ProcessEventTypeEnum; import com.budwk.app.todo.service.TodoService; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.web.commons.base.Globals; import com.budwk.app.zhgh.dayofficework.message.service.GlobalMessageSendService; import lombok.extern.slf4j.Slf4j; import org.nutz.dao.Cnd; @@ -61,9 +64,15 @@ public class ProcessTaskStartEventListener implements ProcessEventListener { for (ProcessTaskActor taskActor : taskActors) { // 模拟发送消息 - String message = StrUtil.format("您有一条待办任务,实例:{},处理环节:{}", taskActor.getActorName(), instanceName, taskDisplayName); + String message = StrUtil.format("您有一条待办任务,实例:{},处理环节:{}", instanceName, taskDisplayName); log.info(message); - globalMessageSendService.sendMessage(taskDisplayName, message, 2, List.of(taskActor.getActorId()), null); + if (!List.of("superadmin" ,"CS2025015", "20182040").contains(SecurityUtil.getUserLoginname())) { + break; + } + JSONObject config = new JSONObject(); + config.set("pcUrl", Globals.AppDomain + task.getFormKey()); + config.set("mobileUrl", Globals.AppDomain + task.getH5FormKey()); + globalMessageSendService.sendMessage(taskDisplayName, message, 2, List.of(taskActor.getActorId()), config); } todoService.saveTask(task); diff --git a/src/main/java/com/budwk/app/flow/service/impl/ProcessInstanceServiceImpl.java b/src/main/java/com/budwk/app/flow/service/impl/ProcessInstanceServiceImpl.java index cbb831c..5cb21fd 100644 --- a/src/main/java/com/budwk/app/flow/service/impl/ProcessInstanceServiceImpl.java +++ b/src/main/java/com/budwk/app/flow/service/impl/ProcessInstanceServiceImpl.java @@ -32,6 +32,8 @@ import com.budwk.app.flow.service.ProcessTaskService; import com.budwk.app.flow.vo.HighLightVO; import com.budwk.app.flow.vo.ProcessInstanceVO; import com.budwk.app.flow.vo.ProcessTaskVO; +import com.budwk.app.todo.service.TodoService; +import com.budwk.app.todo.service.impl.TodoServiceImpl; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Chain; @@ -43,6 +45,7 @@ import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.lang.util.NutMap; +import org.nutz.mvc.Mvcs; import java.util.*; import java.util.stream.Collectors; @@ -558,6 +561,10 @@ public class ProcessInstanceServiceImpl extends BaseServiceImpl List taskIds = taskList.stream().map(ProcessTask::getId).toList(); dao().clear(ProcessTask.class, Cnd.where(ProcessTask::getId, "in", taskIds)); dao().clear(ProcessInstance.class, Cnd.where(ProcessInstance::getId, "=", processInstanceId)); + + // 删除学校待办 + TodoService todoService = Mvcs.getIoc().get(TodoServiceImpl.class); + todoService.deleteProcessInstance(processInstanceId.toString()); } @Override diff --git a/src/main/java/com/budwk/app/sys/controller/SysMsgController.java b/src/main/java/com/budwk/app/sys/controller/SysMsgController.java index 0f538d0..3ba34e8 100644 --- a/src/main/java/com/budwk/app/sys/controller/SysMsgController.java +++ b/src/main/java/com/budwk/app/sys/controller/SysMsgController.java @@ -7,6 +7,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.budwk.app.base.annotation.RepeatSubmit; import com.budwk.app.base.annotation.SLog; +import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.result.Result; @@ -16,16 +17,23 @@ import com.budwk.app.sys.models.Sys_role; import com.budwk.app.sys.services.SysMsgService; import com.budwk.app.sys.services.SysMsgUserService; import com.budwk.app.sys.services.SysUserService; +import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.club.model.ClubUser; +import com.budwk.app.zhgh.club.model.SysClub; +import com.budwk.app.zhgh.club.service.SysClubService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.dao.util.cri.Static; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Lang; import org.nutz.lang.Strings; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; @@ -47,6 +55,8 @@ public class SysMsgController { private SysMsgUserService sysMsgUserService; @Inject private SysUserService sysUserService; + @Inject + private SysClubService sysClubService; @At({"/", "/list/?"}) @Ok("beetl:/platform/sys/msg/index.html") @@ -73,6 +83,9 @@ public class SysMsgController { $condition """); Cnd cnd = Cnd.NEW(); + if(!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) { + cnd.and("msg.createdBy", "=", SecurityUtil.getUserId()); + } cnd.groupBy("msg.id"); if (Strings.isNotBlank(searchType) && !"all".equals(searchType)) { cnd.and("msg.type", "=", searchType); @@ -197,6 +210,28 @@ public class SysMsgController { if (Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())) { cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); } + + SqlExpressionGroup group = new SqlExpressionGroup(); + if(!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) { + if(AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_ADMIN.name(), RoleConstant.BRANCH_UNION_CHAIRMAN.name())) { + group.or("u.unionId", "=", SecurityUtil.getUnionId()); + } + if(AuthUtil.hasRoleOr(RoleConstant.CLUB_PRESIDENT.name(), RoleConstant.CLUB_MANAGER.name(),RoleConstant.CLUB_SECRETARY.name())) { + List myManageClub = sysClubService.getMyManageClub(); + if(Lang.isNotEmpty(myManageClub)) { + List list = myManageClub.stream().map(SysClub::getId).toList(); + List clubUsers = sysClubService.dao().query(ClubUser.class, Cnd.where(ClubUser::getClubId, "in", list)); + if(Lang.isNotEmpty(clubUsers)) { + List clubUserList = clubUsers.stream().map(ClubUser::getUserId).distinct().toList(); + group.or("u.id", "in", clubUserList); + } + } + } + } + if(!group.isEmpty()) { + cnd.and(group); + } + sql.setCondition(cnd); return Result.success().addData(sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql)); } catch (Exception e) { diff --git a/src/main/java/com/budwk/app/sys/controller/SysSignatureController.java b/src/main/java/com/budwk/app/sys/controller/SysSignatureController.java index adbcab6..d4ad211 100644 --- a/src/main/java/com/budwk/app/sys/controller/SysSignatureController.java +++ b/src/main/java/com/budwk/app/sys/controller/SysSignatureController.java @@ -131,7 +131,7 @@ public class SysSignatureController { @Aop(TransAop.READ_COMMITTED) public Result update(@Param("file") TempFile tempFile) { String url = sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), tempFile); - Sys_user_signature sysUserSignature = dao.fetch(Sys_user_signature.class); + Sys_user_signature sysUserSignature = dao.fetch(Sys_user_signature.class, Cnd.where("userId", "=", SecurityUtil.getUserId())); if (ObjectUtil.isNull(sysUserSignature)) { sysUserSignature = new Sys_user_signature(); } diff --git a/src/main/java/com/budwk/app/sys/controller/SysUserController.java b/src/main/java/com/budwk/app/sys/controller/SysUserController.java index 03d93b8..2f6fd91 100644 --- a/src/main/java/com/budwk/app/sys/controller/SysUserController.java +++ b/src/main/java/com/budwk/app/sys/controller/SysUserController.java @@ -361,10 +361,15 @@ public class SysUserController { if (StrUtil.isBlank(pathname)) { } - int i = pathname.indexOf("?"); - if(i > 0) { - pathname = pathname.substring(0, i); - } + int i = pathname.indexOf("?"); + if (i > 0) { + pathname = pathname.substring(0, i); + } + + if (pathname.contains("webvpn")) { + int platform = pathname.indexOf("/platform"); + pathname = pathname.substring(platform); + } // Sys_menu menu = sysMenuService.fetch(Cnd.where(Sys_menu::getHref, "like", pathname + "%")); Sys_menu menu = sysMenuService.fetch(Cnd.where(Sys_menu::getHref, "=", pathname)); if (menu == null) { diff --git a/src/main/java/com/budwk/app/sys/models/Sys_msg.java b/src/main/java/com/budwk/app/sys/models/Sys_msg.java index a58497e..ebb7245 100644 --- a/src/main/java/com/budwk/app/sys/models/Sys_msg.java +++ b/src/main/java/com/budwk/app/sys/models/Sys_msg.java @@ -57,6 +57,12 @@ public class Sys_msg extends BaseModel implements Serializable { @Many(field = "msgId") private List userList; + @Column + @Comment("同步企业微信") + @ColDefine(type = ColType.BOOLEAN) + @Default("0") + private Boolean wechatEnterprise; + @Column @Comment("是否需要反馈") @ColDefine(type = ColType.BOOLEAN) diff --git a/src/main/java/com/budwk/app/sys/services/impl/SysMsgServiceImpl.java b/src/main/java/com/budwk/app/sys/services/impl/SysMsgServiceImpl.java index cf38b46..8026e68 100644 --- a/src/main/java/com/budwk/app/sys/services/impl/SysMsgServiceImpl.java +++ b/src/main/java/com/budwk/app/sys/services/impl/SysMsgServiceImpl.java @@ -105,10 +105,12 @@ public class SysMsgServiceImpl extends BaseServiceImpl implements SysMs // for (String loginName : loginNames) { // smsService.send(loginName, sysMsg.getTitle(), sysMsg.getNote()); // } - ThreadUtil.execute(() -> { - //smsService.massSend(loginNames, sysMsg.getTitle(), HtmlUtil.cleanHtmlTag(StrUtil.blankToDefault(sysMsg.getNote(),"")), sysMsg.getUrl()); - }); - + if(sysMsg.getWechatEnterprise()) { + ThreadUtil.execute(() -> { + //smsService.massSend(loginNames, sysMsg.getTitle(), HtmlUtil.cleanHtmlTag(StrUtil.blankToDefault(sysMsg.getNote(),"")), sysMsg.getUrl()); + smsService.massSendMessage(loginNames, HtmlUtil.cleanHtmlTag(StrUtil.blankToDefault(sysMsg.getNote(),""))); + }); + } return sysMsg; } diff --git a/src/main/java/com/budwk/app/todo/platform/TodoPlatformConfig.java b/src/main/java/com/budwk/app/todo/platform/TodoPlatformConfig.java index f532ec5..76647ab 100644 --- a/src/main/java/com/budwk/app/todo/platform/TodoPlatformConfig.java +++ b/src/main/java/com/budwk/app/todo/platform/TodoPlatformConfig.java @@ -12,7 +12,9 @@ public class TodoPlatformConfig { // token 获取 public static final String TOKEN_URL = "https://gateway.jshvc.edu.cn/token/gateway/accessToken"; // 待办平台基础地址 - public static final String TODO_PLATFORM_BASE_URL = "https://gateway.jshvc.edu.cn/casp-tdc/task/saveOrUpdate"; + public static final String TODO_PLATFORM_BASE_URL = "https://gateway.jshvc.edu.cn"; + // 待办平台新增或者修改 + public static final String TODO_PLATFORM_SAVE_OR_UPDATE_URL = "https://gateway.jshvc.edu.cn/casp-tdc/task/saveOrUpdate"; // 待办平台修改地址 public static final String TODO_PLATFORM_MODIFY_URL = "https://gateway.jshvc.edu.cn/casp-tdc/task/modifyInfo"; // 待办平台删除任务地址 diff --git a/src/main/java/com/budwk/app/todo/service/TodoService.java b/src/main/java/com/budwk/app/todo/service/TodoService.java index 01058ed..e9b3c33 100644 --- a/src/main/java/com/budwk/app/todo/service/TodoService.java +++ b/src/main/java/com/budwk/app/todo/service/TodoService.java @@ -1,7 +1,6 @@ package com.budwk.app.todo.service; import com.budwk.app.flow.entity.ProcessTask; -import com.wisedu.casp.sdk.api.BaseResponse; /** * @ClassName TodoService diff --git a/src/main/java/com/budwk/app/todo/service/impl/TodoServiceImpl.java b/src/main/java/com/budwk/app/todo/service/impl/TodoServiceImpl.java index e222a09..10249a6 100644 --- a/src/main/java/com/budwk/app/todo/service/impl/TodoServiceImpl.java +++ b/src/main/java/com/budwk/app/todo/service/impl/TodoServiceImpl.java @@ -12,7 +12,12 @@ import com.budwk.app.sys.models.Sys_user; import com.budwk.app.todo.platform.TodoPlatformConfig; import com.budwk.app.todo.service.TodoService; import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.web.commons.base.Globals; import com.wisedu.casp.sdk.api.BaseResponse; +import com.wisedu.casp.sdk.api.mc.ChannelInfo; +import com.wisedu.casp.sdk.api.mc.GetEnableChannelByTypeRequest; +import com.wisedu.casp.sdk.api.mc.GetEnableChannelByTypeResponse; +import com.wisedu.casp.sdk.api.mc.constants.ChannelType_Constants; import com.wisedu.casp.sdk.api.tdc.constants.*; import com.wisedu.casp.sdk.api.tdc.model.*; import com.wisedu.casp.sdk.api.tdc.pushtask.ProcessInstanceRealDeleteRequest; @@ -28,6 +33,7 @@ import org.nutz.integration.jedis.RedisService; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.json.Json; +import org.nutz.lang.Lang; import org.nutz.lang.util.NutMap; import java.util.Arrays; @@ -55,7 +61,7 @@ public class TodoServiceImpl implements TodoService { @Override public void saveTask(ProcessTask task) { - if(!SecurityUtil.getUserLoginname().equals("superadmin")) { + if (!List.of("superadmin" ,"CS2025015", "20182040").contains(SecurityUtil.getUserLoginname())) { return; } log.info("新增待办任务,任务数据:{}", Json.toJson(task)); @@ -66,6 +72,7 @@ public class TodoServiceImpl implements TodoService { ProcessDefine define = dao.fetch(ProcessDefine.class, instance.getProcessDefineId()); // 获取流程发起人 String initiatorAccount = Json.fromJson(NutMap.class, instance.getVariable()).getString(FlowConst.INITIATOR_ACCOUNT); + String instanceName = Json.fromJson(NutMap.class, instance.getVariable()).getString("instanceName"); // 获取任务执行人 List taskActors = dao.query(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", task.getId())); List processorList = taskActors.stream().map(o -> new Processor(o.getActorAccount())).toList(); @@ -79,25 +86,45 @@ public class TodoServiceImpl implements TodoService { insertModel.setTaskId(task.getId().toString()); insertModel.setInitiatorId(initiatorAccount); insertModel.setInitiatorType(ProcessorType.USER_ACCOUNT); - insertModel.setSubject(define.getDisplayName()); + insertModel.setSubject(instanceName); insertModel.setPriority(PriorityType.COMMON); insertModel.setTaskType(TaskType.COMMON); insertModel.setProcessors(processorList); insertModel.setProcessType(ProcessType.OR_SIGN); insertModel.setNodeId(task.getId().toString()); - insertModel.setNodeName(task.getTaskName()); - insertModel.setPcViewUrl(task.getFormKey()); - insertModel.setH5ViewUrl(task.getH5FormKey()); + insertModel.setNodeName(task.getDisplayName()); + insertModel.setPcViewUrl(Globals.AppDomain + task.getFormKey()); + insertModel.setH5ViewUrl(Globals.AppDomain + task.getH5FormKey()); // insertModel.setServiceId("xxx"); // insertModel.setServiceName("xxx"); // 任务关联的申请信息 ApplicationModel applicationModel = new ApplicationModel(); applicationModel.setProcessInstanceId(instance.getId().toString()); + applicationModel.setSubject(define.getDisplayName()); + applicationModel.setProcessors(processorList); + applicationModel.setProcessInstanceStatus(ProcessInstanceStatusType.RUNNING); + applicationModel.setNodeId(task.getId().toString()); + applicationModel.setNodeName(task.getDisplayName()); insertModel.setApplicationModel(applicationModel); request.setInsertModel(Collections.singletonList(insertModel)); + /*Client channelClient = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_BASE_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); + GetEnableChannelByTypeRequest channelByTypeRequest = new GetEnableChannelByTypeRequest(); + channelByTypeRequest.setChannelType(ChannelType_Constants.QYWECHAT); + GetEnableChannelByTypeResponse channelByTypeResponse = channelClient.execute(channelByTypeRequest); + log.info("获取待办消息渠道,接口响应数据:{}", Json.toJson(channelByTypeResponse)); + if (channelByTypeResponse.isSuccess()) { + List list = channelByTypeResponse.getData(); + if(Lang.isNotEmpty(list)) { + request.setIsSendMsg(1); + request.setSendChannels("1184803022838996992"); + request.setWxSendType("textcard"); + } + }*/ + + log.info("新增待办任务,请求参数:{}", Json.toJson(request)); BaseResponse response = client.execute(request); log.info("新增待办任务,接口响应数据:{}", Json.toJson(response)); } catch (Exception e) { @@ -107,7 +134,7 @@ public class TodoServiceImpl implements TodoService { @Override public void updateTask(ProcessTask task) { - if(!SecurityUtil.getUserLoginname().equals("superadmin")) { + if (!List.of("superadmin" ,"CS2025015", "20182040").contains(SecurityUtil.getUserLoginname())) { return; } log.info("更新待办任务,任务数据:{}", Json.toJson(task)); @@ -123,7 +150,7 @@ public class TodoServiceImpl implements TodoService { ProcessTaskVO taskVO = flowEngine.processTaskService().findById(task.getId()); // 创建客户端 - Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_MODIFY_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); + Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_BASE_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); // 创建请求对象 SaveOrUpdateRequest request = new SaveOrUpdateRequest(); @@ -142,11 +169,12 @@ public class TodoServiceImpl implements TodoService { applyModel.setProcessInstanceId(instance.getId().toString()); applyModel.setProcessInstanceStatus(ProcessInstanceStatusType.RUNNING); applyModel.setNodeId(task.getId().toString()); - applyModel.setNodeName(task.getTaskName()); + applyModel.setNodeName(task.getDisplayName()); applyModel.setProcessors(processorList); updateModel.setApplyModels(Collections.singletonList(applyModel)); request.setUpdateModel(updateModel); + log.info("更新待办任务,请求参数:{}", Json.toJson(request)); BaseResponse response = client.execute(request); log.info("更新待办任务,接口响应数据:{}", Json.toJson(response)); } catch (Exception e) { @@ -156,13 +184,13 @@ public class TodoServiceImpl implements TodoService { @Override public void modifyInfo(ProcessTask task) { - if(!SecurityUtil.getUserLoginname().equals("superadmin")) { + if (!List.of("superadmin" ,"CS2025015", "20182040").contains(SecurityUtil.getUserLoginname())) { return; } log.info("修改待办任务,任务数据:{}", Json.toJson(task)); try { // 创建客户端 - Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_MODIFY_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); + Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_BASE_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); // 创建请求对象 TaskModifyInfoRequest request = new TaskModifyInfoRequest(); // 需要修改什么后面扩展吧 @@ -170,6 +198,7 @@ public class TodoServiceImpl implements TodoService { request.setSubject("test"); request.setProcessors(Arrays.asList(new Processor("user01"), new Processor("user02"))); + log.info("修改待办任务,请求参数:{}", Json.toJson(request)); BaseResponse response = client.execute(request); log.info("修改待办任务,接口响应数据:{}", Json.toJson(response)); } catch (Exception e) { @@ -179,16 +208,18 @@ public class TodoServiceImpl implements TodoService { @Override public void deleteTask(String taskId) { - if(!SecurityUtil.getUserLoginname().equals("superadmin")) { + if (!List.of("superadmin" ,"CS2025015", "20182040").contains(SecurityUtil.getUserLoginname())) { return; } log.info("删除待办任务,任务ID:{}", taskId); try { // 创建客户端 - Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_DELETE_TASK_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); + Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_BASE_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); // 创建请求对象 TaskRealDeleteRequest request = new TaskRealDeleteRequest(); request.setTaskId(taskId); + + log.info("删除待办任务,请求参数:{}", Json.toJson(request)); BaseResponse response = client.execute(request); log.info("删除待办任务,接口响应数据:{}", Json.toJson(response)); } catch (Exception e) { @@ -198,16 +229,18 @@ public class TodoServiceImpl implements TodoService { @Override public void deleteProcessInstance(String processInstanceId) { - if(!SecurityUtil.getUserLoginname().equals("superadmin")) { + if (!List.of("superadmin" ,"CS2025015", "20182040").contains(SecurityUtil.getUserLoginname())) { return; } log.info("删除待办流程,实例ID:{}", processInstanceId); try { // 创建客户端 - Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_DELETE_INSTANCE_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); + Client client = new DefaultClient(TodoPlatformConfig.TODO_PLATFORM_BASE_URL, TodoPlatformConfig.TODO_APP_ID, TodoPlatformConfig.TODO_APP_SECRET); // 创建请求对象 ProcessInstanceRealDeleteRequest request = new ProcessInstanceRealDeleteRequest(); request.setProcessInstanceId(processInstanceId); + + log.info("删除待办流程,请求参数:{}", Json.toJson(request)); BaseResponse response = client.execute(request); log.info("删除待办流程,接口响应数据:{}", Json.toJson(response)); } catch (Exception e) { diff --git a/src/main/java/com/budwk/app/web/commons/base/Globals.java b/src/main/java/com/budwk/app/web/commons/base/Globals.java index 20535a3..0df0601 100644 --- a/src/main/java/com/budwk/app/web/commons/base/Globals.java +++ b/src/main/java/com/budwk/app/web/commons/base/Globals.java @@ -34,7 +34,7 @@ public class Globals { //项目LOGO public static String AppLogo = ""; //项目域名 - public static String AppDomain = "http://127.0.0.1"; + public static String AppDomain = "https://zhgh.jshvc.edu.cn"; //文件访问域名 public static String AppFileDomain = ""; //学校代码 diff --git a/src/main/java/com/budwk/app/zhgh/activity/declarereimbursement/reimbursement/controller/ActivityReimbursementApplyController.java b/src/main/java/com/budwk/app/zhgh/activity/declarereimbursement/reimbursement/controller/ActivityReimbursementApplyController.java index 5b0d0ef..117c64a 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/declarereimbursement/reimbursement/controller/ActivityReimbursementApplyController.java +++ b/src/main/java/com/budwk/app/zhgh/activity/declarereimbursement/reimbursement/controller/ActivityReimbursementApplyController.java @@ -145,6 +145,7 @@ public class ActivityReimbursementApplyController { args.set("outlayManageSource", activityReimbursementInfo.getOutlayManageSource()); args.set("actualMoney", activityReimbursementInfo.getActualMoney()); args.set("next", activityReimbursementInfo.getReimbursementIdentity()); + args.set("clubId",activityReimbursementInfo.getClubId()); ProcessInstance instance = flowEngine.startProcessInstanceByKey("HDBX", activityReimbursementInfo.getId(), SecurityUtil.getUserId(), args); // 自动完成第一个申请任务 diff --git a/src/main/java/com/budwk/app/zhgh/activity/declarereimbursement/reimbursement/controller/ActivityReimbursementMineController.java b/src/main/java/com/budwk/app/zhgh/activity/declarereimbursement/reimbursement/controller/ActivityReimbursementMineController.java index d0698f7..33f72fa 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/declarereimbursement/reimbursement/controller/ActivityReimbursementMineController.java +++ b/src/main/java/com/budwk/app/zhgh/activity/declarereimbursement/reimbursement/controller/ActivityReimbursementMineController.java @@ -5,14 +5,18 @@ import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.convert.NumberChineseFormatter; import cn.hutool.core.convert.NumberWordFormatter; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Dict; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.budwk.app.base.annotation.SLog; import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.result.Result; import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.base.utils.OfficePlusUtil; import com.budwk.app.base.utils.PageUtil; import com.budwk.app.base.utils.SysOfficeTemplateUtil; import com.budwk.app.flow.engine.FlowEngine; @@ -39,6 +43,7 @@ import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.json.Json; import org.nutz.lang.Lang; import org.nutz.lang.util.NutMap; import org.nutz.mvc.annotation.At; @@ -47,9 +52,12 @@ import org.nutz.mvc.annotation.Ok; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; import java.util.*; /** @@ -129,24 +137,24 @@ public class ActivityReimbursementMineController { """); Cnd cnd = Cnd.NEW(); SqlExpressionGroup group = new SqlExpressionGroup(); - if (AuthUtil.hasPermission("activityReimbursement.apply.schoolHas")){ - group.or("info.reimbursementIdentity","=","school"); + /*if (AuthUtil.hasPermission("activityReimbursement.apply.schoolHas")) { + group.or("info.reimbursementIdentity", "=", "school"); } - if (AuthUtil.hasPermission("activityReimbursement.apply.unionHas")){ + if (AuthUtil.hasPermission("activityReimbursement.apply.unionHas")) { SqlExpressionGroup unionGroup = new SqlExpressionGroup(); unionGroup.and("info.unionId", "=", SecurityUtil.getUnionId()); - unionGroup.and("info.reimbursementIdentity","=","union"); + unionGroup.and("info.reimbursementIdentity", "=", "union"); group.or(unionGroup); } - if (AuthUtil.hasPermission("activityReimbursement.apply.clubHas")){ + if (AuthUtil.hasPermission("activityReimbursement.apply.clubHas")) { SqlExpressionGroup clubGroup = new SqlExpressionGroup(); clubGroup.and("info.clubId", "in", SecurityUtil.getClubIds()); - clubGroup.and("info.reimbursementIdentity","=","club"); + clubGroup.and("info.reimbursementIdentity", "=", "club"); group.or(clubGroup); - } - if (Lang.isNotEmpty(group)){ - cnd.and(group); - }else{ + }*/ + if (!group.isEmpty()) { + cnd.and(group); + } else { cnd.and("info.userId", "=", SecurityUtil.getUserId()); } @@ -158,7 +166,7 @@ public class ActivityReimbursementMineController { cnd.orderBy("info." + pageParam.getPageOrderName(), PageUtil.getOrder(pageParam.getPageOrderBy())); } // cnd.groupBy("t.id"); - cnd.groupBy("info.id"); + cnd.groupBy("info.id"); sql.setCondition(cnd); Pagination pagination = activityReimbursementService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql); return Result.success().addData(pagination); @@ -207,9 +215,11 @@ public class ActivityReimbursementMineController { Sql sql = Sqls.create(""" SELECT info.*, + us.mobile, ins.id AS instanceId FROM `activity_reimbursement_info` info + LEFT JOIN sys_user us on us.id=info.userId LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id WHERE ins.state = 20 AND info.id = @id @@ -257,7 +267,13 @@ public class ActivityReimbursementMineController { // 组合结果 String actualMoneyChinese = integerChinese + decimalChinese; - info.put("actualMoney", actualMoneyChinese); + info.put("bigActualMoney", actualMoneyChinese); + info.put("actualMoney", info.getString("actualMoney")); + + info.put("sign", sysOfficeTemplateUtil.createPictureRenderData(info.getString("sign"))); + info.put("applyTime", info.getString("applyTime").substring(0, 10)); + List billFiles = Json.fromJsonAsList(NutMap.class, info.getString("billFiles")); + info.put("fileNum", billFiles.size()); docData.put("schoolName", Globals.AppName); docData.put("info", info); @@ -325,68 +341,101 @@ public class ActivityReimbursementMineController { doneTaskVos.add(taskVO); } + List auditList = new ArrayList<>(); + // 分工会审核 doneTaskVos.stream().filter(task -> "分工会审核".equals(task.getDisplayName())) .max(Comparator.comparing(ProcessTaskVO::getCreatedAt)) .ifPresent(v -> { Dict taskFormData = v.getTaskFormData(); - HashMap approval = new HashMap<>(); - - approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); - approval.put("user", taskFormData.getStr("tf_userName")); - if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) { - approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign"))); + NutMap map = new NutMap(); + map.put("unit", "分工会审核"); + map.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); + map.put("userName", taskFormData.getStr("tf_userName")); + if (StrUtil.isNotBlank(taskFormData.getStr("tf_userSign"))) { + map.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_userSign"))); } - approval.put("opinion", taskFormData.getStr("tf_opinion")); - docData.put("fgh", approval); + map.put("opinion", taskFormData.getStr("tf_opinion")); + auditList.add(map); }); - // 协会负责人审核 doneTaskVos.stream().filter(task -> "协会负责人审核".equals(task.getDisplayName())) .max(Comparator.comparing(ProcessTaskVO::getCreatedAt)) .ifPresent(v -> { Dict taskFormData = v.getTaskFormData(); - HashMap approval = new HashMap<>(); - - approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); - approval.put("user", taskFormData.getStr("tf_userName")); - if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) { - approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign"))); + NutMap map = new NutMap(); + map.put("unit", "协会负责人审核"); + map.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); + map.put("userName", taskFormData.getStr("tf_userName")); + if (StrUtil.isNotBlank(taskFormData.getStr("tf_userSign"))) { + map.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_userSign"))); } - approval.put("opinion", taskFormData.getStr("tf_opinion")); - docData.put("xh", approval); + map.put("opinion", taskFormData.getStr("tf_opinion")); + auditList.add(map); }); - // 校工会负责人审核 - doneTaskVos.stream().filter(task -> "校工会负责人审核".equals(task.getDisplayName())) + // 协会负责人审核 + doneTaskVos.stream().filter(task -> "校工会财务审核".equals(task.getDisplayName())) .max(Comparator.comparing(ProcessTaskVO::getCreatedAt)) .ifPresent(v -> { Dict taskFormData = v.getTaskFormData(); - HashMap approval = new HashMap<>(); - - approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); - approval.put("user", taskFormData.getStr("tf_userName")); - if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) { - approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign"))); + NutMap map = new NutMap(); + map.put("unit", "校工会财务审核"); + map.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); + map.put("userName", taskFormData.getStr("tf_userName")); + if (StrUtil.isNotBlank(taskFormData.getStr("tf_userSign"))) { + map.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_userSign"))); } - approval.put("opinion", taskFormData.getStr("tf_opinion")); - docData.put("xfzr", approval); + map.put("opinion", taskFormData.getStr("tf_opinion")); + auditList.add(map); + }); + + + + // 校工会负责人审核 + doneTaskVos.stream().filter(task -> "校工会预审".equals(task.getDisplayName())) + .max(Comparator.comparing(ProcessTaskVO::getCreatedAt)) + .ifPresent(v -> { + Dict taskFormData = v.getTaskFormData(); + NutMap map = new NutMap(); + map.put("unit", "校工会预审"); + map.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); + map.put("userName", taskFormData.getStr("tf_userName")); + if (StrUtil.isNotBlank(taskFormData.getStr("tf_userSign"))) { + map.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_userSign"))); + } + map.put("opinion", taskFormData.getStr("tf_opinion")); + auditList.add(map); + }); + + doneTaskVos.stream().filter(task -> "校工会副主席审核".equals(task.getDisplayName())) + .max(Comparator.comparing(ProcessTaskVO::getCreatedAt)) + .ifPresent(v -> { + Dict taskFormData = v.getTaskFormData(); + NutMap map = new NutMap(); + map.put("unit", "校工会副主席审核"); + map.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); + map.put("userName", taskFormData.getStr("tf_userName")); + if (StrUtil.isNotBlank(taskFormData.getStr("tf_userSign"))) { + map.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_userSign"))); + } + map.put("opinion", taskFormData.getStr("tf_opinion")); + auditList.add(map); }); - // 校工会主席审核 doneTaskVos.stream().filter(task -> "校工会主席审核".equals(task.getDisplayName())) .max(Comparator.comparing(ProcessTaskVO::getCreatedAt)) .ifPresent(v -> { Dict taskFormData = v.getTaskFormData(); - HashMap approval = new HashMap<>(); - - approval.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); - approval.put("user", taskFormData.getStr("tf_userName")); - if (StrUtil.isNotBlank(taskFormData.getStr("tf_sign"))) { - approval.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_sign"))); + NutMap map = new NutMap(); + map.put("unit", "校工会主席审核"); + map.put("date", DateUtil.format(v.getFinishTime(), "yyyy年MM月dd日")); + map.put("userName", taskFormData.getStr("tf_userName")); + if (StrUtil.isNotBlank(taskFormData.getStr("tf_userSign"))) { + map.put("sign", sysOfficeTemplateUtil.createPictureRenderData(taskFormData.getStr("tf_userSign"))); } - approval.put("opinion", taskFormData.getStr("tf_opinion")); - docData.put("xzx", approval); + map.put("opinion", taskFormData.getStr("tf_opinion")); + auditList.add(map); }); String budgetsStr = info.getString("budgets"); @@ -396,17 +445,29 @@ public class ActivityReimbursementMineController { } docData.put("budgets", list); + docData.put("auditList", auditList); LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); Configure config = Configure.builder() .bind("budgets", policy) + .bind("auditList", policy) .build(); - String fileName = Globals.AppName + "【" + info.getString("activityName") + "】报销凭证表.docx"; + String fileName = Globals.AppName + "【" + info.getString("activityName") + "】报销凭证表.pdf"; try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("activity_reimbursement_voucher"), config).render(docData).writeAndClose(byteArrayOutputStream); - CommonDownloadUtil.download(fileName, byteArrayOutputStream.toByteArray(), response); + + byte[] bytes = byteArrayOutputStream.toByteArray(); + File sourceFile = File.createTempFile("file_convert_origin", ".docx"); + Files.write(sourceFile.toPath(), bytes, StandardOpenOption.WRITE); + + File pdfFile = File.createTempFile("file_convert", ".pdf"); + OfficePlusUtil.convert(sourceFile.getPath(), pdfFile.getPath()); + CommonDownloadUtil.download(fileName, IoUtil.readBytes(FileUtil.getInputStream(pdfFile)), response); + // 删除临时文件 + FileUtil.del(sourceFile); + FileUtil.del(pdfFile.toPath()); } catch (IOException e) { log.error("报销凭证表导出失败,id:{},错误信息:{}", id, e.getMessage()); } diff --git a/src/main/java/com/budwk/app/zhgh/dayofficework/message/strategy/impl/WechatEnterpriseMessageSendStrategy.java b/src/main/java/com/budwk/app/zhgh/dayofficework/message/strategy/impl/WechatEnterpriseMessageSendStrategy.java index e591409..da465e9 100644 --- a/src/main/java/com/budwk/app/zhgh/dayofficework/message/strategy/impl/WechatEnterpriseMessageSendStrategy.java +++ b/src/main/java/com/budwk/app/zhgh/dayofficework/message/strategy/impl/WechatEnterpriseMessageSendStrategy.java @@ -42,7 +42,7 @@ public class WechatEnterpriseMessageSendStrategy implements GlobalMessageSendStr @Override public boolean isEnabled() { - return GlobalMessageSendStrategy.super.isEnabled(); + return true; } @Override @@ -82,6 +82,6 @@ public class WechatEnterpriseMessageSendStrategy implements GlobalMessageSendStr return; } List list = users.stream().map(Sys_user::getLoginname).toList(); - smsService.massSend(list, title, content, ""); + smsService.massSendTextCard(list, "智慧工会", content, config.getStr("pcUrl"), config.getStr("mobileUrl")); } } diff --git a/src/main/resources/static/components/plugins/sysFilePreview/index.vue b/src/main/resources/static/components/plugins/sysFilePreview/index.vue index 7fcb532..410cd13 100644 --- a/src/main/resources/static/components/plugins/sysFilePreview/index.vue +++ b/src/main/resources/static/components/plugins/sysFilePreview/index.vue @@ -1,20 +1,20 @@ @@ -57,10 +113,46 @@ module.exports = { }, data() { return { - fileList: [] + fileList: [], + fileDialog: false, + defaultActive: 0, + file: {}, + officeLoading: true, } }, methods: { + next() { + this.defaultActive = Number(this.defaultActive) + if(this.defaultActive === this.fileList.length - 1) { + this.$message.error('已经是最后一个附件了') + return + } + this.defaultActive = this.defaultActive + 1 + this.file = this.fileList[this.defaultActive] + }, + previous() { + this.defaultActive = Number(this.defaultActive) + if(this.defaultActive === 0) { + this.$message.error('已经是第一个附件了') + return + } + this.defaultActive = this.defaultActive - 1 + this.file = this.fileList[this.defaultActive] + }, + menuSelect(index) { + index = Number(index) + this.defaultActive = Number(this.defaultActive) + if(index !== this.defaultActive) { + this.officeLoading = true + } + this.defaultActive = index + this.file = this.fileList[index] + }, + onPreView(item, index) { + this.file = item + this.defaultActive = index + this.fileDialog = true + }, buildEchoFileObject(val) { let ids = [] if (this.complete_result) { @@ -111,6 +203,76 @@ module.exports = { } + + diff --git a/src/main/resources/views/layouts/platform_h5.html b/src/main/resources/views/layouts/platform_h5.html index 6e0596c..17ced9b 100644 --- a/src/main/resources/views/layouts/platform_h5.html +++ b/src/main/resources/views/layouts/platform_h5.html @@ -70,10 +70,10 @@ - + >-->