Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
4ef17da7f1
@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.common.util.date;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@ -29,6 +30,18 @@ public class DateUtils {
|
||||
|
||||
public static final String FORMAT_HOUR_MINUTE_SECOND = "HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 根据传入的时间格式,将Date对象,转换成对应的时间格式
|
||||
* @param date
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static String dateFormat(Date date, String format) {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(format);
|
||||
String formattedDate = formatter.format(date);
|
||||
return formattedDate ;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 LocalDateTime 转换成 Date
|
||||
*
|
||||
|
@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
|
||||
|
||||
@ -14,6 +15,7 @@ import javax.validation.constraints.NotNull;
|
||||
@ConfigurationProperties(prefix = "yudao.web")
|
||||
@Validated
|
||||
@Data
|
||||
@Component
|
||||
public class WebProperties {
|
||||
|
||||
@NotNull(message = "APP API 不能为空")
|
||||
|
@ -114,6 +114,12 @@
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-flowable</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId> <!-- 微信登录(小程序) -->
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
|
@ -1,11 +1,17 @@
|
||||
package cn.iocoder.yudao.module.bpm.convert.message;
|
||||
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
|
||||
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
@ -23,4 +29,95 @@ public interface BpmMessageConvert {
|
||||
@Mapping(source = "templateCode", target = "templateCode")
|
||||
@Mapping(source = "templateParams", target = "templateParams")
|
||||
NotifySendSingleToUserReqDTO convert1(Long userId, String templateCode, Map<String, Object> templateParams);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param openId 微信小程序唯一id
|
||||
* @param processInstanceName 流程名称
|
||||
* @param result 审批结果
|
||||
* @param reason 审批原因
|
||||
* @param miniProgramState 小程序的状态
|
||||
* @return
|
||||
*/
|
||||
default WxMaSubscribeMessage convertApprovalResultNotification(String openId, String processInstanceName, String time, String result, String reason, String miniProgramState) {
|
||||
WxMaSubscribeMessage message = new WxMaSubscribeMessage() ;
|
||||
message.setToUser(openId) ;
|
||||
message.setTemplateId("OnJjp5pdjG1PHMoELYaqp3Xq8jWZ5E6ndO0clEIQ4tk") ;
|
||||
//审批类型
|
||||
WxMaSubscribeMessage.MsgData processType = new WxMaSubscribeMessage.MsgData();
|
||||
processType.setName("thing1") ;
|
||||
processType.setValue(processInstanceName) ;
|
||||
message.addData(processType);
|
||||
|
||||
//发起时间
|
||||
WxMaSubscribeMessage.MsgData createTime = new WxMaSubscribeMessage.MsgData();
|
||||
createTime.setName("time2") ;
|
||||
createTime.setValue(time) ;
|
||||
message.addData(createTime);
|
||||
|
||||
//审批时间
|
||||
WxMaSubscribeMessage.MsgData approvalTime = new WxMaSubscribeMessage.MsgData();
|
||||
approvalTime.setName("time7") ;
|
||||
approvalTime.setValue(DateUtils.dateFormat(new Date(),DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)) ;
|
||||
message.addData(approvalTime);
|
||||
|
||||
//审批结果
|
||||
WxMaSubscribeMessage.MsgData approvalResult = new WxMaSubscribeMessage.MsgData();
|
||||
approvalResult.setName("phrase3") ;
|
||||
approvalResult.setValue(result) ;
|
||||
message.addData(approvalResult);
|
||||
|
||||
if(reason != null ) {
|
||||
WxMaSubscribeMessage.MsgData approvalReason = new WxMaSubscribeMessage.MsgData();
|
||||
approvalReason.setName("thing12") ;
|
||||
approvalReason.setValue(reason) ;
|
||||
message.addData(approvalReason);
|
||||
}
|
||||
|
||||
message.setMiniprogramState(miniProgramState) ;
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param openId 微信小程序唯一id
|
||||
* @param processInstanceName 流程名称
|
||||
* @param startUserNickname 申请人
|
||||
* @param time 申请时间
|
||||
* @param schedule 流程进度
|
||||
* @param miniProgramState 小程序的状态
|
||||
* @return
|
||||
*/
|
||||
default WxMaSubscribeMessage convertProcessToDoReminder(String openId, String processInstanceName,String startUserNickname, String time, String schedule, String miniProgramState) {
|
||||
WxMaSubscribeMessage message = new WxMaSubscribeMessage() ;
|
||||
message.setToUser(openId) ;
|
||||
message.setTemplateId("3cP4btlFSSiZk65qVewN_WoT_bh0OfUkYzzTsADOrR4") ;
|
||||
//待办标题
|
||||
WxMaSubscribeMessage.MsgData processType = new WxMaSubscribeMessage.MsgData();
|
||||
processType.setName("thing1") ;
|
||||
processType.setValue("您收到了一条新的待办任务:"+processInstanceName) ;
|
||||
message.addData(processType);
|
||||
|
||||
//申请人
|
||||
WxMaSubscribeMessage.MsgData applicant = new WxMaSubscribeMessage.MsgData();
|
||||
applicant.setName("thing4") ;
|
||||
applicant.setValue(startUserNickname) ;
|
||||
message.addData(applicant);
|
||||
|
||||
//申请时间
|
||||
WxMaSubscribeMessage.MsgData createTime = new WxMaSubscribeMessage.MsgData();
|
||||
createTime.setName("time5") ;
|
||||
createTime.setValue(time) ;
|
||||
message.addData(createTime);
|
||||
|
||||
//当前进度
|
||||
WxMaSubscribeMessage.MsgData currentSchedule = new WxMaSubscribeMessage.MsgData();
|
||||
currentSchedule.setName("thing6") ;
|
||||
currentSchedule.setValue(schedule) ;
|
||||
message.addData(currentSchedule);
|
||||
|
||||
message.setMiniprogramState(miniProgramState) ;
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,14 @@ import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
|
||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
|
||||
import cn.iocoder.yudao.module.system.api.sms.SmsSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableFeignClients(clients = {FileApi.class,RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class, NotifyMessageSendApi.class})
|
||||
@EnableFeignClients(clients = {FileApi.class,RoleApi.class, DeptApi.class, PostApi.class, AdminUserApi.class, SmsSendApi.class, DictDataApi.class, NotifyMessageSendApi.class,
|
||||
// SubscribeMessageSendApi.class
|
||||
})
|
||||
public class RpcConfiguration {
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.message;
|
||||
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
|
||||
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||
import cn.iocoder.yudao.module.bpm.convert.message.BpmMessageConvert;
|
||||
@ -11,13 +14,15 @@ import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenTaskCre
|
||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.sms.SmsSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.SubscribeMessageSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* BPM 消息 Service 实现类
|
||||
@ -35,11 +40,15 @@ public class BpmMessageServiceImpl implements BpmMessageService {
|
||||
@Resource
|
||||
private NotifyMessageSendApi notifyMessageSendApi;
|
||||
|
||||
@Resource
|
||||
private SubscribeMessageSendApi subscribeMessageSendApi ;
|
||||
|
||||
@Resource
|
||||
private WebProperties webProperties;
|
||||
|
||||
@Override
|
||||
public void sendMessageWhenProcessInstanceApprove(BpmMessageSendWhenProcessInstanceApproveReqDTO reqDTO) {
|
||||
//审批通过
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
|
||||
templateParams.put("detailUrl", getProcessInstanceDetailUrl(reqDTO.getProcessInstanceId()));
|
||||
@ -47,10 +56,23 @@ public class BpmMessageServiceImpl implements BpmMessageService {
|
||||
// BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getSmsTemplateCode(), templateParams));
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(BpmMessageConvert.INSTANCE.convert1(reqDTO.getStartUserId(),
|
||||
BpmMessageEnum.PROCESS_INSTANCE_APPROVE.getSmsTemplateCode(), templateParams));
|
||||
|
||||
//发送审批结果通知
|
||||
String openId = getUserOpenId(reqDTO.getStartUserId()) ;
|
||||
if(openId != null ) {
|
||||
// subscribeMessageSendApi.sendApprovalResultNotification(
|
||||
// BpmMessageConvert.INSTANCE.convertApprovalResultNotification(
|
||||
// openId,reqDTO.getProcessInstanceName(), "","通过", null,
|
||||
// /**
|
||||
// * 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
|
||||
// */
|
||||
// WxMaConstants.MiniProgramState.DEVELOPER) ) ;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessageWhenProcessInstanceReject(BpmMessageSendWhenProcessInstanceRejectReqDTO reqDTO) {
|
||||
//审批不通过
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
templateParams.put("processInstanceName", reqDTO.getProcessInstanceName());
|
||||
templateParams.put("reason", reqDTO.getReason());
|
||||
@ -59,10 +81,24 @@ public class BpmMessageServiceImpl implements BpmMessageService {
|
||||
// BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsTemplateCode(), templateParams));
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(BpmMessageConvert.INSTANCE.convert1(
|
||||
reqDTO.getStartUserId(), BpmMessageEnum.PROCESS_INSTANCE_REJECT.getSmsTemplateCode(), templateParams));
|
||||
|
||||
//发送审批结果通知
|
||||
String openId = getUserOpenId(reqDTO.getStartUserId()) ;
|
||||
if(openId != null ) {
|
||||
// subscribeMessageSendApi.sendApprovalResultNotification(
|
||||
// BpmMessageConvert.INSTANCE.convertApprovalResultNotification(
|
||||
// openId,reqDTO.getProcessInstanceName(),"","不通过", reqDTO.getReason(),
|
||||
// /**
|
||||
// * 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
|
||||
// */
|
||||
// WxMaConstants.MiniProgramState.DEVELOPER) ) ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessageWhenTaskAssigned(BpmMessageSendWhenTaskCreatedReqDTO reqDTO) {
|
||||
//任务分配
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId() ;
|
||||
Long startUserId = reqDTO.getStartUserId();
|
||||
//如果发起人和接受人是同一个人,那么不发送站内信,否则就发送
|
||||
@ -76,6 +112,17 @@ public class BpmMessageServiceImpl implements BpmMessageService {
|
||||
// BpmMessageEnum.TASK_ASSIGNED.getSmsTemplateCode(), templateParams));
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(BpmMessageConvert.INSTANCE.convert1(
|
||||
reqDTO.getAssigneeUserId(), BpmMessageEnum.TASK_ASSIGNED.getSmsTemplateCode(), templateParams));
|
||||
|
||||
//发送OA流程待办提醒
|
||||
String openId = getUserOpenId(reqDTO.getStartUserId()) ;
|
||||
if(openId != null ) {
|
||||
|
||||
// subscribeMessageSendApi.sendProcessToDoReminder( BpmMessageConvert.INSTANCE.convertProcessToDoReminder(
|
||||
// openId, reqDTO.getProcessInstanceName(), reqDTO.getStartUserNickname(),"","",
|
||||
// WxMaConstants.MiniProgramState.DEVELOPER ) ) ;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,4 +131,11 @@ public class BpmMessageServiceImpl implements BpmMessageService {
|
||||
return webProperties.getAdminUi().getUrl() + "/process-instance/detail?id=" + taskId;
|
||||
}
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi ;
|
||||
private String getUserOpenId(Long userId) {
|
||||
AdminUserRespDTO adminUserRespDTO = adminUserApi.getUser(userId).getData();
|
||||
String openId = adminUserRespDTO.getOpenId() ;
|
||||
return openId ;
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ yudao:
|
||||
base-package: cn.iocoder.yudao.module.bpm
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
swagger:
|
||||
title: 管理后台
|
||||
description: 提供管理员管理的所有功能
|
||||
|
@ -115,7 +115,7 @@ yudao:
|
||||
base-package: cn.iocoder.yudao.module.infra
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
websocket:
|
||||
enable: true # websocket的开关
|
||||
path: /infra/ws # 路径
|
||||
|
@ -102,5 +102,5 @@ yudao:
|
||||
enable: false
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
demo: true # 开启演示模式
|
||||
|
@ -121,7 +121,7 @@ yudao:
|
||||
tag: ${HOSTNAME}
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
security:
|
||||
mock-enable: true
|
||||
xss:
|
||||
|
@ -102,5 +102,5 @@ yudao:
|
||||
enable: false
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
demo: true # 开启演示模式
|
||||
|
@ -121,7 +121,7 @@ yudao:
|
||||
tag: ${HOSTNAME}
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
security:
|
||||
mock-enable: true
|
||||
xss:
|
||||
|
@ -102,5 +102,5 @@ yudao:
|
||||
enable: false
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
demo: true # 开启演示模式
|
||||
|
@ -121,7 +121,7 @@ yudao:
|
||||
tag: ${HOSTNAME}
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
security:
|
||||
mock-enable: true
|
||||
xss:
|
||||
|
@ -102,6 +102,6 @@ yudao:
|
||||
enable: false
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
demo: true # 开启演示模式
|
||||
tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
|
||||
|
@ -121,7 +121,7 @@ yudao:
|
||||
tag: ${HOSTNAME}
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
security:
|
||||
mock-enable: true
|
||||
xss:
|
||||
|
@ -102,5 +102,5 @@ yudao:
|
||||
enable: false
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
demo: true # 开启演示模式
|
||||
|
@ -121,7 +121,7 @@ yudao:
|
||||
tag: ${HOSTNAME}
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
security:
|
||||
mock-enable: true
|
||||
xss:
|
||||
|
@ -92,7 +92,7 @@ yudao:
|
||||
base-package: cn.iocoder.yudao.module.mp
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
security:
|
||||
permit-all_urls:
|
||||
- /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,不需要登录
|
||||
|
@ -89,7 +89,7 @@ yudao:
|
||||
base-package: cn.iocoder.yudao.module.pay
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
swagger:
|
||||
title: 管理后台
|
||||
description: 提供管理员管理的所有功能
|
||||
|
@ -89,7 +89,7 @@ yudao:
|
||||
base-package: cn.iocoder.yudao.module.report
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
swagger:
|
||||
title: 管理后台
|
||||
description: 提供管理员管理的所有功能
|
||||
|
@ -0,0 +1,25 @@
|
||||
package cn.iocoder.yudao.module.system.api.subscribe;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.dto.SubscribeMessageReqDTO;
|
||||
import cn.iocoder.yudao.module.system.enums.ApiConstants;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
|
||||
@Tag(name = "RPC 服务 - 微信小程序订阅消息发送")
|
||||
public interface SubscribeMessageSendApi {
|
||||
|
||||
String PREFIX = ApiConstants.PREFIX + "/subscribe/send";
|
||||
|
||||
@PostMapping(PREFIX + "/send-approval-result-notification")
|
||||
@Operation(summary = "发送审批结果通知")
|
||||
CommonResult<Long> sendApprovalResultNotification(SubscribeMessageReqDTO reqDTO);
|
||||
|
||||
@PostMapping(PREFIX + "/send-process-todo-reminder")
|
||||
@Operation(summary = "发送OA流程待办提醒")
|
||||
CommonResult<Long> sendProcessToDoReminder(SubscribeMessageReqDTO reqDTO);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package cn.iocoder.yudao.module.system.api.subscribe.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 功能描述
|
||||
*
|
||||
* @author: yj
|
||||
* @date: 2024年02月25日 15:58
|
||||
*/
|
||||
@Data
|
||||
public class MsgData {
|
||||
|
||||
@Schema(description = "模版消息字段名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "thing1")
|
||||
@NotNull(message = "模板消息的名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模版消息字段值", requiredMode = Schema.RequiredMode.REQUIRED, example = "OnJjp5pdjG1PHMoELYaqp3Xq8jWZ5E6ndO0clEIQ4tk")
|
||||
@NotNull(message = "模板消息的value不能为空")
|
||||
private String value;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cn.iocoder.yudao.module.system.api.subscribe.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 功能描述
|
||||
*
|
||||
* @author: yj
|
||||
* @date: 2024年02月25日 15:50
|
||||
*/
|
||||
@Schema(description = "RPC 服务 - 微信小程序订阅消息 Request DTO")
|
||||
@Data
|
||||
public class SubscribeMessageReqDTO {
|
||||
|
||||
@Schema(description = "接收者(用户)的 openid", requiredMode = Schema.RequiredMode.REQUIRED, example = "o3bwX6Yw1bvbMAV-jUNjHrbrJu0I")
|
||||
@NotNull(message = "openid不能为空")
|
||||
private String toUser;
|
||||
|
||||
@Schema(description = "所需下发的模板消息的id", requiredMode = Schema.RequiredMode.REQUIRED, example = "OnJjp5pdjG1PHMoELYaqp3Xq8jWZ5E6ndO0clEIQ4tk")
|
||||
@NotNull(message = "模板消息的id不能为空")
|
||||
private String templateId;
|
||||
|
||||
@Schema(description = "所需下发的模板消息的属性集合", requiredMode = Schema.RequiredMode.REQUIRED, example = "OnJjp5pdjG1PHMoELYaqp3Xq8jWZ5E6ndO0clEIQ4tk")
|
||||
private List<MsgData> data;
|
||||
|
||||
@Schema(description = "跳转小程序类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "developer为开发版;trial为体验版;formal为正式版;默认为正式版")
|
||||
@NotNull(message = "跳转小程序类型不能为空")
|
||||
private String miniprogramState = "formal" ;
|
||||
|
||||
}
|
@ -27,4 +27,6 @@ public class AdminUserRespDTO {
|
||||
@Schema(description = "手机号码", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
|
||||
private String mobile;
|
||||
|
||||
@Schema(description = "微信小程序用户opneId", requiredMode = Schema.RequiredMode.REQUIRED, example = "o3bwX6Yw1bvbMAV-jUNjHrbrJu0I")
|
||||
private String openId;
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package cn.iocoder.yudao.module.system.api.subscribe;
|
||||
|
||||
import cn.binarywang.wx.miniapp.api.WxMaSubscribeService;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.dto.MsgData;
|
||||
import cn.iocoder.yudao.module.system.api.subscribe.dto.SubscribeMessageReqDTO;
|
||||
import lombok.SneakyThrows;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 功能描述 微信小程序发送订阅消息
|
||||
*
|
||||
* @author: yj
|
||||
* @date: 2024年02月25日 11:35
|
||||
*/
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
public class SubscribeMessageSendApiImpl implements SubscribeMessageSendApi{
|
||||
@Resource
|
||||
private WxMaSubscribeService wxMaSubscribeService ;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public CommonResult<Long> sendApprovalResultNotification(SubscribeMessageReqDTO reqDTO) {
|
||||
wxMaSubscribeService.sendSubscribeMsg(initWxMaSubscribeMessage(reqDTO));
|
||||
return success(1L);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public CommonResult<Long> sendProcessToDoReminder(SubscribeMessageReqDTO reqDTO) {
|
||||
wxMaSubscribeService.sendSubscribeMsg(initWxMaSubscribeMessage(reqDTO));
|
||||
return success(1L);
|
||||
}
|
||||
|
||||
private WxMaSubscribeMessage initWxMaSubscribeMessage( SubscribeMessageReqDTO reqDTO ) {
|
||||
WxMaSubscribeMessage message = new WxMaSubscribeMessage() ;
|
||||
message.setToUser(reqDTO.getToUser()) ;
|
||||
message.setTemplateId(reqDTO.getTemplateId());
|
||||
message.setMiniprogramState(reqDTO.getMiniprogramState());
|
||||
List<MsgData> dataList = reqDTO.getData() ;
|
||||
for (MsgData msgData : dataList) {
|
||||
WxMaSubscribeMessage.MsgData wxMsgData = new WxMaSubscribeMessage.MsgData() ;
|
||||
wxMsgData.setName(msgData.getName()) ;
|
||||
wxMsgData.setValue(msgData.getValue()) ;
|
||||
message.addData(wxMsgData) ;
|
||||
}
|
||||
return message ;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.auth;
|
||||
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -170,4 +171,10 @@ public class AuthController {
|
||||
return success(authService.miniAppQuickLogin(reqVO)) ;
|
||||
}
|
||||
|
||||
@PostMapping("/miniapp_code2Session")
|
||||
@PermitAll
|
||||
@Operation(summary = "微信小程序openid", description = "获取微信小程序的openid" )
|
||||
public CommonResult<WxMaJscode2SessionResult> miniAppCode2Session(@RequestBody AuthSocialLoginReqVO reqVO) {
|
||||
return success(authService.miniAppCode2Session(reqVO)) ;
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,9 @@ public class AuthLoginReqVO {
|
||||
@Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62")
|
||||
private String socialState;
|
||||
|
||||
@Schema(description = "openId", requiredMode = Schema.RequiredMode.REQUIRED, example = "o3bwX6Yw1bvbMAV-jUNjHrbrJu0I")
|
||||
private String openId;
|
||||
|
||||
/**
|
||||
* 开启验证码的 Group
|
||||
*/
|
||||
|
@ -31,4 +31,8 @@ public class AuthSocialLoginReqVO {
|
||||
@NotEmpty(message = "state 不能为空")
|
||||
private String state;
|
||||
|
||||
@Schema(description = "openId", requiredMode = Schema.RequiredMode.REQUIRED, example = "o3bwX6Yw1bvbMAV-jUNjHrbrJu0I")
|
||||
@NotEmpty(message = "openId 不能为空")
|
||||
private String openId;
|
||||
|
||||
}
|
||||
|
@ -93,4 +93,8 @@ public class AdminUserDO extends TenantBaseDO {
|
||||
*/
|
||||
private LocalDateTime loginDate;
|
||||
|
||||
/**
|
||||
* 微信小程序openId
|
||||
*/
|
||||
private String openId ;
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import java.util.List;
|
||||
@Mapper
|
||||
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
|
||||
|
||||
default AdminUserDO sgetByOpenId(String openId) { return selectOne(AdminUserDO::getOpenId, openId); }
|
||||
|
||||
default AdminUserDO selectByUsername(String username) {
|
||||
return selectOne(AdminUserDO::getUsername, username);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.service.auth;
|
||||
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
|
||||
@ -77,4 +79,11 @@ public interface AdminAuthService {
|
||||
* @return 登陆结果
|
||||
*/
|
||||
AuthLoginRespVO miniAppQuickLogin(AuthSocialLoginReqVO reqVO) ;
|
||||
|
||||
/**
|
||||
* 获取微信 获取微信小程序的用户唯一标识 openId
|
||||
* @param reqVO jscode
|
||||
* @return 用户唯一标识
|
||||
*/
|
||||
WxMaJscode2SessionResult miniAppCode2Session(AuthSocialLoginReqVO reqVO) ;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.iocoder.yudao.module.system.service.auth;
|
||||
|
||||
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
@ -107,6 +109,12 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
socialUserService.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(),
|
||||
reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState()));
|
||||
}
|
||||
|
||||
if (reqVO.getOpenId() != null) {
|
||||
//绑定用户openId
|
||||
userService.updateUserOpenId(user.getId(),reqVO.getOpenId());
|
||||
}
|
||||
|
||||
// 创建 Token 令牌,记录登录日志
|
||||
return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
|
||||
}
|
||||
@ -259,7 +267,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
phoneNumber = "18611845857" ;
|
||||
String appId = wxMaPhoneNumberInfo.getWatermark().getAppid() ; //小程序的appId
|
||||
|
||||
final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_USERNAME;
|
||||
final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_MOBILE;
|
||||
|
||||
//因为账号就是保存用户的手机号, 所以userName就是手机号
|
||||
// 校验账号是否存在
|
||||
@ -274,6 +282,9 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
throw exception(AUTH_LOGIN_USER_DISABLED);
|
||||
}
|
||||
|
||||
//绑定用户openId
|
||||
userService.updateUserOpenId(user.getId(),reqVO.getOpenId());
|
||||
|
||||
/** 创建 Token 令牌,记录登录日志 */
|
||||
Long userId = user.getId() ;
|
||||
// 插入登陆日志
|
||||
@ -285,4 +296,9 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
return AuthConvert.INSTANCE.convert(accessTokenDO);
|
||||
// return createTokenAfterLoginSuccess(user.getId(), phoneNumber, LoginLogTypeEnum.LOGIN_SOCIAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxMaJscode2SessionResult miniAppCode2Session(AuthSocialLoginReqVO reqVO) {
|
||||
return socialClientService.getWxMaJscode2SessionResult(reqVO.getCode()) ;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.system.service.social;
|
||||
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
|
||||
@ -61,6 +62,13 @@ public interface SocialClientService {
|
||||
*/
|
||||
WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(Integer userType, String phoneCode);
|
||||
|
||||
/**
|
||||
* 获取微信小程序的用户唯一标识 openId
|
||||
* @param jsCode 登录时获取的 code,可通过wx.login获取
|
||||
* @return
|
||||
*/
|
||||
WxMaJscode2SessionResult getWxMaJscode2SessionResult(String jsCode) ;
|
||||
|
||||
// =================== 客户端管理 ===================
|
||||
|
||||
/**
|
||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.social;
|
||||
|
||||
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
||||
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||
import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
@ -336,4 +337,11 @@ public class SocialClientServiceImpl implements SocialClientService {
|
||||
return socialClientMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public WxMaJscode2SessionResult getWxMaJscode2SessionResult(String jsCode) {
|
||||
WxMaService wxMaService = getWxMaService(2) ;
|
||||
WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(jsCode) ;
|
||||
return result ;
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,12 @@ public interface AdminUserService {
|
||||
*/
|
||||
Long createUser(@Valid UserSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 绑定用户微信小程序openId
|
||||
* @param openId
|
||||
*/
|
||||
void updateUserOpenId(Long id, String openId);
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
*
|
||||
@ -111,6 +117,14 @@ public interface AdminUserService {
|
||||
*/
|
||||
AdminUserDO getUserByMobile(String mobile);
|
||||
|
||||
/**
|
||||
* 根据opneId获取用户
|
||||
*
|
||||
* @param openId 微信小程序用户唯一id
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
AdminUserDO getUserByOpenId(String openId) ;
|
||||
|
||||
/**
|
||||
* 获得用户分页列表
|
||||
*
|
||||
|
@ -77,6 +77,20 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
@Resource
|
||||
private FileApi fileApi;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateUserOpenId(Long id,String openId) {
|
||||
userMapper.updateById(new AdminUserDO().setId(id).setOpenId(openId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdminUserDO getUserByOpenId(String openId) {
|
||||
if (openId == null) {
|
||||
return null ;
|
||||
}
|
||||
return userMapper.sgetByOpenId(openId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createUser(UserSaveReqVO createReqVO) {
|
||||
|
@ -134,7 +134,7 @@ yudao:
|
||||
base-package: cn.iocoder.yudao.module.system
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
swagger:
|
||||
title: 管理后台
|
||||
description: 提供管理员管理的所有功能
|
||||
|
@ -84,7 +84,7 @@ yudao:
|
||||
base-package: cn.iocoder.yudao.module.smartfactory
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
swagger:
|
||||
title: 管理后台
|
||||
description: 提供管理员管理的所有功能
|
||||
|
Loading…
Reference in New Issue
Block a user