mp:支持 wx-reply 发送图片消息

This commit is contained in:
YunaiV 2023-01-12 00:24:04 +08:00
parent ec872c702c
commit 29cf770457
3 changed files with 215 additions and 112 deletions

View File

@ -94,3 +94,6 @@ export function setTenantId(username) {
export function removeTenantId() { export function removeTenantId() {
localStorage.removeItem(TenantIdKey) localStorage.removeItem(TenantIdKey)
} }
export class getToken {
}

View File

@ -81,7 +81,7 @@
</div> </div>
</div> </div>
<div class="msg-send" v-loading="sendLoading"> <div class="msg-send" v-loading="sendLoading">
<WxReplySelect :objData="objData"></WxReplySelect> <wx-reply-select :objData="objData" />
<el-button type="success" size="small" class="send-but" @click="sendMsg">发送(S)</el-button> <el-button type="success" size="small" class="send-but" @click="sendMsg">发送(S)</el-button>
</div> </div>
</div> </div>
@ -95,6 +95,7 @@ import {getMessagePage, sendMessage} from '@/api/mp/message'
import WxNews from '@/views/mp/components/wx-news/main.vue'; import WxNews from '@/views/mp/components/wx-news/main.vue';
import WxLocation from '@/views/mp/components/wx-location/main.vue'; import WxLocation from '@/views/mp/components/wx-location/main.vue';
import WxMusic from '@/views/mp/components/wx-music/main.vue'; import WxMusic from '@/views/mp/components/wx-music/main.vue';
import {getUser} from "@/api/mp/user";
export default { export default {
name: "wxMsg", name: "wxMsg",
@ -110,7 +111,7 @@ import {getMessagePage, sendMessage} from '@/api/mp/message'
userId: { userId: {
type: String, type: String,
required: true required: true
} },
}, },
data() { data() {
return { return {
@ -126,17 +127,27 @@ import {getMessagePage, sendMessage} from '@/api/mp/message'
user: { // 使 user: { // 使
nickname: '用户', nickname: '用户',
avatar: require("@/assets/images/profile.jpg"), avatar: require("@/assets/images/profile.jpg"),
accountId: 0, //
}, },
mp: { mp: {
nickname: '公众号', nickname: '公众号',
avatar: require("@/assets/images/wechat.png"), avatar: require("@/assets/images/wechat.png"),
}, },
objData: { // objData: { //
repType: 'text' type: 'text',
}, },
} }
}, },
created() { created() {
//
getUser(this.userId).then(response => {
this.user.nickname = response.data.nickname | this.user.nickname;
this.user.avatar = response.data.avatar | this.user.avatar;
//
this.objData.accountId = response.data.accountId;
})
//
this.refreshChange() this.refreshChange()
}, },
methods:{ methods:{
@ -144,7 +155,7 @@ import {getMessagePage, sendMessage} from '@/api/mp/message'
if (!this.objData) { if (!this.objData) {
return; return;
} }
if (this.objData.repType === 'news') { if (this.objData.type === 'news') {
this.objData.content.articles = [this.objData.content.articles[0]] this.objData.content.articles = [this.objData.content.articles[0]]
this.$message({ this.$message({
showClose: true, showClose: true,
@ -157,7 +168,6 @@ import {getMessagePage, sendMessage} from '@/api/mp/message'
userId: this.userId userId: this.userId
}, { }, {
...this.objData, ...this.objData,
type: this.objData.repType,
// content: this.objData.repContent, // content: this.objData.repContent,
// TODO // TODO
})).then(response => { })).then(response => {
@ -167,7 +177,8 @@ import {getMessagePage, sendMessage} from '@/api/mp/message'
this.scrollToBottom() this.scrollToBottom()
// objData // objData
this.objData = { this.objData = {
repType: 'text' type: 'text',
content: '',
} }
}).catch(() => { }).catch(() => {
this.sendLoading = false this.sendLoading = false

View File

@ -1,30 +1,36 @@
<!-- <!--
- Copyright (C) 2018-2019 - Copyright (C) 2018-2019
- All rights reserved, Designed By www.joolun.com - All rights reserved, Designed By www.joolun.com
芋道源码
移除多余的 rep 为前缀的变量 message 消息更简单
代码优化补充注释提升阅读性
--> -->
<template> <template>
<el-tabs type="border-card" v-model="objData.repType" @tab-click="handleClick"> <el-tabs type="border-card" v-model="objData.type" @tab-click="handleClick">
<!-- 类型 1文本 --> <!-- 类型 1文本 -->
<el-tab-pane name="text"> <el-tab-pane name="text">
<span slot="label"><i class="el-icon-document"></i> 文本</span> <span slot="label"><i class="el-icon-document"></i> 文本</span>
<el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="objData.content" /> <el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="objData.content" @input="inputContent" />
</el-tab-pane> </el-tab-pane>
<!-- 类型 2图片 --> <!-- 类型 2图片 -->
<el-tab-pane name="image"> <el-tab-pane name="image">
<span slot="label"><i class="el-icon-picture"></i> 图片</span> <span slot="label"><i class="el-icon-picture"></i> 图片</span>
<el-row> <el-row>
<div class="select-item" v-if="objData.repUrl"> <!-- 情况一已经选择好素材或者上传好图片 -->
<img class="material-img" :src="objData.repUrl"> <div class="select-item" v-if="objData.url">
<p class="item-name" v-if="objData.repName">{{objData.repName}}</p> <img class="material-img" :src="objData.url">
<el-row class="ope-row"> <el-row class="ope-row">
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button> <el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
</el-row> </el-row>
</div> </div>
<div v-if="!objData.repUrl"> <!-- 情况二未做完上述操作 -->
<div v-else>
<el-row style="text-align: center"> <el-row style="text-align: center">
<!-- 选择素材 -->
<el-col :span="12" class="col-select"> <el-col :span="12" class="col-select">
<el-button type="success" @click="openMaterial">素材库选择<i class="el-icon-circle-check el-icon--right"></i></el-button> <el-button type="success" @click="openMaterial">素材库选择<i class="el-icon-circle-check el-icon--right"></i></el-button>
</el-col> </el-col>
<!-- 文件上传 -->
<el-col :span="12" class="col-add"> <el-col :span="12" class="col-add">
<el-upload :action="actionUrl" :headers="headers" multiple :limit="1" :file-list="fileList" :data="uploadData" <el-upload :action="actionUrl" :headers="headers" multiple :limit="1" :file-list="fileList" :data="uploadData"
:before-upload="beforeImageUpload" :on-success="handleUploadSuccess"> :before-upload="beforeImageUpload" :on-success="handleUploadSuccess">
@ -34,6 +40,7 @@
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
<!-- 点击选择素材会打开下面的弹窗 -->
<el-dialog title="选择图片" :visible.sync="dialogImageVisible" width="90%" append-to-body> <el-dialog title="选择图片" :visible.sync="dialogImageVisible" width="90%" append-to-body>
<WxMaterialSelect :objData="objData" @selectMaterial="selectMaterial"></WxMaterialSelect> <WxMaterialSelect :objData="objData" @selectMaterial="selectMaterial"></WxMaterialSelect>
</el-dialog> </el-dialog>
@ -82,7 +89,7 @@
<el-input v-model="objData.repDesc" placeholder="请输入描述"></el-input> <el-input v-model="objData.repDesc" placeholder="请输入描述"></el-input>
<div style="margin: 20px 0;"></div> <div style="margin: 20px 0;"></div>
<div style="text-align: center;"> <div style="text-align: center;">
<a target="_blank" v-if="objData.repUrl" :href="objData.repUrl"><i class="icon-shipinbofang">&nbsp;播放视频</i></a> <a target="_blank" v-if="objData.url" :href="objData.url"><i class="icon-shipinbofang">&nbsp;播放视频</i></a>
</div> </div>
<div style="margin: 20px 0;"></div> <div style="margin: 20px 0;"></div>
<div style="text-align: center"> <div style="text-align: center">
@ -138,7 +145,7 @@
</div> </div>
</div> </div>
<el-dialog title="选择图片" :visible.sync="dialogThumbVisible" width="80%" append-to-body> <el-dialog title="选择图片" :visible.sync="dialogThumbVisible" width="80%" append-to-body>
<WxMaterialSelect :objData="{repType:'image'}" @selectMaterial="selectMaterial"></WxMaterialSelect> <WxMaterialSelect :objData="{type:'image'}" @selectMaterial="selectMaterial"></WxMaterialSelect>
</el-dialog> </el-dialog>
</el-col> </el-col>
<el-col :span="18"> <el-col :span="18">
@ -148,7 +155,7 @@
</el-col> </el-col>
</el-row> </el-row>
<div style="margin: 20px 0;"></div> <div style="margin: 20px 0;"></div>
<el-input v-model="objData.repUrl" placeholder="请输入音乐链接"></el-input> <el-input v-model="objData.url" placeholder="请输入音乐链接"></el-input>
<div style="margin: 20px 0;"></div> <div style="margin: 20px 0;"></div>
<el-input v-model="objData.repHqUrl" placeholder="请输入高质量音乐链接"></el-input> <el-input v-model="objData.repHqUrl" placeholder="请输入高质量音乐链接"></el-input>
</el-tab-pane> </el-tab-pane>
@ -160,7 +167,7 @@
import WxNews from '@/views/mp/components/wx-news/main.vue' import WxNews from '@/views/mp/components/wx-news/main.vue'
// import WxMaterialSelect from '@/components/wx-material-select/main.vue' // import WxMaterialSelect from '@/components/wx-material-select/main.vue'
import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'; import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue';
import { getToken } from '@/utils/auth' import {getAccessToken, getToken} from '@/utils/auth'
export default { export default {
name: "wxReplySelect", name: "wxReplySelect",
@ -170,11 +177,11 @@
WxVoicePlayer WxVoicePlayer
}, },
props: { props: {
objData:{ objData: { //
type: Object type: Object, // Object 便
required: true,
}, },
// 12稿 newsType:{ // 12稿
newsType:{
type: String, type: String,
default: "1" default: "1"
}, },
@ -193,124 +200,176 @@
descs:[]// descs:[]//
}, },
tableLoading: false, tableLoading: false,
dialogNewsVisible:false,
dialogImageVisible:false, tempObj: new Map().set( // tab
dialogVoiceVisible:false, this.objData.type, //
dialogVideoVisible:false, Object.assign({}, this.objData)), //
dialogThumbVisible:false,
tempObj: new Map().set(this.objData.repType,Object.assign({},this.objData)), // ========== ==========
fileList:[], dialogNewsVisible: false, //
dialogImageVisible: false, //
dialogVoiceVisible: false, //
dialogVideoVisible: false, //
dialogThumbVisible: false, //
// ========== ==========
fileList: [], //
uploadData: { uploadData: {
"mediaType":this.objData.repType, "accountId": undefined,
"type": this.objData.type,
"title":'', "title":'',
"introduction":'' "introduction":''
}, },
actionUrl: process.env.VUE_APP_BASE_API +'/wxmaterial/materialFileUpload', actionUrl: process.env.VUE_APP_BASE_API +'/admin-api/mp/material/upload-temporary',
headers: { headers: { Authorization: "Bearer " + getAccessToken() }, //
Authorization: 'Bearer ' + getToken()
} }
}
},
computed: {
}, },
methods:{ methods:{
beforeThumbImageUpload(file){ beforeThumbImageUpload(file){
const isType = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/bmp' || file.type === 'image/jpg'; const isType = file.type === 'image/jpeg'
const isLt = file.size / 1024 / 1024 < 2; || file.type === 'image/png'
|| file.type === 'image/gif'
|| file.type === 'image/bmp'
|| file.type === 'image/jpg';
if (!isType) { if (!isType) {
this.$message.error('上传图片格式不对!'); this.$message.error('上传图片格式不对!');
return false;
} }
const isLt = file.size / 1024 / 1024 < 2;
if (!isLt) { if (!isLt) {
this.$message.error('上传图片大小不能超过 2M!'); this.$message.error('上传图片大小不能超过 2M!');
return false;
} }
return isType && isLt; this.uploadData.accountId = this.objData.accountId;
}, return true;
deleteObj(){
this.$delete(this.objData,'repName')
this.$delete(this.objData,'repUrl')
this.$delete(this.objData,'content')
}, },
beforeVoiceUpload(file){ beforeVoiceUpload(file){
this.tableLoading = true this.tableLoading = true
const isType = file.type === 'audio/mp3' || file.type === 'audio/wma' || file.type === 'audio/wav' || file.type === 'audio/amr'; //
const isLt = file.size / 1024 / 1024 < 2; const isType = file.type === 'audio/mp3'
|| file.type === 'audio/wma'
|| file.type === 'audio/wav'
|| file.type === 'audio/amr';
if (!isType) { if (!isType) {
this.$message.error('上传语音格式不对!'); this.$message.error('上传语音格式不对!');
return false;
} }
//
const isLt = file.size / 1024 / 1024 < 2;
if (!isLt) { if (!isLt) {
this.$message.error('上传语音大小不能超过 2M!'); this.$message.error('上传语音大小不能超过 2M!');
return false;
} }
return isType && isLt; this.uploadData.accountId = this.objData.accountId;
return true;
}, },
beforeImageUpload(file){ beforeImageUpload(file){
const isType = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/bmp' || file.type === 'image/jpg'; //
const isLt = file.size / 1024 / 1024 < 2; const isType = file.type === 'image/jpeg'
|| file.type === 'image/png'
|| file.type === 'image/gif'
|| file.type === 'image/bmp'
|| file.type === 'image/jpg';
if (!isType) { if (!isType) {
this.$message.error('上传图片格式不对!'); this.$message.error('上传图片格式不对!');
return false;
} }
//
const isLt = file.size / 1024 / 1024 < 2;
if (!isLt) { if (!isLt) {
this.$message.error('上传图片大小不能超过 2M!'); this.$message.error('上传图片大小不能超过 2M!');
return false;
} }
return isType && isLt; this.uploadData.accountId = this.objData.accountId;
return true;
}, },
handleUploadSuccess(response, file, fileList) { handleUploadSuccess(response, file, fileList) {
if(response.code == 200){ if (response.code !== 0) {
this.$message.error('上传出错:' + response.msg)
return false;
}
//
this.fileList = [] this.fileList = []
this.uploadData.title = '' this.uploadData.title = ''
this.uploadData.introduction = '' this.uploadData.introduction = ''
//
let item = response.data let item = response.data
this.selectMaterial(item) this.selectMaterial(item)
}else{
this.$message.error('上传出错:' + response.msg)
}
}, },
handleClick(tab, event){ /**
this.uploadData.mediaType = this.objData.repType * 切换消息类型的 tab
let tempObjItem = this.tempObj.get(this.objData.repType) *
if(tempObjItem){ * @param tab tab
this.objData.repName = tempObjItem.repName ? tempObjItem.repName : null */
this.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null handleClick(tab) {
this.objData.media_id = tempObjItem.media_id ? tempObjItem.media_id : null //
this.objData.repUrl = tempObjItem.repUrl ? tempObjItem.repUrl : null this.uploadData.type = this.objData.type;
this.objData.content = tempObjItem.content ? tempObjItem.content : null if (this.uploadData.type === 'music') { //
this.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null this.uploadData.type = 'thumb';
}else{
this.$delete(this.objData,'repName')
this.$delete(this.objData,'repMediaId')
this.$delete(this.objData,'media_id')
this.$delete(this.objData,'repUrl')
this.$delete(this.objData,'content')
this.$delete(this.objData,'repDesc')
} }
},
selectMaterial(item){
let tempObjItem = {}
tempObjItem.repType = this.objData.repType
tempObjItem.repMediaId = item.mediaId
tempObjItem.media_id = item.mediaId
tempObjItem.content = item.content
this.dialogNewsVisible = false // tempObj objData
this.dialogImageVisible = false let tempObjItem = this.tempObj.get(this.objData.type)
this.dialogVoiceVisible = false // console.log(this.objData.type)
this.dialogVideoVisible = false // console.log(tempObjItem)
this.objData.repMediaId = item.mediaId console.log(this.objData)
this.objData.media_id = item.mediaId // console.log(this.tempObj)
if (tempObjItem) {
this.objData.content = tempObjItem.content ? tempObjItem.content : null
this.objData.mediaId = tempObjItem.mediaId ? tempObjItem.mediaId : null
this.objData.url = tempObjItem.url ? tempObjItem.url : null
// TODO
// this.objData.repName = tempObjItem.repName ? tempObjItem.repName : null
// this.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null
// this.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null
return;
}
// objData
this.objData.mediaId = undefined;
this.objData.content = undefined;
// this.$delete(this.objData,'repName')
// this.$delete(this.objData,'repMediaId')
// this.$delete(this.objData,'mediaId')
// this.$delete(this.objData,'url')
// this.$delete(this.objData,'content') // TODO
// this.$delete(this.objData,'repDesc')
},
/**
* 选择素材将设置设置到 objData 变量
*
* @param item 素材
*/
selectMaterial(item) {
//
this.closeMaterial();
// tempObjItem
let tempObjItem = {}
tempObjItem.type = this.objData.type
tempObjItem.mediaId = item.mediaId
// tempObjItem.repMediaId = item.mediaId // TODO
// tempObjItem.content = item.content // TODO
// this.objData.repMediaId = item.mediaId
this.objData.mediaId = item.mediaId
this.objData.content = item.content this.objData.content = item.content
if(this.objData.repType == 'music'){ if (this.objData.type === 'music') {
tempObjItem.repThumbMediaId = item.mediaId tempObjItem.repThumbMediaId = item.mediaId
tempObjItem.repThumbUrl = item.url tempObjItem.repThumbUrl = item.url
this.objData.repThumbMediaId = item.mediaId this.objData.repThumbMediaId = item.mediaId
this.objData.repThumbUrl = item.url this.objData.repThumbUrl = item.url
this.dialogThumbVisible = false this.dialogThumbVisible = false // TODO
} else{ } else{
tempObjItem.repName = item.name // tempObjItem.repName = item.name
tempObjItem.repUrl = item.url // tempObjItem.url = item.url
this.objData.repName = item.name // this.objData.repName = item.name
this.objData.repUrl = item.url this.objData.mediaId = item.mediaId
this.objData.url = item.url
} }
if(this.objData.repType == 'video'){ if(this.objData.type == 'video'){
// getMaterialVideo({ // getMaterialVideo({
// mediaId:item.mediaId // mediaId:item.mediaId
// }).then(response => { // }).then(response => {
@ -318,33 +377,54 @@
// let data = response.data // let data = response.data
// this.$set(this.objData,'repName',data.title) // this.$set(this.objData,'repName',data.title)
// this.$set(this.objData,'repDesc',data.description) // this.$set(this.objData,'repDesc',data.description)
// this.$set(this.objData,'repUrl',data.downUrl) // this.$set(this.objData,'url',data.downUrl)
// tempObjItem.repDesc = data.description // tempObjItem.repDesc = data.description
// tempObjItem.repUrl = data.downUrl // tempObjItem.url = data.downUrl
// } // }
// }) // })
} }
this.tempObj.set(this.objData.repType,tempObjItem) //
this.tempObj.set(this.objData.type, tempObjItem)
}, },
openMaterial() { openMaterial() {
if(this.objData.repType == 'news'){ if (this.objData.type === 'news') {
this.dialogNewsVisible = true this.dialogNewsVisible = true
}else if(this.objData.repType == 'image'){ } else if(this.objData.type === 'image') {
this.dialogImageVisible = true this.dialogImageVisible = true
}else if(this.objData.repType == 'voice'){ } else if(this.objData.type === 'voice') {
this.dialogVoiceVisible = true this.dialogVoiceVisible = true
}else if(this.objData.repType == 'video'){ } else if(this.objData.type === 'video') {
this.dialogVideoVisible = true this.dialogVideoVisible = true
}else if(this.objData.repType == 'music'){ } else if(this.objData.type === 'music') {
this.dialogThumbVisible = true this.dialogThumbVisible = true
} }
}, },
closeMaterial() {
this.dialogNewsVisible = false
this.dialogImageVisible = false
this.dialogVoiceVisible = false
this.dialogVideoVisible = false
},
deleteObj() {
if (this.objData.type === 'news') {
// TODO
} else if(this.objData.type === 'image') {
this.$delete(this.objData, 'url')
this.$delete(this.objData, 'mediaId')
} else if(this.objData.type === 'voice') {
// TODO
} else if(this.objData.type === 'video') {
// TODO
} else if(this.objData.type === 'music') {
// TODO
}
},
getPage(page, params) { getPage(page, params) {
this.tableLoading = true this.tableLoading = true
// getPage(Object.assign({ // getPage(Object.assign({
// current: page.currentPage, // current: page.currentPage,
// size: page.pageSize, // size: page.pageSize,
// type:this.objData.repType // type:this.objData.type
// }, params)).then(response => { // }, params)).then(response => {
// this.tableData = response.data.items // this.tableData = response.data.items
// this.page.total = response.data.totalCount // this.page.total = response.data.totalCount
@ -357,6 +437,15 @@
this.page.currentPage = 1 this.page.currentPage = 1
this.page.pageSize = val this.page.pageSize = val
this.getPage(this.page) this.getPage(this.page)
},
/**
* 输入时缓存每次 objData tempObj
*
* why不确定为什么 v-model="objData.content" 不能自动缓存所以通过这样的方式
*/
inputContent() {
let tempObjItem = {...this.objData};
this.tempObj.set(this.objData.type, tempObjItem);
} }
} }
}; };