♻️ Refactoring code. 微信管理
This commit is contained in:
1 parent
b864c748b6
commit
3af4a03e10
35 files changed
+1393
-686
No files matched your search
@@ -23,7 +23,7 @@
|
||||
<druid.version>1.1.21</druid.version>
|
||||
<mysql.connector.version>8.0.19</mysql.connector.version>
|
||||
<swagger.core.version>1.5.22</swagger.core.version>
|
||||
<mp.weixin.version>3.6.0</mp.weixin.version>
|
||||
<mp.weixin.version>3.7.0</mp.weixin.version>
|
||||
<ijpay.version>1.2.0</ijpay.version>
|
||||
<fastjson.version>1.2.67</fastjson.version>
|
||||
<aliyun.version>3.0.52.ALL</aliyun.version>
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.pig4cloud.pigx.mp.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/4/25
|
||||
* <p>
|
||||
* 消息类型
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MsgTypeEnum {
|
||||
|
||||
/**
|
||||
* 用户发给公众号
|
||||
*/
|
||||
USER2MP("1", "用户发给公众号"),
|
||||
|
||||
/**
|
||||
* 公众号发给用户
|
||||
*/
|
||||
MP2USER("2", "公众号发给用户");
|
||||
|
||||
/***
|
||||
* 类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String desc;
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.pig4cloud.pigx.mp.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/4/25
|
||||
* <p>
|
||||
* 匹配类型
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ReplyMateEnum {
|
||||
|
||||
/**
|
||||
* 完全匹配
|
||||
*/
|
||||
ALL("1", "完全匹配"),
|
||||
|
||||
/**
|
||||
* 半匹配
|
||||
*/
|
||||
LIKE("2", "半匹配");
|
||||
|
||||
|
||||
/***
|
||||
* 类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String desc;
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.pig4cloud.pigx.mp.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/4/25
|
||||
* <p>
|
||||
* 回复类型
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ReplyTypeEnum {
|
||||
|
||||
/**
|
||||
* 关注自动回复
|
||||
*/
|
||||
ATTENTION("1", "关注时回复"),
|
||||
|
||||
/**
|
||||
* 用户消息回复
|
||||
*/
|
||||
MSG("2", "消息回复"),
|
||||
|
||||
/**
|
||||
* 关键字回复
|
||||
*/
|
||||
KEYWORD("3", "关键词回复");
|
||||
|
||||
/***
|
||||
* 类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String desc;
|
||||
|
||||
|
||||
/**
|
||||
* 根据 type 查找枚举
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public static ReplyTypeEnum getEnumByType(String type) {
|
||||
for (ReplyTypeEnum value : ReplyTypeEnum.values()) {
|
||||
if (value.getType().equals(type)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.pig4cloud.pigx.mp.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2020/4/26
|
||||
* <p>
|
||||
* 公众号订阅状态
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SubStatusEnum {
|
||||
/**
|
||||
* 已关注
|
||||
*/
|
||||
SUBED("1", "已关注"),
|
||||
|
||||
/**
|
||||
* 未关注
|
||||
*/
|
||||
UNSUB("0", "关注");
|
||||
|
||||
|
||||
/***
|
||||
* 类型
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String desc;
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
package com.pig4cloud.pigx.mp.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.mp.constant.ReplyTypeEnum;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAutoReply;
|
||||
import com.pig4cloud.pigx.mp.service.WxAutoReplyService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 消息自动回复
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-04-18 15:40:39
|
||||
*/
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/wxautoreply")
|
||||
public class WxAutoReplyController {
|
||||
|
||||
private final WxAutoReplyService wxAutoReplyService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param wxAutoReply 消息自动回复
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R getWxAutoReplyPage(Page page, WxAutoReply wxAutoReply) {
|
||||
return R.ok(wxAutoReplyService.page(page, Wrappers.query(wxAutoReply)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过id查询消息自动回复
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R getById(@PathVariable("id") String id) {
|
||||
return R.ok(wxAutoReplyService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增消息自动回复
|
||||
*
|
||||
* @param wxAutoReply 消息自动回复
|
||||
* @return R
|
||||
*/
|
||||
@PostMapping
|
||||
public R save(@RequestBody WxAutoReply wxAutoReply) {
|
||||
this.jude(wxAutoReply);
|
||||
return R.ok(wxAutoReplyService.save(wxAutoReply));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改消息自动回复
|
||||
*
|
||||
* @param wxAutoReply 消息自动回复
|
||||
* @return R
|
||||
*/
|
||||
@PutMapping
|
||||
public R updateById(@RequestBody WxAutoReply wxAutoReply) {
|
||||
this.jude(wxAutoReply);
|
||||
return R.ok(wxAutoReplyService.updateById(wxAutoReply));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除消息自动回复
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
public R removeById(@PathVariable String id) {
|
||||
return R.ok(wxAutoReplyService.removeById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* //校验参数
|
||||
*
|
||||
* @param wxAutoReply
|
||||
*/
|
||||
public void jude(WxAutoReply wxAutoReply) {
|
||||
if (ReplyTypeEnum.MSG.getType().equals(wxAutoReply.getType())) {
|
||||
Wrapper<WxAutoReply> queryWrapper = Wrappers.<WxAutoReply>lambdaQuery()
|
||||
.eq(WxAutoReply::getReqType, wxAutoReply.getReqType());
|
||||
List<WxAutoReply> list = wxAutoReplyService.list(queryWrapper);
|
||||
if (wxAutoReply.getId() != null) {
|
||||
if (list != null && list.size() == 1) {
|
||||
if (!list.get(0).getId().equals(wxAutoReply.getId())) {
|
||||
throw new RuntimeException("请求消息类型重复");
|
||||
}
|
||||
}
|
||||
if (list != null && list.size() > 1) {
|
||||
throw new RuntimeException("请求消息类型重复");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ReplyTypeEnum.KEYWORD.getType().equals(wxAutoReply.getType())) {
|
||||
Wrapper<WxAutoReply> queryWrapper = Wrappers.<WxAutoReply>lambdaQuery()
|
||||
.eq(WxAutoReply::getReqKey, wxAutoReply.getReqKey())
|
||||
.eq(WxAutoReply::getRepType, wxAutoReply.getRepMate());
|
||||
List<WxAutoReply> list = wxAutoReplyService.list(queryWrapper);
|
||||
if (list != null && list.size() == 1) {
|
||||
if (!list.get(0).getId().equals(wxAutoReply.getId())) {
|
||||
throw new RuntimeException("关键词重复");
|
||||
}
|
||||
}
|
||||
if (list != null && list.size() > 1) {
|
||||
throw new RuntimeException("关键词重复");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+125
-33
@@ -16,17 +16,32 @@
|
||||
*/
|
||||
package com.pig4cloud.pigx.mp.controller;
|
||||
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsg;
|
||||
import com.pig4cloud.pigx.mp.service.WxFansMsgService;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpConfiguration;
|
||||
import com.pig4cloud.pigx.mp.constant.MsgTypeEnum;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccountFans;
|
||||
import com.pig4cloud.pigx.mp.entity.WxMsg;
|
||||
import com.pig4cloud.pigx.mp.service.WxAccountFansService;
|
||||
import com.pig4cloud.pigx.mp.service.WxMsgService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.WxMpKefuService;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 微信粉丝消息管理
|
||||
@@ -34,77 +49,154 @@ import org.springframework.web.bind.annotation.*;
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:27
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/wxfansmsg")
|
||||
public class WxFansMsgController {
|
||||
|
||||
private final WxFansMsgService wxFansMsgService;
|
||||
private final WxAccountFansService wxAccountFansService;
|
||||
private final WxMsgService wxMsgService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param wxFansMsg 消息
|
||||
* @return
|
||||
* @param page 分页对象
|
||||
* @param msg 查询条件
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R getWxFansMsgPage(Page page, WxFansMsg wxFansMsg) {
|
||||
wxFansMsg.setTenantId(TenantContextHolder.getTenantId());
|
||||
return R.ok(wxFansMsgService.page(page, Wrappers.query(wxFansMsg)));
|
||||
public R getWxMsgPage(Page page, WxMsg msg) {
|
||||
return R.ok(wxMsgService.page(page, Wrappers.query(msg)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过id查询消息
|
||||
* 通过id查询微信消息
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R getById(@PathVariable("id") Integer id) {
|
||||
return R.ok(wxFansMsgService.getById(id));
|
||||
return R.ok(wxMsgService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增消息
|
||||
* 新增微信消息
|
||||
*
|
||||
* @param wxFansMsg 消息
|
||||
* @param wxMsg 微信消息
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("新增消息")
|
||||
@PostMapping
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsg_add')")
|
||||
public R save(@RequestBody WxFansMsg wxFansMsg) {
|
||||
wxFansMsg.setTenantId(TenantContextHolder.getTenantId());
|
||||
return R.ok(wxFansMsgService.save(wxFansMsg));
|
||||
public R save(@RequestBody WxMsg wxMsg) {
|
||||
try {
|
||||
WxAccountFans wxUser = wxAccountFansService.getById(wxMsg.getWxUserId());
|
||||
//入库
|
||||
wxMsg.setNickName(wxUser.getNickname());
|
||||
wxMsg.setHeadimgUrl(wxUser.getHeadimgUrl());
|
||||
wxMsg.setCreateTime(LocalDateTime.now());
|
||||
wxMsg.setType(MsgTypeEnum.MP2USER.getType());
|
||||
WxMpKefuMessage wxMpKefuMessage = null;
|
||||
if (WxConsts.KefuMsgType.TEXT.equals(wxMsg.getRepType())) {
|
||||
wxMsg.setRepContent(wxMsg.getRepContent());
|
||||
wxMpKefuMessage = WxMpKefuMessage.TEXT().build();
|
||||
wxMpKefuMessage.setContent(wxMsg.getRepContent());
|
||||
}
|
||||
if (WxConsts.KefuMsgType.IMAGE.equals(wxMsg.getRepType())) {//图片
|
||||
wxMsg.setRepName(wxMsg.getRepName());
|
||||
wxMsg.setRepUrl(wxMsg.getRepUrl());
|
||||
wxMsg.setRepMediaId(wxMsg.getRepMediaId());
|
||||
wxMpKefuMessage = WxMpKefuMessage.IMAGE().build();
|
||||
wxMpKefuMessage.setMediaId(wxMsg.getRepMediaId());
|
||||
}
|
||||
if (WxConsts.KefuMsgType.VOICE.equals(wxMsg.getRepType())) {
|
||||
wxMsg.setRepName(wxMsg.getRepName());
|
||||
wxMsg.setRepUrl(wxMsg.getRepUrl());
|
||||
wxMsg.setRepMediaId(wxMsg.getRepMediaId());
|
||||
wxMpKefuMessage = WxMpKefuMessage.VOICE().build();
|
||||
wxMpKefuMessage.setMediaId(wxMsg.getRepMediaId());
|
||||
}
|
||||
if (WxConsts.KefuMsgType.VIDEO.equals(wxMsg.getRepType())) {
|
||||
wxMsg.setRepName(wxMsg.getRepName());
|
||||
wxMsg.setRepDesc(wxMsg.getRepDesc());
|
||||
wxMsg.setRepUrl(wxMsg.getRepUrl());
|
||||
wxMsg.setRepMediaId(wxMsg.getRepMediaId());
|
||||
wxMpKefuMessage = WxMpKefuMessage.VIDEO().build();
|
||||
wxMpKefuMessage.setMediaId(wxMsg.getRepMediaId());
|
||||
wxMpKefuMessage.setTitle(wxMsg.getRepName());
|
||||
wxMpKefuMessage.setDescription(wxMsg.getRepDesc());
|
||||
}
|
||||
if (WxConsts.KefuMsgType.MUSIC.equals(wxMsg.getRepType())) {
|
||||
wxMsg.setRepName(wxMsg.getRepName());
|
||||
wxMsg.setRepDesc(wxMsg.getRepDesc());
|
||||
wxMsg.setRepUrl(wxMsg.getRepUrl());
|
||||
wxMsg.setRepHqUrl(wxMsg.getRepHqUrl());
|
||||
wxMpKefuMessage = WxMpKefuMessage.MUSIC().build();
|
||||
wxMpKefuMessage.setTitle(wxMsg.getRepName());
|
||||
wxMpKefuMessage.setDescription(wxMsg.getRepDesc());
|
||||
wxMpKefuMessage.setMusicUrl(wxMsg.getRepUrl());
|
||||
wxMpKefuMessage.setHqMusicUrl(wxMsg.getRepHqUrl());
|
||||
wxMpKefuMessage.setThumbMediaId(wxMsg.getRepThumbMediaId());
|
||||
}
|
||||
if (WxConsts.KefuMsgType.NEWS.equals(wxMsg.getRepType())) {
|
||||
List<WxMpKefuMessage.WxArticle> list = new ArrayList<>();
|
||||
JSONArray jSONArray = JSONUtil.parseObj(wxMsg.getContent()).getJSONArray("articles");
|
||||
WxMpKefuMessage.WxArticle t;
|
||||
for (Object object : jSONArray) {
|
||||
JSONObject jSONObject = JSONUtil.parseObj(JSONUtil.toJsonStr(object));
|
||||
t = new WxMpKefuMessage.WxArticle();
|
||||
t.setTitle(jSONObject.getStr("title"));
|
||||
t.setDescription(jSONObject.getStr("digest"));
|
||||
t.setPicUrl(jSONObject.getStr("thumbUrl"));
|
||||
t.setUrl(jSONObject.getStr("url"));
|
||||
list.add(t);
|
||||
}
|
||||
wxMsg.setRepName(wxMsg.getRepName());
|
||||
wxMsg.setRepDesc(wxMsg.getRepDesc());
|
||||
wxMsg.setRepUrl(wxMsg.getRepUrl());
|
||||
wxMsg.setRepMediaId(wxMsg.getRepMediaId());
|
||||
wxMsg.setContent(wxMsg.getContent());
|
||||
wxMpKefuMessage = WxMpKefuMessage.NEWS().build();
|
||||
wxMpKefuMessage.setArticles(list);
|
||||
}
|
||||
if (wxMpKefuMessage != null) {
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(wxMsg.getAppId());
|
||||
WxMpKefuService wxMpKefuService = wxMpService.getKefuService();
|
||||
wxMpKefuMessage.setToUser(wxUser.getOpenid());
|
||||
wxMpKefuService.sendKefuMessage(wxMpKefuMessage);
|
||||
wxMsgService.save(wxMsg);
|
||||
return R.ok(wxMsg);
|
||||
} else {
|
||||
return R.failed("非法消息类型");
|
||||
}
|
||||
} catch (WxErrorException e) {
|
||||
e.printStackTrace();
|
||||
log.error("新增微信消息失败" + e.getMessage());
|
||||
return R.failed(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改消息
|
||||
* 修改微信消息
|
||||
*
|
||||
* @param wxFansMsg 消息
|
||||
* @param wxMsg 微信消息
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("修改消息")
|
||||
@PutMapping
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsg_edit')")
|
||||
public R updateById(@RequestBody WxFansMsg wxFansMsg) {
|
||||
wxFansMsg.setTenantId(TenantContextHolder.getTenantId());
|
||||
return R.ok(wxFansMsgService.updateById(wxFansMsg));
|
||||
@PreAuthorize("@ss.hasPermi('wxmp:wxmsg:edit')")
|
||||
public R updateById(@RequestBody WxMsg wxMsg) {
|
||||
return R.ok(wxMsgService.updateById(wxMsg));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除消息
|
||||
* 通过id删除微信消息
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("删除消息")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsg_del')")
|
||||
public R removeById(@PathVariable Integer id) {
|
||||
return R.ok(wxFansMsgService.removeById(id));
|
||||
@PreAuthorize("@ss.hasPermi('wxmp:wxmsg:del')")
|
||||
public R removeById(@PathVariable String id) {
|
||||
return R.ok(wxMsgService.removeById(id));
|
||||
}
|
||||
|
||||
}
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.mp.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsgRes;
|
||||
import com.pig4cloud.pigx.mp.service.WxFansMsgResService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* 微信粉丝消息回复管理
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:48
|
||||
*/
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/wxfansmsgres")
|
||||
public class WxFansMsgResController {
|
||||
|
||||
private final WxFansMsgResService wxFansMsgResService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param wxFansMsgRes 回复
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R getWxFansMsgResPage(Page page, WxFansMsgRes wxFansMsgRes) {
|
||||
return R.ok(wxFansMsgResService.page(page, Wrappers.query(wxFansMsgRes)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过id查询回复
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R getById(@PathVariable("id") Integer id) {
|
||||
return R.ok(wxFansMsgResService.getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增回复
|
||||
*
|
||||
* @param wxFansMsgRes 回复
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("新增回复")
|
||||
@PostMapping
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_add')")
|
||||
public R save(@RequestBody WxFansMsgRes wxFansMsgRes) {
|
||||
return wxFansMsgResService.saveAndSend(wxFansMsgRes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改回复
|
||||
*
|
||||
* @param wxFansMsgRes 回复
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("修改回复")
|
||||
@PutMapping
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_edit')")
|
||||
public R updateById(@RequestBody WxFansMsgRes wxFansMsgRes) {
|
||||
return R.ok(wxFansMsgResService.updateById(wxFansMsgRes));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除回复
|
||||
*
|
||||
* @param id id
|
||||
* @return R
|
||||
*/
|
||||
@SysLog("删除回复")
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("@pms.hasPermission('mp_wxfansmsgres_del')")
|
||||
public R removeById(@PathVariable Integer id) {
|
||||
return R.ok(wxFansMsgResService.removeById(id));
|
||||
}
|
||||
|
||||
}
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
package com.pig4cloud.pigx.mp.controller;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpConfiguration;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.WxMpMaterialService;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.material.*;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 微信素材
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-03-23 21:26:35
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/wxmaterial")
|
||||
public class WxMaterialController {
|
||||
|
||||
/**
|
||||
* 上传非图文微信素材
|
||||
*
|
||||
* @param mulFile
|
||||
* @param mediaType
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/materialFileUpload")
|
||||
public R materialFileUpload(@RequestParam("file") MultipartFile mulFile,
|
||||
@RequestParam String appId,
|
||||
@RequestParam("title") String title,
|
||||
@RequestParam("introduction") String introduction,
|
||||
@RequestParam("mediaType") String mediaType) {
|
||||
try {
|
||||
WxMpMaterial material = new WxMpMaterial();
|
||||
material.setName(mulFile.getOriginalFilename());
|
||||
if (WxConsts.MediaFileType.VIDEO.equals(mediaType)) {
|
||||
material.setVideoTitle(title);
|
||||
material.setVideoIntroduction(introduction);
|
||||
}
|
||||
|
||||
File file = FileUtil.newFile(FileUtil.getTmpDirPath() + mulFile.getOriginalFilename());
|
||||
mulFile.transferTo(file);
|
||||
material.setFile(file);
|
||||
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
WxMpMaterialUploadResult wxMpMaterialUploadResult = wxMpMaterialService.materialFileUpload(mediaType, material);
|
||||
WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem wxMpMaterialFileBatchGetResult = new WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem();
|
||||
wxMpMaterialFileBatchGetResult.setName(file.getName());
|
||||
wxMpMaterialFileBatchGetResult.setMediaId(wxMpMaterialUploadResult.getMediaId());
|
||||
wxMpMaterialFileBatchGetResult.setUrl(wxMpMaterialUploadResult.getUrl());
|
||||
FileUtil.del(file);
|
||||
return R.ok(wxMpMaterialFileBatchGetResult);
|
||||
} catch (WxErrorException e) {
|
||||
log.warn("上传非图文微信素材失败: {}", e.getLocalizedMessage());
|
||||
return R.failed(e.getLocalizedMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("上传失败", e);
|
||||
return R.failed(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增图文消息
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/materialNews")
|
||||
public R materialNewsUpload(@RequestBody JSONObject data) {
|
||||
try {
|
||||
JSONArray jSONArray = data.getJSONArray("articles");
|
||||
List<WxMpMaterialNews.WxMpMaterialNewsArticle> articles = jSONArray.toList(WxMpMaterialNews.WxMpMaterialNewsArticle.class);
|
||||
WxMpMaterialNews news = new WxMpMaterialNews();
|
||||
news.setArticles(articles);
|
||||
|
||||
String appId = data.getStr("appId");
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
WxMpMaterialUploadResult wxMpMaterialUploadResult = wxMpMaterialService.materialNewsUpload(news);
|
||||
return R.ok(wxMpMaterialUploadResult);
|
||||
} catch (WxErrorException e) {
|
||||
log.warn("新增图文失败: {}", e.getMessage());
|
||||
return R.failed(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("新增图文失败", e);
|
||||
return R.failed(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改图文消息
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/materialNews")
|
||||
public R materialNewsUpdate(@RequestBody JSONObject data) {
|
||||
try {
|
||||
String mediaId = data.getStr("mediaId");
|
||||
JSONArray jSONArray = data.getJSONArray("articles");
|
||||
List<WxMpMaterialNews.WxMpMaterialNewsArticle> articles = jSONArray.toList(WxMpMaterialNews.WxMpMaterialNewsArticle.class);
|
||||
String appId = data.getStr("appId");
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate = new WxMpMaterialArticleUpdate();
|
||||
wxMpMaterialArticleUpdate.setMediaId(mediaId);
|
||||
int index = 0;
|
||||
for (WxMpMaterialNews.WxMpMaterialNewsArticle article : articles) {
|
||||
wxMpMaterialArticleUpdate.setIndex(index);
|
||||
wxMpMaterialArticleUpdate.setArticles(article);
|
||||
wxMpMaterialService.materialNewsUpdate(wxMpMaterialArticleUpdate);
|
||||
index++;
|
||||
}
|
||||
return R.ok();
|
||||
} catch (WxErrorException e) {
|
||||
log.warn("修改图文失败:{}", e.getLocalizedMessage());
|
||||
return R.failed(e.getLocalizedMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("修改图文失败", e);
|
||||
return R.failed(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图文消息内的图片获取URL
|
||||
*
|
||||
* @param mulFile
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/newsImgUpload")
|
||||
public String newsImgUpload(@RequestParam("file") MultipartFile mulFile, @RequestParam String appId) throws Exception {
|
||||
File file = FileUtil.createTempFile(FileUtil.getTmpDir());
|
||||
mulFile.transferTo(file);
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
WxMediaImgUploadResult wxMediaImgUploadResult = wxMpMaterialService.mediaImgUpload(file);
|
||||
Map<Object, Object> responseData = new HashMap<>();
|
||||
responseData.put("link", wxMediaImgUploadResult.getUrl());
|
||||
FileUtil.del(file);
|
||||
return JSONUtil.toJsonStr(responseData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除微信素材
|
||||
*
|
||||
* @param
|
||||
* @return R
|
||||
*/
|
||||
@DeleteMapping
|
||||
public R materialDel(String appId, String id) {
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
try {
|
||||
return R.ok(wxMpMaterialService.materialDelete(id));
|
||||
} catch (WxErrorException e) {
|
||||
log.error("删除微信素材失败", e);
|
||||
return R.failed(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R getWxMaterialPage(Page page, String type, String appId) {
|
||||
try {
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
int count = (int) page.getSize();
|
||||
int offset = (int) page.getCurrent() * count - count;
|
||||
if (WxConsts.MaterialType.NEWS.equals(type)) {
|
||||
return R.ok(wxMpMaterialService.materialNewsBatchGet(offset, count));
|
||||
} else {
|
||||
return R.ok(wxMpMaterialService.materialFileBatchGet(type, offset, count));
|
||||
}
|
||||
} catch (WxErrorException e) {
|
||||
log.error("查询素材失败", e);
|
||||
return R.failed(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取微信视频素材
|
||||
*
|
||||
* @param
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/materialVideo")
|
||||
public R getMaterialVideo(String mediaId, String appId) {
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
try {
|
||||
return R.ok(wxMpMaterialService.materialVideoInfo(mediaId));
|
||||
} catch (WxErrorException e) {
|
||||
log.error("获取微信视频素材失败", e);
|
||||
return R.failed(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信素材直接文件
|
||||
*
|
||||
* @param
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/materialOther")
|
||||
public ResponseEntity<byte[]> getMaterialOther(String appId, String mediaId, String fileName) throws Exception {
|
||||
try {
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
//获取文件
|
||||
InputStream is = wxMpMaterialService.materialImageOrVoiceDownload(mediaId);
|
||||
byte[] body = new byte[is.available()];
|
||||
is.read(body);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
//设置文件类型
|
||||
headers.add("Content-Disposition", "attchement;filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
||||
headers.add("Content-Type", "application/octet-stream");
|
||||
HttpStatus statusCode = HttpStatus.OK;
|
||||
//返回数据
|
||||
ResponseEntity<byte[]> entity = new ResponseEntity<>(body, headers, statusCode);
|
||||
return entity;
|
||||
} catch (WxErrorException e) {
|
||||
e.printStackTrace();
|
||||
log.error("获取微信素材直接文件失败", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信临时素材直接文件
|
||||
*
|
||||
* @param
|
||||
* @return R
|
||||
*/
|
||||
@GetMapping("/tempMaterialOther")
|
||||
public ResponseEntity<byte[]> getTempMaterialOther(String appId, String mediaId, String fileName) throws Exception {
|
||||
try {
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(appId);
|
||||
WxMpMaterialService wxMpMaterialService = wxMpService.getMaterialService();
|
||||
//获取文件
|
||||
InputStream is = new FileInputStream(wxMpMaterialService.mediaDownload(mediaId));
|
||||
byte[] body = new byte[is.available()];
|
||||
is.read(body);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
//设置文件类型
|
||||
headers.add("Content-Disposition", "attchement;filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
||||
headers.add("Content-Type", "application/octet-stream");
|
||||
HttpStatus statusCode = HttpStatus.OK;
|
||||
//返回数据
|
||||
ResponseEntity<byte[]> entity = new ResponseEntity<>(body, headers, statusCode);
|
||||
return entity;
|
||||
} catch (WxErrorException e) {
|
||||
e.printStackTrace();
|
||||
log.error("获取微信素材直接文件失败", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
-17
@@ -17,11 +17,8 @@
|
||||
package com.pig4cloud.pigx.mp.controller;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
import com.pig4cloud.pigx.mp.entity.WxMpMenu;
|
||||
import com.pig4cloud.pigx.mp.service.WxMenuService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
@@ -41,18 +38,6 @@ public class WxMenuController {
|
||||
|
||||
private final WxMenuService wxMenuService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param wxMpMenu
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public R getWxMpMenuPage(Page page, WxMpMenu wxMpMenu) {
|
||||
return R.ok(wxMenuService.page(page, Wrappers.query(wxMpMenu)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过appid查询微信菜单
|
||||
@@ -95,6 +80,4 @@ public class WxMenuController {
|
||||
public R delete(@PathVariable("appId") String appId) {
|
||||
return wxMenuService.delete(appId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+10
@@ -1,10 +1,15 @@
|
||||
package com.pig4cloud.pigx.mp.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
|
||||
import com.pig4cloud.pigx.common.security.annotation.Inner;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpConfiguration;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpContextHolder;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccount;
|
||||
import com.pig4cloud.pigx.mp.service.WxAccountService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
@@ -21,8 +26,10 @@ import org.springframework.web.bind.annotation.*;
|
||||
@Slf4j
|
||||
@Inner(value = false)
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/{appId}/portal")
|
||||
public class WxPortalController {
|
||||
private final WxAccountService accountService;
|
||||
|
||||
/**
|
||||
* 微信接入校验处理
|
||||
@@ -82,6 +89,9 @@ public class WxPortalController {
|
||||
@RequestParam(name = "encrypt_type", required = false) String encType,
|
||||
@RequestParam(name = "msg_signature", required = false) String msgSignature) {
|
||||
|
||||
WxAccount wxAccount = accountService.getOne(Wrappers.<WxAccount>lambdaQuery()
|
||||
.eq(WxAccount::getAppid, appId));
|
||||
TenantContextHolder.setTenantId(wxAccount.getTenantId());
|
||||
WxMpContextHolder.setAppId(appId);
|
||||
final WxMpService wxService = WxMpConfiguration.getMpServices().get(appId);
|
||||
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
package com.pig4cloud.pigx.mp.controller;
|
||||
|
||||
import com.pig4cloud.pigx.mp.config.WxMpConfiguration;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* @author Edward
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/wx/redirect/{appid}")
|
||||
public class WxRedirectController {
|
||||
|
||||
|
||||
@RequestMapping("/greet")
|
||||
public String greetUser(@PathVariable String appid, @RequestParam String code, ModelMap map) {
|
||||
|
||||
WxMpService mpService = WxMpConfiguration.getMpServices().get(appid);
|
||||
|
||||
try {
|
||||
WxMpOAuth2AccessToken accessToken = mpService.oauth2getAccessToken(code);
|
||||
WxMpUser user = mpService.oauth2getUserInfo(accessToken, null);
|
||||
map.put("user", user);
|
||||
} catch (WxErrorException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return "greet_user";
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package com.pig4cloud.pigx.mp.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 消息自动回复
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-04-18 15:40:39
|
||||
*/
|
||||
@Data
|
||||
@TableName("wx_auto_reply")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class WxAutoReply extends Model<WxAutoReply> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 公众号ID
|
||||
*/
|
||||
private String appId;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createId;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
private String updateId;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 逻辑删除标记(0:显示;1:隐藏)
|
||||
*/
|
||||
private String delFlag;
|
||||
/**
|
||||
* 类型(1、关注时回复;2、消息回复;3、关键词回复)
|
||||
*/
|
||||
@NotNull(message = "类型不能为空")
|
||||
private String type;
|
||||
/**
|
||||
* 关键词
|
||||
*/
|
||||
private String reqKey;
|
||||
/**
|
||||
* 请求消息类型(text:文本;image:图片;voice:语音;video:视频;shortvideo:小视频;location:地理位置)
|
||||
*/
|
||||
private String reqType;
|
||||
/**
|
||||
* 回复消息类型(text:文本;image:图片;voice:语音;video:视频;music:音乐;news:图文)
|
||||
*/
|
||||
@NotNull(message = "回复消息类型不能为空")
|
||||
private String repType;
|
||||
/**
|
||||
* 回复类型文本匹配类型(1、全匹配,2、半匹配)
|
||||
*/
|
||||
private String repMate;
|
||||
/**
|
||||
* 回复类型文本保存文字
|
||||
*/
|
||||
private String repContent;
|
||||
/**
|
||||
* 回复的素材名、视频和音乐的标题
|
||||
*/
|
||||
private String repName;
|
||||
/**
|
||||
* 回复类型imge、voice、news、video的mediaID或音乐缩略图的媒体id
|
||||
*/
|
||||
private String repMediaId;
|
||||
/**
|
||||
* 视频和音乐的描述
|
||||
*/
|
||||
private String repDesc;
|
||||
/**
|
||||
* 链接
|
||||
*/
|
||||
private String repUrl;
|
||||
/**
|
||||
* 高质量链接
|
||||
*/
|
||||
private String repHqUrl;
|
||||
/**
|
||||
* 缩略图的媒体id
|
||||
*/
|
||||
private String repThumbMediaId;
|
||||
/**
|
||||
* 缩略图url
|
||||
*/
|
||||
private String repThumbUrl;
|
||||
|
||||
/**
|
||||
* 图文消息的内容
|
||||
*/
|
||||
private String content;
|
||||
}
|
||||
-123
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.mp.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 微信消息
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:27
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class WxFansMsg extends Model<WxFansMsg> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Integer id;
|
||||
/**
|
||||
* 用户标识
|
||||
*/
|
||||
private String openid;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 头像地址
|
||||
*/
|
||||
private String headimgUrl;
|
||||
/**
|
||||
* 微信账号ID
|
||||
*/
|
||||
private Integer wxAccountId;
|
||||
|
||||
/**
|
||||
* 微信公众号appid
|
||||
*/
|
||||
private String wxAccountAppid;
|
||||
|
||||
/**
|
||||
* 微信公众号名
|
||||
*/
|
||||
private String wxAccountName;
|
||||
|
||||
/**
|
||||
* 消息ID
|
||||
*/
|
||||
private Long msgId;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
private String msgType;
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 最近一条回复内容
|
||||
*/
|
||||
private String resContent;
|
||||
/**
|
||||
* 是否已回复
|
||||
*/
|
||||
private String isRes;
|
||||
/**
|
||||
* 微信素材ID
|
||||
*/
|
||||
private String mediaId;
|
||||
/**
|
||||
* 微信图片URL
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 本地图片路径
|
||||
*/
|
||||
private String picPath;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 是否删除 -1:已删除 0:正常
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 租户
|
||||
*/
|
||||
private Integer tenantId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.pig4cloud.pigx.mp.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 微信消息
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-05-28 16:12:10
|
||||
*/
|
||||
@Data
|
||||
@TableName("wx_msg")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(description = "微信消息")
|
||||
public class WxMsg extends Model<WxMsg> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId
|
||||
private Integer id;
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
private String createId;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
private String updateId;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private LocalDateTime updateTime;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 逻辑删除标记(0:显示;1:隐藏)
|
||||
*/
|
||||
private String delFlag;
|
||||
|
||||
/***
|
||||
* 公众号ID
|
||||
*/
|
||||
private String appId;
|
||||
/**
|
||||
* 公众号名称
|
||||
*/
|
||||
private String appName;
|
||||
/**
|
||||
* 公众号logo
|
||||
*/
|
||||
private String appLogo;
|
||||
/**
|
||||
* 微信用户ID
|
||||
*/
|
||||
private Integer wxUserId;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickName;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String headimgUrl;
|
||||
|
||||
/**
|
||||
* 微信openId
|
||||
*/
|
||||
private String openId;
|
||||
/**
|
||||
* 消息分类(1、用户发给公众号;2、公众号发给用户;)
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 消息类型(text:文本;image:图片;voice:语音;video:视频;shortvideo:小视频;location:地理位置;music:音乐;news:图文;event:推送事件)
|
||||
*/
|
||||
private String repType;
|
||||
/**
|
||||
* 事件类型(subscribe:关注;unsubscribe:取关;CLICK、VIEW:菜单事件)
|
||||
*/
|
||||
private String repEvent;
|
||||
/**
|
||||
* 回复类型文本保存文字
|
||||
*/
|
||||
private String repContent;
|
||||
/**
|
||||
* 回复类型imge、voice、news、video的mediaID或音乐缩略图的媒体id
|
||||
*/
|
||||
private String repMediaId;
|
||||
/**
|
||||
* 回复的素材名、视频和音乐的标题
|
||||
*/
|
||||
private String repName;
|
||||
/**
|
||||
* 视频和音乐的描述
|
||||
*/
|
||||
private String repDesc;
|
||||
/**
|
||||
* 链接
|
||||
*/
|
||||
private String repUrl;
|
||||
/**
|
||||
* 高质量链接
|
||||
*/
|
||||
private String repHqUrl;
|
||||
/**
|
||||
* 图文消息的内容
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 缩略图的媒体id
|
||||
*/
|
||||
private String repThumbMediaId;
|
||||
/**
|
||||
* 缩略图url
|
||||
*/
|
||||
private String repThumbUrl;
|
||||
/**
|
||||
* 地理位置维度
|
||||
*/
|
||||
private Double repLocationX;
|
||||
/**
|
||||
* 地理位置经度
|
||||
*/
|
||||
private Double repLocationY;
|
||||
/**
|
||||
* 地图缩放大小
|
||||
*/
|
||||
private Double repScale;
|
||||
/**
|
||||
* 已读标记(0:是;1:否)
|
||||
*/
|
||||
private String readFlag;
|
||||
|
||||
}
|
||||
+57
-28
@@ -1,10 +1,13 @@
|
||||
package com.pig4cloud.pigx.mp.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.mp.constant.MsgTypeEnum;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccount;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsg;
|
||||
import com.pig4cloud.pigx.mp.service.WxAccountService;
|
||||
import com.pig4cloud.pigx.mp.service.WxFansMsgService;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccountFans;
|
||||
import com.pig4cloud.pigx.mp.entity.WxMsg;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxAccountFansMapper;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxAccountMapper;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxMsgMapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -13,9 +16,9 @@ import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -27,8 +30,9 @@ import java.util.Map;
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class LogHandler extends AbstractHandler {
|
||||
private final WxFansMsgService wxFansMsgService;
|
||||
private final WxAccountService wxAccountService;
|
||||
private final WxAccountFansMapper fansMapper;
|
||||
private final WxAccountMapper accountMapper;
|
||||
private final WxMsgMapper msgMapper;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
@@ -37,32 +41,57 @@ public class LogHandler extends AbstractHandler {
|
||||
WxSessionManager sessionManager) {
|
||||
log.debug("接收到请求消息,内容:{}", wxMessage.getContent());
|
||||
|
||||
if (!WxConsts.XmlMsgType.TEXT.equals(wxMessage.getMsgType())) {
|
||||
log.debug("消息类型其他类型不保存", wxMessage.getContent());
|
||||
return null;
|
||||
}
|
||||
|
||||
WxAccount wxAccount = wxAccountService.getOne(Wrappers.<WxAccount>lambdaQuery()
|
||||
WxAccount wxAccount = accountMapper.selectOne(Wrappers.<WxAccount>lambdaQuery()
|
||||
.eq(WxAccount::getAccount, wxMessage.getToUser()));
|
||||
|
||||
WxAccountFans fans = fansMapper.selectOne(Wrappers.<WxAccountFans>lambdaQuery()
|
||||
.eq(WxAccountFans::getOpenid, wxMessage.getFromUser()));
|
||||
|
||||
WxMpUser wxmpUser = wxMpService.getUserService()
|
||||
.userInfo(wxMessage.getFromUser());
|
||||
|
||||
WxFansMsg wxFansMsg = new WxFansMsg();
|
||||
wxFansMsg.setOpenid(wxmpUser.getOpenId());
|
||||
wxFansMsg.setNickname(wxmpUser.getNickname());
|
||||
wxFansMsg.setHeadimgUrl(wxmpUser.getHeadImgUrl());
|
||||
wxFansMsg.setWxAccountId(wxAccount.getId());
|
||||
wxFansMsg.setWxAccountName(wxAccount.getName());
|
||||
wxFansMsg.setWxAccountAppid(wxAccount.getAppid());
|
||||
wxFansMsg.setMsgType(wxMessage.getMsgType());
|
||||
wxFansMsg.setMsgId(wxMessage.getMsgId());
|
||||
wxFansMsg.setContent(wxMessage.getContent());
|
||||
wxFansMsg.setTenantId(wxAccount.getTenantId());
|
||||
wxFansMsgService.save(wxFansMsg);
|
||||
|
||||
log.debug("保存微信用户信息成功 {}", wxFansMsg);
|
||||
WxMsg wxMsg = new WxMsg();
|
||||
wxMsg.setWxUserId(fans.getId());
|
||||
wxMsg.setNickName(fans.getNickname());
|
||||
wxMsg.setHeadimgUrl(fans.getHeadimgUrl());
|
||||
wxMsg.setType(MsgTypeEnum.USER2MP.getType());
|
||||
wxMsg.setRepEvent(wxMessage.getEvent());
|
||||
wxMsg.setRepType(wxMessage.getMsgType());
|
||||
wxMsg.setRepMediaId(wxMessage.getMediaId());
|
||||
wxMsg.setOpenId(fans.getOpenid());
|
||||
wxMsg.setAppId(wxAccount.getAppid());
|
||||
wxMsg.setAppLogo(wxAccount.getQrUrl());
|
||||
wxMsg.setAppName(wxAccount.getName());
|
||||
if (WxConsts.XmlMsgType.TEXT.equals(wxMessage.getMsgType())) {
|
||||
wxMsg.setRepContent(wxMessage.getContent());
|
||||
}
|
||||
if (WxConsts.XmlMsgType.VOICE.equals(wxMessage.getMsgType())) {
|
||||
wxMsg.setRepName(wxMessage.getMediaId() + "." + wxMessage.getFormat());
|
||||
wxMsg.setRepContent(wxMessage.getRecognition());
|
||||
}
|
||||
if (WxConsts.XmlMsgType.IMAGE.equals(wxMessage.getMsgType())) {
|
||||
wxMsg.setRepUrl(wxMessage.getPicUrl());
|
||||
}
|
||||
if (WxConsts.XmlMsgType.LINK.equals(wxMessage.getMsgType())) {
|
||||
wxMsg.setRepName(wxMessage.getTitle());
|
||||
wxMsg.setRepDesc(wxMessage.getDescription());
|
||||
wxMsg.setRepUrl(wxMessage.getUrl());
|
||||
}
|
||||
if (WxConsts.MediaFileType.FILE.equals(wxMessage.getMsgType())) {
|
||||
wxMsg.setRepName(wxMessage.getTitle());
|
||||
wxMsg.setRepDesc(wxMessage.getDescription());
|
||||
}
|
||||
if (WxConsts.XmlMsgType.VIDEO.equals(wxMessage.getMsgType())) {
|
||||
wxMsg.setRepThumbMediaId(wxMessage.getThumbMediaId());
|
||||
}
|
||||
if (WxConsts.XmlMsgType.LOCATION.equals(wxMessage.getMsgType())) {
|
||||
wxMsg.setRepLocationX(wxMessage.getLocationX());
|
||||
wxMsg.setRepLocationY(wxMessage.getLocationY());
|
||||
wxMsg.setRepScale(wxMessage.getScale());
|
||||
wxMsg.setRepContent(wxMessage.getLabel());
|
||||
}
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
wxMsg.setCreateTime(now);
|
||||
msgMapper.insert(wxMsg);
|
||||
log.debug("保存微信用户信息成功 {}", wxMsg);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+170
-8
@@ -1,30 +1,192 @@
|
||||
package com.pig4cloud.pigx.mp.handler;
|
||||
|
||||
import com.pig4cloud.pigx.mp.builder.TextBuilder;
|
||||
import lombok.SneakyThrows;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpContextHolder;
|
||||
import com.pig4cloud.pigx.mp.constant.MsgTypeEnum;
|
||||
import com.pig4cloud.pigx.mp.constant.ReplyMateEnum;
|
||||
import com.pig4cloud.pigx.mp.constant.ReplyTypeEnum;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccount;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccountFans;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAutoReply;
|
||||
import com.pig4cloud.pigx.mp.entity.WxMsg;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxAccountFansMapper;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxAccountMapper;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxMsgMapper;
|
||||
import com.pig4cloud.pigx.mp.service.WxAutoReplyService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
|
||||
import me.chanjar.weixin.mp.builder.outxml.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
|
||||
|
||||
/**
|
||||
* @author Binary Wang(https://github.com/binarywang)
|
||||
* @author JL
|
||||
*/
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class MsgHandler extends AbstractHandler {
|
||||
private final WxAutoReplyService wxAutoReplyService;
|
||||
private final WxAccountFansMapper wxAccountFansMapper;
|
||||
private final WxAccountMapper wxAccountMapper;
|
||||
private final WxMsgMapper wxMsgMapper;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
Map<String, Object> context, WxMpService weixinService,
|
||||
Map<String, Object> context, WxMpService wxMpService,
|
||||
WxSessionManager sessionManager) {
|
||||
String content = "收到信息内容:" + wxMessage.getContent();
|
||||
|
||||
return new TextBuilder().build(content, wxMessage, weixinService);
|
||||
//组装回复消息
|
||||
if (!wxMessage.getMsgType().equals(XmlMsgType.EVENT)) {
|
||||
WxMpXmlOutMessage rs;
|
||||
WxAccountFans fans = wxAccountFansMapper.selectOne(Wrappers.<WxAccountFans>lambdaQuery()
|
||||
.eq(WxAccountFans::getOpenid, wxMessage.getFromUser()));
|
||||
// 查询公众号 基本信息
|
||||
WxAccount wxAccount = wxAccountMapper.selectOne(Wrappers.<WxAccount>lambdaQuery()
|
||||
.eq(WxAccount::getAccount, wxMessage.getToUser()));
|
||||
//1、先处理是否有文本关键字回复
|
||||
if (WxConsts.KefuMsgType.TEXT.equals(wxMessage.getMsgType())) {
|
||||
//先全匹配
|
||||
List<WxAutoReply> listWxAutoReply = wxAutoReplyService.list(Wrappers
|
||||
.<WxAutoReply>query().lambda()
|
||||
.eq(WxAutoReply::getType, ReplyTypeEnum.KEYWORD.getType())
|
||||
.eq(WxAutoReply::getRepMate, ReplyMateEnum.ALL.getType())
|
||||
.eq(WxAutoReply::getAppId, WxMpContextHolder.getAppId())
|
||||
.eq(WxAutoReply::getReqKey, wxMessage.getContent()));
|
||||
if (listWxAutoReply != null && listWxAutoReply.size() > 0) {
|
||||
rs = getWxMpXmlOutMessage(wxMessage, listWxAutoReply, fans, wxMsgMapper, wxAccount);
|
||||
if (rs != null) {
|
||||
return rs;
|
||||
}
|
||||
}
|
||||
//再半匹配
|
||||
listWxAutoReply = wxAutoReplyService.list(Wrappers
|
||||
.<WxAutoReply>query().lambda()
|
||||
.eq(WxAutoReply::getType, ReplyTypeEnum.KEYWORD.getType())
|
||||
.eq(WxAutoReply::getAppId, WxMpContextHolder.getAppId())
|
||||
.eq(WxAutoReply::getRepMate, ReplyMateEnum.LIKE.getType())
|
||||
.like(WxAutoReply::getReqKey, wxMessage.getContent()));
|
||||
if (listWxAutoReply != null && listWxAutoReply.size() > 0) {
|
||||
rs = getWxMpXmlOutMessage(wxMessage, listWxAutoReply, fans, wxMsgMapper, wxAccount);
|
||||
if (rs != null) {
|
||||
return rs;
|
||||
}
|
||||
}
|
||||
}
|
||||
//2、再处理消息回复
|
||||
List<WxAutoReply> listWxAutoReply = wxAutoReplyService.list(Wrappers
|
||||
.<WxAutoReply>query().lambda()
|
||||
.eq(WxAutoReply::getAppId, WxMpContextHolder.getAppId())
|
||||
.eq(WxAutoReply::getType, ReplyTypeEnum.MSG.getType())
|
||||
.eq(WxAutoReply::getReqType, wxMessage.getMsgType()));
|
||||
rs = getWxMpXmlOutMessage(wxMessage, listWxAutoReply, fans, wxMsgMapper, wxAccount);
|
||||
return rs;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装回复消息,并记录消息
|
||||
*
|
||||
* @param wxMessage
|
||||
* @param listWxAutoReply
|
||||
* @param wxMsgMapper
|
||||
* @param wxAccount
|
||||
* @return
|
||||
*/
|
||||
public static WxMpXmlOutMessage getWxMpXmlOutMessage(WxMpXmlMessage wxMessage
|
||||
, List<WxAutoReply> listWxAutoReply, WxAccountFans fans, WxMsgMapper wxMsgMapper, WxAccount wxAccount) {
|
||||
WxMpXmlOutMessage wxMpXmlOutMessage = null;
|
||||
//记录接收消息
|
||||
|
||||
if (listWxAutoReply != null && listWxAutoReply.size() > 0) {
|
||||
WxAutoReply wxAutoReply = listWxAutoReply.get(0);
|
||||
//记录回复消息
|
||||
WxMsg wxMsg = new WxMsg();
|
||||
wxMsg.setWxUserId(fans.getId());
|
||||
wxMsg.setNickName(fans.getNickname());
|
||||
wxMsg.setHeadimgUrl(fans.getHeadimgUrl());
|
||||
wxMsg.setCreateTime(LocalDateTime.now());
|
||||
wxMsg.setType(MsgTypeEnum.MP2USER.getType());
|
||||
wxMsg.setRepType(wxAutoReply.getRepType());
|
||||
wxMsg.setOpenId(fans.getOpenid());
|
||||
wxMsg.setAppName(wxAccount.getName());
|
||||
wxMsg.setAppLogo(wxAccount.getQrUrl());
|
||||
wxMsg.setAppId(wxAccount.getAppid());
|
||||
//文本
|
||||
if (WxConsts.KefuMsgType.TEXT.equals(wxAutoReply.getRepType())) {
|
||||
wxMsg.setRepContent(wxAutoReply.getRepContent());
|
||||
wxMpXmlOutMessage = new TextBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).content(wxAutoReply.getRepContent()).build();
|
||||
}
|
||||
|
||||
//图片
|
||||
if (WxConsts.KefuMsgType.IMAGE.equals(wxAutoReply.getRepType())) {
|
||||
wxMsg.setRepName(wxAutoReply.getRepName());
|
||||
wxMsg.setRepUrl(wxAutoReply.getRepUrl());
|
||||
wxMsg.setRepMediaId(wxAutoReply.getRepMediaId());
|
||||
wxMpXmlOutMessage = new ImageBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).mediaId(wxAutoReply.getRepMediaId()).build();
|
||||
}
|
||||
if (WxConsts.KefuMsgType.VOICE.equals(wxAutoReply.getRepType())) {
|
||||
wxMsg.setRepName(wxAutoReply.getRepName());
|
||||
wxMsg.setRepUrl(wxAutoReply.getRepUrl());
|
||||
wxMsg.setRepMediaId(wxAutoReply.getRepMediaId());
|
||||
wxMpXmlOutMessage = new VoiceBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).mediaId(wxAutoReply.getRepMediaId()).build();
|
||||
}
|
||||
if (WxConsts.KefuMsgType.VIDEO.equals(wxAutoReply.getRepType())) {
|
||||
wxMsg.setRepName(wxAutoReply.getRepName());
|
||||
wxMsg.setRepDesc(wxAutoReply.getRepDesc());
|
||||
wxMsg.setRepUrl(wxAutoReply.getRepUrl());
|
||||
wxMsg.setRepMediaId(wxAutoReply.getRepMediaId());
|
||||
wxMpXmlOutMessage = new VideoBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).mediaId(wxAutoReply.getRepMediaId())
|
||||
.title(wxAutoReply.getRepName()).description(wxAutoReply.getRepDesc()).build();
|
||||
}
|
||||
if (WxConsts.KefuMsgType.MUSIC.equals(wxAutoReply.getRepType())) {
|
||||
wxMsg.setRepName(wxAutoReply.getRepName());
|
||||
wxMsg.setRepDesc(wxAutoReply.getRepDesc());
|
||||
wxMsg.setRepUrl(wxAutoReply.getRepUrl());
|
||||
wxMsg.setRepHqUrl(wxAutoReply.getRepHqUrl());
|
||||
wxMsg.setRepThumbMediaId(wxAutoReply.getRepThumbMediaId());
|
||||
wxMsg.setRepThumbUrl(wxAutoReply.getRepThumbUrl());
|
||||
wxMpXmlOutMessage = new MusicBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
|
||||
.thumbMediaId(wxAutoReply.getRepThumbMediaId())
|
||||
.title(wxAutoReply.getRepName()).description(wxAutoReply.getRepDesc())
|
||||
.musicUrl(wxAutoReply.getRepUrl()).hqMusicUrl(wxAutoReply.getRepHqUrl()).build();
|
||||
}
|
||||
if (WxConsts.KefuMsgType.NEWS.equals(wxAutoReply.getRepType())) {
|
||||
List<WxMpXmlOutNewsMessage.Item> list = new ArrayList<>();
|
||||
|
||||
JSONObject content = JSONUtil.parseObj(wxAutoReply.getContent());
|
||||
List<JSONObject> listJSONObject = content.getJSONArray("articles").toList(JSONObject.class);
|
||||
WxMpXmlOutNewsMessage.Item t;
|
||||
for (JSONObject jSONObject : listJSONObject) {
|
||||
t = new WxMpXmlOutNewsMessage.Item();
|
||||
t.setTitle(jSONObject.getStr("title"));
|
||||
t.setDescription(jSONObject.getStr("digest"));
|
||||
t.setPicUrl(jSONObject.getStr("thumbUrl"));
|
||||
t.setUrl(jSONObject.getStr("url"));
|
||||
list.add(t);
|
||||
}
|
||||
wxMsg.setRepName(wxAutoReply.getRepName());
|
||||
wxMsg.setRepDesc(wxAutoReply.getRepDesc());
|
||||
wxMsg.setRepUrl(wxAutoReply.getRepUrl());
|
||||
wxMsg.setRepMediaId(wxAutoReply.getRepMediaId());
|
||||
wxMsg.setContent(wxAutoReply.getContent());
|
||||
wxMpXmlOutMessage = new NewsBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).articles(list).build();
|
||||
}
|
||||
wxMsgMapper.insert(wxMsg);
|
||||
}
|
||||
return wxMpXmlOutMessage;
|
||||
}
|
||||
}
|
||||
+63
-27
@@ -1,6 +1,18 @@
|
||||
package com.pig4cloud.pigx.mp.handler;
|
||||
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.mp.builder.TextBuilder;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpContextHolder;
|
||||
import com.pig4cloud.pigx.mp.constant.ReplyTypeEnum;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccount;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccountFans;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAutoReply;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxAccountFansMapper;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxAccountMapper;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxMsgMapper;
|
||||
import com.pig4cloud.pigx.mp.service.WxAutoReplyService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
@@ -10,6 +22,10 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -17,7 +33,12 @@ import java.util.Map;
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class SubscribeHandler extends AbstractHandler {
|
||||
private final WxAutoReplyService wxAutoReplyService;
|
||||
private final WxAccountFansMapper wxAccountFansMapper;
|
||||
private final WxAccountMapper wxAccountMapper;
|
||||
private final WxMsgMapper msgMapper;
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
@@ -26,45 +47,60 @@ public class SubscribeHandler extends AbstractHandler {
|
||||
|
||||
log.info("新关注用户 OPENID: " + wxMessage.getFromUser());
|
||||
|
||||
|
||||
// 获取微信用户基本信息
|
||||
try {
|
||||
WxMpUser userWxInfo = weixinService.getUserService()
|
||||
WxMpUser wxMpUser = weixinService.getUserService()
|
||||
.userInfo(wxMessage.getFromUser(), null);
|
||||
if (userWxInfo != null) {
|
||||
// TODO 可以添加关注用户到本地数据库
|
||||
WxAccountFans wxAccountFans = wxAccountFansMapper.selectOne(Wrappers
|
||||
.<WxAccountFans>lambdaUpdate().eq(WxAccountFans::getOpenid, wxMessage.getFromUser()));
|
||||
|
||||
if (wxAccountFans != null) {
|
||||
wxAccountFansMapper.deleteById(wxAccountFans);
|
||||
}
|
||||
|
||||
wxAccountFans.setOpenid(wxMpUser.getOpenId());
|
||||
wxAccountFans.setSubscribeStatus(String.valueOf(BooleanUtil.toInt(wxMpUser.getSubscribe())));
|
||||
wxAccountFans.setSubscribeTime(LocalDateTime
|
||||
.ofInstant(Instant.ofEpochMilli(wxMpUser.getSubscribeTime() * 1000L)
|
||||
, ZoneId.systemDefault()));
|
||||
wxAccountFans.setNickname(wxMpUser.getNickname());
|
||||
wxAccountFans.setGender(String.valueOf(wxMpUser.getSex()));
|
||||
wxAccountFans.setLanguage(wxMpUser.getLanguage());
|
||||
wxAccountFans.setCountry(wxMpUser.getCountry());
|
||||
wxAccountFans.setProvince(wxMpUser.getProvince());
|
||||
wxAccountFans.setCity(wxMpUser.getCity());
|
||||
wxAccountFans.setHeadimgUrl(wxMpUser.getHeadImgUrl());
|
||||
wxAccountFans.setRemark(wxMpUser.getRemark());
|
||||
|
||||
WxAccount wxAccount = wxAccountMapper.selectOne(Wrappers.<WxAccount>lambdaQuery()
|
||||
.eq(WxAccount::getAppid, WxMpContextHolder.getAppId()));
|
||||
wxAccountFans.setWxAccountId(wxAccount.getId());
|
||||
wxAccountFans.setWxAccountAppid(wxAccount.getAppid());
|
||||
wxAccountFans.setWxAccountName(wxAccount.getName());
|
||||
|
||||
wxAccountFansMapper.insert(wxAccountFans);
|
||||
return this.handleSpecial(wxMessage, wxAccountFans);
|
||||
} catch (WxErrorException e) {
|
||||
log.error("该公众号没有获取用户信息失败!" , e);
|
||||
log.error("该公众号没有获取用户信息失败!", e);
|
||||
}
|
||||
|
||||
|
||||
WxMpXmlOutMessage responseResult = null;
|
||||
try {
|
||||
responseResult = this.handleSpecial(wxMessage);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
if (responseResult != null) {
|
||||
return responseResult;
|
||||
}
|
||||
|
||||
try {
|
||||
return new TextBuilder().build("感谢关注" , wxMessage, weixinService);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
return new TextBuilder().build("感谢关注", wxMessage, weixinService);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理特殊请求,比如如果是扫码进来的,可以做相应处理
|
||||
*/
|
||||
private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage)
|
||||
throws Exception {
|
||||
//TODO
|
||||
return null;
|
||||
private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage, WxAccountFans fans) {
|
||||
//发送关注消息
|
||||
List<WxAutoReply> listWxAutoReply = wxAutoReplyService.list(Wrappers.<WxAutoReply>query().lambda()
|
||||
.eq(WxAutoReply::getType, ReplyTypeEnum.ATTENTION.getType())
|
||||
.eq(WxAutoReply::getAppId,WxMpContextHolder.getAppId()));
|
||||
// 查询公众号 基本信息
|
||||
WxAccount wxAccount = wxAccountMapper.selectOne(Wrappers.<WxAccount>lambdaQuery()
|
||||
.eq(WxAccount::getAccount, wxMessage.getToUser()));
|
||||
WxMpXmlOutMessage wxMpXmlOutMessage = MsgHandler.getWxMpXmlOutMessage(wxMessage, listWxAutoReply, fans, msgMapper, wxAccount);
|
||||
return wxMpXmlOutMessage;
|
||||
}
|
||||
|
||||
}
|
||||
+11
-1
@@ -1,5 +1,10 @@
|
||||
package com.pig4cloud.pigx.mp.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.mp.constant.SubStatusEnum;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAccountFans;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxAccountFansMapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
@@ -14,7 +19,9 @@ import java.util.Map;
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class UnsubscribeHandler extends AbstractHandler {
|
||||
private final WxAccountFansMapper wxAccountFansMapper;
|
||||
|
||||
@Override
|
||||
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||
@@ -22,7 +29,10 @@ public class UnsubscribeHandler extends AbstractHandler {
|
||||
WxSessionManager sessionManager) {
|
||||
String openId = wxMessage.getFromUser();
|
||||
log.info("取消关注用户 OPENID: " + openId);
|
||||
// TODO 可以更新本地数据库为取消关注状态
|
||||
WxAccountFans fans = new WxAccountFans();
|
||||
fans.setSubscribeStatus(SubStatusEnum.UNSUB.getType());
|
||||
wxAccountFansMapper.update(fans, Wrappers
|
||||
.<WxAccountFans>lambdaUpdate().eq(WxAccountFans::getOpenid,openId));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.pig4cloud.pigx.mp.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAutoReply;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 消息自动回复
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-04-18 15:40:39
|
||||
*/
|
||||
@Mapper
|
||||
public interface WxAutoReplyMapper extends BaseMapper<WxAutoReply> {
|
||||
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.mp.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsg;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* lengleng
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:27
|
||||
*/
|
||||
@Mapper
|
||||
public interface WxFansMsgMapper extends BaseMapper<WxFansMsg> {
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.pig4cloud.pigx.mp.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.pig4cloud.pigx.mp.entity.WxMsg;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 微信消息
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-05-28 16:12:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface WxMsgMapper extends BaseMapper<WxMsg> {
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.pig4cloud.pigx.mp.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAutoReply;
|
||||
|
||||
/**
|
||||
* 消息自动回复
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-04-18 15:40:39
|
||||
*/
|
||||
public interface WxAutoReplyService extends IService<WxAutoReply> {
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.mp.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsgRes;
|
||||
|
||||
/**
|
||||
* 微信消息回复业务
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:48
|
||||
*/
|
||||
public interface WxFansMsgResService extends IService<WxFansMsgRes> {
|
||||
|
||||
/**
|
||||
* 保存并发送回复
|
||||
*
|
||||
* @param wxFansMsgRes
|
||||
* @return
|
||||
*/
|
||||
R saveAndSend(WxFansMsgRes wxFansMsgRes);
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.mp.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsg;
|
||||
|
||||
/**
|
||||
* 微信消息业务
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:27
|
||||
*/
|
||||
public interface WxFansMsgService extends IService<WxFansMsg> {
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.pig4cloud.pigx.mp.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.mp.entity.WxMsg;
|
||||
|
||||
/**
|
||||
* 微信消息
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-05-28 16:12:10
|
||||
*/
|
||||
public interface WxMsgService extends IService<WxMsg> {
|
||||
|
||||
}
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
package com.pig4cloud.pigx.mp.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
@@ -105,7 +106,7 @@ public class WxAccountFansServiceImpl extends ServiceImpl<WxAccountFansMapper, W
|
||||
}
|
||||
|
||||
wxAccountFans.setOpenid(wxMpUser.getOpenId());
|
||||
wxAccountFans.setSubscribeStatus(wxMpUser.getSubscribe() ? "1" : "0");
|
||||
wxAccountFans.setSubscribeStatus(String.valueOf(BooleanUtil.toInt(wxMpUser.getSubscribe())));
|
||||
wxAccountFans.setSubscribeTime(LocalDateTime
|
||||
.ofInstant(Instant.ofEpochMilli(wxMpUser.getSubscribeTime() * 1000L)
|
||||
, ZoneId.systemDefault()));
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.mp.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.mp.entity.WxAutoReply;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxAutoReplyMapper;
|
||||
import com.pig4cloud.pigx.mp.service.WxAutoReplyService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 消息自动回复
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-04-18 15:40:39
|
||||
*/
|
||||
@Service
|
||||
public class WxAutoReplyServiceImpl extends ServiceImpl<WxAutoReplyMapper, WxAutoReply> implements WxAutoReplyService {
|
||||
|
||||
}
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.mp.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.security.service.PigxUser;
|
||||
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
|
||||
import com.pig4cloud.pigx.mp.config.WxMpConfiguration;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsg;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsgRes;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxFansMsgMapper;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxFansMsgResMapper;
|
||||
import com.pig4cloud.pigx.mp.service.WxFansMsgResService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 微信消息回复业务
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:48
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class WxFansMsgResServiceImpl extends ServiceImpl<WxFansMsgResMapper, WxFansMsgRes> implements WxFansMsgResService {
|
||||
private final WxFansMsgMapper wxFansMsgMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 保存并发送回复
|
||||
* <p>
|
||||
* 1. 根据消息ID 查询消息的所属 公众号信息
|
||||
* 2. 构建文本客服消息并发送
|
||||
* 3. 完善回复消息并保存
|
||||
* 4. 更新微信消息为已回复
|
||||
*
|
||||
* @param wxFansMsgRes
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R saveAndSend(WxFansMsgRes wxFansMsgRes) {
|
||||
WxFansMsg wxFansMsg = wxFansMsgMapper.selectById(wxFansMsgRes.getFansMsgId());
|
||||
|
||||
String wxAccountAppid = wxFansMsg.getWxAccountAppid();
|
||||
WxMpService wxMpService = WxMpConfiguration.getMpServices().get(wxAccountAppid);
|
||||
|
||||
try {
|
||||
wxMpService.getKefuService().sendKefuMessage(WxMpKefuMessage
|
||||
.TEXT()
|
||||
.toUser(wxFansMsg.getOpenid())
|
||||
.content(wxFansMsgRes.getResContent())
|
||||
.build());
|
||||
} catch (WxErrorException e) {
|
||||
log.error("发送客服消息失败 ", e);
|
||||
return R.failed(e.getError().getErrorMsg());
|
||||
}
|
||||
|
||||
PigxUser user = SecurityUtils.getUser();
|
||||
wxFansMsgRes.setUserId(user.getId());
|
||||
wxFansMsgRes.setUserName(user.getUsername());
|
||||
baseMapper.insert(wxFansMsgRes);
|
||||
|
||||
wxFansMsg.setIsRes("1");
|
||||
wxFansMsgMapper.updateById(wxFansMsg);
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.mp.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.mp.entity.WxFansMsg;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxFansMsgMapper;
|
||||
import com.pig4cloud.pigx.mp.service.WxFansMsgService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 微信消息业务
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2019-03-27 20:45:27
|
||||
*/
|
||||
@Service
|
||||
public class WxFansMsgServiceImpl extends ServiceImpl<WxFansMsgMapper, WxFansMsg> implements WxFansMsgService {
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.mp.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.mp.entity.WxMsg;
|
||||
import com.pig4cloud.pigx.mp.mapper.WxMsgMapper;
|
||||
import com.pig4cloud.pigx.mp.service.WxMsgService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 微信消息
|
||||
*
|
||||
* @author JL
|
||||
* @date 2019-05-28 16:12:10
|
||||
*/
|
||||
@Service
|
||||
public class WxMsgServiceImpl extends ServiceImpl<WxMsgMapper, WxMsg> implements WxMsgService {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2018-2019
|
||||
~ All rights reserved, Designed By www.joolun.com
|
||||
-->
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.pig4cloud.pigx.mp.mapper.WxAutoReplyMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.pig4cloud.pigx.mp.mapper.WxFansMsgMapper">
|
||||
|
||||
<resultMap id="wxFansMsgMap" type="com.pig4cloud.pigx.mp.entity.WxFansMsg">
|
||||
<id property="id" column="id"/>
|
||||
<result property="openid" column="openid"/>
|
||||
<result property="nickname" column="nickname"/>
|
||||
<result property="headimgUrl" column="headimg_url"/>
|
||||
<result property="wxAccountId" column="wx_account_id"/>
|
||||
<result property="wxAccountName" column="wx_account_name"/>
|
||||
<result property="wxAccountAppid" column="wx_account_appid"/>
|
||||
<result property="msgType" column="msg_type"/>
|
||||
<result property="content" column="content"/>
|
||||
<result property="resContent" column="res_content"/>
|
||||
<result property="isRes" column="is_res"/>
|
||||
<result property="mediaId" column="media_id"/>
|
||||
<result property="picUrl" column="pic_url"/>
|
||||
<result property="picPath" column="pic_path"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~
|
||||
~ Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without
|
||||
~ modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ Redistributions of source code must retain the above copyright notice,
|
||||
~ this list of conditions and the following disclaimer.
|
||||
~ Redistributions in binary form must reproduce the above copyright
|
||||
~ notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~ Neither the name of the pig4cloud.com developer nor the names of its
|
||||
~ contributors may be used to endorse or promote products derived from
|
||||
~ this software without specific prior written permission.
|
||||
~ Author: lengleng (wangiegie@gmail.com)
|
||||
~
|
||||
-->
|
||||
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.pig4cloud.pigx.mp.mapper.WxFansMsgResMapper">
|
||||
|
||||
<resultMap id="wxFansMsgResMap" type="com.pig4cloud.pigx.mp.entity.WxFansMsgRes">
|
||||
<id property="id" column="id"/>
|
||||
<result property="fansMsgId" column="fans_msg_id"/>
|
||||
<result property="resContent" column="res_content"/>
|
||||
<result property="userId" column="user_id"/>
|
||||
<result property="userName" column="user_name"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2018-2019
|
||||
~ All rights reserved, Designed By www.joolun.com
|
||||
-->
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.pig4cloud.pigx.mp.mapper.WxMsgMapper">
|
||||
|
||||
</mapper>
|
||||
Reference in new issue
Block a user