微信公众号对接

This commit is contained in:
亚洲
2022-05-31 21:59:03 +08:00
parent add9317d89
commit 1d935f58f8
65 changed files with 11683 additions and 8799 deletions

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yudao-module-wechat-mp</artifactId>
<groupId>cn.iocoder.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>yudao-module-wechat-mp-biz</artifactId>
<name>${project.artifactId}</name>
<description>
微信公众号模块,主要实现 账号管理,粉丝管理 等功能。
</description>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-wechat-mp-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-security</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-mq</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.wechatMp.builder;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractBuilder {
protected final Logger logger = LoggerFactory.getLogger(getClass());
public abstract WxMpXmlOutMessage build(String content,
WxMpXmlMessage wxMessage, WxMpService service);
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.wechatMp.builder;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutImageMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
public class ImageBuilder extends AbstractBuilder {
@Override
public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
WxMpService service) {
WxMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId(content)
.fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
.build();
return m;
}
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.wechatMp.builder;
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.WxMpXmlOutTextMessage;
public class TextBuilder extends AbstractBuilder {
@Override
public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
WxMpService service) {
WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content(content)
.fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
.build();
return m;
}
}

View File

@ -0,0 +1,137 @@
package cn.iocoder.yudao.module.wechatMp.config;
import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo.WxAccountExportReqVO;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import cn.iocoder.yudao.module.wechatMp.handler.*;
import cn.iocoder.yudao.module.wechatMp.service.account.WxAccountService;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.constant.WxMpEventConstants;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
@Slf4j
public class WxMpConfig implements InitializingBean {
private static Map<String, WxMpMessageRouter> routers = Maps.newHashMap();
private static Map<String, WxMpService> mpServices = Maps.newHashMap();
@Autowired
private WxAccountService wxAccountService;
/**
* 初始化公众号配置
*/
public synchronized void initWxConfig() {
WxAccountExportReqVO req = new WxAccountExportReqVO();
List<WxAccountDO> wxAccountList = wxAccountService.getWxAccountList(req);
if (CollectionUtils.isEmpty(wxAccountList)) {
return;
}
WxMpConfig.init(wxAccountList);
log.info("加载公众号配置成功");
}
public static void init(List<WxAccountDO> wxAccountDOS) {
mpServices = wxAccountDOS.stream().map(wxAccountDO -> {
WxMpInMemoryConfigStorage configStorage = new WxMpInMemoryConfigStorage();
configStorage.setAppId(wxAccountDO.getAppid());
configStorage.setSecret(wxAccountDO.getAppsecret());
configStorage.setToken(wxAccountDO.getToken());
configStorage.setAesKey(wxAccountDO.getAeskey());
WxMpService service = new WxMpServiceImpl();
service.setWxMpConfigStorage(configStorage);
routers.put(wxAccountDO.getAppid(), newRouter(service));
return service;
}).collect(Collectors.toMap(s -> s.getWxMpConfigStorage().getAppId(), a -> a, (o, n) -> o));
}
public static Map<String, WxMpMessageRouter> getRouters() {
return routers;
}
public static Map<String, WxMpService> getMpServices() {
return mpServices;
}
private static WxMpMessageRouter newRouter(WxMpService wxMpService) {
final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
// 记录所有事件的日志 (异步执行)
newRouter.rule().handler(SpringUtil.getBean(LogHandler.class)).next();
// 接收客服会话管理事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION)
.handler(SpringUtil.getBean(KfSessionHandler.class)).end();
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION)
.handler(SpringUtil.getBean(KfSessionHandler.class))
.end();
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION)
.handler(SpringUtil.getBean(KfSessionHandler.class)).end();
// 门店审核事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxMpEventConstants.POI_CHECK_NOTIFY)
.handler(SpringUtil.getBean(StoreCheckNotifyHandler.class)).end();
// 自定义菜单事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.MenuButtonType.CLICK).handler(SpringUtil.getBean(MenuHandler.class)).end();
// 点击菜单连接事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.MenuButtonType.VIEW).handler(SpringUtil.getBean(NullHandler.class)).end();
// 关注事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.SUBSCRIBE).handler(SpringUtil.getBean(SubscribeHandler.class))
.end();
// 取消关注事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.UNSUBSCRIBE)
.handler(SpringUtil.getBean(UnsubscribeHandler.class)).end();
// 上报地理位置事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.LOCATION).handler(SpringUtil.getBean(LocationHandler.class))
.end();
// 接收地理位置消息
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION)
.handler(SpringUtil.getBean(LocationHandler.class)).end();
// 扫码事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
.event(WxConsts.EventType.SCAN).handler(SpringUtil.getBean(ScanHandler.class)).end();
// 默认
newRouter.rule().async(false).handler(SpringUtil.getBean(MsgHandler.class)).end();
return newRouter;
}
@Override
public void afterPropertiesSet() throws Exception {
initWxConfig();
}
}

View File

@ -0,0 +1,103 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.account;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo.*;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import cn.iocoder.yudao.module.wechatMp.convert.account.WxAccountConvert;
import cn.iocoder.yudao.module.wechatMp.service.account.WxAccountService;
@Api(tags = "管理后台 - 公众号账户")
@RestController
@RequestMapping("/wechatMp/wx-account")
@Validated
public class WxAccountController {
@Resource
private WxAccountService wxAccountService;
@PostMapping("/create")
@ApiOperation("创建公众号账户")
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account:create')")
public CommonResult<Long> createWxAccount(@Valid @RequestBody WxAccountCreateReqVO createReqVO) {
return success(wxAccountService.createWxAccount(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新公众号账户")
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account:update')")
public CommonResult<Boolean> updateWxAccount(@Valid @RequestBody WxAccountUpdateReqVO updateReqVO) {
wxAccountService.updateWxAccount(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除公众号账户")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account:delete')")
public CommonResult<Boolean> deleteWxAccount(@RequestParam("id") Long id) {
wxAccountService.deleteWxAccount(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得公众号账户")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account:query')")
public CommonResult<WxAccountRespVO> getWxAccount(@RequestParam("id") Long id) {
WxAccountDO wxAccount = wxAccountService.getWxAccount(id);
return success(WxAccountConvert.INSTANCE.convert(wxAccount));
}
@GetMapping("/list")
@ApiOperation("获得公众号账户列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account:query')")
public CommonResult<List<WxAccountRespVO>> getWxAccountList(@RequestParam("ids") Collection<Long> ids) {
List<WxAccountDO> list = wxAccountService.getWxAccountList(ids);
return success(WxAccountConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得公众号账户分页")
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account:query')")
public CommonResult<PageResult<WxAccountRespVO>> getWxAccountPage(@Valid WxAccountPageReqVO pageVO) {
PageResult<WxAccountDO> pageResult = wxAccountService.getWxAccountPage(pageVO);
return success(WxAccountConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出公众号账户 Excel")
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account:export')")
@OperateLog(type = EXPORT)
public void exportWxAccountExcel(@Valid WxAccountExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<WxAccountDO> list = wxAccountService.getWxAccountList(exportReqVO);
// 导出 Excel
List<WxAccountExcelVO> datas = WxAccountConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "公众号账户.xls", "数据", WxAccountExcelVO.class, datas);
}
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
/**
* 公众号账户 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class WxAccountBaseVO {
@ApiModelProperty(value = "公众号名称")
private String name;
@ApiModelProperty(value = "公众号账户")
private String account;
@ApiModelProperty(value = "公众号appid")
private String appid;
@ApiModelProperty(value = "公众号密钥")
private String appsecret;
@ApiModelProperty(value = "公众号token")
private String token;
@ApiModelProperty(value = "加密密钥")
private String aeskey;
@ApiModelProperty(value = "备注")
private String remark;
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 公众号账户创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WxAccountCreateReqVO extends WxAccountBaseVO {
}

View File

@ -0,0 +1,50 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 公众号账户 Excel VO
*
* @author 芋道源码
*/
@Data
public class WxAccountExcelVO {
@ExcelProperty("编号")
private Long id;
@ExcelProperty("公众号名称")
private String name;
@ExcelProperty("公众号账户")
private String account;
@ExcelProperty("公众号appid")
private String appid;
@ExcelProperty("公众号密钥")
private String appsecret;
@ExcelProperty("公众号url")
private String url;
@ExcelProperty("公众号token")
private String token;
@ExcelProperty("加密密钥")
private String aeskey;
@ExcelProperty("二维码图片URL")
private String qrUrl;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "管理后台 - 公众号账户 Excel 导出 Request VO", description = "参数和 WxAccountPageReqVO 是一致的")
@Data
public class WxAccountExportReqVO {
@ApiModelProperty(value = "公众号名称")
private String name;
@ApiModelProperty(value = "公众号账户")
private String account;
@ApiModelProperty(value = "公众号appid")
private String appid;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 公众号账户分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WxAccountPageReqVO extends PageParam {
@ApiModelProperty(value = "公众号名称")
private String name;
@ApiModelProperty(value = "公众号账户")
private String account;
@ApiModelProperty(value = "公众号appid")
private String appid;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
@ApiModel("管理后台 - 公众号账户 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WxAccountRespVO extends WxAccountBaseVO {
@ApiModelProperty(value = "编号", required = true)
private Long id;
@ApiModelProperty(value = "公众号url")
private String url;
@ApiModelProperty(value = "二维码图片URL")
private String qrUrl;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 公众号账户更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WxAccountUpdateReqVO extends WxAccountBaseVO {
@ApiModelProperty(value = "编号", required = true)
@NotNull(message = "编号不能为空")
private Long id;
}

View File

@ -0,0 +1,100 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo.*;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.accountfans.WxAccountFansDO;
import cn.iocoder.yudao.module.wechatMp.convert.accountfans.WxAccountFansConvert;
import cn.iocoder.yudao.module.wechatMp.service.accountfans.WxAccountFansService;
@Api(tags = "管理后台 - 微信公众号粉丝")
@RestController
@RequestMapping("/wechatMp/wx-account-fans")
@Validated
public class WxAccountFansController {
@Resource
private WxAccountFansService wxAccountFansService;
@PostMapping("/create")
@ApiOperation("创建微信公众号粉丝")
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account-fans:create')")
public CommonResult<Long> createWxAccountFans(@Valid @RequestBody WxAccountFansCreateReqVO createReqVO) {
return success(wxAccountFansService.createWxAccountFans(createReqVO));
}
@PutMapping("/update")
@ApiOperation("更新微信公众号粉丝")
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account-fans:update')")
public CommonResult<Boolean> updateWxAccountFans(@Valid @RequestBody WxAccountFansUpdateReqVO updateReqVO) {
wxAccountFansService.updateWxAccountFans(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@ApiOperation("删除微信公众号粉丝")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account-fans:delete')")
public CommonResult<Boolean> deleteWxAccountFans(@RequestParam("id") Long id) {
wxAccountFansService.deleteWxAccountFans(id);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得微信公众号粉丝")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account-fans:query')")
public CommonResult<WxAccountFansRespVO> getWxAccountFans(@RequestParam("id") Long id) {
WxAccountFansDO wxAccountFans = wxAccountFansService.getWxAccountFans(id);
return success(WxAccountFansConvert.INSTANCE.convert(wxAccountFans));
}
@GetMapping("/list")
@ApiOperation("获得微信公众号粉丝列表")
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account-fans:query')")
public CommonResult<List<WxAccountFansRespVO>> getWxAccountFansList(@RequestParam("ids") Collection<Long> ids) {
List<WxAccountFansDO> list = wxAccountFansService.getWxAccountFansList(ids);
return success(WxAccountFansConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@ApiOperation("获得微信公众号粉丝分页")
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account-fans:query')")
public CommonResult<PageResult<WxAccountFansRespVO>> getWxAccountFansPage(@Valid WxAccountFansPageReqVO pageVO) {
PageResult<WxAccountFansDO> pageResult = wxAccountFansService.getWxAccountFansPage(pageVO);
return success(WxAccountFansConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@ApiOperation("导出微信公众号粉丝 Excel")
@PreAuthorize("@ss.hasPermission('wechatMp:wx-account-fans:export')")
@OperateLog(type = EXPORT)
public void exportWxAccountFansExcel(@Valid WxAccountFansExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<WxAccountFansDO> list = wxAccountFansService.getWxAccountFansList(exportReqVO);
// 导出 Excel
List<WxAccountFansExcelVO> datas = WxAccountFansConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "微信公众号粉丝.xls", "数据", WxAccountFansExcelVO.class, datas);
}
}

View File

@ -0,0 +1,58 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 微信公众号粉丝 Base VO提供给添加、修改、详细的子 VO 使用
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
*/
@Data
public class WxAccountFansBaseVO {
@ApiModelProperty(value = "用户标识")
private String openid;
@ApiModelProperty(value = "订阅状态0未关注1已关注")
private String subscribeStatus;
@ApiModelProperty(value = "订阅时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private Date subscribeTime;
@ApiModelProperty(value = "昵称")
private byte[] nickname;
@ApiModelProperty(value = "性别1男2女0未知")
private String gender;
@ApiModelProperty(value = "语言")
private String language;
@ApiModelProperty(value = "国家")
private String country;
@ApiModelProperty(value = "省份")
private String province;
@ApiModelProperty(value = "城市")
private String city;
@ApiModelProperty(value = "头像地址")
private String headimgUrl;
@ApiModelProperty(value = "备注")
private String remark;
@ApiModelProperty(value = "微信公众号ID")
private String wxAccountId;
@ApiModelProperty(value = "微信公众号appid")
private String wxAccountAppid;
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 微信公众号粉丝创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WxAccountFansCreateReqVO extends WxAccountFansBaseVO {
}

View File

@ -0,0 +1,62 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 微信公众号粉丝 Excel VO
*
* @author 芋道源码
*/
@Data
public class WxAccountFansExcelVO {
@ExcelProperty("编号")
private Long id;
@ExcelProperty("用户标识")
private String openid;
@ExcelProperty("订阅状态0未关注1已关注")
private String subscribeStatus;
@ExcelProperty("订阅时间")
private Date subscribeTime;
@ExcelProperty("昵称")
private byte[] nickname;
@ExcelProperty("性别1男2女0未知")
private String gender;
@ExcelProperty("语言")
private String language;
@ExcelProperty("国家")
private String country;
@ExcelProperty("省份")
private String province;
@ExcelProperty("城市")
private String city;
@ExcelProperty("头像地址")
private String headimgUrl;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("微信公众号ID")
private String wxAccountId;
@ExcelProperty("微信公众号appid")
private String wxAccountAppid;
@ExcelProperty("创建时间")
private Date createTime;
}

View File

@ -0,0 +1,67 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel(value = "管理后台 - 微信公众号粉丝 Excel 导出 Request VO", description = "参数和 WxAccountFansPageReqVO 是一致的")
@Data
public class WxAccountFansExportReqVO {
@ApiModelProperty(value = "用户标识")
private String openid;
@ApiModelProperty(value = "订阅状态0未关注1已关注")
private String subscribeStatus;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始订阅时间")
private Date beginSubscribeTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束订阅时间")
private Date endSubscribeTime;
@ApiModelProperty(value = "昵称")
private String nickname;
@ApiModelProperty(value = "性别1男2女0未知")
private String gender;
@ApiModelProperty(value = "语言")
private String language;
@ApiModelProperty(value = "国家")
private String country;
@ApiModelProperty(value = "省份")
private String province;
@ApiModelProperty(value = "城市")
private String city;
@ApiModelProperty(value = "头像地址")
private String headimgUrl;
@ApiModelProperty(value = "备注")
private String remark;
@ApiModelProperty(value = "微信公众号ID")
private String wxAccountId;
@ApiModelProperty(value = "微信公众号appid")
private String wxAccountAppid;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
}

View File

@ -0,0 +1,69 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ApiModel("管理后台 - 微信公众号粉丝分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WxAccountFansPageReqVO extends PageParam {
@ApiModelProperty(value = "用户标识")
private String openid;
@ApiModelProperty(value = "订阅状态0未关注1已关注")
private String subscribeStatus;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始订阅时间")
private Date beginSubscribeTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束订阅时间")
private Date endSubscribeTime;
@ApiModelProperty(value = "昵称")
private String nickname;
@ApiModelProperty(value = "性别1男2女0未知")
private String gender;
@ApiModelProperty(value = "语言")
private String language;
@ApiModelProperty(value = "国家")
private String country;
@ApiModelProperty(value = "省份")
private String province;
@ApiModelProperty(value = "城市")
private String city;
@ApiModelProperty(value = "头像地址")
private String headimgUrl;
@ApiModelProperty(value = "备注")
private String remark;
@ApiModelProperty(value = "微信公众号ID")
private String wxAccountId;
@ApiModelProperty(value = "微信公众号appid")
private String wxAccountAppid;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "开始创建时间")
private Date beginCreateTime;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ApiModelProperty(value = "结束创建时间")
private Date endCreateTime;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
@ApiModel("管理后台 - 微信公众号粉丝 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WxAccountFansRespVO extends WxAccountFansBaseVO {
@ApiModelProperty(value = "编号", required = true)
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
import javax.validation.constraints.*;
@ApiModel("管理后台 - 微信公众号粉丝更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class WxAccountFansUpdateReqVO extends WxAccountFansBaseVO {
@ApiModelProperty(value = "编号", required = true)
@NotNull(message = "编号不能为空")
private Long id;
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.wechatMp.convert.account;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo.*;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
/**
* 公众号账户 Convert
*
* @author 芋道源码
*/
@Mapper
public interface WxAccountConvert {
WxAccountConvert INSTANCE = Mappers.getMapper(WxAccountConvert.class);
WxAccountDO convert(WxAccountCreateReqVO bean);
WxAccountDO convert(WxAccountUpdateReqVO bean);
WxAccountRespVO convert(WxAccountDO bean);
List<WxAccountRespVO> convertList(List<WxAccountDO> list);
PageResult<WxAccountRespVO> convertPage(PageResult<WxAccountDO> page);
List<WxAccountExcelVO> convertList02(List<WxAccountDO> list);
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.wechatMp.convert.accountfans;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo.*;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.accountfans.WxAccountFansDO;
/**
* 微信公众号粉丝 Convert
*
* @author 芋道源码
*/
@Mapper
public interface WxAccountFansConvert {
WxAccountFansConvert INSTANCE = Mappers.getMapper(WxAccountFansConvert.class);
WxAccountFansDO convert(WxAccountFansCreateReqVO bean);
WxAccountFansDO convert(WxAccountFansUpdateReqVO bean);
WxAccountFansRespVO convert(WxAccountFansDO bean);
List<WxAccountFansRespVO> convertList(List<WxAccountFansDO> list);
PageResult<WxAccountFansRespVO> convertPage(PageResult<WxAccountFansDO> page);
List<WxAccountFansExcelVO> convertList02(List<WxAccountFansDO> list);
}

View File

@ -0,0 +1,65 @@
package cn.iocoder.yudao.module.wechatMp.dal.dataobject.account;
import lombok.*;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 公众号账户 DO
*
* @author 芋道源码
*/
@TableName("wx_account")
@KeySequence("wx_account_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WxAccountDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 公众号名称
*/
private String name;
/**
* 公众号账户
*/
private String account;
/**
* 公众号appid
*/
private String appid;
/**
* 公众号密钥
*/
private String appsecret;
/**
* 公众号url
*/
private String url;
/**
* 公众号token
*/
private String token;
/**
* 加密密钥
*/
private String aeskey;
/**
* 二维码图片URL
*/
private String qrUrl;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.wechatMp.dal.dataobject.accountfans;
import lombok.*;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 微信公众号粉丝 DO
*
* @author 芋道源码
*/
@TableName("wx_account_fans")
@KeySequence("wx_account_fans_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WxAccountFansDO extends BaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 用户标识
*/
private String openid;
/**
* 订阅状态0未关注1已关注
*/
private String subscribeStatus;
/**
* 订阅时间
*/
private Date subscribeTime;
/**
* 昵称
*/
private byte[] nickname;
/**
* 性别1男2女0未知
*/
private String gender;
/**
* 语言
*/
private String language;
/**
* 国家
*/
private String country;
/**
* 省份
*/
private String province;
/**
* 城市
*/
private String city;
/**
* 头像地址
*/
private String headimgUrl;
/**
* 备注
*/
private String remark;
/**
* 微信公众号ID
*/
private String wxAccountId;
/**
* 微信公众号appid
*/
private String wxAccountAppid;
}

View File

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.wechatMp.dal.mysql.account;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo.*;
/**
* 公众号账户 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface WxAccountMapper extends BaseMapperX<WxAccountDO> {
default PageResult<WxAccountDO> selectPage(WxAccountPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<WxAccountDO>()
.likeIfPresent(WxAccountDO::getName, reqVO.getName())
.eqIfPresent(WxAccountDO::getAccount, reqVO.getAccount())
.eqIfPresent(WxAccountDO::getAppid, reqVO.getAppid())
.betweenIfPresent(WxAccountDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc(WxAccountDO::getId));
}
default List<WxAccountDO> selectList(WxAccountExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<WxAccountDO>()
.likeIfPresent(WxAccountDO::getName, reqVO.getName())
.eqIfPresent(WxAccountDO::getAccount, reqVO.getAccount())
.eqIfPresent(WxAccountDO::getAppid, reqVO.getAppid())
.betweenIfPresent(WxAccountDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc(WxAccountDO::getId));
}
}

View File

@ -0,0 +1,58 @@
package cn.iocoder.yudao.module.wechatMp.dal.mysql.accountfans;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.accountfans.WxAccountFansDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo.*;
/**
* 微信公众号粉丝 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface WxAccountFansMapper extends BaseMapperX<WxAccountFansDO> {
default PageResult<WxAccountFansDO> selectPage(WxAccountFansPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<WxAccountFansDO>()
.eqIfPresent(WxAccountFansDO::getOpenid, reqVO.getOpenid())
.eqIfPresent(WxAccountFansDO::getSubscribeStatus, reqVO.getSubscribeStatus())
.betweenIfPresent(WxAccountFansDO::getSubscribeTime, reqVO.getBeginSubscribeTime(), reqVO.getEndSubscribeTime())
.likeIfPresent(WxAccountFansDO::getNickname, reqVO.getNickname())
.eqIfPresent(WxAccountFansDO::getGender, reqVO.getGender())
.eqIfPresent(WxAccountFansDO::getLanguage, reqVO.getLanguage())
.eqIfPresent(WxAccountFansDO::getCountry, reqVO.getCountry())
.eqIfPresent(WxAccountFansDO::getProvince, reqVO.getProvince())
.eqIfPresent(WxAccountFansDO::getCity, reqVO.getCity())
.eqIfPresent(WxAccountFansDO::getHeadimgUrl, reqVO.getHeadimgUrl())
.eqIfPresent(WxAccountFansDO::getRemark, reqVO.getRemark())
.eqIfPresent(WxAccountFansDO::getWxAccountId, reqVO.getWxAccountId())
.eqIfPresent(WxAccountFansDO::getWxAccountAppid, reqVO.getWxAccountAppid())
.betweenIfPresent(WxAccountFansDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc(WxAccountFansDO::getId));
}
default List<WxAccountFansDO> selectList(WxAccountFansExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<WxAccountFansDO>()
.eqIfPresent(WxAccountFansDO::getOpenid, reqVO.getOpenid())
.eqIfPresent(WxAccountFansDO::getSubscribeStatus, reqVO.getSubscribeStatus())
.betweenIfPresent(WxAccountFansDO::getSubscribeTime, reqVO.getBeginSubscribeTime(), reqVO.getEndSubscribeTime())
.likeIfPresent(WxAccountFansDO::getNickname, reqVO.getNickname())
.eqIfPresent(WxAccountFansDO::getGender, reqVO.getGender())
.eqIfPresent(WxAccountFansDO::getLanguage, reqVO.getLanguage())
.eqIfPresent(WxAccountFansDO::getCountry, reqVO.getCountry())
.eqIfPresent(WxAccountFansDO::getProvince, reqVO.getProvince())
.eqIfPresent(WxAccountFansDO::getCity, reqVO.getCity())
.eqIfPresent(WxAccountFansDO::getHeadimgUrl, reqVO.getHeadimgUrl())
.eqIfPresent(WxAccountFansDO::getRemark, reqVO.getRemark())
.eqIfPresent(WxAccountFansDO::getWxAccountId, reqVO.getWxAccountId())
.eqIfPresent(WxAccountFansDO::getWxAccountAppid, reqVO.getWxAccountAppid())
.betweenIfPresent(WxAccountFansDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
.orderByDesc(WxAccountFansDO::getId));
}
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class KfSessionHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService wxMpService,
WxSessionManager sessionManager) {
//TODO 对会话做处理
return null;
}
}

View File

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import cn.iocoder.yudao.module.wechatMp.builder.TextBuilder;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;
import java.util.Map;
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
@Component
@Slf4j
public class LocationHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService wxMpService,
WxSessionManager sessionManager) {
if (wxMessage.getMsgType().equals(XmlMsgType.LOCATION)) {
//TODO 接收处理用户发送的地理位置消息
try {
String content = "感谢反馈,您的的地理位置已收到!";
return new TextBuilder().build(content, wxMessage, null);
} catch (Exception e) {
log.error("位置消息接收处理失败", e);
return null;
}
}
//上报地理位置事件
log.info("上报地理位置,纬度 : {},经度 : {},精度 : {}",
wxMessage.getLatitude(), wxMessage.getLongitude(), String.valueOf(wxMessage.getPrecision()));
//TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用
return null;
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@Slf4j
public class LogHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService wxMpService,
WxSessionManager sessionManager) {
log.info("接收到请求消息,内容:{}", JsonUtils.toJsonString(wxMessage));
return null;
}
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;
import java.util.Map;
import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType;
@Component
public class MenuHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService weixinService,
WxSessionManager sessionManager) {
String msg = wxMessage.getEventKey();
if (MenuButtonType.VIEW.equals(wxMessage.getEvent())) {
return null;
}
return WxMpXmlOutMessage.TEXT().content(msg)
.fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
.build();
}
}

View File

@ -0,0 +1,184 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.wechatMp.builder.TextBuilder;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import cn.iocoder.yudao.module.wechatMp.service.account.WxAccountService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
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.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
@Component
@Slf4j
public class MsgHandler implements WxMpMessageHandler {
/*
@Autowired
WxReceiveTextService wxReceiveTextService;
@Autowired
WxTextTemplateService wxTextTemplateService;
@Autowired
WxAccountService wxAccountService;
@Autowired
WxFansMsgService wxFansMsgService;
*/
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService weixinService,
WxSessionManager sessionManager) {
/* log.info( "收到信息内容:", JsonUtils.toJsonString(wxMessage) );
log.info( "关键字:", wxMessage.getContent() );
if (!wxMessage.getMsgType().equals(XmlMsgType.EVENT)) {
//可以选择将消息保存到本地
// 获取微信用户基本信息
try {
WxMpUser wxmpUser = weixinService.getUserService()
.userInfo(wxMessage.getFromUser(), null);
if (wxmpUser != null) {
WxAccountDO wxAccount = wxAccountService.findBy( WxAccountDO::getAccount,wxMessage.getToUser());
if(wxAccount != null){
if(wxMessage.getMsgType().equals( XmlMsgType.TEXT )){
WxFansMsg wxFansMsg = new WxFansMsg();
wxFansMsg.setOpenid( wxmpUser.getOpenId() );
try {
wxFansMsg.setNickname(wxmpUser.getNickname().getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
wxFansMsg.setHeadimgUrl( wxmpUser.getHeadImgUrl() );
wxFansMsg.setWxAccountId( String.valueOf( wxAccount.getId() ) );
wxFansMsg.setMsgType( wxMessage.getMsgType());
wxFansMsg.setContent( wxMessage.getContent() );
wxFansMsg.setIsRes( "1" );
wxFansMsg.setCreateTime( DateUtil.date() );
wxFansMsg.setUpdateTime( DateUtil.date() );
//组装回复消息
String content = processContent(wxMessage);
content = HtmlUtil.escape( content );
wxFansMsg.setResContent( content );
wxFansMsgService.save( wxFansMsg );
return new TextBuilder().build(content, wxMessage, weixinService);
}
if(wxMessage.getMsgType().equals( XmlMsgType.IMAGE )){
WxFansMsg wxFansMsg = new WxFansMsg();
wxFansMsg.setOpenid( wxmpUser.getOpenId() );
try {
wxFansMsg.setNickname(wxmpUser.getNickname().getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
wxFansMsg.setHeadimgUrl( wxmpUser.getHeadImgUrl() );
wxFansMsg.setWxAccountId( String.valueOf( wxAccount.getId() ) );
wxFansMsg.setMsgType( wxMessage.getMsgType());
wxFansMsg.setMediaId( wxMessage.getMediaId() );
wxFansMsg.setPicUrl( wxMessage.getPicUrl() );
File downloadDir = new File(downloadDirStr);
if (!downloadDir.exists()) {
downloadDir.mkdirs();
}
String filepath = downloadDirStr + String.valueOf( System.currentTimeMillis() ) + ".png";
//微信pic url下载到本地防止失效
long size = HttpUtil.downloadFile(wxMessage.getPicUrl(), FileUtil.file(filepath));
log.info("download pic size : {}",size);
wxFansMsg.setPicPath( filepath );
wxFansMsg.setIsRes( "0" );
wxFansMsg.setCreateTime( DateUtil.date() );
wxFansMsg.setUpdateTime( DateUtil.date() );
wxFansMsgService.save( wxFansMsg );
}
}
}
} catch (WxErrorException e) {
if (e.getError().getErrorCode() == 48001) {
log.info("该公众号没有获取用户信息权限!");
}
}
}
//当用户输入关键词如“你好”,“客服”等,并且有客服在线时,把消息转发给在线客服
// try {
// if (StringUtils.startsWithAny(wxMessage.getContent(), "你好", "客服")
// && weixinService.getKefuService().kfOnlineList()
// .getKfOnlineList().size() > 0) {
// return WxMpXmlOutMessage.TRANSFER_CUSTOMER_SERVICE()
// .fromUser(wxMessage.getToUser())
// .toUser(wxMessage.getFromUser()).build();
// }
// } catch (WxErrorException e) {
// e.printStackTrace();
// }
//组装默认回复消息
String content = defaultResponseContent;//默认
return new TextBuilder().build(content, wxMessage, weixinService);
*/
return null;
}
//处理回复信息,优先级,关键字、智能机器人、默认值
String processContent(WxMpXmlMessage wxMessage){
String content = "";
/* content = processReceiveTextContent(wxMessage);
if(StringUtils.isNotBlank( content )){
return content;
}
content = defaultResponseContent;*/
return content;
}
//处理关键字
String processReceiveTextContent(WxMpXmlMessage wxMessage){
String content = "";
/* WxAccountDO wxAccount = wxAccountService.findBy( WxAccountDO::getAccount,wxMessage.getToUser());
if(wxAccount != null){
WxReceiveText wxReceiveTextTpl = new WxReceiveText();
wxReceiveTextTpl.setWxAccountId( String.valueOf( wxAccount.getId() ) );
wxReceiveTextTpl.setReceiveText( wxMessage.getContent() );
List<WxReceiveText> wxReceiveTextList = wxReceiveTextService.findListByReceiveTest( wxReceiveTextTpl );
if(wxReceiveTextList != null && wxReceiveTextList.size() > 0){
WxReceiveText wxReceiveText = wxReceiveTextList.get( 0 );
WxTextTemplate wxTextTemplate = wxTextTemplateService.findById( Integer.parseInt( wxReceiveText.getTplId() ) );
content = wxTextTemplate.getContent();
}
}*/
return content;
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class NullHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService wxMpService,
WxSessionManager sessionManager) {
return null;
}
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class ScanHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map<String, Object> map,
WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException {
// 扫码事件处理
return null;
}
}

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 门店审核事件处理
*
*/
@Component
public class StoreCheckNotifyHandler implements WxMpMessageHandler {
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService wxMpService,
WxSessionManager sessionManager) {
// TODO 处理门店审核事件
return null;
}
}

View File

@ -0,0 +1,164 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.wechatMp.builder.TextBuilder;
import cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo.WxAccountFansCreateReqVO;
import cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo.WxAccountFansUpdateReqVO;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.accountfans.WxAccountFansDO;
import cn.iocoder.yudao.module.wechatMp.service.account.WxAccountService;
import cn.iocoder.yudao.module.wechatMp.service.accountfans.WxAccountFansService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.util.Map;
@Component
@Slf4j
public class SubscribeHandler implements WxMpMessageHandler {
/* @Autowired
private WxTextTemplateService wxTextTemplateService;
@Autowired
private WxAccountService wxAccountService;
@Autowired
private WxSubscribeTextService wxSubscribeTextService;
@Autowired
private WxAccountFansService wxAccountFansService;
@Autowired
private WxAccountFansTagService wxAccountFansTagService;*/
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService weixinService,
WxSessionManager sessionManager) throws WxErrorException {
log.info("新关注用户 OPENID: " + wxMessage.getFromUser());
/*
// 获取微信用户基本信息
try {
WxMpUser wxmpUser = weixinService.getUserService()
.userInfo(wxMessage.getFromUser(), null);
if (wxmpUser != null) {
// 可以添加关注用户到本地数据库
WxAccountDO wxAccount = wxAccountService.findBy(WxAccountDO::getAccount, wxMessage.getToUser());
if (wxAccount != null) {
WxAccountFansDO wxAccountFans = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, wxmpUser.getOpenId());
if (wxAccountFans == null) {//insert
WxAccountFansCreateReqVO wxAccountFansCreateReqVO = new WxAccountFansCreateReqVO();
wxAccountFansCreateReqVO.setOpenid(wxmpUser.getOpenId());
wxAccountFansCreateReqVO.setSubscribeStatus(wxmpUser.getSubscribe() ? "1" : "0");
wxAccountFansCreateReqVO.setSubscribeTime(DateUtil.date(wxmpUser.getSubscribeTime() * 1000L));
try {
wxAccountFansCreateReqVO.setNickname(wxmpUser.getNickname().getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
wxAccountFansCreateReqVO.setGender(String.valueOf(wxmpUser.getSex()));
wxAccountFansCreateReqVO.setLanguage(wxmpUser.getLanguage());
wxAccountFansCreateReqVO.setCountry(wxmpUser.getCountry());
wxAccountFansCreateReqVO.setProvince(wxmpUser.getProvince());
wxAccountFansCreateReqVO.setCity(wxmpUser.getCity());
wxAccountFansCreateReqVO.setHeadimgUrl(wxmpUser.getHeadImgUrl());
wxAccountFansCreateReqVO.setRemark(wxmpUser.getRemark());
wxAccountFansCreateReqVO.setWxAccountId(String.valueOf(wxAccount.getId()));
wxAccountFansCreateReqVO.setWxAccountAppid(wxAccount.getAppid());
wxAccountFansService.createWxAccountFans(wxAccountFansCreateReqVO);
//process tags
wxAccountFansTagService.processFansTags(wxAccount, wxmpUser);
} else {//update
WxAccountFansUpdateReqVO wxAccountFansUpdateReqVO = new WxAccountFansUpdateReqVO();
wxAccountFansUpdateReqVO.setId(wxAccountFans.getId());
wxAccountFansUpdateReqVO.setOpenid(wxmpUser.getOpenId());
wxAccountFansUpdateReqVO.setSubscribeStatus(wxmpUser.getSubscribe() ? "1" : "0");
wxAccountFansUpdateReqVO.setSubscribeTime(DateUtil.date(wxmpUser.getSubscribeTime() * 1000L));
try {
wxAccountFans.setNickname(wxmpUser.getNickname().getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
wxAccountFansUpdateReqVO.setGender(String.valueOf(wxmpUser.getSex()));
wxAccountFansUpdateReqVO.setLanguage(wxmpUser.getLanguage());
wxAccountFansUpdateReqVO.setCountry(wxmpUser.getCountry());
wxAccountFansUpdateReqVO.setProvince(wxmpUser.getProvince());
wxAccountFansUpdateReqVO.setCity(wxmpUser.getCity());
wxAccountFansUpdateReqVO.setHeadimgUrl(wxmpUser.getHeadImgUrl());
wxAccountFansUpdateReqVO.setRemark(wxmpUser.getRemark());
wxAccountFansUpdateReqVO.setWxAccountId(String.valueOf(wxAccount.getId()));
wxAccountFansUpdateReqVO.setWxAccountAppid(wxAccount.getAppid());
wxAccountFansService.updateWxAccountFans(wxAccountFansUpdateReqVO);
//process tags
wxAccountFansTagService.processFansTags(wxAccount, wxmpUser);
}
}
}
} catch (WxErrorException e) {
if (e.getError().getErrorCode() == 48001) {
log.info("该公众号没有获取用户信息权限!");
}
}
WxMpXmlOutMessage responseResult = null;
try {
responseResult = this.handleSpecial(wxMessage);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
if (responseResult != null) {
return responseResult;
}
try {
String content = "感谢关注!";//默认
WxAccountDO wxAccount = wxAccountService.findBy(WxAccountDO::getAccount, wxMessage.getToUser());
if (wxAccount != null) {
WxSubscribeText wxSubscribeText = wxSubscribeTextService.findBy("wxAccountId", String.valueOf(wxAccount.getId()));
if (wxSubscribeText != null) {
WxTextTemplate wxTextTemplate = wxTextTemplateService.findById(Integer.parseInt(wxSubscribeText.getTplId()));
if (wxTextTemplate != null) {
content = wxTextTemplate.getContent();
}
}
}
log.info("wxMessage : {}", JsonUtils.toJsonString(wxMessage));
return new TextBuilder().build(content, wxMessage, weixinService);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
*/
return null;
}
/**
* 处理特殊请求,比如如果是扫码进来的,可以做相应处理
*/
private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage)
throws Exception {
//TODO
return null;
}
}

View File

@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.wechatMp.handler;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo.WxAccountFansUpdateReqVO;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.accountfans.WxAccountFansDO;
import cn.iocoder.yudao.module.wechatMp.service.account.WxAccountService;
import cn.iocoder.yudao.module.wechatMp.service.accountfans.WxAccountFansService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@Slf4j
public class UnsubscribeHandler implements WxMpMessageHandler {
@Autowired
private WxAccountService wxAccountService;
@Autowired
private WxAccountFansService wxAccountFansService;
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
Map<String, Object> context, WxMpService wxMpService,
WxSessionManager sessionManager) {
String openId = wxMessage.getFromUser();
log.info("取消关注用户 OPENID: " + openId);
// TODO 可以更新本地数据库为取消关注状态
WxAccountDO wxAccountDO = wxAccountService.findBy(WxAccountDO::getAccount, wxMessage.getToUser());
if (wxAccountDO != null) {
WxAccountFansDO wxAccountFansDO = wxAccountFansService.findBy(WxAccountFansDO::getOpenid, openId);
if (wxAccountFansDO != null) {
WxAccountFansUpdateReqVO wxAccountFansUpdateReqVO = new WxAccountFansUpdateReqVO();
wxAccountFansUpdateReqVO.setId(wxAccountDO.getId());
wxAccountFansDO.setSubscribeStatus("0");//取消订阅
wxAccountFansService.updateWxAccountFans(wxAccountFansUpdateReqVO);
}
}
return null;
}
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.wechatMp.mq.costomer.dict;
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
import cn.iocoder.yudao.module.wechatMp.config.WxMpConfig;
import cn.iocoder.yudao.module.wechatMp.mq.message.dict.WxConfigDataRefreshMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 针对 {@link WxConfigDataRefreshMessage} 的消费者
*
* @author lyz
*/
@Component
@Slf4j
public class WxConfigDataRefreshConsumer extends AbstractChannelMessageListener<WxConfigDataRefreshMessage> {
@Resource
private WxMpConfig wxMpConfig;
@Override
public void onMessage(WxConfigDataRefreshMessage message) {
log.info("[onMessage][收到 WxConfigData 刷新消息]");
wxMpConfig.initWxConfig();
}
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.wechatMp.mq.message.dict;
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 微信配置数据刷新 Message
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class WxConfigDataRefreshMessage extends AbstractChannelMessage {
@Override
public String getChannel() {
return "wechat-mp.wx-config-data.refresh";
}
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.wechatMp.mq.producer.dict;
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
import cn.iocoder.yudao.module.wechatMp.mq.message.dict.WxConfigDataRefreshMessage;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 微信配置数据相关消息的 Producer
*/
@Component
public class WxMpConfigDataProducer {
@Resource
private RedisMQTemplate redisMQTemplate;
/**
* 发送 {@link WxConfigDataRefreshMessage} 消息
*/
public void sendDictDataRefreshMessage() {
WxConfigDataRefreshMessage message = new WxConfigDataRefreshMessage();
redisMQTemplate.send(message);
}
}

View File

@ -0,0 +1,80 @@
package cn.iocoder.yudao.module.wechatMp.service.account;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo.*;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
/**
* 公众号账户 Service 接口
*
* @author 芋道源码
*/
public interface WxAccountService {
/**
* 创建公众号账户
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createWxAccount(@Valid WxAccountCreateReqVO createReqVO);
/**
* 更新公众号账户
*
* @param updateReqVO 更新信息
*/
void updateWxAccount(@Valid WxAccountUpdateReqVO updateReqVO);
/**
* 删除公众号账户
*
* @param id 编号
*/
void deleteWxAccount(Long id);
/**
* 获得公众号账户
*
* @param id 编号
* @return 公众号账户
*/
WxAccountDO getWxAccount(Long id);
/**
* 获得公众号账户列表
*
* @param ids 编号
* @return 公众号账户列表
*/
List<WxAccountDO> getWxAccountList(Collection<Long> ids);
/**
* 获得公众号账户分页
*
* @param pageReqVO 分页查询
* @return 公众号账户分页
*/
PageResult<WxAccountDO> getWxAccountPage(WxAccountPageReqVO pageReqVO);
/**
* 获得公众号账户列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 公众号账户列表
*/
List<WxAccountDO> getWxAccountList(WxAccountExportReqVO exportReqVO);
/**
* 查询账户
*
* @param field
* @param val
* @return
*/
WxAccountDO findBy(SFunction<WxAccountDO,?> field, Object val);
}

View File

@ -0,0 +1,97 @@
package cn.iocoder.yudao.module.wechatMp.service.account;
import cn.iocoder.yudao.module.wechatMp.mq.producer.dict.WxMpConfigDataProducer;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.module.wechatMp.controller.admin.account.vo.*;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.wechatMp.convert.account.WxAccountConvert;
import cn.iocoder.yudao.module.wechatMp.dal.mysql.account.WxAccountMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.wechatMp.enums.ErrorCodeConstants.*;
/**
* 公众号账户 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class WxAccountServiceImpl implements WxAccountService {
@Resource
private WxAccountMapper wxAccountMapper;
@Resource
private WxMpConfigDataProducer wxMpConfigDataProducer;
@Override
public Long createWxAccount(WxAccountCreateReqVO createReqVO) {
// 插入
WxAccountDO wxAccount = WxAccountConvert.INSTANCE.convert(createReqVO);
wxAccountMapper.insert(wxAccount);
wxMpConfigDataProducer.sendDictDataRefreshMessage();
// 返回
return wxAccount.getId();
}
@Override
public void updateWxAccount(WxAccountUpdateReqVO updateReqVO) {
// 校验存在
this.validateWxAccountExists(updateReqVO.getId());
// 更新
WxAccountDO updateObj = WxAccountConvert.INSTANCE.convert(updateReqVO);
wxAccountMapper.updateById(updateObj);
wxMpConfigDataProducer.sendDictDataRefreshMessage();
}
@Override
public void deleteWxAccount(Long id) {
// 校验存在
this.validateWxAccountExists(id);
// 删除
wxAccountMapper.deleteById(id);
wxMpConfigDataProducer.sendDictDataRefreshMessage();
}
private void validateWxAccountExists(Long id) {
if (wxAccountMapper.selectById(id) == null) {
throw exception(WX_ACCOUNT_NOT_EXISTS);
}
}
@Override
public WxAccountDO getWxAccount(Long id) {
return wxAccountMapper.selectById(id);
}
@Override
public List<WxAccountDO> getWxAccountList(Collection<Long> ids) {
return wxAccountMapper.selectBatchIds(ids);
}
@Override
public PageResult<WxAccountDO> getWxAccountPage(WxAccountPageReqVO pageReqVO) {
return wxAccountMapper.selectPage(pageReqVO);
}
@Override
public List<WxAccountDO> getWxAccountList(WxAccountExportReqVO exportReqVO) {
return wxAccountMapper.selectList(exportReqVO);
}
@Override
public WxAccountDO findBy(SFunction<WxAccountDO, ?> field, Object val) {
return wxAccountMapper.selectOne(field, val);
}
}

View File

@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.wechatMp.service.accountfans;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo.*;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.account.WxAccountDO;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.accountfans.WxAccountFansDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
/**
* 微信公众号粉丝 Service 接口
*
* @author 芋道源码
*/
public interface WxAccountFansService {
/**
* 创建微信公众号粉丝
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createWxAccountFans(@Valid WxAccountFansCreateReqVO createReqVO);
/**
* 更新微信公众号粉丝
*
* @param updateReqVO 更新信息
*/
void updateWxAccountFans(@Valid WxAccountFansUpdateReqVO updateReqVO);
/**
* 删除微信公众号粉丝
*
* @param id 编号
*/
void deleteWxAccountFans(Long id);
/**
* 获得微信公众号粉丝
*
* @param id 编号
* @return 微信公众号粉丝
*/
WxAccountFansDO getWxAccountFans(Long id);
/**
* 获得微信公众号粉丝列表
*
* @param ids 编号
* @return 微信公众号粉丝列表
*/
List<WxAccountFansDO> getWxAccountFansList(Collection<Long> ids);
/**
* 获得微信公众号粉丝分页
*
* @param pageReqVO 分页查询
* @return 微信公众号粉丝分页
*/
PageResult<WxAccountFansDO> getWxAccountFansPage(WxAccountFansPageReqVO pageReqVO);
/**
* 获得微信公众号粉丝列表, 用于 Excel 导出
*
* @param exportReqVO 查询条件
* @return 微信公众号粉丝列表
*/
List<WxAccountFansDO> getWxAccountFansList(WxAccountFansExportReqVO exportReqVO);
/**
* 查询粉丝
*
* @param sFunction
* @param val
* @return
*/
WxAccountFansDO findBy(SFunction<WxAccountFansDO, ?> sFunction, Object val);
}

View File

@ -0,0 +1,90 @@
package cn.iocoder.yudao.module.wechatMp.service.accountfans;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.module.wechatMp.controller.admin.accountfans.vo.*;
import cn.iocoder.yudao.module.wechatMp.dal.dataobject.accountfans.WxAccountFansDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.wechatMp.convert.accountfans.WxAccountFansConvert;
import cn.iocoder.yudao.module.wechatMp.dal.mysql.accountfans.WxAccountFansMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.wechatMp.enums.ErrorCodeConstants.*;
/**
* 微信公众号粉丝 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class WxAccountFansServiceImpl implements WxAccountFansService {
@Resource
private WxAccountFansMapper wxAccountFansMapper;
@Override
public Long createWxAccountFans(WxAccountFansCreateReqVO createReqVO) {
// 插入
WxAccountFansDO wxAccountFans = WxAccountFansConvert.INSTANCE.convert(createReqVO);
wxAccountFansMapper.insert(wxAccountFans);
// 返回
return wxAccountFans.getId();
}
@Override
public void updateWxAccountFans(WxAccountFansUpdateReqVO updateReqVO) {
// 校验存在
this.validateWxAccountFansExists(updateReqVO.getId());
// 更新
WxAccountFansDO updateObj = WxAccountFansConvert.INSTANCE.convert(updateReqVO);
wxAccountFansMapper.updateById(updateObj);
}
@Override
public void deleteWxAccountFans(Long id) {
// 校验存在
this.validateWxAccountFansExists(id);
// 删除
wxAccountFansMapper.deleteById(id);
}
private void validateWxAccountFansExists(Long id) {
if (wxAccountFansMapper.selectById(id) == null) {
throw exception(WX_ACCOUNT_FANS_NOT_EXISTS);
}
}
@Override
public WxAccountFansDO getWxAccountFans(Long id) {
return wxAccountFansMapper.selectById(id);
}
@Override
public List<WxAccountFansDO> getWxAccountFansList(Collection<Long> ids) {
return wxAccountFansMapper.selectBatchIds(ids);
}
@Override
public PageResult<WxAccountFansDO> getWxAccountFansPage(WxAccountFansPageReqVO pageReqVO) {
return wxAccountFansMapper.selectPage(pageReqVO);
}
@Override
public List<WxAccountFansDO> getWxAccountFansList(WxAccountFansExportReqVO exportReqVO) {
return wxAccountFansMapper.selectList(exportReqVO);
}
@Override
public WxAccountFansDO findBy(SFunction<WxAccountFansDO, ?> sFunction, Object val) {
return wxAccountFansMapper.selectOne(sFunction, val);
}
}