Commit b5815a62fc05fc91501de4a9c461f84433cebe3e
1 parent
64fa3a7e
mp:自定义菜单的图文选择
Showing
5 changed files
with
59 additions
and
28 deletions
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuBaseVO.java
| @@ -57,6 +57,10 @@ public class MpMenuBaseVO { | @@ -57,6 +57,10 @@ public class MpMenuBaseVO { | ||
| 57 | @NotEmpty(message = "小程序的页面路径不能为空", groups = MiniProgramButtonGroup.class) | 57 | @NotEmpty(message = "小程序的页面路径不能为空", groups = MiniProgramButtonGroup.class) |
| 58 | private String miniProgramPagePath; | 58 | private String miniProgramPagePath; |
| 59 | 59 | ||
| 60 | + @ApiModelProperty(value ="跳转图文的媒体编号", example = "jCQk93AIIgp8ixClWcW_NXXqBKInNWNmq2XnPeDZl7IMVqWiNeL4FfELtggRXd83") | ||
| 61 | + @NotEmpty(message = "跳转图文的媒体编号不能为空", groups = ViewLimitedButtonGroup.class) | ||
| 62 | + private String articleId; | ||
| 63 | + | ||
| 60 | // ========== 消息内容 ========== | 64 | // ========== 消息内容 ========== |
| 61 | 65 | ||
| 62 | @ApiModelProperty(value = "消息类型", example = "text", | 66 | @ApiModelProperty(value = "消息类型", example = "text", |
| @@ -65,7 +69,7 @@ public class MpMenuBaseVO { | @@ -65,7 +69,7 @@ public class MpMenuBaseVO { | ||
| 65 | private String replyMessageType; | 69 | private String replyMessageType; |
| 66 | 70 | ||
| 67 | @ApiModelProperty(value = "回复的消息内容", example = "欢迎关注") | 71 | @ApiModelProperty(value = "回复的消息内容", example = "欢迎关注") |
| 68 | - @NotEmpty(message = "回复的消息内容不能为空", groups = {TextMessageGroup.class}) | 72 | + @NotEmpty(message = "回复的消息内容不能为空", groups = TextMessageGroup.class) |
| 69 | private String replyContent; | 73 | private String replyContent; |
| 70 | 74 | ||
| 71 | @ApiModelProperty(value = "回复的媒体 id", example = "123456") | 75 | @ApiModelProperty(value = "回复的媒体 id", example = "123456") |
| @@ -96,7 +100,7 @@ public class MpMenuBaseVO { | @@ -96,7 +100,7 @@ public class MpMenuBaseVO { | ||
| 96 | * | 100 | * |
| 97 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS | 101 | * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS |
| 98 | */ | 102 | */ |
| 99 | - @NotNull(message = "回复的图文消息不能为空", groups = NewsMessageGroup.class) | 103 | + @NotNull(message = "回复的图文消息不能为空", groups = {NewsMessageGroup.class, ViewLimitedButtonGroup.class}) |
| 100 | @Valid | 104 | @Valid |
| 101 | private List<MpMessageDO.Article> replyArticles; | 105 | private List<MpMessageDO.Article> replyArticles; |
| 102 | 106 |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/menu/MpMenuDO.java
| @@ -96,6 +96,11 @@ public class MpMenuDO extends BaseDO { | @@ -96,6 +96,11 @@ public class MpMenuDO extends BaseDO { | ||
| 96 | */ | 96 | */ |
| 97 | private String miniProgramPagePath; | 97 | private String miniProgramPagePath; |
| 98 | 98 | ||
| 99 | + /** | ||
| 100 | + * 跳转图文的媒体编号 | ||
| 101 | + */ | ||
| 102 | + private String articleId; | ||
| 103 | + | ||
| 99 | // ========== 消息内容 ========== | 104 | // ========== 消息内容 ========== |
| 100 | 105 | ||
| 101 | /** | 106 | /** |
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/mp/core/util/MpUtils.java
| @@ -72,6 +72,9 @@ public class MpUtils { | @@ -72,6 +72,9 @@ public class MpUtils { | ||
| 72 | group = ScanCodeWaitMsgButtonGroup.class; | 72 | group = ScanCodeWaitMsgButtonGroup.class; |
| 73 | validateMessage(validator, messageType, button); // 需要额外校验回复的消息格式 | 73 | validateMessage(validator, messageType, button); // 需要额外校验回复的消息格式 |
| 74 | break; | 74 | break; |
| 75 | + case "article_" + WxConsts.MenuButtonType.VIEW_LIMITED: | ||
| 76 | + group = ViewLimitedButtonGroup.class; | ||
| 77 | + break; | ||
| 75 | case WxConsts.MenuButtonType.SCANCODE_PUSH: // 不用校验,直接 return 即可 | 78 | case WxConsts.MenuButtonType.SCANCODE_PUSH: // 不用校验,直接 return 即可 |
| 76 | case WxConsts.MenuButtonType.PIC_SYSPHOTO: | 79 | case WxConsts.MenuButtonType.PIC_SYSPHOTO: |
| 77 | case WxConsts.MenuButtonType.PIC_PHOTO_OR_ALBUM: | 80 | case WxConsts.MenuButtonType.PIC_PHOTO_OR_ALBUM: |
| @@ -156,4 +159,9 @@ public class MpUtils { | @@ -156,4 +159,9 @@ public class MpUtils { | ||
| 156 | * SCANCODE_WAITMSG 类型的按钮,参数校验 Group | 159 | * SCANCODE_WAITMSG 类型的按钮,参数校验 Group |
| 157 | */ | 160 | */ |
| 158 | public interface ScanCodeWaitMsgButtonGroup {} | 161 | public interface ScanCodeWaitMsgButtonGroup {} |
| 162 | + | ||
| 163 | + /** | ||
| 164 | + * VIEW_LIMITED 类型的按钮,参数校验 Group | ||
| 165 | + */ | ||
| 166 | + public interface ViewLimitedButtonGroup {} | ||
| 159 | } | 167 | } |
yudao-ui-admin/src/views/mp/components/wx-news/main.vue
| @@ -42,9 +42,9 @@ | @@ -42,9 +42,9 @@ | ||
| 42 | type: Array // title - 标题;description - 描述;picUrl - 图片连接;url - 跳转链接 | 42 | type: Array // title - 标题;description - 描述;picUrl - 图片连接;url - 跳转链接 |
| 43 | } | 43 | } |
| 44 | }, | 44 | }, |
| 45 | - created() { | ||
| 46 | - console.log(this.articles) | ||
| 47 | - }, | 45 | + // created() { |
| 46 | + // console.log(this.articles) | ||
| 47 | + // }, | ||
| 48 | }; | 48 | }; |
| 49 | </script> | 49 | </script> |
| 50 | 50 |
yudao-ui-admin/src/views/mp/menu/index.vue
| @@ -113,21 +113,23 @@ SOFTWARE. | @@ -113,21 +113,23 @@ SOFTWARE. | ||
| 113 | </div> | 113 | </div> |
| 114 | <div class="configur_content" v-if="tempObj.type === 'article_view_limited'"> | 114 | <div class="configur_content" v-if="tempObj.type === 'article_view_limited'"> |
| 115 | <el-row> | 115 | <el-row> |
| 116 | - <div class="select-item" v-if="tempObj && tempObj.content && tempObj.content.articles"> | ||
| 117 | - <WxNews :objData="tempObj.content.articles"></WxNews> | 116 | + <div class="select-item" v-if="tempObj && tempObj.replyArticles"> |
| 117 | + <wx-news :articles="tempObj.replyArticles" /> | ||
| 118 | <el-row class="ope-row"> | 118 | <el-row class="ope-row"> |
| 119 | - <el-button type="danger" icon="el-icon-delete" circle @click="deleteTempObj" /> | 119 | + <el-button type="danger" icon="el-icon-delete" circle @click="deleteMaterial" /> |
| 120 | </el-row> | 120 | </el-row> |
| 121 | </div> | 121 | </div> |
| 122 | - <div v-if="!tempObj.content || !tempObj.content.articles"> | 122 | + <div v-else> |
| 123 | <el-row> | 123 | <el-row> |
| 124 | <el-col :span="24" style="text-align: center"> | 124 | <el-col :span="24" style="text-align: center"> |
| 125 | - <el-button type="success" @click="openMaterial">素材库选择<i class="el-icon-circle-check el-icon--right"></i></el-button> | 125 | + <el-button type="success" @click="openMaterial"> |
| 126 | + 素材库选择<i class="el-icon-circle-check el-icon--right"></i> | ||
| 127 | + </el-button> | ||
| 126 | </el-col> | 128 | </el-col> |
| 127 | </el-row> | 129 | </el-row> |
| 128 | </div> | 130 | </div> |
| 129 | <el-dialog title="选择图文" :visible.sync="dialogNewsVisible" width="90%"> | 131 | <el-dialog title="选择图文" :visible.sync="dialogNewsVisible" width="90%"> |
| 130 | - <WxMaterialSelect :objData="{repType:'news'}" @selectMaterial="selectMaterial"></WxMaterialSelect> | 132 | + <wx-material-select :objData="{type: 'news', accountId: this.accountId}" @selectMaterial="selectMaterial" /> |
| 131 | </el-dialog> | 133 | </el-dialog> |
| 132 | </el-row> | 134 | </el-row> |
| 133 | </div> | 135 | </div> |
| @@ -148,7 +150,7 @@ SOFTWARE. | @@ -148,7 +150,7 @@ SOFTWARE. | ||
| 148 | <script> | 150 | <script> |
| 149 | import WxReplySelect from '@/views/mp/components/wx-reply/main.vue' | 151 | import WxReplySelect from '@/views/mp/components/wx-reply/main.vue' |
| 150 | import WxNews from '@/views/mp/components/wx-news/main.vue'; | 152 | import WxNews from '@/views/mp/components/wx-news/main.vue'; |
| 151 | -import WxMaterialSelect from '@/views/mp/components/wx-news/main.vue' | 153 | +import WxMaterialSelect from '@/views/mp/components/wx-material-select/main.vue' |
| 152 | import { deleteMenu, getMenuList, saveMenu } from "@/api/mp/menu"; | 154 | import { deleteMenu, getMenuList, saveMenu } from "@/api/mp/menu"; |
| 153 | import { getSimpleAccounts } from "@/api/mp/account"; | 155 | import { getSimpleAccounts } from "@/api/mp/account"; |
| 154 | 156 | ||
| @@ -359,10 +361,9 @@ export default { | @@ -359,10 +361,9 @@ export default { | ||
| 359 | this.$delete( item, 'miniProgramPagePath') | 361 | this.$delete( item, 'miniProgramPagePath') |
| 360 | this.$delete( item, 'url') | 362 | this.$delete( item, 'url') |
| 361 | this.$delete( item, 'reply') | 363 | this.$delete( item, 'reply') |
| 362 | - // TODO 芋艿:需要搞的属性弄下 | ||
| 363 | - | ||
| 364 | - this.$delete( item, 'article_id') | ||
| 365 | - this.$delete( item, 'textContent') | 364 | + this.$delete( item, 'articleId') |
| 365 | + this.$delete( item, 'replyArticles') | ||
| 366 | + // 关闭配置面板 | ||
| 366 | this.showConfigureContent = false | 367 | this.showConfigureContent = false |
| 367 | } | 368 | } |
| 368 | 369 | ||
| @@ -471,24 +472,37 @@ export default { | @@ -471,24 +472,37 @@ export default { | ||
| 471 | openMaterial() { | 472 | openMaterial() { |
| 472 | this.dialogNewsVisible = true | 473 | this.dialogNewsVisible = true |
| 473 | }, | 474 | }, |
| 474 | - selectMaterial(item){ | ||
| 475 | - if(item.content.articles.length>1){ | 475 | + selectMaterial(item) { |
| 476 | + const articleId = item.articleId; | ||
| 477 | + const articles = item.content.newsItem; | ||
| 478 | + // 提示,针对多图文 | ||
| 479 | + if (articles.length > 1) { | ||
| 476 | this.$alert('您选择的是多图文,将默认跳转第一篇', '提示', { | 480 | this.$alert('您选择的是多图文,将默认跳转第一篇', '提示', { |
| 477 | confirmButtonText: '确定' | 481 | confirmButtonText: '确定' |
| 478 | }) | 482 | }) |
| 479 | } | 483 | } |
| 480 | this.dialogNewsVisible = false | 484 | this.dialogNewsVisible = false |
| 481 | - this.tempObj.article_id = item.articleId | ||
| 482 | - this.tempObj.mediaName = item.name | ||
| 483 | - this.tempObj.url = item.url | ||
| 484 | - item.mediaType = this.tempObj.mediaType | ||
| 485 | - item.content.articles = item.content.articles.slice(0,1) | ||
| 486 | - this.tempObj.content = item.content | 485 | + |
| 486 | + // 设置菜单的回复 | ||
| 487 | + this.tempObj.articleId = articleId; | ||
| 488 | + this.tempObj.replyArticles = []; | ||
| 489 | + articles.forEach(article => { | ||
| 490 | + this.tempObj.replyArticles.push({ | ||
| 491 | + title: article.title, | ||
| 492 | + description: article.digest, | ||
| 493 | + picUrl: article.picUrl, | ||
| 494 | + url: article.url, | ||
| 495 | + }) | ||
| 496 | + }) | ||
| 497 | + // this.tempObj.mediaName = item.name | ||
| 498 | + // this.tempObj.url = item.url | ||
| 499 | + // item.mediaType = this.tempObj.mediaType | ||
| 500 | + // item.content.articles = item.content.articles.slice(0,1) | ||
| 501 | + // this.tempObj.content = item.content | ||
| 487 | }, | 502 | }, |
| 488 | - deleteTempObj() { | ||
| 489 | - this.$delete(this.tempObj,'repName') | ||
| 490 | - this.$delete(this.tempObj,'repUrl') | ||
| 491 | - this.$delete(this.tempObj,'content') | 503 | + deleteMaterial() { |
| 504 | + this.$delete(this.tempObj,'articleId') | ||
| 505 | + this.$delete(this.tempObj,'replyArticles') | ||
| 492 | }, | 506 | }, |
| 493 | }, | 507 | }, |
| 494 | } | 508 | } |