Commit 68ef11ee8723013380a79c3c2c41e4007caddd1a
1 parent
6fc0b3fc
mp:完善微信公众号的消息
Showing
52 changed files
with
378 additions
and
494 deletions
yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java
| @@ -15,8 +15,8 @@ public interface ErrorCodeConstants { | @@ -15,8 +15,8 @@ public interface ErrorCodeConstants { | ||
| 15 | ErrorCode ACCOUNT_CLEAR_QUOTA_FAIL = new ErrorCode(1006000001, "清空公众号的 API 配额失败,原因:{}"); | 15 | ErrorCode ACCOUNT_CLEAR_QUOTA_FAIL = new ErrorCode(1006000001, "清空公众号的 API 配额失败,原因:{}"); |
| 16 | 16 | ||
| 17 | // ========== 公众号统计 1006001000============ | 17 | // ========== 公众号统计 1006001000============ |
| 18 | - ErrorCode STATISTICS_GET_USER_SUMMARY_FAIL = new ErrorCode(1006001000, "获取用户增减数据失败,原因:{}"); | ||
| 19 | - ErrorCode STATISTICS_GET_USER_CUMULATE_FAIL = new ErrorCode(1006001001, "获得用户累计数据失败,原因:{}"); | 18 | + ErrorCode STATISTICS_GET_USER_SUMMARY_FAIL = new ErrorCode(1006001000, "获取粉丝增减数据失败,原因:{}"); |
| 19 | + ErrorCode STATISTICS_GET_USER_CUMULATE_FAIL = new ErrorCode(1006001001, "获得粉丝累计数据失败,原因:{}"); | ||
| 20 | ErrorCode STATISTICS_GET_UPSTREAM_MESSAGE_FAIL = new ErrorCode(1006001002, "获得消息发送概况数据失败,原因:{}"); | 20 | ErrorCode STATISTICS_GET_UPSTREAM_MESSAGE_FAIL = new ErrorCode(1006001002, "获得消息发送概况数据失败,原因:{}"); |
| 21 | ErrorCode STATISTICS_GET_INTERFACE_SUMMARY_FAIL = new ErrorCode(1006001003, "获得接口分析数据失败,原因:{}"); | 21 | ErrorCode STATISTICS_GET_INTERFACE_SUMMARY_FAIL = new ErrorCode(1006001003, "获得接口分析数据失败,原因:{}"); |
| 22 | 22 | ||
| @@ -28,8 +28,8 @@ public interface ErrorCodeConstants { | @@ -28,8 +28,8 @@ public interface ErrorCodeConstants { | ||
| 28 | ErrorCode TAG_GET_FAIL = new ErrorCode(1006002001, "获得标签失败,原因:{}"); | 28 | ErrorCode TAG_GET_FAIL = new ErrorCode(1006002001, "获得标签失败,原因:{}"); |
| 29 | 29 | ||
| 30 | // ========== 公众号粉丝 1006003000============ | 30 | // ========== 公众号粉丝 1006003000============ |
| 31 | - ErrorCode USER_NOT_EXISTS = new ErrorCode(1006003000, "用户不存在"); | ||
| 32 | - ErrorCode USER_UPDATE_TAG_FAIL = new ErrorCode(1006003001, "更新用户标签失败,原因:{}"); | 31 | + ErrorCode USER_NOT_EXISTS = new ErrorCode(1006003000, "粉丝不存在"); |
| 32 | + ErrorCode USER_UPDATE_TAG_FAIL = new ErrorCode(1006003001, "更新粉丝标签失败,原因:{}"); | ||
| 33 | 33 | ||
| 34 | // ========== 公众号素材 1006004000============ | 34 | // ========== 公众号素材 1006004000============ |
| 35 | ErrorCode MATERIAL_NOT_EXISTS = new ErrorCode(1006004000, "素材不存在"); | 35 | ErrorCode MATERIAL_NOT_EXISTS = new ErrorCode(1006004000, "素材不存在"); |
yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/message/MpMessageSendFromEnum.java
| @@ -12,8 +12,8 @@ import lombok.Getter; | @@ -12,8 +12,8 @@ import lombok.Getter; | ||
| 12 | @AllArgsConstructor | 12 | @AllArgsConstructor |
| 13 | public enum MpMessageSendFromEnum { | 13 | public enum MpMessageSendFromEnum { |
| 14 | 14 | ||
| 15 | - USER_TO_MP(1, "用户发送给公众号"), | ||
| 16 | - MP_TO_USER(2, "公众号发给用户"), | 15 | + USER_TO_MP(1, "粉丝发送给公众号"), |
| 16 | + MP_TO_USER(2, "公众号发给粉丝"), | ||
| 17 | ; | 17 | ; |
| 18 | 18 | ||
| 19 | /** | 19 | /** |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuBaseVO.java
| @@ -14,7 +14,7 @@ import java.util.List; | @@ -14,7 +14,7 @@ import java.util.List; | ||
| 14 | import static cn.iocoder.yudao.module.mp.framework.mp.core.util.MpUtils.*; | 14 | import static cn.iocoder.yudao.module.mp.framework.mp.core.util.MpUtils.*; |
| 15 | 15 | ||
| 16 | /** | 16 | /** |
| 17 | - * 微信菜单 Base VO,提供给添加、修改、详细的子 VO 使用 | 17 | + * 公众号菜单 Base VO,提供给添加、修改、详细的子 VO 使用 |
| 18 | * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | 18 | * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 |
| 19 | */ | 19 | */ |
| 20 | @Data | 20 | @Data |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java
| 1 | package cn.iocoder.yudao.module.mp.controller.admin.menu.vo; | 1 | package cn.iocoder.yudao.module.mp.controller.admin.menu.vo; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | ||
| 4 | import io.swagger.annotations.ApiModel; | 3 | import io.swagger.annotations.ApiModel; |
| 5 | import io.swagger.annotations.ApiModelProperty; | 4 | import io.swagger.annotations.ApiModelProperty; |
| 6 | import lombok.Data; | 5 | import lombok.Data; |
| 7 | import lombok.EqualsAndHashCode; | 6 | import lombok.EqualsAndHashCode; |
| 8 | import lombok.ToString; | 7 | import lombok.ToString; |
| 9 | 8 | ||
| 10 | -import javax.validation.constraints.NotNull; | ||
| 11 | import java.util.Date; | 9 | import java.util.Date; |
| 12 | 10 | ||
| 13 | -// TODO swagger 文档 | ||
| 14 | -@ApiModel("管理后台 - 微信菜单 Response VO") | 11 | +@ApiModel("管理后台 - 公众号菜单 Response VO") |
| 15 | @Data | 12 | @Data |
| 16 | @EqualsAndHashCode(callSuper = true) | 13 | @EqualsAndHashCode(callSuper = true) |
| 17 | @ToString(callSuper = true) | 14 | @ToString(callSuper = true) |
| 18 | public class MpMenuRespVO extends MpMenuBaseVO { | 15 | public class MpMenuRespVO extends MpMenuBaseVO { |
| 19 | 16 | ||
| 20 | - @ApiModelProperty(value = "主键", required = true) | 17 | + @ApiModelProperty(value = "主键", required = true, example = "1024") |
| 21 | private Long id; | 18 | private Long id; |
| 22 | 19 | ||
| 23 | @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") | 20 | @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") |
| 24 | - @NotNull(message = "公众号账号的编号不能为空") | ||
| 25 | private Long accountId; | 21 | private Long accountId; |
| 26 | 22 | ||
| 27 | - /** | ||
| 28 | - * 微信公众号 appid | ||
| 29 | - * | ||
| 30 | - * 冗余 {@link MpAccountDO#getAppId()} | ||
| 31 | - */ | 23 | + @ApiModelProperty(value = "公众号 appId", required = true, example = "wx1234567890ox") |
| 32 | private String appId; | 24 | private String appId; |
| 33 | 25 | ||
| 34 | @ApiModelProperty(value = "创建时间", required = true) | 26 | @ApiModelProperty(value = "创建时间", required = true) |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuSaveReqVO.java
| @@ -9,7 +9,6 @@ import javax.validation.constraints.NotEmpty; | @@ -9,7 +9,6 @@ import javax.validation.constraints.NotEmpty; | ||
| 9 | import javax.validation.constraints.NotNull; | 9 | import javax.validation.constraints.NotNull; |
| 10 | import java.util.List; | 10 | import java.util.List; |
| 11 | 11 | ||
| 12 | -// TODO 芋艿:swagger 文档 | ||
| 13 | @ApiModel("管理后台 - 公众号菜单保存 Request VO") | 12 | @ApiModel("管理后台 - 公众号菜单保存 Request VO") |
| 14 | @Data | 13 | @Data |
| 15 | public class MpMenuSaveReqVO { | 14 | public class MpMenuSaveReqVO { |
| @@ -22,9 +21,13 @@ public class MpMenuSaveReqVO { | @@ -22,9 +21,13 @@ public class MpMenuSaveReqVO { | ||
| 22 | @Valid | 21 | @Valid |
| 23 | private List<Menu> menus; | 22 | private List<Menu> menus; |
| 24 | 23 | ||
| 24 | + @ApiModel("管理后台 - 公众号菜单保存时的每个菜单") | ||
| 25 | @Data | 25 | @Data |
| 26 | public static class Menu extends MpMenuBaseVO { | 26 | public static class Menu extends MpMenuBaseVO { |
| 27 | 27 | ||
| 28 | + /** | ||
| 29 | + * 子菜单数组 | ||
| 30 | + */ | ||
| 28 | private List<Menu> children; | 31 | private List<Menu> children; |
| 29 | 32 | ||
| 30 | } | 33 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpAutoReplyController.java
| @@ -40,7 +40,7 @@ public class MpAutoReplyController { | @@ -40,7 +40,7 @@ public class MpAutoReplyController { | ||
| 40 | 40 | ||
| 41 | @GetMapping("/get") | 41 | @GetMapping("/get") |
| 42 | @ApiOperation("获得公众号自动回复") | 42 | @ApiOperation("获得公众号自动回复") |
| 43 | - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024") | 43 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) |
| 44 | @PreAuthorize("@ss.hasPermission('mp:auto-reply:query')") | 44 | @PreAuthorize("@ss.hasPermission('mp:auto-reply:query')") |
| 45 | public CommonResult<MpAutoReplyRespVO> getAutoReply(@RequestParam("id") Long id) { | 45 | public CommonResult<MpAutoReplyRespVO> getAutoReply(@RequestParam("id") Long id) { |
| 46 | MpAutoReplyDO autoReply = mpAutoReplyService.getAutoReply(id); | 46 | MpAutoReplyDO autoReply = mpAutoReplyService.getAutoReply(id); |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpMessageController.java
| @@ -29,10 +29,10 @@ public class MpMessageController { | @@ -29,10 +29,10 @@ public class MpMessageController { | ||
| 29 | private MpMessageService mpMessageService; | 29 | private MpMessageService mpMessageService; |
| 30 | 30 | ||
| 31 | @GetMapping("/page") | 31 | @GetMapping("/page") |
| 32 | - @ApiOperation("获得粉丝消息分页") | 32 | + @ApiOperation("获得公众号消息分页") |
| 33 | @PreAuthorize("@ss.hasPermission('mp:message:query')") | 33 | @PreAuthorize("@ss.hasPermission('mp:message:query')") |
| 34 | - public CommonResult<PageResult<MpMessageRespVO>> getWxFansMsgPage(@Valid MpMessagePageReqVO pageVO) { | ||
| 35 | - PageResult<MpMessageDO> pageResult = mpMessageService.getWxFansMsgPage(pageVO); | 34 | + public CommonResult<PageResult<MpMessageRespVO>> getMessagePage(@Valid MpMessagePageReqVO pageVO) { |
| 35 | + PageResult<MpMessageDO> pageResult = mpMessageService.getMessagePage(pageVO); | ||
| 36 | return success(MpMessageConvert.INSTANCE.convertPage(pageResult)); | 36 | return success(MpMessageConvert.INSTANCE.convertPage(pageResult)); |
| 37 | } | 37 | } |
| 38 | 38 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyCreateReqVO.java
| @@ -14,8 +14,8 @@ import javax.validation.constraints.NotNull; | @@ -14,8 +14,8 @@ import javax.validation.constraints.NotNull; | ||
| 14 | @ToString(callSuper = true) | 14 | @ToString(callSuper = true) |
| 15 | public class MpAutoReplyCreateReqVO extends MpAutoReplyBaseVO { | 15 | public class MpAutoReplyCreateReqVO extends MpAutoReplyBaseVO { |
| 16 | 16 | ||
| 17 | - @ApiModelProperty(value = "微信公众号 ID", required = true, example = "1024") | ||
| 18 | - @NotNull(message = "微信公众号 ID不能为空") | 17 | + @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") |
| 18 | + @NotNull(message = "公众号账号的编号不能为空") | ||
| 19 | private Long accountId; | 19 | private Long accountId; |
| 20 | 20 | ||
| 21 | } | 21 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyRespVO.java
| @@ -17,9 +17,9 @@ public class MpAutoReplyRespVO extends MpAutoReplyBaseVO { | @@ -17,9 +17,9 @@ public class MpAutoReplyRespVO extends MpAutoReplyBaseVO { | ||
| 17 | @ApiModelProperty(value = "主键", required = true, example = "1024") | 17 | @ApiModelProperty(value = "主键", required = true, example = "1024") |
| 18 | private Long id; | 18 | private Long id; |
| 19 | 19 | ||
| 20 | - @ApiModelProperty(value = "微信公众号 ID", required = true, example = "1024") | 20 | + @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") |
| 21 | private Long accountId; | 21 | private Long accountId; |
| 22 | - @ApiModelProperty(value = "微信公众号 appid", required = true, example = "wx1234567890") | 22 | + @ApiModelProperty(value = "公众号 appId", required = true, example = "wx1234567890") |
| 23 | private String appId; | 23 | private String appId; |
| 24 | 24 | ||
| 25 | @ApiModelProperty(value = "创建时间", required = true) | 25 | @ApiModelProperty(value = "创建时间", required = true) |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageBaseVO.java deleted
| 1 | -package cn.iocoder.yudao.module.mp.controller.admin.message.vo.message; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; | ||
| 4 | -import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO; | ||
| 5 | -import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; | ||
| 6 | -import cn.iocoder.yudao.module.mp.enums.message.MpMessageSendFromEnum; | ||
| 7 | -import com.baomidou.mybatisplus.annotation.TableField; | ||
| 8 | -import lombok.Data; | ||
| 9 | -import me.chanjar.weixin.common.api.WxConsts; | ||
| 10 | - | ||
| 11 | -import java.util.List; | ||
| 12 | - | ||
| 13 | -// TODO 芋艿:VO 的注解 | ||
| 14 | -/** | ||
| 15 | - * 粉丝消息 Base VO,提供给添加、修改、详细的子 VO 使用 | ||
| 16 | - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | ||
| 17 | - */ | ||
| 18 | -@Data | ||
| 19 | -public class MpMessageBaseVO { | ||
| 20 | - | ||
| 21 | - /** | ||
| 22 | - * 微信公众号消息 id | ||
| 23 | - */ | ||
| 24 | - private Long msgId; | ||
| 25 | - /** | ||
| 26 | - * 微信公众号 ID | ||
| 27 | - * | ||
| 28 | - * 关联 {@link MpAccountDO#getId()} | ||
| 29 | - */ | ||
| 30 | - private Long accountId; | ||
| 31 | - /** | ||
| 32 | - * 微信公众号 appid | ||
| 33 | - * | ||
| 34 | - * 冗余 {@link MpAccountDO#getAppId()} | ||
| 35 | - */ | ||
| 36 | - private String appId; | ||
| 37 | - /** | ||
| 38 | - * 微信用户编号 | ||
| 39 | - * | ||
| 40 | - * 关联 {@link MpUserDO#getId()} | ||
| 41 | - */ | ||
| 42 | - private Long userId; | ||
| 43 | - /** | ||
| 44 | - * 用户标识 | ||
| 45 | - * | ||
| 46 | - * 冗余 {@link MpUserDO#getOpenid()} | ||
| 47 | - */ | ||
| 48 | - private String openid; | ||
| 49 | - | ||
| 50 | - /** | ||
| 51 | - * 消息类型 | ||
| 52 | - * | ||
| 53 | - * 枚举 {@link WxConsts.XmlMsgType} | ||
| 54 | - */ | ||
| 55 | - private String type; | ||
| 56 | - /** | ||
| 57 | - * 消息来源 | ||
| 58 | - * | ||
| 59 | - * 枚举 {@link MpMessageSendFromEnum} | ||
| 60 | - */ | ||
| 61 | - private Integer sendFrom; | ||
| 62 | - | ||
| 63 | - // ========= 普通消息内容 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html | ||
| 64 | - | ||
| 65 | - /** | ||
| 66 | - * 消息内容 | ||
| 67 | - * | ||
| 68 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 TEXT | ||
| 69 | - */ | ||
| 70 | - private String content; | ||
| 71 | - | ||
| 72 | - /** | ||
| 73 | - * 通过素材管理中的接口上传多媒体文件,得到的 id | ||
| 74 | - * | ||
| 75 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 IMAGE、VOICE、VIDEO | ||
| 76 | - */ | ||
| 77 | - private String mediaId; | ||
| 78 | - /** | ||
| 79 | - * 媒体文件的 URL | ||
| 80 | - */ | ||
| 81 | - private String mediaUrl; | ||
| 82 | - /** | ||
| 83 | - * 语音识别后文本 | ||
| 84 | - * | ||
| 85 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 VOICE | ||
| 86 | - */ | ||
| 87 | - private String recognition; | ||
| 88 | - /** | ||
| 89 | - * 语音格式,如 amr,speex 等 | ||
| 90 | - * | ||
| 91 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 VOICE | ||
| 92 | - */ | ||
| 93 | - private String format; | ||
| 94 | - /** | ||
| 95 | - * 标题 | ||
| 96 | - * | ||
| 97 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 VIDEO、MUSIC、LINK | ||
| 98 | - */ | ||
| 99 | - private String title; | ||
| 100 | - /** | ||
| 101 | - * 描述 | ||
| 102 | - * | ||
| 103 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 VIDEO、MUSIC | ||
| 104 | - */ | ||
| 105 | - private String description; | ||
| 106 | - | ||
| 107 | - /** | ||
| 108 | - * 缩略图的媒体 id,通过素材管理中的接口上传多媒体文件,得到的 id | ||
| 109 | - * | ||
| 110 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 VIDEO | ||
| 111 | - */ | ||
| 112 | - private String thumbMediaId; | ||
| 113 | - /** | ||
| 114 | - * 缩略图的媒体 URL | ||
| 115 | - * | ||
| 116 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 VIDEO | ||
| 117 | - */ | ||
| 118 | - private String thumbMediaUrl; | ||
| 119 | - | ||
| 120 | - /** | ||
| 121 | - * 点击图文消息跳转链接 | ||
| 122 | - * | ||
| 123 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 LINK | ||
| 124 | - */ | ||
| 125 | - private String url; | ||
| 126 | - | ||
| 127 | - /** | ||
| 128 | - * 地理位置维度 | ||
| 129 | - * | ||
| 130 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 LOCATION | ||
| 131 | - */ | ||
| 132 | - private Double locationX; | ||
| 133 | - /** | ||
| 134 | - * 地理位置经度 | ||
| 135 | - * | ||
| 136 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 LOCATION | ||
| 137 | - */ | ||
| 138 | - private Double locationY; | ||
| 139 | - /** | ||
| 140 | - * 地图缩放大小 | ||
| 141 | - * | ||
| 142 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 LOCATION | ||
| 143 | - */ | ||
| 144 | - private Double scale; | ||
| 145 | - /** | ||
| 146 | - * 详细地址 | ||
| 147 | - * | ||
| 148 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 LOCATION | ||
| 149 | - * | ||
| 150 | - * 例如说杨浦区黄兴路 221-4 号临 | ||
| 151 | - */ | ||
| 152 | - private String label; | ||
| 153 | - | ||
| 154 | - /** | ||
| 155 | - * 图文消息数组 | ||
| 156 | - * | ||
| 157 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS | ||
| 158 | - */ | ||
| 159 | - @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) | ||
| 160 | - private List<MpMessageDO.Article> articles; | ||
| 161 | - | ||
| 162 | - /** | ||
| 163 | - * 音乐链接 | ||
| 164 | - * | ||
| 165 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC | ||
| 166 | - */ | ||
| 167 | - private String musicUrl; | ||
| 168 | - /** | ||
| 169 | - * 高质量音乐链接 | ||
| 170 | - * | ||
| 171 | - * WIFI 环境优先使用该链接播放音乐 | ||
| 172 | - * | ||
| 173 | - * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC | ||
| 174 | - */ | ||
| 175 | - private String hqMusicUrl; | ||
| 176 | - | ||
| 177 | - // ========= 事件推送 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html | ||
| 178 | - | ||
| 179 | - /** | ||
| 180 | - * 事件类型 | ||
| 181 | - * | ||
| 182 | - * 枚举 {@link WxConsts.EventType} | ||
| 183 | - */ | ||
| 184 | - private String event; | ||
| 185 | - /** | ||
| 186 | - * 事件 Key | ||
| 187 | - * | ||
| 188 | - * 1. {@link WxConsts.EventType} 的 SCAN:qrscene_ 为前缀,后面为二维码的参数值 | ||
| 189 | - * 2. {@link WxConsts.EventType} 的 CLICK:与自定义菜单接口中 KEY 值对应 | ||
| 190 | - */ | ||
| 191 | - private String eventKey; | ||
| 192 | - | ||
| 193 | -} |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessagePageReqVO.java
| @@ -4,23 +4,31 @@ import lombok.*; | @@ -4,23 +4,31 @@ import lombok.*; | ||
| 4 | 4 | ||
| 5 | import io.swagger.annotations.*; | 5 | import io.swagger.annotations.*; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 7 | +import org.springframework.format.annotation.DateTimeFormat; | ||
| 7 | 8 | ||
| 8 | -@ApiModel("管理后台 - 粉丝消息分页 Request VO") | 9 | +import javax.validation.constraints.NotNull; |
| 10 | +import java.time.LocalDateTime; | ||
| 11 | + | ||
| 12 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 13 | + | ||
| 14 | +@ApiModel("管理后台 - 公众号消息分页 Request VO") | ||
| 9 | @Data | 15 | @Data |
| 10 | @EqualsAndHashCode(callSuper = true) | 16 | @EqualsAndHashCode(callSuper = true) |
| 11 | @ToString(callSuper = true) | 17 | @ToString(callSuper = true) |
| 12 | public class MpMessagePageReqVO extends PageParam { | 18 | public class MpMessagePageReqVO extends PageParam { |
| 13 | 19 | ||
| 14 | - @ApiModelProperty(value = "用户标识") | ||
| 15 | - private String openId; | ||
| 16 | - | ||
| 17 | - @ApiModelProperty(value = "昵称") | ||
| 18 | - private String nickname; | ||
| 19 | - | ||
| 20 | - @ApiModelProperty(value = "微信账号ID") | 20 | + @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") |
| 21 | + @NotNull(message = "公众号账号的编号不能为空") | ||
| 21 | private Long accountId; | 22 | private Long accountId; |
| 22 | 23 | ||
| 23 | - @ApiModelProperty(value = "消息类型") | 24 | + @ApiModelProperty(value = "消息类型", example = "text", notes = "参见 WxConsts.XmlMsgType 枚举") |
| 24 | private String type; | 25 | private String type; |
| 25 | 26 | ||
| 27 | + @ApiModelProperty(value = "公众号粉丝标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") | ||
| 28 | + private String openid; | ||
| 29 | + | ||
| 30 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 31 | + @ApiModelProperty(value = "创建时间") | ||
| 32 | + private LocalDateTime[] createTime; | ||
| 33 | + | ||
| 26 | } | 34 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageRespVO.java
| 1 | package cn.iocoder.yudao.module.mp.controller.admin.message.vo.message; | 1 | package cn.iocoder.yudao.module.mp.controller.admin.message.vo.message; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.TableField; | ||
| 3 | import io.swagger.annotations.ApiModel; | 5 | import io.swagger.annotations.ApiModel; |
| 4 | import io.swagger.annotations.ApiModelProperty; | 6 | import io.swagger.annotations.ApiModelProperty; |
| 5 | import lombok.Data; | 7 | import lombok.Data; |
| 6 | -import lombok.EqualsAndHashCode; | ||
| 7 | -import lombok.ToString; | 8 | +import me.chanjar.weixin.common.api.WxConsts; |
| 8 | 9 | ||
| 9 | import java.util.Date; | 10 | import java.util.Date; |
| 11 | +import java.util.List; | ||
| 10 | 12 | ||
| 11 | -@ApiModel("管理后台 - 粉丝消息 Response VO") | 13 | +@ApiModel("管理后台 - 公众号消息 Response VO") |
| 12 | @Data | 14 | @Data |
| 13 | -@EqualsAndHashCode(callSuper = true) | ||
| 14 | -@ToString(callSuper = true) | ||
| 15 | -public class MpMessageRespVO extends MpMessageBaseVO { | 15 | +public class MpMessageRespVO { |
| 16 | 16 | ||
| 17 | - @ApiModelProperty(value = "主键", required = true) | 17 | + @ApiModelProperty(value = "主键", required = true, example = "1024") |
| 18 | private Integer id; | 18 | private Integer id; |
| 19 | 19 | ||
| 20 | + @ApiModelProperty(value = "微信公众号消息 id", required = true, example = "23953173569869169") | ||
| 21 | + private Long msgId; | ||
| 22 | + | ||
| 23 | + @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1") | ||
| 24 | + private Long accountId; | ||
| 25 | + @ApiModelProperty(value = "公众号账号的 appid", required = true, example = "wx1234567890") | ||
| 26 | + private String appId; | ||
| 27 | + | ||
| 28 | + @ApiModelProperty(value = "公众号粉丝编号", required = true, example = "2048") | ||
| 29 | + private Long userId; | ||
| 30 | + @ApiModelProperty(value = "公众号粉丝标志", required = true, example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") | ||
| 31 | + private String openid; | ||
| 32 | + | ||
| 33 | + @ApiModelProperty(value = "消息类型", required = true, example = "text", notes = "参见 WxConsts.XmlMsgType 枚举") | ||
| 34 | + private String type; | ||
| 35 | + @ApiModelProperty(value = "消息来源", required = true, example = "1", notes = "参见 MpMessageSendFromEnum 枚举") | ||
| 36 | + private Integer sendFrom; | ||
| 37 | + | ||
| 38 | + // ========= 普通消息内容 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html | ||
| 39 | + | ||
| 40 | + @ApiModelProperty(value = "消息内容", example = "你好呀", notes = "消息类型为 text 时,才有值") | ||
| 41 | + private String content; | ||
| 42 | + | ||
| 43 | + @ApiModelProperty(value = "媒体素材的编号", example = "1234567890", notes = "消息类型为 image、voice、video 时,才有值") | ||
| 44 | + private String mediaId; | ||
| 45 | + @ApiModelProperty(value = "媒体文件的 URL", example = "https://www.iocoder.cn/xxx.png", | ||
| 46 | + notes = "消息类型为 image、voice、video 时,才有值") | ||
| 47 | + private String mediaUrl; | ||
| 48 | + | ||
| 49 | + @ApiModelProperty(value = "语音识别后文本", example = "语音识别后文本", notes = "消息类型为 voice 时,才有值") | ||
| 50 | + private String recognition; | ||
| 51 | + @ApiModelProperty(value = "语音格式", example = "amr", notes = "消息类型为 voice 时,才有值") | ||
| 52 | + private String format; | ||
| 53 | + | ||
| 54 | + @ApiModelProperty(value = "标题", example = "我是标题", notes = "消息类型为 video、music、link 时,才有值") | ||
| 55 | + private String title; | ||
| 56 | + | ||
| 57 | + @ApiModelProperty(value = "描述", example = "我是描述", notes = "消息类型为 video、music 时,才有值") | ||
| 58 | + private String description; | ||
| 59 | + | ||
| 60 | + @ApiModelProperty(value = "缩略图的媒体 id", example = "1234567890", notes = "消息类型为 video、music 时,才有值") | ||
| 61 | + private String thumbMediaId; | ||
| 62 | + @ApiModelProperty(value = "缩略图的媒体 URL", example = "https://www.iocoder.cn/xxx.png", | ||
| 63 | + notes = "消息类型为 video、music 时,才有值") | ||
| 64 | + private String thumbMediaUrl; | ||
| 65 | + | ||
| 66 | + @ApiModelProperty(value = "点击图文消息跳转链接", example = "https://www.iocoder.cn", notes = "消息类型为 link 时,才有值") | ||
| 67 | + private String url; | ||
| 68 | + | ||
| 69 | + @ApiModelProperty(value = "地理位置维度", example = "23.137466", notes = "消息类型为 location 时,才有值") | ||
| 70 | + private Double locationX; | ||
| 71 | + | ||
| 72 | + @ApiModelProperty(value = "地理位置经度", example = "113.352425", notes = "消息类型为 location 时,才有值") | ||
| 73 | + private Double locationY; | ||
| 74 | + | ||
| 75 | + @ApiModelProperty(value = "地图缩放大小", example = "13", notes = "消息类型为 location 时,才有值") | ||
| 76 | + private Double scale; | ||
| 77 | + | ||
| 78 | + @ApiModelProperty(value = "详细地址", example = "杨浦区黄兴路 221-4 号临", notes = "消息类型为 location 时,才有值") | ||
| 79 | + private String label; | ||
| 80 | + | ||
| 81 | + /** | ||
| 82 | + * 图文消息数组 | ||
| 83 | + * | ||
| 84 | + * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS | ||
| 85 | + */ | ||
| 86 | + @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) | ||
| 87 | + private List<MpMessageDO.Article> articles; | ||
| 88 | + | ||
| 89 | + @ApiModelProperty(value = "音乐链接", example = "https://www.iocoder.cn/xxx.mp3", notes = "消息类型为 music 时,才有值") | ||
| 90 | + private String musicUrl; | ||
| 91 | + @ApiModelProperty(value = "高质量音乐链接", example = "https://www.iocoder.cn/xxx.mp3", notes = "消息类型为 music 时,才有值") | ||
| 92 | + private String hqMusicUrl; | ||
| 93 | + | ||
| 94 | + // ========= 事件推送 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html | ||
| 95 | + | ||
| 96 | + @ApiModelProperty(value = "事件类型", example = "subscribe", notes = "参见 WxConsts.EventType 枚举") | ||
| 97 | + private String event; | ||
| 98 | + @ApiModelProperty(value = "事件 Key", example = "qrscene_123456", notes = "参见 WxConsts.EventType 枚举") | ||
| 99 | + private String eventKey; | ||
| 100 | + | ||
| 20 | @ApiModelProperty(value = "创建时间", required = true) | 101 | @ApiModelProperty(value = "创建时间", required = true) |
| 21 | private Date createTime; | 102 | private Date createTime; |
| 22 | 103 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenHandleMessageReqVO.java
| @@ -4,7 +4,6 @@ package cn.iocoder.yudao.module.mp.controller.admin.open.vo; | @@ -4,7 +4,6 @@ package cn.iocoder.yudao.module.mp.controller.admin.open.vo; | ||
| 4 | import io.swagger.annotations.ApiModel; | 4 | import io.swagger.annotations.ApiModel; |
| 5 | import io.swagger.annotations.ApiModelProperty; | 5 | import io.swagger.annotations.ApiModelProperty; |
| 6 | import lombok.Data; | 6 | import lombok.Data; |
| 7 | -import org.springframework.web.bind.annotation.RequestParam; | ||
| 8 | 7 | ||
| 9 | import javax.validation.constraints.NotEmpty; | 8 | import javax.validation.constraints.NotEmpty; |
| 10 | 9 | ||
| @@ -26,8 +25,8 @@ public class MpOpenHandleMessageReqVO { | @@ -26,8 +25,8 @@ public class MpOpenHandleMessageReqVO { | ||
| 26 | @NotEmpty(message = "随机数不能为空") | 25 | @NotEmpty(message = "随机数不能为空") |
| 27 | private String nonce; | 26 | private String nonce; |
| 28 | 27 | ||
| 29 | - @ApiModelProperty(value = "用户 openid", required = true, example = "oz-Jdtyn-WGm4C4I5Z-nvBMO_ZfY") | ||
| 30 | - @NotEmpty(message = "用户 openid 不能为空") | 28 | + @ApiModelProperty(value = "粉丝 openid", required = true, example = "oz-Jdtyn-WGm4C4I5Z-nvBMO_ZfY") |
| 29 | + @NotEmpty(message = "粉丝 openid 不能为空") | ||
| 31 | private String openid; | 30 | private String openid; |
| 32 | 31 | ||
| 33 | @ApiModelProperty(value = "消息加密类型", example = "aes") | 32 | @ApiModelProperty(value = "消息加密类型", example = "aes") |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/MpStatisticsController.java
| @@ -31,7 +31,7 @@ public class MpStatisticsController { | @@ -31,7 +31,7 @@ public class MpStatisticsController { | ||
| 31 | private MpStatisticsService mpStatisticsService; | 31 | private MpStatisticsService mpStatisticsService; |
| 32 | 32 | ||
| 33 | @GetMapping("/user-summary") | 33 | @GetMapping("/user-summary") |
| 34 | - @ApiOperation("获得用户增减数据") | 34 | + @ApiOperation("获得粉丝增减数据") |
| 35 | @PreAuthorize("@ss.hasPermission('mp:statistics:query')") | 35 | @PreAuthorize("@ss.hasPermission('mp:statistics:query')") |
| 36 | public CommonResult<List<MpStatisticsUserSummaryRespVO>> getUserSummary(MpStatisticsGetReqVO getReqVO) { | 36 | public CommonResult<List<MpStatisticsUserSummaryRespVO>> getUserSummary(MpStatisticsGetReqVO getReqVO) { |
| 37 | List<WxDataCubeUserSummary> list = mpStatisticsService.getUserSummary( | 37 | List<WxDataCubeUserSummary> list = mpStatisticsService.getUserSummary( |
| @@ -40,7 +40,7 @@ public class MpStatisticsController { | @@ -40,7 +40,7 @@ public class MpStatisticsController { | ||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | @GetMapping("/user-cumulate") | 42 | @GetMapping("/user-cumulate") |
| 43 | - @ApiOperation("获得用户累计数据") | 43 | + @ApiOperation("获得粉丝累计数据") |
| 44 | @PreAuthorize("@ss.hasPermission('mp:statistics:query')") | 44 | @PreAuthorize("@ss.hasPermission('mp:statistics:query')") |
| 45 | public CommonResult<List<MpStatisticsUserCumulateRespVO>> getUserCumulate(MpStatisticsGetReqVO getReqVO) { | 45 | public CommonResult<List<MpStatisticsUserCumulateRespVO>> getUserCumulate(MpStatisticsGetReqVO getReqVO) { |
| 46 | List<WxDataCubeUserCumulate> list = mpStatisticsService.getUserCumulate( | 46 | List<WxDataCubeUserCumulate> list = mpStatisticsService.getUserCumulate( |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsInterfaceSummaryRespVO.java
| @@ -13,7 +13,7 @@ public class MpStatisticsInterfaceSummaryRespVO { | @@ -13,7 +13,7 @@ public class MpStatisticsInterfaceSummaryRespVO { | ||
| 13 | @ApiModelProperty(value = "日期", required = true) | 13 | @ApiModelProperty(value = "日期", required = true) |
| 14 | private Date refDate; | 14 | private Date refDate; |
| 15 | 15 | ||
| 16 | - @ApiModelProperty(value = "通过服务器配置地址获得消息后,被动回复用户消息的次数", required = true, example = "10") | 16 | + @ApiModelProperty(value = "通过服务器配置地址获得消息后,被动回复粉丝消息的次数", required = true, example = "10") |
| 17 | private Integer callbackCount; | 17 | private Integer callbackCount; |
| 18 | 18 | ||
| 19 | @ApiModelProperty(value = "上述动作的失败次数", required = true, example = "20") | 19 | @ApiModelProperty(value = "上述动作的失败次数", required = true, example = "20") |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUpstreamMessageRespVO.java
| @@ -6,14 +6,14 @@ import lombok.Data; | @@ -6,14 +6,14 @@ import lombok.Data; | ||
| 6 | 6 | ||
| 7 | import java.util.Date; | 7 | import java.util.Date; |
| 8 | 8 | ||
| 9 | -@ApiModel("管理后台 - 某一天的用户增减数据 Response VO") | 9 | +@ApiModel("管理后台 - 某一天的粉丝增减数据 Response VO") |
| 10 | @Data | 10 | @Data |
| 11 | public class MpStatisticsUpstreamMessageRespVO { | 11 | public class MpStatisticsUpstreamMessageRespVO { |
| 12 | 12 | ||
| 13 | @ApiModelProperty(value = "日期", required = true) | 13 | @ApiModelProperty(value = "日期", required = true) |
| 14 | private Date refDate; | 14 | private Date refDate; |
| 15 | 15 | ||
| 16 | - @ApiModelProperty(value = "上行发送了(向公众号发送了)消息的用户数", required = true, example = "10") | 16 | + @ApiModelProperty(value = "上行发送了(向公众号发送了)消息的粉丝数", required = true, example = "10") |
| 17 | private Integer messageUser; | 17 | private Integer messageUser; |
| 18 | 18 | ||
| 19 | @ApiModelProperty(value = "上行发送了消息的消息总数", required = true, example = "20") | 19 | @ApiModelProperty(value = "上行发送了消息的消息总数", required = true, example = "20") |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserCumulateRespVO.java
| @@ -13,7 +13,7 @@ public class MpStatisticsUserCumulateRespVO { | @@ -13,7 +13,7 @@ public class MpStatisticsUserCumulateRespVO { | ||
| 13 | @ApiModelProperty(value = "日期", required = true) | 13 | @ApiModelProperty(value = "日期", required = true) |
| 14 | private Date refDate; | 14 | private Date refDate; |
| 15 | 15 | ||
| 16 | - @ApiModelProperty(value = "累计用户量", required = true, example = "10") | 16 | + @ApiModelProperty(value = "累计粉丝量", required = true, example = "10") |
| 17 | private Integer cumulateUser; | 17 | private Integer cumulateUser; |
| 18 | 18 | ||
| 19 | } | 19 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserSummaryRespVO.java
| @@ -6,20 +6,20 @@ import lombok.Data; | @@ -6,20 +6,20 @@ import lombok.Data; | ||
| 6 | 6 | ||
| 7 | import java.util.Date; | 7 | import java.util.Date; |
| 8 | 8 | ||
| 9 | -@ApiModel("管理后台 - 某一天的用户增减数据 Response VO") | 9 | +@ApiModel("管理后台 - 某一天的粉丝增减数据 Response VO") |
| 10 | @Data | 10 | @Data |
| 11 | public class MpStatisticsUserSummaryRespVO { | 11 | public class MpStatisticsUserSummaryRespVO { |
| 12 | 12 | ||
| 13 | @ApiModelProperty(value = "日期", required = true) | 13 | @ApiModelProperty(value = "日期", required = true) |
| 14 | private Date refDate; | 14 | private Date refDate; |
| 15 | 15 | ||
| 16 | - @ApiModelProperty(value = "用户来源", required = true, example = "0") | 16 | + @ApiModelProperty(value = "粉丝来源", required = true, example = "0") |
| 17 | private Integer userSource; | 17 | private Integer userSource; |
| 18 | 18 | ||
| 19 | - @ApiModelProperty(value = "新关注的用户数量", required = true, example = "10") | 19 | + @ApiModelProperty(value = "新关注的粉丝数量", required = true, example = "10") |
| 20 | private Integer newUser; | 20 | private Integer newUser; |
| 21 | 21 | ||
| 22 | - @ApiModelProperty(value = "取消关注的用户数量", required = true, example = "20") | 22 | + @ApiModelProperty(value = "取消关注的粉丝数量", required = true, example = "20") |
| 23 | private Integer cancelUser; | 23 | private Integer cancelUser; |
| 24 | 24 | ||
| 25 | } | 25 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserPageReqVO.java
| @@ -19,10 +19,10 @@ public class MpUserPageReqVO extends PageParam { | @@ -19,10 +19,10 @@ public class MpUserPageReqVO extends PageParam { | ||
| 19 | @NotNull(message = "公众号账号的编号不能为空") | 19 | @NotNull(message = "公众号账号的编号不能为空") |
| 20 | private Long accountId; | 20 | private Long accountId; |
| 21 | 21 | ||
| 22 | - @ApiModelProperty(value = "公众号用户标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", notes = "模糊匹配") | 22 | + @ApiModelProperty(value = "公众号粉丝标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", notes = "模糊匹配") |
| 23 | private String openid; | 23 | private String openid; |
| 24 | 24 | ||
| 25 | - @ApiModelProperty(value = "公众号用户昵称", example = "芋艿", notes = "模糊匹配") | 25 | + @ApiModelProperty(value = "公众号粉丝昵称", example = "芋艿", notes = "模糊匹配") |
| 26 | private String nickname; | 26 | private String nickname; |
| 27 | 27 | ||
| 28 | } | 28 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserRespVO.java
| @@ -15,7 +15,7 @@ public class MpUserRespVO { | @@ -15,7 +15,7 @@ public class MpUserRespVO { | ||
| 15 | @ApiModelProperty(value = "编号", required = true, example = "1024") | 15 | @ApiModelProperty(value = "编号", required = true, example = "1024") |
| 16 | private Long id; | 16 | private Long id; |
| 17 | 17 | ||
| 18 | - @ApiModelProperty(value = "公众号用户标识", required = true, example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") | 18 | + @ApiModelProperty(value = "公众号粉丝标识", required = true, example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") |
| 19 | private String openid; | 19 | private String openid; |
| 20 | 20 | ||
| 21 | @ApiModelProperty(value = "关注状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") | 21 | @ApiModelProperty(value = "关注状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/material/MpMaterialDO.java
| @@ -32,13 +32,13 @@ public class MpMaterialDO extends BaseDO { | @@ -32,13 +32,13 @@ public class MpMaterialDO extends BaseDO { | ||
| 32 | @TableId | 32 | @TableId |
| 33 | private Long id; | 33 | private Long id; |
| 34 | /** | 34 | /** |
| 35 | - * 微信公众号 ID | 35 | + * 公众号账号的编号 |
| 36 | * | 36 | * |
| 37 | * 关联 {@link MpAccountDO#getId()} | 37 | * 关联 {@link MpAccountDO#getId()} |
| 38 | */ | 38 | */ |
| 39 | private Long accountId; | 39 | private Long accountId; |
| 40 | /** | 40 | /** |
| 41 | - * 微信公众号 appid | 41 | + * 公众号 appId |
| 42 | * | 42 | * |
| 43 | * 冗余 {@link MpAccountDO#getAppId()} | 43 | * 冗余 {@link MpAccountDO#getAppId()} |
| 44 | */ | 44 | */ |
| @@ -71,8 +71,8 @@ public class MpMaterialDO extends BaseDO { | @@ -71,8 +71,8 @@ public class MpMaterialDO extends BaseDO { | ||
| 71 | * | 71 | * |
| 72 | * 永久素材:非空 | 72 | * 永久素材:非空 |
| 73 | * 临时素材:可能为空。 | 73 | * 临时素材:可能为空。 |
| 74 | - * 1. 为空的情况:用户主动发送的图片、语音等 | ||
| 75 | - * 2. 非空的情况:主动发送给用户的图片、语音等 | 74 | + * 1. 为空的情况:粉丝主动发送的图片、语音等 |
| 75 | + * 2. 非空的情况:主动发送给粉丝的图片、语音等 | ||
| 76 | */ | 76 | */ |
| 77 | private String name; | 77 | private String name; |
| 78 | 78 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/menu/MpMenuDO.java
| @@ -16,7 +16,7 @@ import me.chanjar.weixin.common.api.WxConsts.MenuButtonType; | @@ -16,7 +16,7 @@ import me.chanjar.weixin.common.api.WxConsts.MenuButtonType; | ||
| 16 | import java.util.List; | 16 | import java.util.List; |
| 17 | 17 | ||
| 18 | /** | 18 | /** |
| 19 | - * 微信菜单 DO | 19 | + * 公众号菜单 DO |
| 20 | * | 20 | * |
| 21 | * @author 芋道源码 | 21 | * @author 芋道源码 |
| 22 | */ | 22 | */ |
| @@ -38,13 +38,13 @@ public class MpMenuDO extends BaseDO { | @@ -38,13 +38,13 @@ public class MpMenuDO extends BaseDO { | ||
| 38 | @TableId | 38 | @TableId |
| 39 | private Long id; | 39 | private Long id; |
| 40 | /** | 40 | /** |
| 41 | - * 微信公众号 ID | 41 | + * 公众号账号的编号 |
| 42 | * | 42 | * |
| 43 | * 关联 {@link MpAccountDO#getId()} | 43 | * 关联 {@link MpAccountDO#getId()} |
| 44 | */ | 44 | */ |
| 45 | private Long accountId; | 45 | private Long accountId; |
| 46 | /** | 46 | /** |
| 47 | - * 微信公众号 appid | 47 | + * 公众号 appId |
| 48 | * | 48 | * |
| 49 | * 冗余 {@link MpAccountDO#getAppId()} | 49 | * 冗余 {@link MpAccountDO#getAppId()} |
| 50 | */ | 50 | */ |
| @@ -77,7 +77,7 @@ public class MpMenuDO extends BaseDO { | @@ -77,7 +77,7 @@ public class MpMenuDO extends BaseDO { | ||
| 77 | /** | 77 | /** |
| 78 | * 网页链接 | 78 | * 网页链接 |
| 79 | * | 79 | * |
| 80 | - * 用户点击菜单可打开链接,不超过 1024 字节 | 80 | + * 粉丝点击菜单可打开链接,不超过 1024 字节 |
| 81 | * | 81 | * |
| 82 | * 类型为 {@link WxConsts.XmlMsgType} 的 VIEW、MINIPROGRAM | 82 | * 类型为 {@link WxConsts.XmlMsgType} 的 VIEW、MINIPROGRAM |
| 83 | */ | 83 | */ |
| @@ -146,13 +146,13 @@ public class MpMenuDO extends BaseDO { | @@ -146,13 +146,13 @@ public class MpMenuDO extends BaseDO { | ||
| 146 | private String replyDescription; | 146 | private String replyDescription; |
| 147 | 147 | ||
| 148 | /** | 148 | /** |
| 149 | - * 缩略图的媒体 id,通过素材管理中的接口上传多媒体文件,得到的 id | 149 | + * 回复的缩略图的媒体 id,通过素材管理中的接口上传多媒体文件,得到的 id |
| 150 | * | 150 | * |
| 151 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC、VIDEO | 151 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC、VIDEO |
| 152 | */ | 152 | */ |
| 153 | private String replyThumbMediaId; | 153 | private String replyThumbMediaId; |
| 154 | /** | 154 | /** |
| 155 | - * 缩略图的媒体 URL | 155 | + * 回复的缩略图的媒体 URL |
| 156 | * | 156 | * |
| 157 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC、VIDEO | 157 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC、VIDEO |
| 158 | */ | 158 | */ |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/message/MpAutoReplyDO.java
| @@ -40,13 +40,13 @@ public class MpAutoReplyDO extends BaseDO { | @@ -40,13 +40,13 @@ public class MpAutoReplyDO extends BaseDO { | ||
| 40 | @TableId | 40 | @TableId |
| 41 | private Long id; | 41 | private Long id; |
| 42 | /** | 42 | /** |
| 43 | - * 微信公众号 ID | 43 | + * 公众号账号的编号 |
| 44 | * | 44 | * |
| 45 | * 关联 {@link MpAccountDO#getId()} | 45 | * 关联 {@link MpAccountDO#getId()} |
| 46 | */ | 46 | */ |
| 47 | private Long accountId; | 47 | private Long accountId; |
| 48 | /** | 48 | /** |
| 49 | - * 微信公众号 appid | 49 | + * 公众号 appId |
| 50 | * | 50 | * |
| 51 | * 冗余 {@link MpAccountDO#getAppId()} | 51 | * 冗余 {@link MpAccountDO#getAppId()} |
| 52 | */ | 52 | */ |
| @@ -126,6 +126,19 @@ public class MpAutoReplyDO extends BaseDO { | @@ -126,6 +126,19 @@ public class MpAutoReplyDO extends BaseDO { | ||
| 126 | private String responseDescription; | 126 | private String responseDescription; |
| 127 | 127 | ||
| 128 | /** | 128 | /** |
| 129 | + * 回复的缩略图的媒体 id,通过素材管理中的接口上传多媒体文件,得到的 id | ||
| 130 | + * | ||
| 131 | + * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC、VIDEO | ||
| 132 | + */ | ||
| 133 | + private String responseThumbMediaId; | ||
| 134 | + /** | ||
| 135 | + * 回复的缩略图的媒体 URL | ||
| 136 | + * | ||
| 137 | + * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC、VIDEO | ||
| 138 | + */ | ||
| 139 | + private String responseThumbMediaUrl; | ||
| 140 | + | ||
| 141 | + /** | ||
| 129 | * 回复的图文消息 | 142 | * 回复的图文消息 |
| 130 | * | 143 | * |
| 131 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS | 144 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS |
| @@ -133,4 +146,19 @@ public class MpAutoReplyDO extends BaseDO { | @@ -133,4 +146,19 @@ public class MpAutoReplyDO extends BaseDO { | ||
| 133 | @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) | 146 | @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) |
| 134 | private List<MpMessageDO.Article> responseArticles; | 147 | private List<MpMessageDO.Article> responseArticles; |
| 135 | 148 | ||
| 149 | + /** | ||
| 150 | + * 回复的音乐链接 | ||
| 151 | + * | ||
| 152 | + * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC | ||
| 153 | + */ | ||
| 154 | + private String responseMusicUrl; | ||
| 155 | + /** | ||
| 156 | + * 回复的高质量音乐链接 | ||
| 157 | + * | ||
| 158 | + * WIFI 环境优先使用该链接播放音乐 | ||
| 159 | + * | ||
| 160 | + * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC | ||
| 161 | + */ | ||
| 162 | + private String responseHqMusicUrl; | ||
| 163 | + | ||
| 136 | } | 164 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/message/MpMessageDO.java
| @@ -40,25 +40,25 @@ public class MpMessageDO extends BaseDO { | @@ -40,25 +40,25 @@ public class MpMessageDO extends BaseDO { | ||
| 40 | */ | 40 | */ |
| 41 | private Long msgId; | 41 | private Long msgId; |
| 42 | /** | 42 | /** |
| 43 | - * 微信公众号 ID | 43 | + * 公众号账号的 ID |
| 44 | * | 44 | * |
| 45 | * 关联 {@link MpAccountDO#getId()} | 45 | * 关联 {@link MpAccountDO#getId()} |
| 46 | */ | 46 | */ |
| 47 | private Long accountId; | 47 | private Long accountId; |
| 48 | /** | 48 | /** |
| 49 | - * 微信公众号 appid | 49 | + * 公众号 appid |
| 50 | * | 50 | * |
| 51 | * 冗余 {@link MpAccountDO#getAppId()} | 51 | * 冗余 {@link MpAccountDO#getAppId()} |
| 52 | */ | 52 | */ |
| 53 | private String appId; | 53 | private String appId; |
| 54 | /** | 54 | /** |
| 55 | - * 微信用户编号 | 55 | + * 公众号粉丝的编号 |
| 56 | * | 56 | * |
| 57 | * 关联 {@link MpUserDO#getId()} | 57 | * 关联 {@link MpUserDO#getId()} |
| 58 | */ | 58 | */ |
| 59 | private Long userId; | 59 | private Long userId; |
| 60 | /** | 60 | /** |
| 61 | - * 用户标识 | 61 | + * 公众号粉丝标志 |
| 62 | * | 62 | * |
| 63 | * 冗余 {@link MpUserDO#getOpenid()} | 63 | * 冗余 {@link MpUserDO#getOpenid()} |
| 64 | */ | 64 | */ |
| @@ -87,7 +87,7 @@ public class MpMessageDO extends BaseDO { | @@ -87,7 +87,7 @@ public class MpMessageDO extends BaseDO { | ||
| 87 | private String content; | 87 | private String content; |
| 88 | 88 | ||
| 89 | /** | 89 | /** |
| 90 | - * 通过素材管理中的接口上传多媒体文件,得到的 id | 90 | + * 媒体文件的编号 |
| 91 | * | 91 | * |
| 92 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 IMAGE、VOICE、VIDEO | 92 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 IMAGE、VOICE、VIDEO |
| 93 | */ | 93 | */ |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/tag/MpTagDO.java
| @@ -43,13 +43,13 @@ public class MpTagDO extends BaseDO { | @@ -43,13 +43,13 @@ public class MpTagDO extends BaseDO { | ||
| 43 | private Integer count; | 43 | private Integer count; |
| 44 | 44 | ||
| 45 | /** | 45 | /** |
| 46 | - * 微信公众号 ID | 46 | + * 公众号账号的编号 |
| 47 | * | 47 | * |
| 48 | * 关联 {@link MpAccountDO#getId()} | 48 | * 关联 {@link MpAccountDO#getId()} |
| 49 | */ | 49 | */ |
| 50 | private Long accountId; | 50 | private Long accountId; |
| 51 | /** | 51 | /** |
| 52 | - * 微信公众号 appid | 52 | + * 公众号 appId |
| 53 | * | 53 | * |
| 54 | * 冗余 {@link MpAccountDO#getAppId()} | 54 | * 冗余 {@link MpAccountDO#getAppId()} |
| 55 | */ | 55 | */ |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/user/MpUserDO.java
| @@ -35,7 +35,7 @@ public class MpUserDO extends BaseDO { | @@ -35,7 +35,7 @@ public class MpUserDO extends BaseDO { | ||
| 35 | @TableId | 35 | @TableId |
| 36 | private Long id; | 36 | private Long id; |
| 37 | /** | 37 | /** |
| 38 | - * 用户标识 | 38 | + * 粉丝标识 |
| 39 | */ | 39 | */ |
| 40 | private String openid; | 40 | private String openid; |
| 41 | /** | 41 | /** |
| @@ -95,13 +95,13 @@ public class MpUserDO extends BaseDO { | @@ -95,13 +95,13 @@ public class MpUserDO extends BaseDO { | ||
| 95 | private List<Long> tagIds; | 95 | private List<Long> tagIds; |
| 96 | 96 | ||
| 97 | /** | 97 | /** |
| 98 | - * 微信公众号 ID | 98 | + * 公众号账号的编号 |
| 99 | * | 99 | * |
| 100 | * 关联 {@link MpAccountDO#getId()} | 100 | * 关联 {@link MpAccountDO#getId()} |
| 101 | */ | 101 | */ |
| 102 | private Long accountId; | 102 | private Long accountId; |
| 103 | /** | 103 | /** |
| 104 | - * 微信公众号 appid | 104 | + * 公众号 appId |
| 105 | * | 105 | * |
| 106 | * 冗余 {@link MpAccountDO#getAppId()} | 106 | * 冗余 {@link MpAccountDO#getAppId()} |
| 107 | */ | 107 | */ |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/message/MpMessageMapper.java
| @@ -13,9 +13,9 @@ public interface MpMessageMapper extends BaseMapperX<MpMessageDO> { | @@ -13,9 +13,9 @@ public interface MpMessageMapper extends BaseMapperX<MpMessageDO> { | ||
| 13 | default PageResult<MpMessageDO> selectPage(MpMessagePageReqVO reqVO) { | 13 | default PageResult<MpMessageDO> selectPage(MpMessagePageReqVO reqVO) { |
| 14 | return selectPage(reqVO, new LambdaQueryWrapperX<MpMessageDO>() | 14 | return selectPage(reqVO, new LambdaQueryWrapperX<MpMessageDO>() |
| 15 | .eqIfPresent(MpMessageDO::getAccountId, reqVO.getAccountId()) | 15 | .eqIfPresent(MpMessageDO::getAccountId, reqVO.getAccountId()) |
| 16 | - .eqIfPresent(MpMessageDO::getOpenid, reqVO.getOpenId()) | ||
| 17 | -// .likeIfPresent(MpMessageDO::getNickname, reqVO.getNickname()) | ||
| 18 | .eqIfPresent(MpMessageDO::getType, reqVO.getType()) | 16 | .eqIfPresent(MpMessageDO::getType, reqVO.getType()) |
| 17 | + .eqIfPresent(MpMessageDO::getOpenid, reqVO.getOpenid()) | ||
| 18 | + .betweenIfPresent(MpMessageDO::getCreateTime, reqVO.getCreateTime()) | ||
| 19 | .orderByDesc(MpMessageDO::getId)); | 19 | .orderByDesc(MpMessageDO::getId)); |
| 20 | } | 20 | } |
| 21 | 21 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/mp/core/DefaultMpServiceFactory.java
| @@ -103,7 +103,6 @@ public class DefaultMpServiceFactory implements MpServiceFactory { | @@ -103,7 +103,6 @@ public class DefaultMpServiceFactory implements MpServiceFactory { | ||
| 103 | 103 | ||
| 104 | private WxMpService buildMpService(MpAccountDO account) { | 104 | private WxMpService buildMpService(MpAccountDO account) { |
| 105 | // 第一步,创建 WxMpRedisConfigImpl 对象 | 105 | // 第一步,创建 WxMpRedisConfigImpl 对象 |
| 106 | - // TODO 芋艿:需要确认下,redis key 的存储结构 | ||
| 107 | WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl( | 106 | WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl( |
| 108 | redisTemplateWxRedisOps, mpProperties.getConfigStorage().getKeyPrefix()); | 107 | redisTemplateWxRedisOps, mpProperties.getConfigStorage().getKeyPrefix()); |
| 109 | configStorage.setAppId(account.getAppId()); | 108 | configStorage.setAppId(account.getAppId()); |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/menu/MenuHandler.java
| @@ -18,7 +18,7 @@ import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType; | @@ -18,7 +18,7 @@ import static me.chanjar.weixin.common.api.WxConsts.MenuButtonType; | ||
| 18 | /** | 18 | /** |
| 19 | * 自定义菜单的事件处理器 | 19 | * 自定义菜单的事件处理器 |
| 20 | * | 20 | * |
| 21 | - * 逻辑:用户点击菜单时,触发对应的回复 | 21 | + * 逻辑:粉丝点击菜单时,触发对应的回复 |
| 22 | * | 22 | * |
| 23 | * @author 芋道源码 | 23 | * @author 芋道源码 |
| 24 | */ | 24 | */ |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/other/KfSessionHandler.java
| @@ -20,8 +20,7 @@ public class KfSessionHandler implements WxMpMessageHandler { | @@ -20,8 +20,7 @@ public class KfSessionHandler implements WxMpMessageHandler { | ||
| 20 | @Override | 20 | @Override |
| 21 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, | 21 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 22 | WxMpService wxMpService, WxSessionManager sessionManager) { | 22 | WxMpService wxMpService, WxSessionManager sessionManager) { |
| 23 | - // TODO 对会话做处理 | ||
| 24 | - return null; | 23 | + throw new UnsupportedOperationException("未实现该处理,请自行重写"); |
| 25 | } | 24 | } |
| 26 | 25 | ||
| 27 | } | 26 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/other/NullHandler.java
| @@ -18,7 +18,7 @@ public class NullHandler implements WxMpMessageHandler { | @@ -18,7 +18,7 @@ public class NullHandler implements WxMpMessageHandler { | ||
| 18 | @Override | 18 | @Override |
| 19 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, | 19 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 20 | WxMpService wxMpService, WxSessionManager sessionManager) { | 20 | WxMpService wxMpService, WxSessionManager sessionManager) { |
| 21 | - return null; | 21 | + throw new UnsupportedOperationException("未实现该处理,请自行重写"); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } | 24 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/other/ScanHandler.java
| @@ -17,9 +17,9 @@ import java.util.Map; | @@ -17,9 +17,9 @@ import java.util.Map; | ||
| 17 | public class ScanHandler implements WxMpMessageHandler { | 17 | public class ScanHandler implements WxMpMessageHandler { |
| 18 | 18 | ||
| 19 | @Override | 19 | @Override |
| 20 | - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map<String, Object> map, | 20 | + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map<String, Object> context, |
| 21 | WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException { | 21 | WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException { |
| 22 | - // 扫码事件处理 | ||
| 23 | - return null; | 22 | + throw new UnsupportedOperationException("未实现该处理,请自行重写"); |
| 24 | } | 23 | } |
| 24 | + | ||
| 25 | } | 25 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/other/StoreCheckNotifyHandler.java
| @@ -16,11 +16,9 @@ import java.util.Map; | @@ -16,11 +16,9 @@ import java.util.Map; | ||
| 16 | public class StoreCheckNotifyHandler implements WxMpMessageHandler { | 16 | public class StoreCheckNotifyHandler implements WxMpMessageHandler { |
| 17 | 17 | ||
| 18 | @Override | 18 | @Override |
| 19 | - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | ||
| 20 | - Map<String, Object> context, WxMpService wxMpService, | ||
| 21 | - WxSessionManager sessionManager) { | ||
| 22 | - // TODO 处理门店审核事件 | ||
| 23 | - return null; | 19 | + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 20 | + WxMpService wxMpService, WxSessionManager sessionManager) { | ||
| 21 | + throw new UnsupportedOperationException("未实现该处理,请自行重写"); | ||
| 24 | } | 22 | } |
| 25 | 23 | ||
| 26 | } | 24 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/user/LocationHandler.java
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/user/SubscribeHandler.java
| 1 | package cn.iocoder.yudao.module.mp.service.handler.user; | 1 | package cn.iocoder.yudao.module.mp.service.handler.user; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; | ||
| 4 | import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder; | 3 | import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder; |
| 5 | -import cn.iocoder.yudao.module.mp.service.account.MpAccountService; | ||
| 6 | import cn.iocoder.yudao.module.mp.service.message.MpAutoReplyService; | 4 | import cn.iocoder.yudao.module.mp.service.message.MpAutoReplyService; |
| 7 | import cn.iocoder.yudao.module.mp.service.user.MpUserService; | 5 | import cn.iocoder.yudao.module.mp.service.user.MpUserService; |
| 8 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| @@ -13,7 +11,6 @@ import me.chanjar.weixin.mp.api.WxMpService; | @@ -13,7 +11,6 @@ import me.chanjar.weixin.mp.api.WxMpService; | ||
| 13 | import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | 11 | import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; |
| 14 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | 12 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; |
| 15 | import me.chanjar.weixin.mp.bean.result.WxMpUser; | 13 | import me.chanjar.weixin.mp.bean.result.WxMpUser; |
| 16 | -import org.springframework.context.annotation.Lazy; | ||
| 17 | import org.springframework.stereotype.Component; | 14 | import org.springframework.stereotype.Component; |
| 18 | 15 | ||
| 19 | import javax.annotation.Resource; | 16 | import javax.annotation.Resource; |
| @@ -36,16 +33,16 @@ public class SubscribeHandler implements WxMpMessageHandler { | @@ -36,16 +33,16 @@ public class SubscribeHandler implements WxMpMessageHandler { | ||
| 36 | @Override | 33 | @Override |
| 37 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, | 34 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 38 | WxMpService weixinService, WxSessionManager sessionManager) throws WxErrorException { | 35 | WxMpService weixinService, WxSessionManager sessionManager) throws WxErrorException { |
| 39 | - // 第一步,从公众号平台,获取用户信息 | ||
| 40 | - log.info("[handle][用户({}) 关注]", wxMessage.getFromUser()); | 36 | + // 第一步,从公众号平台,获取粉丝信息 |
| 37 | + log.info("[handle][粉丝({}) 关注]", wxMessage.getFromUser()); | ||
| 41 | WxMpUser wxMpUser = null; | 38 | WxMpUser wxMpUser = null; |
| 42 | try { | 39 | try { |
| 43 | wxMpUser = weixinService.getUserService().userInfo(wxMessage.getFromUser()); | 40 | wxMpUser = weixinService.getUserService().userInfo(wxMessage.getFromUser()); |
| 44 | } catch (WxErrorException e) { | 41 | } catch (WxErrorException e) { |
| 45 | - log.error("[handle][用户({})] 获取用户信息失败!", wxMessage.getFromUser(), e); | 42 | + log.error("[handle][粉丝({})] 获取粉丝信息失败!", wxMessage.getFromUser(), e); |
| 46 | } | 43 | } |
| 47 | 44 | ||
| 48 | - // 第二步,保存用户信息 | 45 | + // 第二步,保存粉丝信息 |
| 49 | mpUserService.saveUser(MpContextHolder.getAppId(), wxMpUser); | 46 | mpUserService.saveUser(MpContextHolder.getAppId(), wxMpUser); |
| 50 | 47 | ||
| 51 | // 第三步,回复关注的欢迎语 | 48 | // 第三步,回复关注的欢迎语 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/user/UnsubscribeHandler.java
| @@ -31,7 +31,7 @@ public class UnsubscribeHandler implements WxMpMessageHandler { | @@ -31,7 +31,7 @@ public class UnsubscribeHandler implements WxMpMessageHandler { | ||
| 31 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | 31 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, |
| 32 | Map<String, Object> context, WxMpService wxMpService, | 32 | Map<String, Object> context, WxMpService wxMpService, |
| 33 | WxSessionManager sessionManager) { | 33 | WxSessionManager sessionManager) { |
| 34 | - log.info("[handle][用户({}) 取消关注]", wxMessage.getFromUser()); | 34 | + log.info("[handle][粉丝({}) 取消关注]", wxMessage.getFromUser()); |
| 35 | mpUserService.updateUserUnsubscribe(MpContextHolder.getAppId(), wxMessage.getFromUser()); | 35 | mpUserService.updateUserUnsubscribe(MpContextHolder.getAppId(), wxMessage.getFromUser()); |
| 36 | return null; | 36 | return null; |
| 37 | } | 37 | } |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/menu/MpMenuService.java
| @@ -29,11 +29,11 @@ public interface MpMenuService { | @@ -29,11 +29,11 @@ public interface MpMenuService { | ||
| 29 | void deleteMenuByAccountId(Long accountId); | 29 | void deleteMenuByAccountId(Long accountId); |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | - * 用户点击菜单按钮时,回复对应的消息 | 32 | + * 粉丝点击菜单按钮时,回复对应的消息 |
| 33 | * | 33 | * |
| 34 | * @param appId 公众号 AppId | 34 | * @param appId 公众号 AppId |
| 35 | * @param key 菜单按钮的标识 | 35 | * @param key 菜单按钮的标识 |
| 36 | - * @param openid 用户的 openid | 36 | + * @param openid 粉丝的 openid |
| 37 | * @return 消息 | 37 | * @return 消息 |
| 38 | */ | 38 | */ |
| 39 | WxMpXmlOutMessage reply(String appId, String key, String openid); | 39 | WxMpXmlOutMessage reply(String appId, String key, String openid); |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/message/MpAutoReplyService.java
| @@ -64,7 +64,7 @@ public interface MpAutoReplyService { | @@ -64,7 +64,7 @@ public interface MpAutoReplyService { | ||
| 64 | WxMpXmlOutMessage replyForMessage(String appId, WxMpXmlMessage wxMessage); | 64 | WxMpXmlOutMessage replyForMessage(String appId, WxMpXmlMessage wxMessage); |
| 65 | 65 | ||
| 66 | /** | 66 | /** |
| 67 | - * 当用户关注时,自动回复 | 67 | + * 当粉丝关注时,自动回复 |
| 68 | * | 68 | * |
| 69 | * @param appId 微信公众号 appId | 69 | * @param appId 微信公众号 appId |
| 70 | * @param wxMessage 消息 | 70 | * @param wxMessage 消息 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/message/MpAutoReplyServiceImpl.java
| @@ -136,7 +136,7 @@ public class MpAutoReplyServiceImpl implements MpAutoReplyService { | @@ -136,7 +136,7 @@ public class MpAutoReplyServiceImpl implements MpAutoReplyService { | ||
| 136 | 136 | ||
| 137 | @Override | 137 | @Override |
| 138 | public void deleteAutoReply(Long id) { | 138 | public void deleteAutoReply(Long id) { |
| 139 | - // 校验用户存在 | 139 | + // 校验粉丝存在 |
| 140 | validateAutoReplyExists(id); | 140 | validateAutoReplyExists(id); |
| 141 | 141 | ||
| 142 | // 删除自动回复 | 142 | // 删除自动回复 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/message/MpMessageService.java
| @@ -11,23 +11,22 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | @@ -11,23 +11,22 @@ import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | ||
| 11 | import javax.validation.Valid; | 11 | import javax.validation.Valid; |
| 12 | 12 | ||
| 13 | /** | 13 | /** |
| 14 | - * 粉丝消息 Service 接口 | 14 | + * 公众号消息 Service 接口 |
| 15 | * | 15 | * |
| 16 | * @author 芋道源码 | 16 | * @author 芋道源码 |
| 17 | */ | 17 | */ |
| 18 | public interface MpMessageService { | 18 | public interface MpMessageService { |
| 19 | 19 | ||
| 20 | - // TODO 芋艿:方法名要优化下 | ||
| 21 | /** | 20 | /** |
| 22 | - * 获得粉丝消息分页 | 21 | + * 获得公众号消息分页 |
| 23 | * | 22 | * |
| 24 | * @param pageReqVO 分页查询 | 23 | * @param pageReqVO 分页查询 |
| 25 | - * @return 粉丝消息分页 | 24 | + * @return 公众号消息分页 |
| 26 | */ | 25 | */ |
| 27 | - PageResult<MpMessageDO> getWxFansMsgPage(MpMessagePageReqVO pageReqVO); | 26 | + PageResult<MpMessageDO> getMessagePage(MpMessagePageReqVO pageReqVO); |
| 28 | 27 | ||
| 29 | /** | 28 | /** |
| 30 | - * 从公众号,接收到用户消息 | 29 | + * 从公众号,接收到粉丝消息 |
| 31 | * | 30 | * |
| 32 | * @param appId 微信公众号 appId | 31 | * @param appId 微信公众号 appId |
| 33 | * @param wxMessage 消息 | 32 | * @param wxMessage 消息 |
| @@ -35,7 +34,7 @@ public interface MpMessageService { | @@ -35,7 +34,7 @@ public interface MpMessageService { | ||
| 35 | void receiveMessage(String appId, WxMpXmlMessage wxMessage); | 34 | void receiveMessage(String appId, WxMpXmlMessage wxMessage); |
| 36 | 35 | ||
| 37 | /** | 36 | /** |
| 38 | - * 使用公众号,给用户回复消息 | 37 | + * 使用公众号,给粉丝回复消息 |
| 39 | * | 38 | * |
| 40 | * 例如说:自动回复、客服消息、菜单回复消息等场景 | 39 | * 例如说:自动回复、客服消息、菜单回复消息等场景 |
| 41 | * | 40 | * |
| @@ -47,7 +46,7 @@ public interface MpMessageService { | @@ -47,7 +46,7 @@ public interface MpMessageService { | ||
| 47 | WxMpXmlOutMessage sendOutMessage(@Valid MpMessageSendOutReqBO sendReqBO); | 46 | WxMpXmlOutMessage sendOutMessage(@Valid MpMessageSendOutReqBO sendReqBO); |
| 48 | 47 | ||
| 49 | /** | 48 | /** |
| 50 | - * 使用公众号,给用户发送【客服】消息 | 49 | + * 使用公众号,给粉丝发送【客服】消息 |
| 51 | * | 50 | * |
| 52 | * 注意,该方法会真实发送消息 | 51 | * 注意,该方法会真实发送消息 |
| 53 | * | 52 | * |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/message/MpMessageServiceImpl.java
| @@ -63,7 +63,7 @@ public class MpMessageServiceImpl implements MpMessageService { | @@ -63,7 +63,7 @@ public class MpMessageServiceImpl implements MpMessageService { | ||
| 63 | private Validator validator; | 63 | private Validator validator; |
| 64 | 64 | ||
| 65 | @Override | 65 | @Override |
| 66 | - public PageResult<MpMessageDO> getWxFansMsgPage(MpMessagePageReqVO pageReqVO) { | 66 | + public PageResult<MpMessageDO> getMessagePage(MpMessagePageReqVO pageReqVO) { |
| 67 | return mpMessageMapper.selectPage(pageReqVO); | 67 | return mpMessageMapper.selectPage(pageReqVO); |
| 68 | } | 68 | } |
| 69 | 69 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/message/bo/MpMessageSendOutReqBO.java
| @@ -14,7 +14,7 @@ import java.util.List; | @@ -14,7 +14,7 @@ import java.util.List; | ||
| 14 | /** | 14 | /** |
| 15 | * 公众号消息发送 Request BO | 15 | * 公众号消息发送 Request BO |
| 16 | * | 16 | * |
| 17 | - * 为什么要有该 BO 呢?在自动回复、客服消息、菜单回复消息等场景,都涉及到 MP 给用户发送消息,所以使用该 BO 统一承接 | 17 | + * 为什么要有该 BO 呢?在自动回复、客服消息、菜单回复消息等场景,都涉及到 MP 给粉丝发送消息,所以使用该 BO 统一承接 |
| 18 | * | 18 | * |
| 19 | * @author 芋道源码 | 19 | * @author 芋道源码 |
| 20 | */ | 20 | */ |
| @@ -27,9 +27,9 @@ public class MpMessageSendOutReqBO { | @@ -27,9 +27,9 @@ public class MpMessageSendOutReqBO { | ||
| 27 | @NotEmpty(message = "公众号 appId 不能为空") | 27 | @NotEmpty(message = "公众号 appId 不能为空") |
| 28 | private String appId; | 28 | private String appId; |
| 29 | /** | 29 | /** |
| 30 | - * 公众号用户 openid | 30 | + * 公众号粉丝 openid |
| 31 | */ | 31 | */ |
| 32 | - @NotEmpty(message = "公众号用户 openid 不能为空") | 32 | + @NotEmpty(message = "公众号粉丝 openid 不能为空") |
| 33 | private String openid; | 33 | private String openid; |
| 34 | 34 | ||
| 35 | // ========== 消息内容 ========== | 35 | // ========== 消息内容 ========== |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/statistics/MpStatisticsService.java
| @@ -16,20 +16,20 @@ import java.util.List; | @@ -16,20 +16,20 @@ import java.util.List; | ||
| 16 | public interface MpStatisticsService { | 16 | public interface MpStatisticsService { |
| 17 | 17 | ||
| 18 | /** | 18 | /** |
| 19 | - * 获取用户增减数据 | 19 | + * 获取粉丝增减数据 |
| 20 | * | 20 | * |
| 21 | * @param accountId 公众号账号编号 | 21 | * @param accountId 公众号账号编号 |
| 22 | * @param date 时间区间 | 22 | * @param date 时间区间 |
| 23 | - * @return 用户增减数据 | 23 | + * @return 粉丝增减数据 |
| 24 | */ | 24 | */ |
| 25 | List<WxDataCubeUserSummary> getUserSummary(Long accountId, LocalDateTime[] date); | 25 | List<WxDataCubeUserSummary> getUserSummary(Long accountId, LocalDateTime[] date); |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | - * 获取用户累计数据 | 28 | + * 获取粉丝累计数据 |
| 29 | * | 29 | * |
| 30 | * @param accountId 公众号账号编号 | 30 | * @param accountId 公众号账号编号 |
| 31 | * @param date 时间区间 | 31 | * @param date 时间区间 |
| 32 | - * @return 用户累计数据 | 32 | + * @return 粉丝累计数据 |
| 33 | */ | 33 | */ |
| 34 | List<WxDataCubeUserCumulate> getUserCumulate(Long accountId, LocalDateTime[] date); | 34 | List<WxDataCubeUserCumulate> getUserCumulate(Long accountId, LocalDateTime[] date); |
| 35 | 35 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/user/MpUserServiceImpl.java
| @@ -99,11 +99,11 @@ public class MpUserServiceImpl implements MpUserService { | @@ -99,11 +99,11 @@ public class MpUserServiceImpl implements MpUserService { | ||
| 99 | // for 循环,避免递归出意外问题,导致死循环 | 99 | // for 循环,避免递归出意外问题,导致死循环 |
| 100 | String nextOpenid = null; | 100 | String nextOpenid = null; |
| 101 | for (int i = 0; i < Short.MAX_VALUE; i++) { | 101 | for (int i = 0; i < Short.MAX_VALUE; i++) { |
| 102 | - log.info("[syncUser][第({}) 次加载公众号用户列表,nextOpenid({})]", i, nextOpenid); | 102 | + log.info("[syncUser][第({}) 次加载公众号粉丝列表,nextOpenid({})]", i, nextOpenid); |
| 103 | try { | 103 | try { |
| 104 | nextOpenid = syncUser0(account, nextOpenid); | 104 | nextOpenid = syncUser0(account, nextOpenid); |
| 105 | } catch (WxErrorException e) { | 105 | } catch (WxErrorException e) { |
| 106 | - log.error("[syncUser][第({}) 次同步用户异常]", i, e); | 106 | + log.error("[syncUser][第({}) 次同步粉丝异常]", i, e); |
| 107 | break; | 107 | break; |
| 108 | } | 108 | } |
| 109 | // 如果 nextOpenid 为空,表示已经同步完毕 | 109 | // 如果 nextOpenid 为空,表示已经同步完毕 |
| @@ -114,17 +114,17 @@ public class MpUserServiceImpl implements MpUserService { | @@ -114,17 +114,17 @@ public class MpUserServiceImpl implements MpUserService { | ||
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | private String syncUser0(MpAccountDO account, String nextOpenid) throws WxErrorException { | 116 | private String syncUser0(MpAccountDO account, String nextOpenid) throws WxErrorException { |
| 117 | - // 第一步,从公众号流式加载用户 | 117 | + // 第一步,从公众号流式加载粉丝 |
| 118 | WxMpService mpService = mpServiceFactory.getRequiredMpService(account.getId()); | 118 | WxMpService mpService = mpServiceFactory.getRequiredMpService(account.getId()); |
| 119 | WxMpUserList wxUserList = mpService.getUserService().userList(nextOpenid); | 119 | WxMpUserList wxUserList = mpService.getUserService().userList(nextOpenid); |
| 120 | if (CollUtil.isEmpty(wxUserList.getOpenids())) { | 120 | if (CollUtil.isEmpty(wxUserList.getOpenids())) { |
| 121 | return null; | 121 | return null; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | - // 第二步,分批加载用户信息 | 124 | + // 第二步,分批加载粉丝信息 |
| 125 | List<List<String>> openidsList = CollUtil.split(wxUserList.getOpenids(), 100); | 125 | List<List<String>> openidsList = CollUtil.split(wxUserList.getOpenids(), 100); |
| 126 | for (List<String> openids : openidsList) { | 126 | for (List<String> openids : openidsList) { |
| 127 | - log.info("[syncUser][批量加载用户信息,openids({})]", openids); | 127 | + log.info("[syncUser][批量加载粉丝信息,openids({})]", openids); |
| 128 | List<WxMpUser> wxUsers = mpService.getUserService().userInfoList(openids); | 128 | List<WxMpUser> wxUsers = mpService.getUserService().userInfoList(openids); |
| 129 | batchSaveUser(account, wxUsers); | 129 | batchSaveUser(account, wxUsers); |
| 130 | } | 130 | } |
| @@ -137,7 +137,7 @@ public class MpUserServiceImpl implements MpUserService { | @@ -137,7 +137,7 @@ public class MpUserServiceImpl implements MpUserService { | ||
| 137 | if (CollUtil.isEmpty(wxUsers)) { | 137 | if (CollUtil.isEmpty(wxUsers)) { |
| 138 | return; | 138 | return; |
| 139 | } | 139 | } |
| 140 | - // 1. 获得数据库已保存的用户列表 | 140 | + // 1. 获得数据库已保存的粉丝列表 |
| 141 | List<MpUserDO> dbUsers = mpUserMapper.selectListByAppIdAndOpenid(account.getAppId(), | 141 | List<MpUserDO> dbUsers = mpUserMapper.selectListByAppIdAndOpenid(account.getAppId(), |
| 142 | CollectionUtils.convertList(wxUsers, WxMpUser::getOpenId)); | 142 | CollectionUtils.convertList(wxUsers, WxMpUser::getOpenId)); |
| 143 | Map<String, MpUserDO> openId2Users = CollectionUtils.convertMap(dbUsers, MpUserDO::getOpenid); | 143 | Map<String, MpUserDO> openId2Users = CollectionUtils.convertMap(dbUsers, MpUserDO::getOpenid); |
yudao-ui-admin/src/api/mp/draft.js
| @@ -9,7 +9,7 @@ export function getDraftPage(query) { | @@ -9,7 +9,7 @@ export function getDraftPage(query) { | ||
| 9 | }) | 9 | }) |
| 10 | } | 10 | } |
| 11 | 11 | ||
| 12 | -// 创建草稿 | 12 | +// 创建公众号草稿 |
| 13 | export function createDraft(accountId, articles) { | 13 | export function createDraft(accountId, articles) { |
| 14 | return request({ | 14 | return request({ |
| 15 | url: '/mp/draft/create?accountId=' + accountId, | 15 | url: '/mp/draft/create?accountId=' + accountId, |
| @@ -20,7 +20,7 @@ export function createDraft(accountId, articles) { | @@ -20,7 +20,7 @@ export function createDraft(accountId, articles) { | ||
| 20 | }) | 20 | }) |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | -// 更新草稿 | 23 | +// 更新公众号草稿 |
| 24 | export function updateDraft(accountId, mediaId, articles) { | 24 | export function updateDraft(accountId, mediaId, articles) { |
| 25 | return request({ | 25 | return request({ |
| 26 | url: '/mp/draft/update?accountId=' + accountId + '&mediaId=' + mediaId, | 26 | url: '/mp/draft/update?accountId=' + accountId + '&mediaId=' + mediaId, |
| @@ -29,7 +29,7 @@ export function updateDraft(accountId, mediaId, articles) { | @@ -29,7 +29,7 @@ export function updateDraft(accountId, mediaId, articles) { | ||
| 29 | }) | 29 | }) |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | -// 删除草稿 | 32 | +// 删除公众号草稿 |
| 33 | export function deleteDraft(accountId, mediaId) { | 33 | export function deleteDraft(accountId, mediaId) { |
| 34 | return request({ | 34 | return request({ |
| 35 | url: '/mp/draft/delete?accountId=' + accountId + '&mediaId=' + mediaId, | 35 | url: '/mp/draft/delete?accountId=' + accountId + '&mediaId=' + mediaId, |
yudao-ui-admin/src/api/mp/message.js
yudao-ui-admin/src/utils/dict.js
| @@ -60,6 +60,7 @@ export const DICT_TYPE = { | @@ -60,6 +60,7 @@ export const DICT_TYPE = { | ||
| 60 | 60 | ||
| 61 | // ========== MP 模块 ========== | 61 | // ========== MP 模块 ========== |
| 62 | MP_AUTO_REPLY_REQUEST_MATCH: 'mp_auto_reply_request_match', // 自动回复请求匹配类型 | 62 | MP_AUTO_REPLY_REQUEST_MATCH: 'mp_auto_reply_request_match', // 自动回复请求匹配类型 |
| 63 | + MP_MESSAGE_TYPE: 'mp_message_type', // 消息类型 | ||
| 63 | 64 | ||
| 64 | // ========== MALL - PRODUCT 模块 ========== | 65 | // ========== MALL - PRODUCT 模块 ========== |
| 65 | PRODUCT_SPU_STATUS: 'product_spu_status', // 商品 SPU 状态 | 66 | PRODUCT_SPU_STATUS: 'product_spu_status', // 商品 SPU 状态 |
yudao-ui-admin/src/views/mp/autoReply/index.vue
| @@ -50,49 +50,12 @@ SOFTWARE. | @@ -50,49 +50,12 @@ SOFTWARE. | ||
| 50 | </el-col> | 50 | </el-col> |
| 51 | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" /> | 51 | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" /> |
| 52 | </el-row> | 52 | </el-row> |
| 53 | - <!-- 列表 --> | 53 | + <!-- tab 项 --> |
| 54 | <el-tab-pane name="1"> | 54 | <el-tab-pane name="1"> |
| 55 | <span slot="label"><i class="el-icon-star-off"></i> 关注时回复</span> | 55 | <span slot="label"><i class="el-icon-star-off"></i> 关注时回复</span> |
| 56 | - <el-table v-loading="loading" :data="list"> | ||
| 57 | - <el-table-column label="回复消息类型" align="center" prop="responseMessageType"/> | ||
| 58 | - <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | ||
| 59 | - <template slot-scope="scope"> | ||
| 60 | - <span>{{ parseTime(scope.row.createTime) }}</span> | ||
| 61 | - </template> | ||
| 62 | - </el-table-column> | ||
| 63 | - <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||
| 64 | - <template slot-scope="scope"> | ||
| 65 | - <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | ||
| 66 | - v-hasPermi="['mp:auto-reply:update']">修改 | ||
| 67 | - </el-button> | ||
| 68 | - <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | ||
| 69 | - v-hasPermi="['mp:auto-reply:delete']">删除 | ||
| 70 | - </el-button> | ||
| 71 | - </template> | ||
| 72 | - </el-table-column> | ||
| 73 | - </el-table> | ||
| 74 | </el-tab-pane> | 56 | </el-tab-pane> |
| 75 | <el-tab-pane name="2"> | 57 | <el-tab-pane name="2"> |
| 76 | <span slot="label"><i class="el-icon-chat-line-round"></i> 消息回复</span> | 58 | <span slot="label"><i class="el-icon-chat-line-round"></i> 消息回复</span> |
| 77 | - <el-table v-loading="loading" :data="list"> | ||
| 78 | - <el-table-column label="请求消息类型" align="center" prop="requestMessageType"/> | ||
| 79 | - <el-table-column label="回复消息类型" align="center" prop="responseMessageType"/> | ||
| 80 | - <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | ||
| 81 | - <template slot-scope="scope"> | ||
| 82 | - <span>{{ parseTime(scope.row.createTime) }}</span> | ||
| 83 | - </template> | ||
| 84 | - </el-table-column> | ||
| 85 | - <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||
| 86 | - <template slot-scope="scope"> | ||
| 87 | - <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | ||
| 88 | - v-hasPermi="['mp:auto-reply:update']">修改 | ||
| 89 | - </el-button> | ||
| 90 | - <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | ||
| 91 | - v-hasPermi="['mp:auto-reply:delete']">删除 | ||
| 92 | - </el-button> | ||
| 93 | - </template> | ||
| 94 | - </el-table-column> | ||
| 95 | - </el-table> | ||
| 96 | </el-tab-pane> | 59 | </el-tab-pane> |
| 97 | <el-tab-pane name="3"> | 60 | <el-tab-pane name="3"> |
| 98 | <span slot="label"><i class="el-icon-news"></i> 关键词回复</span> | 61 | <span slot="label"><i class="el-icon-news"></i> 关键词回复</span> |
| @@ -101,13 +64,42 @@ SOFTWARE. | @@ -101,13 +64,42 @@ SOFTWARE. | ||
| 101 | 64 | ||
| 102 | <!-- 列表 --> | 65 | <!-- 列表 --> |
| 103 | <el-table v-loading="loading" :data="list"> | 66 | <el-table v-loading="loading" :data="list"> |
| 104 | - <el-table-column label="关键词" align="center" prop="requestKeyword"/> | ||
| 105 | - <el-table-column label="匹配类型" align="center" prop="requestMatch"> | 67 | + <el-table-column label="请求消息类型" align="center" prop="requestMessageType" v-if="type === '2'" /> |
| 68 | + <el-table-column label="关键词" align="center" prop="requestKeyword" v-if="type === '3'" /> | ||
| 69 | + <el-table-column label="匹配类型" align="center" prop="requestMatch" v-if="type === '3'"> | ||
| 106 | <template v-slot="scope"> | 70 | <template v-slot="scope"> |
| 107 | <dict-tag :type="DICT_TYPE.MP_AUTO_REPLY_REQUEST_MATCH" :value="scope.row.requestMatch"/> | 71 | <dict-tag :type="DICT_TYPE.MP_AUTO_REPLY_REQUEST_MATCH" :value="scope.row.requestMatch"/> |
| 108 | </template> | 72 | </template> |
| 109 | </el-table-column> | 73 | </el-table-column> |
| 110 | - <el-table-column label="回复消息类型" align="center" prop="responseMessageType"/> | 74 | + <el-table-column label="回复消息类型" align="center"> |
| 75 | + <template v-slot="scope"> | ||
| 76 | + <dict-tag :type="DICT_TYPE.MP_MESSAGE_TYPE" :value="scope.row.responseMessageType"/> | ||
| 77 | + </template> | ||
| 78 | + </el-table-column> | ||
| 79 | + <el-table-column label="回复内容" align="center"> | ||
| 80 | + <template slot-scope="scope"> | ||
| 81 | + <div v-if="scope.row.responseMessageType === 'text'">{{ scope.row.responseContent }}</div> | ||
| 82 | + <div v-else-if="scope.row.responseMessageType === 'voice'"> | ||
| 83 | + <wx-voice-player :url="scope.row.responseMediaUrl" /> | ||
| 84 | + </div> | ||
| 85 | + <div v-else-if="scope.row.responseMessageType === 'image'"> | ||
| 86 | + <a target="_blank" :href="scope.row.responseMediaUrl"> | ||
| 87 | + <img :src="scope.row.responseMediaUrl" style="width: 100px"> | ||
| 88 | + </a> | ||
| 89 | + </div> | ||
| 90 | + <div v-else-if="scope.row.responseMessageType === 'video' || scope.row.responseMessageType === 'shortvideo'"> | ||
| 91 | + <wx-video-player :url="scope.row.responseMediaUrl" style="margin-top: 10px" /> | ||
| 92 | + </div> | ||
| 93 | + <div v-else-if="scope.row.responseMessageType === 'news'"> | ||
| 94 | + <wx-news :articles="scope.row.responseArticles" /> | ||
| 95 | + </div> | ||
| 96 | + <div v-else-if="scope.row.responseMessageType === 'music'"> | ||
| 97 | + <wx-music :title="scope.row.responseTitle" :description="scope.row.responseDescription" | ||
| 98 | + :thumb-media-url="scope.row.responseThumbMediaUrl" | ||
| 99 | + :music-url="scope.row.responseMusicUrl" :hq-music-url="scope.row.responseHqMusicUrl" /> | ||
| 100 | + </div> | ||
| 101 | + </template> | ||
| 102 | + </el-table-column> | ||
| 111 | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | 103 | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| 112 | <template slot-scope="scope"> | 104 | <template slot-scope="scope"> |
| 113 | <span>{{ parseTime(scope.row.createTime) }}</span> | 105 | <span>{{ parseTime(scope.row.createTime) }}</span> |
| @@ -130,9 +122,9 @@ SOFTWARE. | @@ -130,9 +122,9 @@ SOFTWARE. | ||
| 130 | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> | 122 | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| 131 | <el-form-item label="消息类型" prop="requestMessageType" v-if="type === '2'"> | 123 | <el-form-item label="消息类型" prop="requestMessageType" v-if="type === '2'"> |
| 132 | <el-select v-model="form.requestMessageType" placeholder="请选择"> | 124 | <el-select v-model="form.requestMessageType" placeholder="请选择"> |
| 133 | - <el-option v-for="item in dictData.get('wx_req_type')" :key="item.value" :label="item.label" | ||
| 134 | - :value="item.value" :disabled="item.disabled" v-if="item.value !== 'event'"> | ||
| 135 | - </el-option> | 125 | + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.MP_MESSAGE_TYPE)" |
| 126 | + :key="dict.value" :label="dict.label" :value="dict.value" | ||
| 127 | + v-if="requestMessageTypes.includes(dict.value)"/> | ||
| 136 | </el-select> | 128 | </el-select> |
| 137 | </el-form-item> | 129 | </el-form-item> |
| 138 | <el-form-item label="匹配类型" prop="requestMatch" v-if="type === '3'"> | 130 | <el-form-item label="匹配类型" prop="requestMatch" v-if="type === '3'"> |
| @@ -157,6 +149,12 @@ SOFTWARE. | @@ -157,6 +149,12 @@ SOFTWARE. | ||
| 157 | </template> | 149 | </template> |
| 158 | 150 | ||
| 159 | <script> | 151 | <script> |
| 152 | +import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'; | ||
| 153 | +import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'; | ||
| 154 | +import WxMsg from '@/views/mp/components/wx-msg/main.vue'; | ||
| 155 | +import WxLocation from '@/views/mp/components/wx-location/main.vue'; | ||
| 156 | +import WxMusic from '@/views/mp/components/wx-music/main.vue'; | ||
| 157 | +import WxNews from '@/views/mp/components/wx-news/main.vue'; | ||
| 160 | import WxReplySelect from '@/views/mp/components/wx-reply/main.vue' | 158 | import WxReplySelect from '@/views/mp/components/wx-reply/main.vue' |
| 161 | import { getSimpleAccounts } from "@/api/mp/account"; | 159 | import { getSimpleAccounts } from "@/api/mp/account"; |
| 162 | import { createAutoReply, deleteAutoReply, getAutoReply, getAutoReplyPage, updateAutoReply } from "@/api/mp/autoReply"; | 160 | import { createAutoReply, deleteAutoReply, getAutoReply, getAutoReplyPage, updateAutoReply } from "@/api/mp/autoReply"; |
| @@ -164,12 +162,20 @@ import { createAutoReply, deleteAutoReply, getAutoReply, getAutoReplyPage, updat | @@ -164,12 +162,20 @@ import { createAutoReply, deleteAutoReply, getAutoReply, getAutoReplyPage, updat | ||
| 164 | export default { | 162 | export default { |
| 165 | name: 'mpAutoReply', | 163 | name: 'mpAutoReply', |
| 166 | components: { | 164 | components: { |
| 165 | + WxVideoPlayer, | ||
| 166 | + WxVoicePlayer, | ||
| 167 | + WxMsg, | ||
| 168 | + WxLocation, | ||
| 169 | + WxMusic, | ||
| 170 | + WxNews, | ||
| 167 | WxReplySelect | 171 | WxReplySelect |
| 168 | }, | 172 | }, |
| 169 | data() { | 173 | data() { |
| 170 | return { | 174 | return { |
| 171 | // tab 类型(1、关注时回复;2、消息回复;3、关键词回复) | 175 | // tab 类型(1、关注时回复;2、消息回复;3、关键词回复) |
| 172 | type: '3', | 176 | type: '3', |
| 177 | + // 允许选择的请求消息类型 | ||
| 178 | + requestMessageTypes: ['text', 'image', 'voice', 'video', 'shortvideo', 'location', 'link'], | ||
| 173 | // 遮罩层 | 179 | // 遮罩层 |
| 174 | loading: true, | 180 | loading: true, |
| 175 | // 显示搜索条件 | 181 | // 显示搜索条件 |
| @@ -202,8 +208,6 @@ export default { | @@ -202,8 +208,6 @@ export default { | ||
| 202 | }, | 208 | }, |
| 203 | hackResetWxReplySelect: false, // 重置 WxReplySelect 组件,解决无法清除的问题 | 209 | hackResetWxReplySelect: false, // 重置 WxReplySelect 组件,解决无法清除的问题 |
| 204 | 210 | ||
| 205 | - dictData: new Map(), | ||
| 206 | - | ||
| 207 | // 公众号账号列表 | 211 | // 公众号账号列表 |
| 208 | accounts: [] | 212 | accounts: [] |
| 209 | } | 213 | } |
| @@ -218,33 +222,6 @@ export default { | @@ -218,33 +222,6 @@ export default { | ||
| 218 | // 加载数据 | 222 | // 加载数据 |
| 219 | this.getList(); | 223 | this.getList(); |
| 220 | }) | 224 | }) |
| 221 | - | ||
| 222 | - // TODO 芋艿:字典数据,一起搞 | ||
| 223 | - this.dictData.set('wx_req_type',[{ | ||
| 224 | - value: 'text', | ||
| 225 | - label: '文本' | ||
| 226 | - },{ | ||
| 227 | - value: 'image', | ||
| 228 | - label: '图片' | ||
| 229 | - },{ | ||
| 230 | - value: 'voice', | ||
| 231 | - label: '语音' | ||
| 232 | - },{ | ||
| 233 | - value: 'video', | ||
| 234 | - label: '视频' | ||
| 235 | - },{ | ||
| 236 | - value: 'shortvideo', | ||
| 237 | - label: '小视频' | ||
| 238 | - },{ | ||
| 239 | - value: 'location', | ||
| 240 | - label: '地理位置' | ||
| 241 | - },{ | ||
| 242 | - value: 'link', | ||
| 243 | - label: '链接消息' | ||
| 244 | - },{ | ||
| 245 | - value: 'event', | ||
| 246 | - label: '事件推送' | ||
| 247 | - }]) | ||
| 248 | }, | 225 | }, |
| 249 | methods: { | 226 | methods: { |
| 250 | /** 查询列表 */ | 227 | /** 查询列表 */ |
| @@ -295,7 +272,8 @@ export default { | @@ -295,7 +272,8 @@ export default { | ||
| 295 | this.open = true | 272 | this.open = true |
| 296 | this.title = '新增自动回复'; | 273 | this.title = '新增自动回复'; |
| 297 | this.objData = { | 274 | this.objData = { |
| 298 | - type : 'text' | 275 | + type : 'text', |
| 276 | + accountId: this.queryParams.accountId, | ||
| 299 | } | 277 | } |
| 300 | }, | 278 | }, |
| 301 | /** 修改按钮操作 */ | 279 | /** 修改按钮操作 */ |
yudao-ui-admin/src/views/mp/components/wx-msg/main.vue
| @@ -9,13 +9,13 @@ | @@ -9,13 +9,13 @@ | ||
| 9 | <div class="msg-main"> | 9 | <div class="msg-main"> |
| 10 | <div class="msg-div" :id="'msg-div' + nowStr"> | 10 | <div class="msg-div" :id="'msg-div' + nowStr"> |
| 11 | <!-- 加载更多 --> | 11 | <!-- 加载更多 --> |
| 12 | - <div v-loading="tableLoading"></div> | ||
| 13 | - <div v-if="!tableLoading"> | 12 | + <div v-loading="loading"></div> |
| 13 | + <div v-if="!loading"> | ||
| 14 | <div class="el-table__empty-block" v-if="loadMore" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span></div> | 14 | <div class="el-table__empty-block" v-if="loadMore" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span></div> |
| 15 | <div class="el-table__empty-block" v-if="!loadMore"><span class="el-table__empty-text">没有更多了</span></div> | 15 | <div class="el-table__empty-block" v-if="!loadMore"><span class="el-table__empty-text">没有更多了</span></div> |
| 16 | </div> | 16 | </div> |
| 17 | <!-- 消息列表 --> | 17 | <!-- 消息列表 --> |
| 18 | - <div class="execution" v-for="item in tableData" :key='item.id'> | 18 | + <div class="execution" v-for="item in list" :key='item.id'> |
| 19 | <div class="avue-comment" :class="item.sendFrom === 2 ? 'avue-comment--reverse' : ''"> | 19 | <div class="avue-comment" :class="item.sendFrom === 2 ? 'avue-comment--reverse' : ''"> |
| 20 | <div class="avatar-div"> | 20 | <div class="avatar-div"> |
| 21 | <img :src="item.sendFrom === 1 ? user.avatar : mp.avatar" class="avue-comment__avatar"> | 21 | <img :src="item.sendFrom === 1 ? user.avatar : mp.avatar" class="avue-comment__avatar"> |
| @@ -124,20 +124,20 @@ import { getUser } from "@/api/mp/user"; | @@ -124,20 +124,20 @@ import { getUser } from "@/api/mp/user"; | ||
| 124 | }, | 124 | }, |
| 125 | props: { | 125 | props: { |
| 126 | userId: { | 126 | userId: { |
| 127 | - type: String, | 127 | + type: Number, |
| 128 | required: true | 128 | required: true |
| 129 | }, | 129 | }, |
| 130 | }, | 130 | }, |
| 131 | data() { | 131 | data() { |
| 132 | return { | 132 | return { |
| 133 | nowStr: new Date().getTime(), // 当前的时间戳,用于每次消息加载后,回到原位置;具体见 :id="'msg-div' + nowStr" 处 | 133 | nowStr: new Date().getTime(), // 当前的时间戳,用于每次消息加载后,回到原位置;具体见 :id="'msg-div' + nowStr" 处 |
| 134 | - sendLoading: false, // 发送消息是否加载中 | ||
| 135 | - tableLoading: false, // 消息列表是否正在加载中 | 134 | + loading: false, // 消息列表是否正在加载中 |
| 136 | loadMore: true, // 是否可以加载更多 | 135 | loadMore: true, // 是否可以加载更多 |
| 137 | - tableData: [], // 消息列表 | ||
| 138 | - page: { | 136 | + list: [], // 消息列表 |
| 137 | + queryParams: { | ||
| 139 | pageNo: 1, // 当前页数 | 138 | pageNo: 1, // 当前页数 |
| 140 | pageSize: 14, // 每页显示多少条 | 139 | pageSize: 14, // 每页显示多少条 |
| 140 | + accountId: undefined, | ||
| 141 | }, | 141 | }, |
| 142 | user: { // 由于微信不再提供昵称,直接使用“用户”展示 | 142 | user: { // 由于微信不再提供昵称,直接使用“用户”展示 |
| 143 | nickname: '用户', | 143 | nickname: '用户', |
| @@ -148,6 +148,9 @@ import { getUser } from "@/api/mp/user"; | @@ -148,6 +148,9 @@ import { getUser } from "@/api/mp/user"; | ||
| 148 | nickname: '公众号', | 148 | nickname: '公众号', |
| 149 | avatar: require("@/assets/images/wechat.png"), | 149 | avatar: require("@/assets/images/wechat.png"), |
| 150 | }, | 150 | }, |
| 151 | + | ||
| 152 | + // ========= 消息发送 ========= | ||
| 153 | + sendLoading: false, // 发送消息是否加载中 | ||
| 151 | objData: { // 微信发送消息 | 154 | objData: { // 微信发送消息 |
| 152 | type: 'text', | 155 | type: 'text', |
| 153 | }, | 156 | }, |
| @@ -156,14 +159,19 @@ import { getUser } from "@/api/mp/user"; | @@ -156,14 +159,19 @@ import { getUser } from "@/api/mp/user"; | ||
| 156 | created() { | 159 | created() { |
| 157 | // 获得用户信息 | 160 | // 获得用户信息 |
| 158 | getUser(this.userId).then(response => { | 161 | getUser(this.userId).then(response => { |
| 159 | - this.user.nickname = response.data.nickname | this.user.nickname; | ||
| 160 | - this.user.avatar = response.data.avatar | this.user.avatar; | 162 | + this.user.nickname = response.data.nickname && response.data.nickname.length > 0 ? |
| 163 | + response.data.nickname : this.user.nickname; | ||
| 164 | + this.user.avatar = response.data.avatar && this.user.avatar.length > 0 ? | ||
| 165 | + response.data.avatar : this.user.avatar; | ||
| 166 | + this.user.accountId = response.data.accountId; | ||
| 161 | // 设置公众号账号编号 | 167 | // 设置公众号账号编号 |
| 168 | + this.queryParams.accountId = response.data.accountId; | ||
| 162 | this.objData.accountId = response.data.accountId; | 169 | this.objData.accountId = response.data.accountId; |
| 163 | - }) | ||
| 164 | 170 | ||
| 165 | - // 加载消息 | ||
| 166 | - this.refreshChange() | 171 | + // 加载消息 |
| 172 | + console.log(this.queryParams) | ||
| 173 | + this.refreshChange() | ||
| 174 | + }) | ||
| 167 | }, | 175 | }, |
| 168 | methods:{ | 176 | methods:{ |
| 169 | sendMsg(){ | 177 | sendMsg(){ |
| @@ -190,7 +198,7 @@ import { getUser } from "@/api/mp/user"; | @@ -190,7 +198,7 @@ import { getUser } from "@/api/mp/user"; | ||
| 190 | })).then(response => { | 198 | })).then(response => { |
| 191 | this.sendLoading = false | 199 | this.sendLoading = false |
| 192 | // 添加到消息列表,并滚动 | 200 | // 添加到消息列表,并滚动 |
| 193 | - this.tableData = [...this.tableData , ...[response.data] ] | 201 | + this.list = [...this.list , ...[response.data] ] |
| 194 | this.scrollToBottom() | 202 | this.scrollToBottom() |
| 195 | // 重置 objData 状态 | 203 | // 重置 objData 状态 |
| 196 | this.$refs['replySelect'].deleteObj(); // 重置,避免 tab 的数据未清理 | 204 | this.$refs['replySelect'].deleteObj(); // 重置,避免 tab 的数据未清理 |
| @@ -199,15 +207,16 @@ import { getUser } from "@/api/mp/user"; | @@ -199,15 +207,16 @@ import { getUser } from "@/api/mp/user"; | ||
| 199 | }) | 207 | }) |
| 200 | }, | 208 | }, |
| 201 | loadingMore() { | 209 | loadingMore() { |
| 202 | - this.page.pageNo++ | ||
| 203 | - this.getPage(this.page) | 210 | + this.queryParams.pageNo++ |
| 211 | + this.getPage(this.queryParams) | ||
| 204 | }, | 212 | }, |
| 205 | getPage(page, params) { | 213 | getPage(page, params) { |
| 206 | - this.tableLoading = true | 214 | + this.loading = true |
| 207 | getMessagePage(Object.assign({ | 215 | getMessagePage(Object.assign({ |
| 208 | pageNo: page.pageNo, | 216 | pageNo: page.pageNo, |
| 209 | pageSize: page.pageSize, | 217 | pageSize: page.pageSize, |
| 210 | - userId: this.userId | 218 | + userId: this.userId, |
| 219 | + accountId: page.accountId, | ||
| 211 | }, params)).then(response => { | 220 | }, params)).then(response => { |
| 212 | // 计算当前的滚动高度 | 221 | // 计算当前的滚动高度 |
| 213 | const msgDiv = document.getElementById('msg-div' + this.nowStr); | 222 | const msgDiv = document.getElementById('msg-div' + this.nowStr); |
| @@ -218,16 +227,16 @@ import { getUser } from "@/api/mp/user"; | @@ -218,16 +227,16 @@ import { getUser } from "@/api/mp/user"; | ||
| 218 | 227 | ||
| 219 | // 处理数据 | 228 | // 处理数据 |
| 220 | const data = response.data.list.reverse(); | 229 | const data = response.data.list.reverse(); |
| 221 | - this.tableData = [...data, ...this.tableData] | ||
| 222 | - this.tableLoading = false | ||
| 223 | - if (data.length < this.page.pageSize || data.length === 0){ | 230 | + this.list = [...data, ...this.list] |
| 231 | + this.loading = false | ||
| 232 | + if (data.length < this.queryParams.pageSize || data.length === 0){ | ||
| 224 | this.loadMore = false | 233 | this.loadMore = false |
| 225 | } | 234 | } |
| 226 | - this.page.pageNo = page.pageNo | ||
| 227 | - this.page.pageSize = page.pageSize | 235 | + this.queryParams.pageNo = page.pageNo |
| 236 | + this.queryParams.pageSize = page.pageSize | ||
| 228 | 237 | ||
| 229 | // 滚动到原来的位置 | 238 | // 滚动到原来的位置 |
| 230 | - if(this.page.pageNo === 1) { // 定位到消息底部 | 239 | + if(this.queryParams.pageNo === 1) { // 定位到消息底部 |
| 231 | this.scrollToBottom() | 240 | this.scrollToBottom() |
| 232 | } else if (data.length !== 0) { // 定位滚动条 | 241 | } else if (data.length !== 0) { // 定位滚动条 |
| 233 | this.$nextTick(() => { | 242 | this.$nextTick(() => { |
| @@ -242,7 +251,7 @@ import { getUser } from "@/api/mp/user"; | @@ -242,7 +251,7 @@ import { getUser } from "@/api/mp/user"; | ||
| 242 | * 刷新回调 | 251 | * 刷新回调 |
| 243 | */ | 252 | */ |
| 244 | refreshChange() { | 253 | refreshChange() { |
| 245 | - this.getPage(this.page) | 254 | + this.getPage(this.queryParams) |
| 246 | }, | 255 | }, |
| 247 | /** 定位到消息底部 */ | 256 | /** 定位到消息底部 */ |
| 248 | scrollToBottom: function () { | 257 | scrollToBottom: function () { |
| @@ -267,6 +276,8 @@ import { getUser } from "@/api/mp/user"; | @@ -267,6 +276,8 @@ import { getUser } from "@/api/mp/user"; | ||
| 267 | height: 50vh; | 276 | height: 50vh; |
| 268 | overflow: auto; | 277 | overflow: auto; |
| 269 | background-color: #eaeaea; | 278 | background-color: #eaeaea; |
| 279 | + margin-left: 10px; | ||
| 280 | + margin-right: 10px; | ||
| 270 | } | 281 | } |
| 271 | .msg-send { | 282 | .msg-send { |
| 272 | padding: 10px; | 283 | padding: 10px; |
yudao-ui-admin/src/views/mp/menu/index.vue
| @@ -66,8 +66,8 @@ SOFTWARE. | @@ -66,8 +66,8 @@ SOFTWARE. | ||
| 66 | <div class="menu_bottom menu_addicon" v-if="this.menuList.length < 3" @click="addMenu"><i class="el-icon-plus"></i></div> | 66 | <div class="menu_bottom menu_addicon" v-if="this.menuList.length < 3" @click="addMenu"><i class="el-icon-plus"></i></div> |
| 67 | </div> | 67 | </div> |
| 68 | <div class="save_div"> | 68 | <div class="save_div"> |
| 69 | - <el-button class="save_btn" type="success" size="small" @click="handleSave">保存并发布菜单</el-button> | ||
| 70 | - <el-button class="save_btn" type="danger" size="small" @click="handleDelete">清空菜单</el-button> | 69 | + <el-button class="save_btn" type="success" size="small" @click="handleSave" v-hasPermi="['mp:menu:save']">保存并发布菜单</el-button> |
| 70 | + <el-button class="save_btn" type="danger" size="small" @click="handleDelete" v-hasPermi="['mp:menu:delete']">清空菜单</el-button> | ||
| 71 | </div> | 71 | </div> |
| 72 | </div> | 72 | </div> |
| 73 | <!--右边配置--> | 73 | <!--右边配置--> |
yudao-ui-admin/src/views/mp/message/index.vue
| @@ -8,18 +8,19 @@ | @@ -8,18 +8,19 @@ | ||
| 8 | <el-option v-for="item in accounts" :key="parseInt(item.id)" :label="item.name" :value="parseInt(item.id)" /> | 8 | <el-option v-for="item in accounts" :key="parseInt(item.id)" :label="item.name" :value="parseInt(item.id)" /> |
| 9 | </el-select> | 9 | </el-select> |
| 10 | </el-form-item> | 10 | </el-form-item> |
| 11 | - <!-- 等待处理 --> | ||
| 12 | - <el-form-item label="消息类型" prop="msgType"> | ||
| 13 | - <el-select v-model="queryParams.msgType" placeholder="请选择消息类型" clearable size="small"> | ||
| 14 | - <el-option label="请选择字典生成" value=""/> | 11 | + <!-- TODO 等待处理 --> |
| 12 | + <el-form-item label="消息类型" prop="type"> | ||
| 13 | + <el-select v-model="queryParams.type" placeholder="请选择消息类型" clearable size="small"> | ||
| 14 | + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.MP_MESSAGE_TYPE)" | ||
| 15 | + :key="dict.value" :label="dict.label" :value="dict.value"/> | ||
| 15 | </el-select> | 16 | </el-select> |
| 16 | </el-form-item> | 17 | </el-form-item> |
| 17 | <el-form-item label="用户标识" prop="openid"> | 18 | <el-form-item label="用户标识" prop="openid"> |
| 18 | <el-input v-model="queryParams.openid" placeholder="请输入用户标识" clearable @keyup.enter.native="handleQuery"/> | 19 | <el-input v-model="queryParams.openid" placeholder="请输入用户标识" clearable @keyup.enter.native="handleQuery"/> |
| 19 | </el-form-item> | 20 | </el-form-item> |
| 20 | - <el-form-item label="创建时间"> | ||
| 21 | - <el-date-picker v-model="dateRangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd" | ||
| 22 | - type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/> | 21 | + <el-form-item label="创建时间" prop="createTime"> |
| 22 | + <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" | ||
| 23 | + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" /> | ||
| 23 | </el-form-item> | 24 | </el-form-item> |
| 24 | <el-form-item> | 25 | <el-form-item> |
| 25 | <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> | 26 | <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> |
| @@ -42,12 +43,11 @@ | @@ -42,12 +43,11 @@ | ||
| 42 | <el-table-column label="消息类型" align="center" prop="type" width="80"/> | 43 | <el-table-column label="消息类型" align="center" prop="type" width="80"/> |
| 43 | <el-table-column label="发送方" align="center" prop="sendFrom" width="80"> | 44 | <el-table-column label="发送方" align="center" prop="sendFrom" width="80"> |
| 44 | <template slot-scope="scope"> | 45 | <template slot-scope="scope"> |
| 45 | - <el-tag v-if="scope.row.sendFrom === 1" type="success">用户</el-tag> | 46 | + <el-tag v-if="scope.row.sendFrom === 1" type="success">粉丝</el-tag> |
| 46 | <el-tag v-else type="info">公众号</el-tag> | 47 | <el-tag v-else type="info">公众号</el-tag> |
| 47 | </template> | 48 | </template> |
| 48 | </el-table-column> | 49 | </el-table-column> |
| 49 | <el-table-column label="用户标识" align="center" prop="openid" width="300" /> | 50 | <el-table-column label="用户标识" align="center" prop="openid" width="300" /> |
| 50 | - <!-- TODO 芋艿:发送/接收 --> | ||
| 51 | <el-table-column label="内容" prop="content"> | 51 | <el-table-column label="内容" prop="content"> |
| 52 | <template slot-scope="scope"> | 52 | <template slot-scope="scope"> |
| 53 | <!-- 【事件】区域 --> | 53 | <!-- 【事件】区域 --> |
| @@ -118,10 +118,9 @@ | @@ -118,10 +118,9 @@ | ||
| 118 | </el-table-column> | 118 | </el-table-column> |
| 119 | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | 119 | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| 120 | <template slot-scope="scope"> | 120 | <template slot-scope="scope"> |
| 121 | - <!-- TODO 芋艿:增加消息按钮 --> | ||
| 122 | -<!-- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"--> | ||
| 123 | -<!-- v-hasPermi="['mp:message:update']">修改--> | ||
| 124 | -<!-- </el-button>--> | 121 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleSend(scope.row)" |
| 122 | + v-hasPermi="['mp:message:send']">消息 | ||
| 123 | + </el-button> | ||
| 125 | </template> | 124 | </template> |
| 126 | </el-table-column> | 125 | </el-table-column> |
| 127 | </el-table> | 126 | </el-table> |
| @@ -129,24 +128,26 @@ | @@ -129,24 +128,26 @@ | ||
| 129 | <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | 128 | <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" |
| 130 | @pagination="getList"/> | 129 | @pagination="getList"/> |
| 131 | 130 | ||
| 132 | - <el-dialog title="用户消息" :visible.sync="open" width="40%"> | ||
| 133 | - <wx-msg user-id="3" v-if="true" /> | 131 | + <!-- 发送消息的弹窗 --> |
| 132 | + <el-dialog title="粉丝消息列表" :visible.sync="open" width="50%"> | ||
| 133 | + <wx-msg :user-id="userId" v-if="open" /> | ||
| 134 | </el-dialog> | 134 | </el-dialog> |
| 135 | 135 | ||
| 136 | </div> | 136 | </div> |
| 137 | </template> | 137 | </template> |
| 138 | 138 | ||
| 139 | <script> | 139 | <script> |
| 140 | -import { getMessagePage } from "@/api/mp/message"; | ||
| 141 | import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'; | 140 | import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'; |
| 142 | import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'; | 141 | import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'; |
| 143 | import WxMsg from '@/views/mp/components/wx-msg/main.vue'; | 142 | import WxMsg from '@/views/mp/components/wx-msg/main.vue'; |
| 144 | import WxLocation from '@/views/mp/components/wx-location/main.vue'; | 143 | import WxLocation from '@/views/mp/components/wx-location/main.vue'; |
| 145 | import WxMusic from '@/views/mp/components/wx-music/main.vue'; | 144 | import WxMusic from '@/views/mp/components/wx-music/main.vue'; |
| 146 | import WxNews from '@/views/mp/components/wx-news/main.vue'; | 145 | import WxNews from '@/views/mp/components/wx-news/main.vue'; |
| 146 | +import { getMessagePage } from "@/api/mp/message"; | ||
| 147 | +import { getSimpleAccounts } from "@/api/mp/account"; | ||
| 147 | 148 | ||
| 148 | export default { | 149 | export default { |
| 149 | - name: "WxFansMsg", | 150 | + name: "MpMessage", |
| 150 | components: { | 151 | components: { |
| 151 | WxVideoPlayer, | 152 | WxVideoPlayer, |
| 152 | WxVoicePlayer, | 153 | WxVoicePlayer, |
| @@ -167,76 +168,52 @@ export default { | @@ -167,76 +168,52 @@ export default { | ||
| 167 | total: 0, | 168 | total: 0, |
| 168 | // 粉丝消息列表 | 169 | // 粉丝消息列表 |
| 169 | list: [], | 170 | list: [], |
| 170 | - // 弹出层标题 | ||
| 171 | - title: "", | ||
| 172 | // 是否显示弹出层 | 171 | // 是否显示弹出层 |
| 173 | - open: true, | 172 | + open: false, |
| 174 | // 查询参数 | 173 | // 查询参数 |
| 175 | - dateRangeCreateTime: [], | ||
| 176 | queryParams: { | 174 | queryParams: { |
| 177 | pageNo: 1, | 175 | pageNo: 1, |
| 178 | pageSize: 10, | 176 | pageSize: 10, |
| 179 | openid: null, | 177 | openid: null, |
| 180 | - nickname: null, | ||
| 181 | - headimgUrl: null, | ||
| 182 | - wxAccountId: null, | ||
| 183 | - msgType: null, | ||
| 184 | - content: null, | ||
| 185 | - resContent: null, | ||
| 186 | - isRes: null, | ||
| 187 | - mediaId: null, | ||
| 188 | - picUrl: null, | ||
| 189 | - picPath: null, | 178 | + accountId: null, |
| 179 | + type: null, | ||
| 180 | + createTime: [] | ||
| 190 | }, | 181 | }, |
| 191 | - // 表单参数 | ||
| 192 | - form: {}, | ||
| 193 | - // 表单校验 | ||
| 194 | - rules: {}, | 182 | + // 操作的用户编号 |
| 183 | + userId: 0, | ||
| 195 | 184 | ||
| 196 | // 公众号账号列表 | 185 | // 公众号账号列表 |
| 197 | accounts: [] | 186 | accounts: [] |
| 198 | }; | 187 | }; |
| 199 | }, | 188 | }, |
| 200 | created() { | 189 | created() { |
| 201 | - this.getList(); | 190 | + getSimpleAccounts().then(response => { |
| 191 | + this.accounts = response.data; | ||
| 192 | + // 默认选中第一个 | ||
| 193 | + if (this.accounts.length > 0) { | ||
| 194 | + this.queryParams.accountId = this.accounts[0].id; | ||
| 195 | + } | ||
| 196 | + // 加载数据 | ||
| 197 | + this.getList(); | ||
| 198 | + }) | ||
| 202 | }, | 199 | }, |
| 203 | methods: { | 200 | methods: { |
| 204 | /** 查询列表 */ | 201 | /** 查询列表 */ |
| 205 | getList() { | 202 | getList() { |
| 203 | + // 如果没有选中公众号账号,则进行提示。 | ||
| 204 | + if (!this.queryParams.accountId) { | ||
| 205 | + this.$message.error('未选中公众号,无法查询消息') | ||
| 206 | + return false | ||
| 207 | + } | ||
| 208 | + | ||
| 206 | this.loading = true; | 209 | this.loading = true; |
| 207 | - // 处理查询参数 | ||
| 208 | - let params = {...this.queryParams}; | ||
| 209 | - this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); | ||
| 210 | // 执行查询 | 210 | // 执行查询 |
| 211 | - getMessagePage(params).then(response => { | 211 | + getMessagePage(this.queryParams).then(response => { |
| 212 | this.list = response.data.list; | 212 | this.list = response.data.list; |
| 213 | this.total = response.data.total; | 213 | this.total = response.data.total; |
| 214 | this.loading = false; | 214 | this.loading = false; |
| 215 | }); | 215 | }); |
| 216 | }, | 216 | }, |
| 217 | - /** 取消按钮 */ | ||
| 218 | - cancel() { | ||
| 219 | - this.open = false; | ||
| 220 | - this.reset(); | ||
| 221 | - }, | ||
| 222 | - /** 表单重置 */ | ||
| 223 | - reset() { | ||
| 224 | - this.form = { | ||
| 225 | - id: undefined, | ||
| 226 | - openid: undefined, | ||
| 227 | - nickname: undefined, | ||
| 228 | - headimgUrl: undefined, | ||
| 229 | - wxAccountId: undefined, | ||
| 230 | - msgType: undefined, | ||
| 231 | - content: undefined, | ||
| 232 | - resContent: undefined, | ||
| 233 | - isRes: undefined, | ||
| 234 | - mediaId: undefined, | ||
| 235 | - picUrl: undefined, | ||
| 236 | - picPath: undefined, | ||
| 237 | - }; | ||
| 238 | - this.resetForm("form"); | ||
| 239 | - }, | ||
| 240 | /** 搜索按钮操作 */ | 217 | /** 搜索按钮操作 */ |
| 241 | handleQuery() { | 218 | handleQuery() { |
| 242 | this.queryParams.pageNo = 1; | 219 | this.queryParams.pageNo = 1; |
| @@ -244,10 +221,17 @@ export default { | @@ -244,10 +221,17 @@ export default { | ||
| 244 | }, | 221 | }, |
| 245 | /** 重置按钮操作 */ | 222 | /** 重置按钮操作 */ |
| 246 | resetQuery() { | 223 | resetQuery() { |
| 247 | - this.dateRangeCreateTime = []; | ||
| 248 | this.resetForm("queryForm"); | 224 | this.resetForm("queryForm"); |
| 225 | + // 默认选中第一个 | ||
| 226 | + if (this.accounts.length > 0) { | ||
| 227 | + this.queryParams.accountId = this.accounts[0].id; | ||
| 228 | + } | ||
| 249 | this.handleQuery(); | 229 | this.handleQuery(); |
| 250 | }, | 230 | }, |
| 231 | + handleSend(row) { | ||
| 232 | + this.userId = row.userId; | ||
| 233 | + this.open = true; | ||
| 234 | + }, | ||
| 251 | } | 235 | } |
| 252 | }; | 236 | }; |
| 253 | </script> | 237 | </script> |
yudao-ui-admin/src/views/mp/statistics/index.vue
| @@ -77,7 +77,7 @@ require('echarts/lib/component/legend') | @@ -77,7 +77,7 @@ require('echarts/lib/component/legend') | ||
| 77 | import { getInterfaceSummary, getUserSummary, getUserCumulate, getUpstreamMessage} from '@/api/mp/statistics' | 77 | import { getInterfaceSummary, getUserSummary, getUserCumulate, getUpstreamMessage} from '@/api/mp/statistics' |
| 78 | import { datePickerOptions } from "@/utils/constants"; | 78 | import { datePickerOptions } from "@/utils/constants"; |
| 79 | import {addTime, beginOfDay, betweenDay, endOfDay, formatDate} from "@/utils/dateUtils"; | 79 | import {addTime, beginOfDay, betweenDay, endOfDay, formatDate} from "@/utils/dateUtils"; |
| 80 | -import {getSimpleAccounts} from "@/api/mp/account"; | 80 | +import { getSimpleAccounts } from "@/api/mp/account"; |
| 81 | 81 | ||
| 82 | export default { | 82 | export default { |
| 83 | name: 'mpStatistics', | 83 | name: 'mpStatistics', |