Commit 02ccf52d6c5476e549cc164e980531d45a957d6d
1 parent
5901ab66
mp:增加发送【图文】消息
Showing
8 changed files
with
91 additions
and
87 deletions
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpDraftController.http
| ... | ... | @@ -19,6 +19,14 @@ tenant-id: {{adminTenentId}} |
| 19 | 19 | "content": "我是内容", |
| 20 | 20 | "contentSourceUrl": "https://www.iocoder.cn", |
| 21 | 21 | "thumbMediaId": "r6ryvl6LrxBU0miaST4Y-pIcmK-zAAId-9TGgy-DrSLhjVuWbuT3ZBjk9K1yQ0Dn" |
| 22 | + }, | |
| 23 | + { | |
| 24 | + "title": "我是标题 2", | |
| 25 | + "author": "我是作者 2", | |
| 26 | + "digest": "我是摘要 2", | |
| 27 | + "content": "我是内容 2", | |
| 28 | + "contentSourceUrl": "https://www.iocoder.cn", | |
| 29 | + "thumbMediaId": "r6ryvl6LrxBU0miaST4Y-pIcmK-zAAId-9TGgy-DrSLhjVuWbuT3ZBjk9K1yQ0Dn" | |
| 22 | 30 | } |
| 23 | 31 | ] |
| 24 | 32 | } | ... | ... |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpFreePublishController.http
| ... | ... | @@ -5,7 +5,7 @@ Authorization: Bearer {{token}} |
| 5 | 5 | tenant-id: {{adminTenentId}} |
| 6 | 6 | |
| 7 | 7 | ### 请求 /mp/free-publish/submit 接口 => 成功 |
| 8 | -POST {{baseUrl}}/mp/free-publish/submit?accountId=1&mediaId=r6ryvl6LrxBU0miaST4Y-pEm50d1qKxNPkZVzrRZthSJHKCgiylCf4tARZfybZ_O | |
| 8 | +POST {{baseUrl}}/mp/free-publish/submit?accountId=1&mediaId=r6ryvl6LrxBU0miaST4Y-vilmd7iS51D8IPddxflWrau0hIQ2ovY8YanO5jlgUcM | |
| 9 | 9 | Content-Type: application/json |
| 10 | 10 | Authorization: Bearer {{token}} |
| 11 | 11 | tenant-id: {{adminTenentId}} | ... | ... |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpFreePublishController.java
| ... | ... | @@ -44,6 +44,7 @@ public class MpFreePublishController { |
| 44 | 44 | } catch (WxErrorException e) { |
| 45 | 45 | throw exception(FREE_PUBLISH_LIST_FAIL, e.getError().getErrorMsg()); |
| 46 | 46 | } |
| 47 | + // todo 芋艿:需要查询对应的缩略图,不然前端无法展示 | |
| 47 | 48 | |
| 48 | 49 | // 返回分页 |
| 49 | 50 | return success(new PageResult<>(publicationRecords.getItems(), publicationRecords.getTotalCount().longValue())); | ... | ... |
yudao-ui-admin/src/api/mp/freePublish.js
0 → 100644
yudao-ui-admin/src/views/mp/components/wx-material-select/main.vue
| ... | ... | @@ -48,7 +48,7 @@ |
| 48 | 48 | </el-table> |
| 49 | 49 | <!-- 分页组件 --> |
| 50 | 50 | <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" |
| 51 | - @pagination="getMaterialPage"/> | |
| 51 | + @pagination="getPage"/> | |
| 52 | 52 | </div> |
| 53 | 53 | <div v-else-if="objData.type === 'video'"> |
| 54 | 54 | <!-- 列表 --> |
| ... | ... | @@ -78,41 +78,32 @@ |
| 78 | 78 | <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" |
| 79 | 79 | @pagination="getMaterialPage"/> |
| 80 | 80 | </div> |
| 81 | - <div v-else-if="objData.type == 'news'"> | |
| 81 | + <div v-else-if="objData.type === 'news'"> | |
| 82 | 82 | <div class="waterfall" v-loading="loading"> |
| 83 | - <div class="waterfall-item" v-for="item in list" :key="item.mediaId" v-if="item.content && item.content.articles"> | |
| 84 | - <WxNews :objData="item.content.articles"></WxNews> | |
| 83 | + <div class="waterfall-item" v-for="item in list" :key="item.mediaId" v-if="item.content && item.content.newsItem"> | |
| 84 | + <wx-news :articles="item.content.newsItem" /> | |
| 85 | 85 | <el-row class="ope-row"> |
| 86 | - <el-button size="mini" type="success" @click="selectMaterial(item)">选择<i class="el-icon-circle-check el-icon--right"></i></el-button> | |
| 86 | + <el-button size="mini" type="success" @click="selectMaterial(item)"> | |
| 87 | + 选择<i class="el-icon-circle-check el-icon--right"></i> | |
| 88 | + </el-button> | |
| 87 | 89 | </el-row> |
| 88 | 90 | </div> |
| 89 | 91 | </div> |
| 90 | - <div v-if="list.length <=0 && !loading" class="el-table__empty-block"> | |
| 92 | + <!-- 分页组件 --> | |
| 93 | + <div v-if="list.length <= 0 && !loading" class="el-table__empty-block"> | |
| 91 | 94 | <span class="el-table__empty-text">暂无数据</span> |
| 92 | 95 | </div> |
| 93 | - <span slot="footer" class="dialog-footer"> | |
| 94 | - <el-pagination | |
| 95 | - @size-change="sizeChange" | |
| 96 | - :current-page.sync="page.currentPage" | |
| 97 | - :page-sizes="[10, 20]" | |
| 98 | - :page-size="page.pageSize" | |
| 99 | - layout="total, sizes, prev, pager, next, jumper" | |
| 100 | - :total="page.total" | |
| 101 | - class="pagination" | |
| 102 | - > | |
| 103 | - </el-pagination> | |
| 104 | - </span> | |
| 96 | + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 97 | + @pagination="getMaterialPage"/> | |
| 105 | 98 | </div> |
| 106 | 99 | </template> |
| 107 | 100 | |
| 108 | 101 | <script> |
| 109 | - | |
| 110 | - // import { tableOptionVoice } from '@/const/crud/wxmp/wxmaterial_voice' | |
| 111 | - // import { tableOptionVideo } from '@/const/crud/wxmp/wxmaterial_video' | |
| 112 | 102 | import WxNews from '@/views/mp/components/wx-news/main.vue'; |
| 113 | 103 | import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'; |
| 114 | 104 | import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'; |
| 115 | 105 | import { getMaterialPage } from "@/api/mp/material"; |
| 106 | + import {getFreePublishPage} from "@/api/mp/freePublish"; | |
| 116 | 107 | |
| 117 | 108 | export default { |
| 118 | 109 | name: "wxMaterialSelect", |
| ... | ... | @@ -143,56 +134,40 @@ |
| 143 | 134 | queryParams: { |
| 144 | 135 | pageNo: 1, |
| 145 | 136 | pageSize: 10, |
| 137 | + accountId: this.objData.accountId, | |
| 146 | 138 | }, |
| 147 | 139 | // tableOptionVoice: tableOptionVoice, |
| 148 | 140 | // tableOptionVideo: tableOptionVideo, |
| 149 | 141 | } |
| 150 | 142 | }, |
| 151 | 143 | created() { |
| 152 | - this.getPage(this.page) | |
| 144 | + this.getPage() | |
| 153 | 145 | }, |
| 154 | 146 | methods:{ |
| 155 | - selectMaterial(item){ | |
| 147 | + selectMaterial(item) { | |
| 156 | 148 | this.$emit('selectMaterial', item) |
| 157 | 149 | }, |
| 158 | - getPage(page, params) { | |
| 150 | + getPage() { | |
| 159 | 151 | this.loading = true |
| 160 | - if(this.objData.type == 'news'){ // 【图文】 | |
| 161 | - if(this.newsType == '1'){ | |
| 162 | - getPageNews(Object.assign({ | |
| 163 | - current: page.currentPage, | |
| 164 | - size: page.pageSize, | |
| 165 | - appId:this.appId, | |
| 166 | - }, params)).then(response => { | |
| 167 | - let tableData = response.data.items | |
| 168 | - tableData.forEach(item => { | |
| 169 | - item.mediaId = item.articleId | |
| 170 | - item.content.articles = item.content.newsItem | |
| 171 | - }) | |
| 172 | - this.list = tableData | |
| 173 | - this.page.total = response.data.totalCount | |
| 174 | - this.page.currentPage = page.currentPage | |
| 175 | - this.page.pageSize = page.pageSize | |
| 176 | - this.loading = false | |
| 177 | - }) | |
| 178 | - }else if(this.newsType == '2'){ | |
| 179 | - getPageNewsDraft(Object.assign({ | |
| 180 | - current: page.currentPage, | |
| 181 | - size: page.pageSize, | |
| 182 | - appId:this.appId, | |
| 183 | - }, params)).then(response => { | |
| 184 | - let tableData = response.data.items | |
| 185 | - tableData.forEach(item => { | |
| 186 | - item.mediaId = item.mediaId | |
| 187 | - item.content.articles = item.content.newsItem | |
| 188 | - }) | |
| 189 | - this.list = tableData | |
| 190 | - this.page.total = response.data.totalCount | |
| 191 | - this.page.currentPage = page.currentPage | |
| 192 | - this.page.pageSize = page.pageSize | |
| 193 | - this.loading = false | |
| 152 | + if (this.objData.type === 'news' && this.newsType === '1') { // 【图文】+ 【已发布】 | |
| 153 | + this.getFreePublishPage(); | |
| 154 | + } else if (this.objData.type === 'news' && this.newsType === '2') { // 【图文】+ 【草稿】 | |
| 155 | + getPageNewsDraft(Object.assign({ | |
| 156 | + current: page.currentPage, | |
| 157 | + size: page.pageSize, | |
| 158 | + appId:this.appId, | |
| 159 | + }, params)).then(response => { | |
| 160 | + let tableData = response.data.items | |
| 161 | + tableData.forEach(item => { | |
| 162 | + item.mediaId = item.mediaId | |
| 163 | + item.content.articles = item.content.newsItem | |
| 194 | 164 | }) |
| 195 | - } | |
| 165 | + this.list = tableData | |
| 166 | + this.page.total = response.data.totalCount | |
| 167 | + this.page.currentPage = page.currentPage | |
| 168 | + this.page.pageSize = page.pageSize | |
| 169 | + this.loading = false | |
| 170 | + }) | |
| 196 | 171 | } else { // 【素材】 |
| 197 | 172 | this.getMaterialPage(); |
| 198 | 173 | } |
| ... | ... | @@ -208,20 +183,20 @@ |
| 208 | 183 | this.loading = false |
| 209 | 184 | }) |
| 210 | 185 | }, |
| 211 | - sizeChange(val) { | |
| 212 | - this.page.currentPage = 1 | |
| 213 | - this.page.pageSize = val | |
| 214 | - this.getPage(this.page) | |
| 215 | - }, | |
| 216 | - currentChange(val) { | |
| 217 | - this.page.currentPage = val | |
| 218 | - this.getPage(this.page) | |
| 219 | - }, | |
| 220 | - /** | |
| 221 | - * 刷新回调 | |
| 222 | - */ | |
| 223 | - refreshChange(page) { | |
| 224 | - this.getPage(this.page) | |
| 186 | + getFreePublishPage() { | |
| 187 | + getFreePublishPage(this.queryParams).then(response => { | |
| 188 | + // 将 thumbUrl 转成 picUrl,保证 wx-news 组件可以预览封面 | |
| 189 | + response.data.list.forEach(item => { | |
| 190 | + const newsItem = item.content.newsItem; | |
| 191 | + newsItem.forEach(article => { | |
| 192 | + article.picUrl = article.thumbUrl; | |
| 193 | + }) | |
| 194 | + }) | |
| 195 | + this.list = response.data.list | |
| 196 | + this.total = response.data.total | |
| 197 | + }).finally(() => { | |
| 198 | + this.loading = false | |
| 199 | + }) | |
| 225 | 200 | } |
| 226 | 201 | } |
| 227 | 202 | }; | ... | ... |
yudao-ui-admin/src/views/mp/components/wx-msg/main.vue
| ... | ... | @@ -155,21 +155,23 @@ import { getUser } from "@/api/mp/user"; |
| 155 | 155 | if (!this.objData) { |
| 156 | 156 | return; |
| 157 | 157 | } |
| 158 | - if (this.objData.type === 'news') { | |
| 159 | - this.objData.content.articles = [this.objData.content.articles[0]] | |
| 158 | + // 公众号限制:客服消息,公众号只允许发送一条 | |
| 159 | + if (this.objData.type === 'news' | |
| 160 | + && this.objData.articles.length > 1) { | |
| 161 | + this.objData.articles = [this.objData.articles[0]] | |
| 160 | 162 | this.$message({ |
| 161 | 163 | showClose: true, |
| 162 | - message: '图文消息条数限制在1条以内,已默认发送第一条', | |
| 164 | + message: '图文消息条数限制在 1 条以内,已默认发送第一条', | |
| 163 | 165 | type: 'success' |
| 164 | 166 | }) |
| 165 | 167 | } |
| 168 | + | |
| 169 | + // 执行发送 | |
| 166 | 170 | this.sendLoading = true |
| 167 | 171 | sendMessage(Object.assign({ |
| 168 | 172 | userId: this.userId |
| 169 | 173 | }, { |
| 170 | - ...this.objData, | |
| 171 | - // content: this.objData.repContent, | |
| 172 | - // TODO 芋艿:临时适配,保证可用 | |
| 174 | + ...this.objData | |
| 173 | 175 | })).then(response => { |
| 174 | 176 | this.sendLoading = false |
| 175 | 177 | // 添加到消息列表,并滚动 | ... | ... |
yudao-ui-admin/src/views/mp/components/wx-news/main.vue
yudao-ui-admin/src/views/mp/components/wx-reply/main.vue
| ... | ... | @@ -118,18 +118,20 @@ |
| 118 | 118 | </el-row> |
| 119 | 119 | </el-row> |
| 120 | 120 | </el-tab-pane> |
| 121 | + <!-- 类型 5:图文 --> | |
| 121 | 122 | <el-tab-pane name="news"> |
| 122 | 123 | <span slot="label"><i class="el-icon-news"></i> 图文</span> |
| 123 | 124 | <el-row> |
| 124 | - <div class="select-item" v-if="objData.content"> | |
| 125 | - <WxNews :objData="objData.content.articles"></WxNews> | |
| 125 | + <div class="select-item" v-if="objData.articles"> | |
| 126 | + <wx-news :articles="objData.articles" /> | |
| 126 | 127 | <el-row class="ope-row"> |
| 127 | - <el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button> | |
| 128 | + <el-button type="danger" icon="el-icon-delete" circle @click="deleteObj" /> | |
| 128 | 129 | </el-row> |
| 129 | 130 | </div> |
| 131 | + <!-- 选择素材 --> | |
| 130 | 132 | <div v-if="!objData.content"> |
| 131 | 133 | <el-row style="text-align: center"> |
| 132 | - <el-col :span="24" class="col-select2"> | |
| 134 | + <el-col :span="24"> | |
| 133 | 135 | <el-button type="success" @click="openMaterial">{{newsType === '1' ? '选择已发布图文' : '选择草稿箱图文'}}<i class="el-icon-circle-check el-icon--right"></i></el-button> |
| 134 | 136 | </el-col> |
| 135 | 137 | </el-row> |
| ... | ... | @@ -369,7 +371,10 @@ |
| 369 | 371 | // 创建 tempObjItem 对象,并设置对应的值 |
| 370 | 372 | let tempObjItem = {} |
| 371 | 373 | tempObjItem.type = this.objData.type; |
| 372 | - if (this.objData.type === 'music') { // 音乐需要特殊处理,因为选择的是图片的缩略图 | |
| 374 | + if (this.objData.type === 'news') { | |
| 375 | + tempObjItem.articles = item.content.newsItem | |
| 376 | + this.objData.articles = item.content.newsItem | |
| 377 | + } else if (this.objData.type === 'music') { // 音乐需要特殊处理,因为选择的是图片的缩略图 | |
| 373 | 378 | tempObjItem.thumbMediaId = item.mediaId |
| 374 | 379 | this.objData.thumbMediaId = item.mediaId |
| 375 | 380 | tempObjItem.thumbMediaUrl = item.url |
| ... | ... | @@ -431,7 +436,7 @@ |
| 431 | 436 | }, |
| 432 | 437 | deleteObj() { |
| 433 | 438 | if (this.objData.type === 'news') { |
| 434 | - this.objData.articles = [] | |
| 439 | + this.$delete(this.objData, 'articles'); | |
| 435 | 440 | } else if(this.objData.type === 'image') { |
| 436 | 441 | this.objData.mediaId = null |
| 437 | 442 | this.objData.url = null | ... | ... |