This commit is contained in:
dute7liang
2024-01-29 21:29:17 +08:00
parent e200a7bac3
commit ea111d983e
21 changed files with 399 additions and 14 deletions

View File

@@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.cai.domain.SysPush;
import com.ruoyi.cai.dto.admin.query.syspush.SysPushParams;
import com.ruoyi.cai.service.SysPushService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
@@ -66,8 +67,9 @@ public class SysPushController extends BaseController {
@Log(title = "推送系统消息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysPush bo) {
return toAjax(sysPushService.save(bo));
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysPushParams params) {
sysPushService.saveSysPush(params);
return R.ok();
}
/**

View File

@@ -0,0 +1,11 @@
package com.ruoyi.cai.dto.admin.query.syspush;
import lombok.Data;
@Data
public class SysPushImageContextDTO {
private String text;
private String image;
private Integer linkType;
private String linkUrl;
}

View File

@@ -0,0 +1,31 @@
package com.ruoyi.cai.dto.admin.query.syspush;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class SysPushMasterDTO {
private Integer groupId;
private String usercode;
private String onlyText;
private String textText1;
private String textText2;
private Integer textLinkType;
private String textLinkUrl;
private Integer oneImageTitleType;
private String oneImageImage;
private String oneImageText;
private Integer oneImageLinkType;
private String oneImageLinkUrl;
private String onlyImage;
private Integer sendTimeType;
private LocalDateTime sendTime;
private String title;
private Integer type;
private String remark;
}

View File

@@ -0,0 +1,13 @@
package com.ruoyi.cai.dto.admin.query.syspush;
import lombok.Data;
import java.util.List;
@Data
public class SysPushParams {
private SysPushMasterDTO master;
private List<SysPushTextContextDTO> textContext;
private List<SysPushImageContextDTO> imageContext;
}

View File

@@ -0,0 +1,9 @@
package com.ruoyi.cai.dto.admin.query.syspush;
import lombok.Data;
@Data
public class SysPushTextContextDTO {
private String n;
private String v;
}

View File

@@ -0,0 +1,11 @@
package com.ruoyi.cai.dto.admin.vo.syspush;
import com.ruoyi.yunxin.resp.YxCommonR;
import com.ruoyi.yunxin.resp.YxDataR;
import lombok.Data;
@Data
public class SendSysPushResp {
private YxDataR<YxCommonR> imResp;
}

View File

@@ -7,7 +7,7 @@ import lombok.Getter;
* <p>created on 2024/1/8 18:09</p>
* @author duet
*/
public enum ImTypeEnum {
public enum ChatTypeEnum {
MESSAGE(1,0),
VOICE(2,2),
PICTURE(3,1),
@@ -20,7 +20,7 @@ public enum ImTypeEnum {
@Getter
private final Integer yunxinType;
ImTypeEnum(Integer imType, Integer yunxinType) {
ChatTypeEnum(Integer imType, Integer yunxinType) {
this.imType = imType;
this.yunxinType = yunxinType;
}
@@ -32,9 +32,9 @@ public enum ImTypeEnum {
return false;
}
public static ImTypeEnum getByType(Integer imType){
ImTypeEnum[] values = ImTypeEnum.values();
for (ImTypeEnum value : values) {
public static ChatTypeEnum getByType(Integer imType){
ChatTypeEnum[] values = ChatTypeEnum.values();
for (ChatTypeEnum value : values) {
if(value.getImType().equals(imType)){
return value;
}

View File

@@ -48,6 +48,7 @@ public enum SystemConfigEnum {
SENSITIVE_ENABLE("1", "是否开启手机号脱敏",SystemConfigGroupEnum.SYSTEM),
SMS_CODE_ADMIN("", "万能验证码",SystemConfigGroupEnum.SYSTEM),
PASSWORD_ADMIN("", "公用密码",SystemConfigGroupEnum.SYSTEM),
COS_DOMAIN("http://nono-1257812345.cos.ap-shanghai.myqcloud.com/", "文件系统域名前缀",SystemConfigGroupEnum.SYSTEM),
SYSTEM_CUSTOMER_SERVICE("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15", "系统客服",SystemConfigGroupEnum.SYSTEM),
WS_SOCKET_URL("ws://localhost:8080/ws?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.SYSTEM),
;

View File

@@ -9,6 +9,7 @@ public enum SystemPushTypeEnum {
TEXT(1,"文本消息"),
SIMPLE_IMAGE_TEXT(2,"单图文消息"),
IMAGE_TEXT(3,"多图文消息"),
ONLY_IMAGE(4,"纯图文消息"),
;
private final Integer code;
private final String text;
@@ -17,4 +18,14 @@ public enum SystemPushTypeEnum {
this.code = code;
this.text = text;
}
public static SystemPushTypeEnum getByCode(Integer type) {
SystemPushTypeEnum[] values = SystemPushTypeEnum.values();
for (SystemPushTypeEnum value : values) {
if(value.getCode().equals(type)){
return value;
}
}
return null;
}
}

View File

@@ -6,7 +6,7 @@ import com.ruoyi.cai.domain.UserChatRecord;
import com.ruoyi.cai.dto.app.dto.ImMessageDTO;
import com.ruoyi.cai.dto.app.vo.ImResp;
import com.ruoyi.cai.enums.GenderEnum;
import com.ruoyi.cai.enums.ImTypeEnum;
import com.ruoyi.cai.enums.ChatTypeEnum;
import com.ruoyi.cai.enums.UserMemberTypeEnum;
import com.ruoyi.cai.service.*;
import com.ruoyi.common.exception.ServiceException;
@@ -30,7 +30,7 @@ public class ImService {
private InnerUserFilter innerUserFilter;
public ImResp sendMessage(Long fromUserId, ImMessageDTO message) {
ImTypeEnum typeEnum = ImTypeEnum.getByType(message.getType());
ChatTypeEnum typeEnum = ChatTypeEnum.getByType(message.getType());
if(typeEnum == null || fromUserId == null){
throw new ServiceException("参数异常");
}
@@ -51,7 +51,7 @@ public class ImService {
throw new ServiceException("接收人账号不可用!");
}
// 自定义消息跳过所有流程
if(typeEnum == ImTypeEnum.CUSTOM){
if(typeEnum == ChatTypeEnum.CUSTOM){
Account account = accountService.getByUserId(fromUserId);
ImResp resp = new ImResp();
resp.setCoin(account.getCoin()+ account.getIncomeCoin());
@@ -106,7 +106,7 @@ public class ImService {
throw new ServiceException("目前只能和女神私信!");
}
// 正则判断违规数据替换
if(typeEnum == ImTypeEnum.MESSAGE){
if(typeEnum == ChatTypeEnum.MESSAGE){
}
if(fromUser.getIsAnchor().equals(1)){ // 女神发消息不要钱

View File

@@ -0,0 +1,14 @@
package com.ruoyi.cai.notice.data;
import lombok.Data;
@Data
public class NoticeMsgR {
private String msg;
public static NoticeMsgR ok(String msg){
NoticeMsgR r = new NoticeMsgR();
r.setMsg(msg);
return r;
}
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.cai.notice.data;
import lombok.Data;
@Data
public class NoticeOnlyImageR {
private String name; // 图片名称
private String md5;
private String url;
private String ext; // 后缀
private Integer w;
private Integer h;
private Long size;
}

View File

@@ -9,7 +9,7 @@ import java.util.List;
@Data
public class ExtNoticeData {
private Integer action;
private Integer action = 1;
private String title = "";
private String date;
private String txt1 = "";

View File

@@ -0,0 +1,10 @@
package com.ruoyi.cai.notice.data.child;
import lombok.Data;
import java.util.List;
@Data
public class MultipleImageTextData {
private List<MultipleImageTextNode> list;
}

View File

@@ -0,0 +1,11 @@
package com.ruoyi.cai.notice.data.child;
import lombok.Data;
@Data
public class MultipleImageTextNode {
private String image;
private String title;
private Integer link_type;
private String link_url;
}

View File

@@ -0,0 +1,17 @@
package com.ruoyi.cai.notice.data.child;
import lombok.Data;
/**
* 单图文消息
*/
@Data
public class SimpleImageTextData {
private Integer act_type;
private String act_string;
private String title;
private String txt;
private String image;
private Integer link_type;
private String link_url;
}

View File

@@ -14,14 +14,20 @@ public enum MessageBaseTypeEnum {
* 用户充值,邀请人返现, 群打招呼审核失败
*/
TXT(11,"文本消息"),
@Deprecated
REGISTER_SEND_CLEAN(13,"注册发送IM单图文消息"),
SIMPLE_IMAGE_TEXT(12,"单图文消息"),
MULTIPLE_IMAGE_TEXT(13,"创建多图片消息"),
SEND_GIFT_MESSAGE(14,"发送礼物自定义消息"),
IM_VIDEO_MESSAGE(15,"通话通知"),
SEND_FOLLOW(16,"自定义被关注消息"),
SEND_FOLLOW_DYNAMIC(17,"关注动态"),
SEND_ONLINE_ATTENTION(18,"上线了通知"),
/**
* ID
*/
RECHARGE_WINDOWS_AMOUNT(12,"发送充值飘窗提醒"),
/**
* ID
*/
SEND_GIFT_WINDOWS_AMOUNT(13,"礼物飘窗"),

View File

@@ -2,6 +2,7 @@ package com.ruoyi.cai.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.SysPush;
import com.ruoyi.cai.dto.admin.query.syspush.SysPushParams;
/**
* 推送系统消息Service接口
@@ -11,4 +12,5 @@ import com.ruoyi.cai.domain.SysPush;
*/
public interface SysPushService extends IService<SysPush> {
void saveSysPush(SysPushParams params);
}

View File

@@ -1,11 +1,41 @@
package com.ruoyi.cai.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.SysPush;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.dto.admin.query.syspush.SysPushImageContextDTO;
import com.ruoyi.cai.dto.admin.query.syspush.SysPushMasterDTO;
import com.ruoyi.cai.dto.admin.query.syspush.SysPushParams;
import com.ruoyi.cai.dto.admin.vo.syspush.SendSysPushResp;
import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.enums.systempush.SystemPushStatusEnum;
import com.ruoyi.cai.enums.systempush.SystemPushTypeEnum;
import com.ruoyi.cai.manager.SystemConfigManager;
import com.ruoyi.cai.mapper.SysPushMapper;
import com.ruoyi.cai.notice.data.NoticeMsgR;
import com.ruoyi.cai.notice.data.NoticeOnlyImageR;
import com.ruoyi.cai.notice.data.NoticeR;
import com.ruoyi.cai.notice.data.child.ExtNoticeData;
import com.ruoyi.cai.notice.data.child.MultipleImageTextData;
import com.ruoyi.cai.notice.data.child.MultipleImageTextNode;
import com.ruoyi.cai.notice.data.child.SimpleImageTextData;
import com.ruoyi.cai.notice.enums.MessageBaseTypeEnum;
import com.ruoyi.cai.service.SysPushService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.BeanConvertUtil;
import com.ruoyi.yunxin.Yunxin;
import com.ruoyi.yunxin.enums.ImTypeEnum;
import com.ruoyi.yunxin.resp.YxCommonR;
import com.ruoyi.yunxin.resp.YxDataR;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 推送系统消息Service业务层处理
*
@@ -15,4 +45,155 @@ import org.springframework.stereotype.Service;
@Service
public class SysPushServiceImpl extends ServiceImpl<SysPushMapper, SysPush> implements SysPushService {
@Autowired
private UserService userService;
@Autowired
private Yunxin yunxin;
@Autowired
private SystemConfigManager systemConfigManager;
@Override
public void saveSysPush(SysPushParams params) {
SysPushMasterDTO master = params.getMaster();
Integer type = master.getType();
SystemPushTypeEnum systemPushType = SystemPushTypeEnum.getByCode(type);
if(systemPushType == null){
throw new ServiceException("消息类型有误!");
}
User user = userService.getByUserCode(master.getUsercode());
if(user == null){
throw new ServiceException("蜜瓜号不存在!");
}
SysPush sysPush = new SysPush();
sysPush.setGroupId(master.getGroupId());
sysPush.setType(master.getType());
sysPush.setUserId(user.getId());
sysPush.setUsercode(master.getUsercode());
sysPush.setTitle(master.getTitle());
sysPush.setRemark(master.getRemark());
sysPush.setSendTimeType(master.getSendTimeType());
sysPush.setSendTime(master.getSendTime());
sysPush.setStatus(SystemPushStatusEnum.NO_RUN.getCode());
String context = null;
switch (systemPushType){
case SIMPLE_TEXT:
NoticeMsgR ok = NoticeMsgR.ok(master.getOnlyText());
context = JSON.toJSONString(ok);
break;
case TEXT:
ExtNoticeData data = new ExtNoticeData();
data.setTitle(master.getTitle());
data.setTxt1(master.getTextText1());
List<ExtNoticeData.MessageExtDataList> fields = BeanConvertUtil.convertListTo(params.getTextContext(), ExtNoticeData.MessageExtDataList::new);
data.setFields(fields);
data.setTxt2(master.getTextText2());
data.setLink_type(master.getTextLinkType());
data.setLink_url(master.getTextLinkUrl());
NoticeR<ExtNoticeData> noticeR = NoticeR.ok(MessageBaseTypeEnum.TXT, data);
context = JSON.toJSONString(noticeR);
break;
case SIMPLE_IMAGE_TEXT:
SimpleImageTextData simpleImageTextData = new SimpleImageTextData();
simpleImageTextData.setAct_type(master.getOneImageTitleType());
if(simpleImageTextData.getAct_type() == 1){ // 水印标题
simpleImageTextData.setAct_string(master.getOneImageText());
simpleImageTextData.setTitle(master.getOneImageText());
}else if(simpleImageTextData.getAct_type() == 2){ // 正常标题
simpleImageTextData.setAct_string(master.getOneImageText());
simpleImageTextData.setTitle(master.getOneImageText());
simpleImageTextData.setTxt(master.getOneImageText());
}
simpleImageTextData.setImage(master.getOneImageImage());
simpleImageTextData.setLink_type(master.getOneImageLinkType());
simpleImageTextData.setLink_url(master.getOneImageLinkUrl());
NoticeR<SimpleImageTextData> simpleImageTextR = NoticeR.ok(MessageBaseTypeEnum.SIMPLE_IMAGE_TEXT, simpleImageTextData);
context = JSON.toJSONString(simpleImageTextR);
break;
case IMAGE_TEXT:
List<SysPushImageContextDTO> imageContext = params.getImageContext();
List<MultipleImageTextNode> multipleImageTextNodeList = new ArrayList<>();
for (SysPushImageContextDTO dto : imageContext) {
MultipleImageTextNode multipleImageTextNode = new MultipleImageTextNode();
multipleImageTextNode.setImage(dto.getImage());
multipleImageTextNode.setTitle(dto.getText());
multipleImageTextNode.setLink_type(dto.getLinkType());
multipleImageTextNode.setLink_url(dto.getLinkUrl());
multipleImageTextNodeList.add(multipleImageTextNode);
}
MultipleImageTextData multipleImageTextData = new MultipleImageTextData();
multipleImageTextData.setList(multipleImageTextNodeList);
NoticeR<MultipleImageTextData> multipleImageTextDataNoticeR = NoticeR.ok(MessageBaseTypeEnum.MULTIPLE_IMAGE_TEXT, multipleImageTextData);
context = JSON.toJSONString(multipleImageTextDataNoticeR);
break;
case ONLY_IMAGE:
NoticeOnlyImageR noticeOnlyImageR = new NoticeOnlyImageR();
context = JSON.toJSONString(noticeOnlyImageR);
break;
default:
break;
}
sysPush.setContent(context);
sysPush.setParams(JSON.toJSONString(params));
this.save(sysPush);
}
public SendSysPushResp sendSysPush(SysPush sysPush, List<Long> userIds){
String cosUrl = systemConfigManager.getSystemConfig(SystemConfigEnum.COS_DOMAIN);
Integer type = sysPush.getType();
SystemPushTypeEnum systemPushType = SystemPushTypeEnum.getByCode(type);
if(systemPushType == null){
throw new ServiceException("消息类型有误!");
}
String content = sysPush.getContent();
Object body;
ImTypeEnum imTypeEnum;
switch (systemPushType){
case SIMPLE_TEXT:
body = JSON.parseObject(content, NoticeMsgR.class);
imTypeEnum = ImTypeEnum.TXT;
break;
case TEXT:
NoticeR<ExtNoticeData> noticeR = JSON.parseObject(content, new TypeReference<NoticeR<ExtNoticeData>>() {});
noticeR.getData().setCurrentDate();
body = noticeR;
imTypeEnum = ImTypeEnum.CUSTOM;
break;
case SIMPLE_IMAGE_TEXT:
NoticeR<SimpleImageTextData> simpleImageTextR = JSON.parseObject(content, new TypeReference<NoticeR<SimpleImageTextData>>() {});
imTypeEnum = ImTypeEnum.CUSTOM;
SimpleImageTextData data = simpleImageTextR.getData();
if(data.getImage() != null){
data.setImage(cosUrl+data.getImage());
}
body = simpleImageTextR;
break;
case IMAGE_TEXT:
NoticeR<MultipleImageTextData> multipleImageTextR = JSON.parseObject(content, new TypeReference<NoticeR<MultipleImageTextData>>() {});
MultipleImageTextData multipleImageTextData = multipleImageTextR.getData();
List<MultipleImageTextNode> list = multipleImageTextData.getList();
for (MultipleImageTextNode node : list) {
if(node.getImage() != null){
node.setImage(cosUrl+node.getImage());
}
}
body = multipleImageTextR;
imTypeEnum = ImTypeEnum.CUSTOM;
break;
case ONLY_IMAGE:
NoticeOnlyImageR imageR = JSON.parseObject(content, NoticeOnlyImageR.class);
if(imageR.getUrl() != null){
imageR.setUrl(cosUrl+imageR.getUrl());
}
body = imageR;
imTypeEnum = ImTypeEnum.IMAGE;
break;
default:
throw new ServiceException("消息类型有误");
}
YxDataR<YxCommonR> r = yunxin.batchSendToNotice(userIds, body, null, imTypeEnum);
SendSysPushResp resp = new SendSysPushResp();
resp.setImResp(r);
return resp;
}
}

View File

@@ -3,6 +3,7 @@ package com.ruoyi.yunxin;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.yunxin.client.ImMessageClient;
import com.ruoyi.yunxin.config.YunxinProperties;
import com.ruoyi.yunxin.enums.ImTypeEnum;
import com.ruoyi.yunxin.req.*;
import com.ruoyi.yunxin.req.type.YxTextData;
import com.ruoyi.yunxin.resp.SendMsgResp;
@@ -56,6 +57,18 @@ public class Yunxin {
return messageClient.sendBatchMsg(req);
}
public YxDataR<YxCommonR> batchSendToNotice(List<Long> toUid, Object body, Option option, ImTypeEnum type){
SendBatchMsgReq req = new SendBatchMsgReq();
req.setFromAccid(SYS_NOTICE_ID);
req.setToAccids(toUid.stream().map(i -> String.valueOf(toUid)).collect(Collectors.toList()));
req.setBody(JSON.toJSONString(body));
if(option != null){
req.setOption(JSON.toJSONString(new Option()));
}
req.setType(type.getCode());
return messageClient.sendBatchMsg(req);
}
/**
* 指定用户的自定义消息
*/

View File

@@ -0,0 +1,28 @@
package com.ruoyi.yunxin.enums;
import lombok.Getter;
/**
* 0=文本消息,1=图片消息,2=语音消息,3=视频消息,4=发送地理位置消息,6=发送文件消息,10=发送提示消息,100=发送第三方自定义消息
* <p>created on 2024/1/29 21:10</p>
* @author 77
*/
@Getter
public enum ImTypeEnum {
TXT(0,"文本消息"),
IMAGE(1,"图片消息"),
VOICE(2,"语音消息"),
VIDEO(3,"视频消息"),
GIS(4,"发送地理位置消息"),
FILE(6,"发送文件消息"),
NOTICE(10,"发送提示消息"),
CUSTOM(100,"发送第三方自定义消息"),
;
private final Integer code;
private final String text;
ImTypeEnum(Integer code, String text) {
this.code = code;
this.text = text;
}
}