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 | 15 | ErrorCode ACCOUNT_CLEAR_QUOTA_FAIL = new ErrorCode(1006000001, "清空公众号的 API 配额失败,原因:{}"); |
| 16 | 16 | |
| 17 | 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 | 20 | ErrorCode STATISTICS_GET_UPSTREAM_MESSAGE_FAIL = new ErrorCode(1006001002, "获得消息发送概况数据失败,原因:{}"); |
| 21 | 21 | ErrorCode STATISTICS_GET_INTERFACE_SUMMARY_FAIL = new ErrorCode(1006001003, "获得接口分析数据失败,原因:{}"); |
| 22 | 22 | |
| ... | ... | @@ -28,8 +28,8 @@ public interface ErrorCodeConstants { |
| 28 | 28 | ErrorCode TAG_GET_FAIL = new ErrorCode(1006002001, "获得标签失败,原因:{}"); |
| 29 | 29 | |
| 30 | 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 | 34 | // ========== 公众号素材 1006004000============ |
| 35 | 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
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 | 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 | 18 | * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 |
| 19 | 19 | */ |
| 20 | 20 | @Data | ... | ... |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java
| 1 | 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 | 3 | import io.swagger.annotations.ApiModel; |
| 5 | 4 | import io.swagger.annotations.ApiModelProperty; |
| 6 | 5 | import lombok.Data; |
| 7 | 6 | import lombok.EqualsAndHashCode; |
| 8 | 7 | import lombok.ToString; |
| 9 | 8 | |
| 10 | -import javax.validation.constraints.NotNull; | |
| 11 | 9 | import java.util.Date; |
| 12 | 10 | |
| 13 | -// TODO swagger 文档 | |
| 14 | -@ApiModel("管理后台 - 微信菜单 Response VO") | |
| 11 | +@ApiModel("管理后台 - 公众号菜单 Response VO") | |
| 15 | 12 | @Data |
| 16 | 13 | @EqualsAndHashCode(callSuper = true) |
| 17 | 14 | @ToString(callSuper = true) |
| 18 | 15 | public class MpMenuRespVO extends MpMenuBaseVO { |
| 19 | 16 | |
| 20 | - @ApiModelProperty(value = "主键", required = true) | |
| 17 | + @ApiModelProperty(value = "主键", required = true, example = "1024") | |
| 21 | 18 | private Long id; |
| 22 | 19 | |
| 23 | 20 | @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") |
| 24 | - @NotNull(message = "公众号账号的编号不能为空") | |
| 25 | 21 | private Long accountId; |
| 26 | 22 | |
| 27 | - /** | |
| 28 | - * 微信公众号 appid | |
| 29 | - * | |
| 30 | - * 冗余 {@link MpAccountDO#getAppId()} | |
| 31 | - */ | |
| 23 | + @ApiModelProperty(value = "公众号 appId", required = true, example = "wx1234567890ox") | |
| 32 | 24 | private String appId; |
| 33 | 25 | |
| 34 | 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 | 9 | import javax.validation.constraints.NotNull; |
| 10 | 10 | import java.util.List; |
| 11 | 11 | |
| 12 | -// TODO 芋艿:swagger 文档 | |
| 13 | 12 | @ApiModel("管理后台 - 公众号菜单保存 Request VO") |
| 14 | 13 | @Data |
| 15 | 14 | public class MpMenuSaveReqVO { |
| ... | ... | @@ -22,9 +21,13 @@ public class MpMenuSaveReqVO { |
| 22 | 21 | @Valid |
| 23 | 22 | private List<Menu> menus; |
| 24 | 23 | |
| 24 | + @ApiModel("管理后台 - 公众号菜单保存时的每个菜单") | |
| 25 | 25 | @Data |
| 26 | 26 | public static class Menu extends MpMenuBaseVO { |
| 27 | 27 | |
| 28 | + /** | |
| 29 | + * 子菜单数组 | |
| 30 | + */ | |
| 28 | 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 | 40 | |
| 41 | 41 | @GetMapping("/get") |
| 42 | 42 | @ApiOperation("获得公众号自动回复") |
| 43 | - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024") | |
| 43 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | |
| 44 | 44 | @PreAuthorize("@ss.hasPermission('mp:auto-reply:query')") |
| 45 | 45 | public CommonResult<MpAutoReplyRespVO> getAutoReply(@RequestParam("id") Long id) { |
| 46 | 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 | 29 | private MpMessageService mpMessageService; |
| 30 | 30 | |
| 31 | 31 | @GetMapping("/page") |
| 32 | - @ApiOperation("获得粉丝消息分页") | |
| 32 | + @ApiOperation("获得公众号消息分页") | |
| 33 | 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 | 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 | 14 | @ToString(callSuper = true) |
| 15 | 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 | 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 | 17 | @ApiModelProperty(value = "主键", required = true, example = "1024") |
| 18 | 18 | private Long id; |
| 19 | 19 | |
| 20 | - @ApiModelProperty(value = "微信公众号 ID", required = true, example = "1024") | |
| 20 | + @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") | |
| 21 | 21 | private Long accountId; |
| 22 | - @ApiModelProperty(value = "微信公众号 appid", required = true, example = "wx1234567890") | |
| 22 | + @ApiModelProperty(value = "公众号 appId", required = true, example = "wx1234567890") | |
| 23 | 23 | private String appId; |
| 24 | 24 | |
| 25 | 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 | 4 | |
| 5 | 5 | import io.swagger.annotations.*; |
| 6 | 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 | 15 | @Data |
| 10 | 16 | @EqualsAndHashCode(callSuper = true) |
| 11 | 17 | @ToString(callSuper = true) |
| 12 | 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 | 22 | private Long accountId; |
| 22 | 23 | |
| 23 | - @ApiModelProperty(value = "消息类型") | |
| 24 | + @ApiModelProperty(value = "消息类型", example = "text", notes = "参见 WxConsts.XmlMsgType 枚举") | |
| 24 | 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 | 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 | 5 | import io.swagger.annotations.ApiModel; |
| 4 | 6 | import io.swagger.annotations.ApiModelProperty; |
| 5 | 7 | import lombok.Data; |
| 6 | -import lombok.EqualsAndHashCode; | |
| 7 | -import lombok.ToString; | |
| 8 | +import me.chanjar.weixin.common.api.WxConsts; | |
| 8 | 9 | |
| 9 | 10 | import java.util.Date; |
| 11 | +import java.util.List; | |
| 10 | 12 | |
| 11 | -@ApiModel("管理后台 - 粉丝消息 Response VO") | |
| 13 | +@ApiModel("管理后台 - 公众号消息 Response VO") | |
| 12 | 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 | 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 | 101 | @ApiModelProperty(value = "创建时间", required = true) |
| 21 | 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 | 4 | import io.swagger.annotations.ApiModel; |
| 5 | 5 | import io.swagger.annotations.ApiModelProperty; |
| 6 | 6 | import lombok.Data; |
| 7 | -import org.springframework.web.bind.annotation.RequestParam; | |
| 8 | 7 | |
| 9 | 8 | import javax.validation.constraints.NotEmpty; |
| 10 | 9 | |
| ... | ... | @@ -26,8 +25,8 @@ public class MpOpenHandleMessageReqVO { |
| 26 | 25 | @NotEmpty(message = "随机数不能为空") |
| 27 | 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 | 30 | private String openid; |
| 32 | 31 | |
| 33 | 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 | 31 | private MpStatisticsService mpStatisticsService; |
| 32 | 32 | |
| 33 | 33 | @GetMapping("/user-summary") |
| 34 | - @ApiOperation("获得用户增减数据") | |
| 34 | + @ApiOperation("获得粉丝增减数据") | |
| 35 | 35 | @PreAuthorize("@ss.hasPermission('mp:statistics:query')") |
| 36 | 36 | public CommonResult<List<MpStatisticsUserSummaryRespVO>> getUserSummary(MpStatisticsGetReqVO getReqVO) { |
| 37 | 37 | List<WxDataCubeUserSummary> list = mpStatisticsService.getUserSummary( |
| ... | ... | @@ -40,7 +40,7 @@ public class MpStatisticsController { |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | @GetMapping("/user-cumulate") |
| 43 | - @ApiOperation("获得用户累计数据") | |
| 43 | + @ApiOperation("获得粉丝累计数据") | |
| 44 | 44 | @PreAuthorize("@ss.hasPermission('mp:statistics:query')") |
| 45 | 45 | public CommonResult<List<MpStatisticsUserCumulateRespVO>> getUserCumulate(MpStatisticsGetReqVO getReqVO) { |
| 46 | 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 | 13 | @ApiModelProperty(value = "日期", required = true) |
| 14 | 14 | private Date refDate; |
| 15 | 15 | |
| 16 | - @ApiModelProperty(value = "通过服务器配置地址获得消息后,被动回复用户消息的次数", required = true, example = "10") | |
| 16 | + @ApiModelProperty(value = "通过服务器配置地址获得消息后,被动回复粉丝消息的次数", required = true, example = "10") | |
| 17 | 17 | private Integer callbackCount; |
| 18 | 18 | |
| 19 | 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 | 6 | |
| 7 | 7 | import java.util.Date; |
| 8 | 8 | |
| 9 | -@ApiModel("管理后台 - 某一天的用户增减数据 Response VO") | |
| 9 | +@ApiModel("管理后台 - 某一天的粉丝增减数据 Response VO") | |
| 10 | 10 | @Data |
| 11 | 11 | public class MpStatisticsUpstreamMessageRespVO { |
| 12 | 12 | |
| 13 | 13 | @ApiModelProperty(value = "日期", required = true) |
| 14 | 14 | private Date refDate; |
| 15 | 15 | |
| 16 | - @ApiModelProperty(value = "上行发送了(向公众号发送了)消息的用户数", required = true, example = "10") | |
| 16 | + @ApiModelProperty(value = "上行发送了(向公众号发送了)消息的粉丝数", required = true, example = "10") | |
| 17 | 17 | private Integer messageUser; |
| 18 | 18 | |
| 19 | 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 | 13 | @ApiModelProperty(value = "日期", required = true) |
| 14 | 14 | private Date refDate; |
| 15 | 15 | |
| 16 | - @ApiModelProperty(value = "累计用户量", required = true, example = "10") | |
| 16 | + @ApiModelProperty(value = "累计粉丝量", required = true, example = "10") | |
| 17 | 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 | 6 | |
| 7 | 7 | import java.util.Date; |
| 8 | 8 | |
| 9 | -@ApiModel("管理后台 - 某一天的用户增减数据 Response VO") | |
| 9 | +@ApiModel("管理后台 - 某一天的粉丝增减数据 Response VO") | |
| 10 | 10 | @Data |
| 11 | 11 | public class MpStatisticsUserSummaryRespVO { |
| 12 | 12 | |
| 13 | 13 | @ApiModelProperty(value = "日期", required = true) |
| 14 | 14 | private Date refDate; |
| 15 | 15 | |
| 16 | - @ApiModelProperty(value = "用户来源", required = true, example = "0") | |
| 16 | + @ApiModelProperty(value = "粉丝来源", required = true, example = "0") | |
| 17 | 17 | private Integer userSource; |
| 18 | 18 | |
| 19 | - @ApiModelProperty(value = "新关注的用户数量", required = true, example = "10") | |
| 19 | + @ApiModelProperty(value = "新关注的粉丝数量", required = true, example = "10") | |
| 20 | 20 | private Integer newUser; |
| 21 | 21 | |
| 22 | - @ApiModelProperty(value = "取消关注的用户数量", required = true, example = "20") | |
| 22 | + @ApiModelProperty(value = "取消关注的粉丝数量", required = true, example = "20") | |
| 23 | 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 | 19 | @NotNull(message = "公众号账号的编号不能为空") |
| 20 | 20 | private Long accountId; |
| 21 | 21 | |
| 22 | - @ApiModelProperty(value = "公众号用户标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", notes = "模糊匹配") | |
| 22 | + @ApiModelProperty(value = "公众号粉丝标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", notes = "模糊匹配") | |
| 23 | 23 | private String openid; |
| 24 | 24 | |
| 25 | - @ApiModelProperty(value = "公众号用户昵称", example = "芋艿", notes = "模糊匹配") | |
| 25 | + @ApiModelProperty(value = "公众号粉丝昵称", example = "芋艿", notes = "模糊匹配") | |
| 26 | 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 | 15 | @ApiModelProperty(value = "编号", required = true, example = "1024") |
| 16 | 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 | 19 | private String openid; |
| 20 | 20 | |
| 21 | 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 | 32 | @TableId |
| 33 | 33 | private Long id; |
| 34 | 34 | /** |
| 35 | - * 微信公众号 ID | |
| 35 | + * 公众号账号的编号 | |
| 36 | 36 | * |
| 37 | 37 | * 关联 {@link MpAccountDO#getId()} |
| 38 | 38 | */ |
| 39 | 39 | private Long accountId; |
| 40 | 40 | /** |
| 41 | - * 微信公众号 appid | |
| 41 | + * 公众号 appId | |
| 42 | 42 | * |
| 43 | 43 | * 冗余 {@link MpAccountDO#getAppId()} |
| 44 | 44 | */ |
| ... | ... | @@ -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 | 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 | 16 | import java.util.List; |
| 17 | 17 | |
| 18 | 18 | /** |
| 19 | - * 微信菜单 DO | |
| 19 | + * 公众号菜单 DO | |
| 20 | 20 | * |
| 21 | 21 | * @author 芋道源码 |
| 22 | 22 | */ |
| ... | ... | @@ -38,13 +38,13 @@ public class MpMenuDO extends BaseDO { |
| 38 | 38 | @TableId |
| 39 | 39 | private Long id; |
| 40 | 40 | /** |
| 41 | - * 微信公众号 ID | |
| 41 | + * 公众号账号的编号 | |
| 42 | 42 | * |
| 43 | 43 | * 关联 {@link MpAccountDO#getId()} |
| 44 | 44 | */ |
| 45 | 45 | private Long accountId; |
| 46 | 46 | /** |
| 47 | - * 微信公众号 appid | |
| 47 | + * 公众号 appId | |
| 48 | 48 | * |
| 49 | 49 | * 冗余 {@link MpAccountDO#getAppId()} |
| 50 | 50 | */ |
| ... | ... | @@ -77,7 +77,7 @@ public class MpMenuDO extends BaseDO { |
| 77 | 77 | /** |
| 78 | 78 | * 网页链接 |
| 79 | 79 | * |
| 80 | - * 用户点击菜单可打开链接,不超过 1024 字节 | |
| 80 | + * 粉丝点击菜单可打开链接,不超过 1024 字节 | |
| 81 | 81 | * |
| 82 | 82 | * 类型为 {@link WxConsts.XmlMsgType} 的 VIEW、MINIPROGRAM |
| 83 | 83 | */ |
| ... | ... | @@ -146,13 +146,13 @@ public class MpMenuDO extends BaseDO { |
| 146 | 146 | private String replyDescription; |
| 147 | 147 | |
| 148 | 148 | /** |
| 149 | - * 缩略图的媒体 id,通过素材管理中的接口上传多媒体文件,得到的 id | |
| 149 | + * 回复的缩略图的媒体 id,通过素材管理中的接口上传多媒体文件,得到的 id | |
| 150 | 150 | * |
| 151 | 151 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 MUSIC、VIDEO |
| 152 | 152 | */ |
| 153 | 153 | private String replyThumbMediaId; |
| 154 | 154 | /** |
| 155 | - * 缩略图的媒体 URL | |
| 155 | + * 回复的缩略图的媒体 URL | |
| 156 | 156 | * |
| 157 | 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 | 40 | @TableId |
| 41 | 41 | private Long id; |
| 42 | 42 | /** |
| 43 | - * 微信公众号 ID | |
| 43 | + * 公众号账号的编号 | |
| 44 | 44 | * |
| 45 | 45 | * 关联 {@link MpAccountDO#getId()} |
| 46 | 46 | */ |
| 47 | 47 | private Long accountId; |
| 48 | 48 | /** |
| 49 | - * 微信公众号 appid | |
| 49 | + * 公众号 appId | |
| 50 | 50 | * |
| 51 | 51 | * 冗余 {@link MpAccountDO#getAppId()} |
| 52 | 52 | */ |
| ... | ... | @@ -126,6 +126,19 @@ public class MpAutoReplyDO extends BaseDO { |
| 126 | 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 | 144 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS |
| ... | ... | @@ -133,4 +146,19 @@ public class MpAutoReplyDO extends BaseDO { |
| 133 | 146 | @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) |
| 134 | 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 | 40 | */ |
| 41 | 41 | private Long msgId; |
| 42 | 42 | /** |
| 43 | - * 微信公众号 ID | |
| 43 | + * 公众号账号的 ID | |
| 44 | 44 | * |
| 45 | 45 | * 关联 {@link MpAccountDO#getId()} |
| 46 | 46 | */ |
| 47 | 47 | private Long accountId; |
| 48 | 48 | /** |
| 49 | - * 微信公众号 appid | |
| 49 | + * 公众号 appid | |
| 50 | 50 | * |
| 51 | 51 | * 冗余 {@link MpAccountDO#getAppId()} |
| 52 | 52 | */ |
| 53 | 53 | private String appId; |
| 54 | 54 | /** |
| 55 | - * 微信用户编号 | |
| 55 | + * 公众号粉丝的编号 | |
| 56 | 56 | * |
| 57 | 57 | * 关联 {@link MpUserDO#getId()} |
| 58 | 58 | */ |
| 59 | 59 | private Long userId; |
| 60 | 60 | /** |
| 61 | - * 用户标识 | |
| 61 | + * 公众号粉丝标志 | |
| 62 | 62 | * |
| 63 | 63 | * 冗余 {@link MpUserDO#getOpenid()} |
| 64 | 64 | */ |
| ... | ... | @@ -87,7 +87,7 @@ public class MpMessageDO extends BaseDO { |
| 87 | 87 | private String content; |
| 88 | 88 | |
| 89 | 89 | /** |
| 90 | - * 通过素材管理中的接口上传多媒体文件,得到的 id | |
| 90 | + * 媒体文件的编号 | |
| 91 | 91 | * |
| 92 | 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 | 43 | private Integer count; |
| 44 | 44 | |
| 45 | 45 | /** |
| 46 | - * 微信公众号 ID | |
| 46 | + * 公众号账号的编号 | |
| 47 | 47 | * |
| 48 | 48 | * 关联 {@link MpAccountDO#getId()} |
| 49 | 49 | */ |
| 50 | 50 | private Long accountId; |
| 51 | 51 | /** |
| 52 | - * 微信公众号 appid | |
| 52 | + * 公众号 appId | |
| 53 | 53 | * |
| 54 | 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 | 35 | @TableId |
| 36 | 36 | private Long id; |
| 37 | 37 | /** |
| 38 | - * 用户标识 | |
| 38 | + * 粉丝标识 | |
| 39 | 39 | */ |
| 40 | 40 | private String openid; |
| 41 | 41 | /** |
| ... | ... | @@ -95,13 +95,13 @@ public class MpUserDO extends BaseDO { |
| 95 | 95 | private List<Long> tagIds; |
| 96 | 96 | |
| 97 | 97 | /** |
| 98 | - * 微信公众号 ID | |
| 98 | + * 公众号账号的编号 | |
| 99 | 99 | * |
| 100 | 100 | * 关联 {@link MpAccountDO#getId()} |
| 101 | 101 | */ |
| 102 | 102 | private Long accountId; |
| 103 | 103 | /** |
| 104 | - * 微信公众号 appid | |
| 104 | + * 公众号 appId | |
| 105 | 105 | * |
| 106 | 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 | 13 | default PageResult<MpMessageDO> selectPage(MpMessagePageReqVO reqVO) { |
| 14 | 14 | return selectPage(reqVO, new LambdaQueryWrapperX<MpMessageDO>() |
| 15 | 15 | .eqIfPresent(MpMessageDO::getAccountId, reqVO.getAccountId()) |
| 16 | - .eqIfPresent(MpMessageDO::getOpenid, reqVO.getOpenId()) | |
| 17 | -// .likeIfPresent(MpMessageDO::getNickname, reqVO.getNickname()) | |
| 18 | 16 | .eqIfPresent(MpMessageDO::getType, reqVO.getType()) |
| 17 | + .eqIfPresent(MpMessageDO::getOpenid, reqVO.getOpenid()) | |
| 18 | + .betweenIfPresent(MpMessageDO::getCreateTime, reqVO.getCreateTime()) | |
| 19 | 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 | 103 | |
| 104 | 104 | private WxMpService buildMpService(MpAccountDO account) { |
| 105 | 105 | // 第一步,创建 WxMpRedisConfigImpl 对象 |
| 106 | - // TODO 芋艿:需要确认下,redis key 的存储结构 | |
| 107 | 106 | WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl( |
| 108 | 107 | redisTemplateWxRedisOps, mpProperties.getConfigStorage().getKeyPrefix()); |
| 109 | 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
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 | 20 | @Override |
| 21 | 21 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 22 | 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 | 18 | @Override |
| 19 | 19 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 20 | 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 | 17 | public class ScanHandler implements WxMpMessageHandler { |
| 18 | 18 | |
| 19 | 19 | @Override |
| 20 | - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map<String, Object> map, | |
| 20 | + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map<String, Object> context, | |
| 21 | 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 | 16 | public class StoreCheckNotifyHandler implements WxMpMessageHandler { |
| 17 | 17 | |
| 18 | 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 | 1 | package cn.iocoder.yudao.module.mp.service.handler.user; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; | |
| 4 | 3 | import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder; |
| 5 | -import cn.iocoder.yudao.module.mp.service.account.MpAccountService; | |
| 6 | 4 | import cn.iocoder.yudao.module.mp.service.message.MpAutoReplyService; |
| 7 | 5 | import cn.iocoder.yudao.module.mp.service.user.MpUserService; |
| 8 | 6 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -13,7 +11,6 @@ import me.chanjar.weixin.mp.api.WxMpService; |
| 13 | 11 | import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; |
| 14 | 12 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; |
| 15 | 13 | import me.chanjar.weixin.mp.bean.result.WxMpUser; |
| 16 | -import org.springframework.context.annotation.Lazy; | |
| 17 | 14 | import org.springframework.stereotype.Component; |
| 18 | 15 | |
| 19 | 16 | import javax.annotation.Resource; |
| ... | ... | @@ -36,16 +33,16 @@ public class SubscribeHandler implements WxMpMessageHandler { |
| 36 | 33 | @Override |
| 37 | 34 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, |
| 38 | 35 | WxMpService weixinService, WxSessionManager sessionManager) throws WxErrorException { |
| 39 | - // 第一步,从公众号平台,获取用户信息 | |
| 40 | - log.info("[handle][用户({}) 关注]", wxMessage.getFromUser()); | |
| 36 | + // 第一步,从公众号平台,获取粉丝信息 | |
| 37 | + log.info("[handle][粉丝({}) 关注]", wxMessage.getFromUser()); | |
| 41 | 38 | WxMpUser wxMpUser = null; |
| 42 | 39 | try { |
| 43 | 40 | wxMpUser = weixinService.getUserService().userInfo(wxMessage.getFromUser()); |
| 44 | 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 | 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 | 31 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, |
| 32 | 32 | Map<String, Object> context, WxMpService wxMpService, |
| 33 | 33 | WxSessionManager sessionManager) { |
| 34 | - log.info("[handle][用户({}) 取消关注]", wxMessage.getFromUser()); | |
| 34 | + log.info("[handle][粉丝({}) 取消关注]", wxMessage.getFromUser()); | |
| 35 | 35 | mpUserService.updateUserUnsubscribe(MpContextHolder.getAppId(), wxMessage.getFromUser()); |
| 36 | 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 | 29 | void deleteMenuByAccountId(Long accountId); |
| 30 | 30 | |
| 31 | 31 | /** |
| 32 | - * 用户点击菜单按钮时,回复对应的消息 | |
| 32 | + * 粉丝点击菜单按钮时,回复对应的消息 | |
| 33 | 33 | * |
| 34 | 34 | * @param appId 公众号 AppId |
| 35 | 35 | * @param key 菜单按钮的标识 |
| 36 | - * @param openid 用户的 openid | |
| 36 | + * @param openid 粉丝的 openid | |
| 37 | 37 | * @return 消息 |
| 38 | 38 | */ |
| 39 | 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
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/message/MpAutoReplyServiceImpl.java
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 | 11 | import javax.validation.Valid; |
| 12 | 12 | |
| 13 | 13 | /** |
| 14 | - * 粉丝消息 Service 接口 | |
| 14 | + * 公众号消息 Service 接口 | |
| 15 | 15 | * |
| 16 | 16 | * @author 芋道源码 |
| 17 | 17 | */ |
| 18 | 18 | public interface MpMessageService { |
| 19 | 19 | |
| 20 | - // TODO 芋艿:方法名要优化下 | |
| 21 | 20 | /** |
| 22 | - * 获得粉丝消息分页 | |
| 21 | + * 获得公众号消息分页 | |
| 23 | 22 | * |
| 24 | 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 | 31 | * @param appId 微信公众号 appId |
| 33 | 32 | * @param wxMessage 消息 |
| ... | ... | @@ -35,7 +34,7 @@ public interface MpMessageService { |
| 35 | 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 | 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 | 63 | private Validator validator; |
| 64 | 64 | |
| 65 | 65 | @Override |
| 66 | - public PageResult<MpMessageDO> getWxFansMsgPage(MpMessagePageReqVO pageReqVO) { | |
| 66 | + public PageResult<MpMessageDO> getMessagePage(MpMessagePageReqVO pageReqVO) { | |
| 67 | 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 | 14 | /** |
| 15 | 15 | * 公众号消息发送 Request BO |
| 16 | 16 | * |
| 17 | - * 为什么要有该 BO 呢?在自动回复、客服消息、菜单回复消息等场景,都涉及到 MP 给用户发送消息,所以使用该 BO 统一承接 | |
| 17 | + * 为什么要有该 BO 呢?在自动回复、客服消息、菜单回复消息等场景,都涉及到 MP 给粉丝发送消息,所以使用该 BO 统一承接 | |
| 18 | 18 | * |
| 19 | 19 | * @author 芋道源码 |
| 20 | 20 | */ |
| ... | ... | @@ -27,9 +27,9 @@ public class MpMessageSendOutReqBO { |
| 27 | 27 | @NotEmpty(message = "公众号 appId 不能为空") |
| 28 | 28 | private String appId; |
| 29 | 29 | /** |
| 30 | - * 公众号用户 openid | |
| 30 | + * 公众号粉丝 openid | |
| 31 | 31 | */ |
| 32 | - @NotEmpty(message = "公众号用户 openid 不能为空") | |
| 32 | + @NotEmpty(message = "公众号粉丝 openid 不能为空") | |
| 33 | 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 | 16 | public interface MpStatisticsService { |
| 17 | 17 | |
| 18 | 18 | /** |
| 19 | - * 获取用户增减数据 | |
| 19 | + * 获取粉丝增减数据 | |
| 20 | 20 | * |
| 21 | 21 | * @param accountId 公众号账号编号 |
| 22 | 22 | * @param date 时间区间 |
| 23 | - * @return 用户增减数据 | |
| 23 | + * @return 粉丝增减数据 | |
| 24 | 24 | */ |
| 25 | 25 | List<WxDataCubeUserSummary> getUserSummary(Long accountId, LocalDateTime[] date); |
| 26 | 26 | |
| 27 | 27 | /** |
| 28 | - * 获取用户累计数据 | |
| 28 | + * 获取粉丝累计数据 | |
| 29 | 29 | * |
| 30 | 30 | * @param accountId 公众号账号编号 |
| 31 | 31 | * @param date 时间区间 |
| 32 | - * @return 用户累计数据 | |
| 32 | + * @return 粉丝累计数据 | |
| 33 | 33 | */ |
| 34 | 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 | 99 | // for 循环,避免递归出意外问题,导致死循环 |
| 100 | 100 | String nextOpenid = null; |
| 101 | 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 | 103 | try { |
| 104 | 104 | nextOpenid = syncUser0(account, nextOpenid); |
| 105 | 105 | } catch (WxErrorException e) { |
| 106 | - log.error("[syncUser][第({}) 次同步用户异常]", i, e); | |
| 106 | + log.error("[syncUser][第({}) 次同步粉丝异常]", i, e); | |
| 107 | 107 | break; |
| 108 | 108 | } |
| 109 | 109 | // 如果 nextOpenid 为空,表示已经同步完毕 |
| ... | ... | @@ -114,17 +114,17 @@ public class MpUserServiceImpl implements MpUserService { |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | private String syncUser0(MpAccountDO account, String nextOpenid) throws WxErrorException { |
| 117 | - // 第一步,从公众号流式加载用户 | |
| 117 | + // 第一步,从公众号流式加载粉丝 | |
| 118 | 118 | WxMpService mpService = mpServiceFactory.getRequiredMpService(account.getId()); |
| 119 | 119 | WxMpUserList wxUserList = mpService.getUserService().userList(nextOpenid); |
| 120 | 120 | if (CollUtil.isEmpty(wxUserList.getOpenids())) { |
| 121 | 121 | return null; |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | - // 第二步,分批加载用户信息 | |
| 124 | + // 第二步,分批加载粉丝信息 | |
| 125 | 125 | List<List<String>> openidsList = CollUtil.split(wxUserList.getOpenids(), 100); |
| 126 | 126 | for (List<String> openids : openidsList) { |
| 127 | - log.info("[syncUser][批量加载用户信息,openids({})]", openids); | |
| 127 | + log.info("[syncUser][批量加载粉丝信息,openids({})]", openids); | |
| 128 | 128 | List<WxMpUser> wxUsers = mpService.getUserService().userInfoList(openids); |
| 129 | 129 | batchSaveUser(account, wxUsers); |
| 130 | 130 | } |
| ... | ... | @@ -137,7 +137,7 @@ public class MpUserServiceImpl implements MpUserService { |
| 137 | 137 | if (CollUtil.isEmpty(wxUsers)) { |
| 138 | 138 | return; |
| 139 | 139 | } |
| 140 | - // 1. 获得数据库已保存的用户列表 | |
| 140 | + // 1. 获得数据库已保存的粉丝列表 | |
| 141 | 141 | List<MpUserDO> dbUsers = mpUserMapper.selectListByAppIdAndOpenid(account.getAppId(), |
| 142 | 142 | CollectionUtils.convertList(wxUsers, WxMpUser::getOpenId)); |
| 143 | 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 | 9 | }) |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | -// 创建草稿 | |
| 12 | +// 创建公众号草稿 | |
| 13 | 13 | export function createDraft(accountId, articles) { |
| 14 | 14 | return request({ |
| 15 | 15 | url: '/mp/draft/create?accountId=' + accountId, |
| ... | ... | @@ -20,7 +20,7 @@ export function createDraft(accountId, articles) { |
| 20 | 20 | }) |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | -// 更新草稿 | |
| 23 | +// 更新公众号草稿 | |
| 24 | 24 | export function updateDraft(accountId, mediaId, articles) { |
| 25 | 25 | return request({ |
| 26 | 26 | url: '/mp/draft/update?accountId=' + accountId + '&mediaId=' + mediaId, |
| ... | ... | @@ -29,7 +29,7 @@ export function updateDraft(accountId, mediaId, articles) { |
| 29 | 29 | }) |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | -// 删除草稿 | |
| 32 | +// 删除公众号草稿 | |
| 33 | 33 | export function deleteDraft(accountId, mediaId) { |
| 34 | 34 | return request({ |
| 35 | 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 | 60 | |
| 61 | 61 | // ========== MP 模块 ========== |
| 62 | 62 | MP_AUTO_REPLY_REQUEST_MATCH: 'mp_auto_reply_request_match', // 自动回复请求匹配类型 |
| 63 | + MP_MESSAGE_TYPE: 'mp_message_type', // 消息类型 | |
| 63 | 64 | |
| 64 | 65 | // ========== MALL - PRODUCT 模块 ========== |
| 65 | 66 | PRODUCT_SPU_STATUS: 'product_spu_status', // 商品 SPU 状态 | ... | ... |
yudao-ui-admin/src/views/mp/autoReply/index.vue
| ... | ... | @@ -50,49 +50,12 @@ SOFTWARE. |
| 50 | 50 | </el-col> |
| 51 | 51 | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" /> |
| 52 | 52 | </el-row> |
| 53 | - <!-- 列表 --> | |
| 53 | + <!-- tab 项 --> | |
| 54 | 54 | <el-tab-pane name="1"> |
| 55 | 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 | 56 | </el-tab-pane> |
| 75 | 57 | <el-tab-pane name="2"> |
| 76 | 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 | 59 | </el-tab-pane> |
| 97 | 60 | <el-tab-pane name="3"> |
| 98 | 61 | <span slot="label"><i class="el-icon-news"></i> 关键词回复</span> |
| ... | ... | @@ -101,13 +64,42 @@ SOFTWARE. |
| 101 | 64 | |
| 102 | 65 | <!-- 列表 --> |
| 103 | 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 | 70 | <template v-slot="scope"> |
| 107 | 71 | <dict-tag :type="DICT_TYPE.MP_AUTO_REPLY_REQUEST_MATCH" :value="scope.row.requestMatch"/> |
| 108 | 72 | </template> |
| 109 | 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 | 103 | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| 112 | 104 | <template slot-scope="scope"> |
| 113 | 105 | <span>{{ parseTime(scope.row.createTime) }}</span> |
| ... | ... | @@ -130,9 +122,9 @@ SOFTWARE. |
| 130 | 122 | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| 131 | 123 | <el-form-item label="消息类型" prop="requestMessageType" v-if="type === '2'"> |
| 132 | 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 | 128 | </el-select> |
| 137 | 129 | </el-form-item> |
| 138 | 130 | <el-form-item label="匹配类型" prop="requestMatch" v-if="type === '3'"> |
| ... | ... | @@ -157,6 +149,12 @@ SOFTWARE. |
| 157 | 149 | </template> |
| 158 | 150 | |
| 159 | 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 | 158 | import WxReplySelect from '@/views/mp/components/wx-reply/main.vue' |
| 161 | 159 | import { getSimpleAccounts } from "@/api/mp/account"; |
| 162 | 160 | import { createAutoReply, deleteAutoReply, getAutoReply, getAutoReplyPage, updateAutoReply } from "@/api/mp/autoReply"; |
| ... | ... | @@ -164,12 +162,20 @@ import { createAutoReply, deleteAutoReply, getAutoReply, getAutoReplyPage, updat |
| 164 | 162 | export default { |
| 165 | 163 | name: 'mpAutoReply', |
| 166 | 164 | components: { |
| 165 | + WxVideoPlayer, | |
| 166 | + WxVoicePlayer, | |
| 167 | + WxMsg, | |
| 168 | + WxLocation, | |
| 169 | + WxMusic, | |
| 170 | + WxNews, | |
| 167 | 171 | WxReplySelect |
| 168 | 172 | }, |
| 169 | 173 | data() { |
| 170 | 174 | return { |
| 171 | 175 | // tab 类型(1、关注时回复;2、消息回复;3、关键词回复) |
| 172 | 176 | type: '3', |
| 177 | + // 允许选择的请求消息类型 | |
| 178 | + requestMessageTypes: ['text', 'image', 'voice', 'video', 'shortvideo', 'location', 'link'], | |
| 173 | 179 | // 遮罩层 |
| 174 | 180 | loading: true, |
| 175 | 181 | // 显示搜索条件 |
| ... | ... | @@ -202,8 +208,6 @@ export default { |
| 202 | 208 | }, |
| 203 | 209 | hackResetWxReplySelect: false, // 重置 WxReplySelect 组件,解决无法清除的问题 |
| 204 | 210 | |
| 205 | - dictData: new Map(), | |
| 206 | - | |
| 207 | 211 | // 公众号账号列表 |
| 208 | 212 | accounts: [] |
| 209 | 213 | } |
| ... | ... | @@ -218,33 +222,6 @@ export default { |
| 218 | 222 | // 加载数据 |
| 219 | 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 | 226 | methods: { |
| 250 | 227 | /** 查询列表 */ |
| ... | ... | @@ -295,7 +272,8 @@ export default { |
| 295 | 272 | this.open = true |
| 296 | 273 | this.title = '新增自动回复'; |
| 297 | 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 | 9 | <div class="msg-main"> |
| 10 | 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 | 14 | <div class="el-table__empty-block" v-if="loadMore" @click="loadingMore"><span class="el-table__empty-text">点击加载更多</span></div> |
| 15 | 15 | <div class="el-table__empty-block" v-if="!loadMore"><span class="el-table__empty-text">没有更多了</span></div> |
| 16 | 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 | 19 | <div class="avue-comment" :class="item.sendFrom === 2 ? 'avue-comment--reverse' : ''"> |
| 20 | 20 | <div class="avatar-div"> |
| 21 | 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 | 124 | }, |
| 125 | 125 | props: { |
| 126 | 126 | userId: { |
| 127 | - type: String, | |
| 127 | + type: Number, | |
| 128 | 128 | required: true |
| 129 | 129 | }, |
| 130 | 130 | }, |
| 131 | 131 | data() { |
| 132 | 132 | return { |
| 133 | 133 | nowStr: new Date().getTime(), // 当前的时间戳,用于每次消息加载后,回到原位置;具体见 :id="'msg-div' + nowStr" 处 |
| 134 | - sendLoading: false, // 发送消息是否加载中 | |
| 135 | - tableLoading: false, // 消息列表是否正在加载中 | |
| 134 | + loading: false, // 消息列表是否正在加载中 | |
| 136 | 135 | loadMore: true, // 是否可以加载更多 |
| 137 | - tableData: [], // 消息列表 | |
| 138 | - page: { | |
| 136 | + list: [], // 消息列表 | |
| 137 | + queryParams: { | |
| 139 | 138 | pageNo: 1, // 当前页数 |
| 140 | 139 | pageSize: 14, // 每页显示多少条 |
| 140 | + accountId: undefined, | |
| 141 | 141 | }, |
| 142 | 142 | user: { // 由于微信不再提供昵称,直接使用“用户”展示 |
| 143 | 143 | nickname: '用户', |
| ... | ... | @@ -148,6 +148,9 @@ import { getUser } from "@/api/mp/user"; |
| 148 | 148 | nickname: '公众号', |
| 149 | 149 | avatar: require("@/assets/images/wechat.png"), |
| 150 | 150 | }, |
| 151 | + | |
| 152 | + // ========= 消息发送 ========= | |
| 153 | + sendLoading: false, // 发送消息是否加载中 | |
| 151 | 154 | objData: { // 微信发送消息 |
| 152 | 155 | type: 'text', |
| 153 | 156 | }, |
| ... | ... | @@ -156,14 +159,19 @@ import { getUser } from "@/api/mp/user"; |
| 156 | 159 | created() { |
| 157 | 160 | // 获得用户信息 |
| 158 | 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 | 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 | 176 | methods:{ |
| 169 | 177 | sendMsg(){ |
| ... | ... | @@ -190,7 +198,7 @@ import { getUser } from "@/api/mp/user"; |
| 190 | 198 | })).then(response => { |
| 191 | 199 | this.sendLoading = false |
| 192 | 200 | // 添加到消息列表,并滚动 |
| 193 | - this.tableData = [...this.tableData , ...[response.data] ] | |
| 201 | + this.list = [...this.list , ...[response.data] ] | |
| 194 | 202 | this.scrollToBottom() |
| 195 | 203 | // 重置 objData 状态 |
| 196 | 204 | this.$refs['replySelect'].deleteObj(); // 重置,避免 tab 的数据未清理 |
| ... | ... | @@ -199,15 +207,16 @@ import { getUser } from "@/api/mp/user"; |
| 199 | 207 | }) |
| 200 | 208 | }, |
| 201 | 209 | loadingMore() { |
| 202 | - this.page.pageNo++ | |
| 203 | - this.getPage(this.page) | |
| 210 | + this.queryParams.pageNo++ | |
| 211 | + this.getPage(this.queryParams) | |
| 204 | 212 | }, |
| 205 | 213 | getPage(page, params) { |
| 206 | - this.tableLoading = true | |
| 214 | + this.loading = true | |
| 207 | 215 | getMessagePage(Object.assign({ |
| 208 | 216 | pageNo: page.pageNo, |
| 209 | 217 | pageSize: page.pageSize, |
| 210 | - userId: this.userId | |
| 218 | + userId: this.userId, | |
| 219 | + accountId: page.accountId, | |
| 211 | 220 | }, params)).then(response => { |
| 212 | 221 | // 计算当前的滚动高度 |
| 213 | 222 | const msgDiv = document.getElementById('msg-div' + this.nowStr); |
| ... | ... | @@ -218,16 +227,16 @@ import { getUser } from "@/api/mp/user"; |
| 218 | 227 | |
| 219 | 228 | // 处理数据 |
| 220 | 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 | 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 | 240 | this.scrollToBottom() |
| 232 | 241 | } else if (data.length !== 0) { // 定位滚动条 |
| 233 | 242 | this.$nextTick(() => { |
| ... | ... | @@ -242,7 +251,7 @@ import { getUser } from "@/api/mp/user"; |
| 242 | 251 | * 刷新回调 |
| 243 | 252 | */ |
| 244 | 253 | refreshChange() { |
| 245 | - this.getPage(this.page) | |
| 254 | + this.getPage(this.queryParams) | |
| 246 | 255 | }, |
| 247 | 256 | /** 定位到消息底部 */ |
| 248 | 257 | scrollToBottom: function () { |
| ... | ... | @@ -267,6 +276,8 @@ import { getUser } from "@/api/mp/user"; |
| 267 | 276 | height: 50vh; |
| 268 | 277 | overflow: auto; |
| 269 | 278 | background-color: #eaeaea; |
| 279 | + margin-left: 10px; | |
| 280 | + margin-right: 10px; | |
| 270 | 281 | } |
| 271 | 282 | .msg-send { |
| 272 | 283 | padding: 10px; | ... | ... |
yudao-ui-admin/src/views/mp/menu/index.vue
| ... | ... | @@ -66,8 +66,8 @@ SOFTWARE. |
| 66 | 66 | <div class="menu_bottom menu_addicon" v-if="this.menuList.length < 3" @click="addMenu"><i class="el-icon-plus"></i></div> |
| 67 | 67 | </div> |
| 68 | 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 | 71 | </div> |
| 72 | 72 | </div> |
| 73 | 73 | <!--右边配置--> | ... | ... |
yudao-ui-admin/src/views/mp/message/index.vue
| ... | ... | @@ -8,18 +8,19 @@ |
| 8 | 8 | <el-option v-for="item in accounts" :key="parseInt(item.id)" :label="item.name" :value="parseInt(item.id)" /> |
| 9 | 9 | </el-select> |
| 10 | 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 | 16 | </el-select> |
| 16 | 17 | </el-form-item> |
| 17 | 18 | <el-form-item label="用户标识" prop="openid"> |
| 18 | 19 | <el-input v-model="queryParams.openid" placeholder="请输入用户标识" clearable @keyup.enter.native="handleQuery"/> |
| 19 | 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 | 24 | </el-form-item> |
| 24 | 25 | <el-form-item> |
| 25 | 26 | <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> |
| ... | ... | @@ -42,12 +43,11 @@ |
| 42 | 43 | <el-table-column label="消息类型" align="center" prop="type" width="80"/> |
| 43 | 44 | <el-table-column label="发送方" align="center" prop="sendFrom" width="80"> |
| 44 | 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 | 47 | <el-tag v-else type="info">公众号</el-tag> |
| 47 | 48 | </template> |
| 48 | 49 | </el-table-column> |
| 49 | 50 | <el-table-column label="用户标识" align="center" prop="openid" width="300" /> |
| 50 | - <!-- TODO 芋艿:发送/接收 --> | |
| 51 | 51 | <el-table-column label="内容" prop="content"> |
| 52 | 52 | <template slot-scope="scope"> |
| 53 | 53 | <!-- 【事件】区域 --> |
| ... | ... | @@ -118,10 +118,9 @@ |
| 118 | 118 | </el-table-column> |
| 119 | 119 | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| 120 | 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 | 124 | </template> |
| 126 | 125 | </el-table-column> |
| 127 | 126 | </el-table> |
| ... | ... | @@ -129,24 +128,26 @@ |
| 129 | 128 | <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" |
| 130 | 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 | 134 | </el-dialog> |
| 135 | 135 | |
| 136 | 136 | </div> |
| 137 | 137 | </template> |
| 138 | 138 | |
| 139 | 139 | <script> |
| 140 | -import { getMessagePage } from "@/api/mp/message"; | |
| 141 | 140 | import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'; |
| 142 | 141 | import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'; |
| 143 | 142 | import WxMsg from '@/views/mp/components/wx-msg/main.vue'; |
| 144 | 143 | import WxLocation from '@/views/mp/components/wx-location/main.vue'; |
| 145 | 144 | import WxMusic from '@/views/mp/components/wx-music/main.vue'; |
| 146 | 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 | 149 | export default { |
| 149 | - name: "WxFansMsg", | |
| 150 | + name: "MpMessage", | |
| 150 | 151 | components: { |
| 151 | 152 | WxVideoPlayer, |
| 152 | 153 | WxVoicePlayer, |
| ... | ... | @@ -167,76 +168,52 @@ export default { |
| 167 | 168 | total: 0, |
| 168 | 169 | // 粉丝消息列表 |
| 169 | 170 | list: [], |
| 170 | - // 弹出层标题 | |
| 171 | - title: "", | |
| 172 | 171 | // 是否显示弹出层 |
| 173 | - open: true, | |
| 172 | + open: false, | |
| 174 | 173 | // 查询参数 |
| 175 | - dateRangeCreateTime: [], | |
| 176 | 174 | queryParams: { |
| 177 | 175 | pageNo: 1, |
| 178 | 176 | pageSize: 10, |
| 179 | 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 | 186 | accounts: [] |
| 198 | 187 | }; |
| 199 | 188 | }, |
| 200 | 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 | 200 | methods: { |
| 204 | 201 | /** 查询列表 */ |
| 205 | 202 | getList() { |
| 203 | + // 如果没有选中公众号账号,则进行提示。 | |
| 204 | + if (!this.queryParams.accountId) { | |
| 205 | + this.$message.error('未选中公众号,无法查询消息') | |
| 206 | + return false | |
| 207 | + } | |
| 208 | + | |
| 206 | 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 | 212 | this.list = response.data.list; |
| 213 | 213 | this.total = response.data.total; |
| 214 | 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 | 218 | handleQuery() { |
| 242 | 219 | this.queryParams.pageNo = 1; |
| ... | ... | @@ -244,10 +221,17 @@ export default { |
| 244 | 221 | }, |
| 245 | 222 | /** 重置按钮操作 */ |
| 246 | 223 | resetQuery() { |
| 247 | - this.dateRangeCreateTime = []; | |
| 248 | 224 | this.resetForm("queryForm"); |
| 225 | + // 默认选中第一个 | |
| 226 | + if (this.accounts.length > 0) { | |
| 227 | + this.queryParams.accountId = this.accounts[0].id; | |
| 228 | + } | |
| 249 | 229 | this.handleQuery(); |
| 250 | 230 | }, |
| 231 | + handleSend(row) { | |
| 232 | + this.userId = row.userId; | |
| 233 | + this.open = true; | |
| 234 | + }, | |
| 251 | 235 | } |
| 252 | 236 | }; |
| 253 | 237 | </script> | ... | ... |
yudao-ui-admin/src/views/mp/statistics/index.vue
| ... | ... | @@ -77,7 +77,7 @@ require('echarts/lib/component/legend') |
| 77 | 77 | import { getInterfaceSummary, getUserSummary, getUserCumulate, getUpstreamMessage} from '@/api/mp/statistics' |
| 78 | 78 | import { datePickerOptions } from "@/utils/constants"; |
| 79 | 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 | 82 | export default { |
| 83 | 83 | name: 'mpStatistics', | ... | ... |