parent
a543ae0a4e
commit
af546a04e3
@ -39,79 +39,79 @@
|
|||||||
:style="item.sendFrom === 2 ? 'background: #6BED72;' : ''"
|
:style="item.sendFrom === 2 ? 'background: #6BED72;' : ''"
|
||||||
>
|
>
|
||||||
<!-- 【事件】区域 -->
|
<!-- 【事件】区域 -->
|
||||||
<div v-if="item.type === 'event' && item.event === 'subscribe'">
|
<div v-if="item.type === MsgType.Event && item.event === 'subscribe'">
|
||||||
<el-tag type="success">关注</el-tag>
|
<el-tag type="success">关注</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'unsubscribe'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'unsubscribe'">
|
||||||
<el-tag type="danger">取消关注</el-tag>
|
<el-tag type="danger">取消关注</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'CLICK'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'CLICK'">
|
||||||
<el-tag>点击菜单</el-tag>
|
<el-tag>点击菜单</el-tag>
|
||||||
【{{ item.eventKey }}】
|
【{{ item.eventKey }}】
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'VIEW'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'VIEW'">
|
||||||
<el-tag>点击菜单链接</el-tag>
|
<el-tag>点击菜单链接</el-tag>
|
||||||
【{{ item.eventKey }}】
|
【{{ item.eventKey }}】
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'scancode_waitmsg'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'scancode_waitmsg'">
|
||||||
<el-tag>扫码结果</el-tag>
|
<el-tag>扫码结果</el-tag>
|
||||||
【{{ item.eventKey }}】
|
【{{ item.eventKey }}】
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'scancode_push'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'scancode_push'">
|
||||||
<el-tag>扫码结果</el-tag>
|
<el-tag>扫码结果</el-tag>
|
||||||
【{{ item.eventKey }}】
|
【{{ item.eventKey }}】
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'pic_sysphoto'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'pic_sysphoto'">
|
||||||
<el-tag>系统拍照发图</el-tag>
|
<el-tag>系统拍照发图</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'pic_photo_or_album'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'pic_photo_or_album'">
|
||||||
<el-tag>拍照或者相册</el-tag>
|
<el-tag>拍照或者相册</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'pic_weixin'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'pic_weixin'">
|
||||||
<el-tag>微信相册</el-tag>
|
<el-tag>微信相册</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event' && item.event === 'location_select'">
|
<div v-else-if="item.type === MsgType.Event && item.event === 'location_select'">
|
||||||
<el-tag>选择地理位置</el-tag>
|
<el-tag>选择地理位置</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'event'">
|
<div v-else-if="item.type === MsgType.Event">
|
||||||
<el-tag type="danger">未知事件类型</el-tag>
|
<el-tag type="danger">未知事件类型</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<!-- 【消息】区域 -->
|
<!-- 【消息】区域 -->
|
||||||
<div v-else-if="item.type === 'text'">{{ item.content }}</div>
|
<div v-else-if="item.type === MsgType.Text">{{ item.content }}</div>
|
||||||
<div v-else-if="item.type === 'voice'">
|
<div v-else-if="item.type === MsgType.Voice">
|
||||||
<wx-voice-player :url="item.mediaUrl" :content="item.recognition" />
|
<WxVoicePlayer :url="item.mediaUrl" :content="item.recognition" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'image'">
|
<div v-else-if="item.type === MsgType.Image">
|
||||||
<a target="_blank" :href="item.mediaUrl">
|
<a target="_blank" :href="item.mediaUrl">
|
||||||
<img :src="item.mediaUrl" style="width: 100px" />
|
<img :src="item.mediaUrl" style="width: 100px" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else-if="item.type === 'video' || item.type === 'shortvideo'"
|
v-else-if="item.type === MsgType.Video || item.type === 'shortvideo'"
|
||||||
style="text-align: center"
|
style="text-align: center"
|
||||||
>
|
>
|
||||||
<wx-video-player :url="item.mediaUrl" />
|
<WxVideoPlayer :url="item.mediaUrl" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'link'" class="avue-card__detail">
|
<div v-else-if="item.type === MsgType.Link" class="avue-card__detail">
|
||||||
<el-link type="success" :underline="false" target="_blank" :href="item.url">
|
<el-link type="success" :underline="false" target="_blank" :href="item.url">
|
||||||
<div class="avue-card__title"><i class="el-icon-link"></i>{{ item.title }}</div>
|
<div class="avue-card__title"><i class="el-icon-link"></i>{{ item.title }}</div>
|
||||||
</el-link>
|
</el-link>
|
||||||
<div class="avue-card__info" style="height: unset">{{ item.description }}</div>
|
<div class="avue-card__info" style="height: unset">{{ item.description }}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- TODO 芋艿:待完善 -->
|
<!-- TODO 芋艿:待完善 -->
|
||||||
<div v-else-if="item.type === 'location'">
|
<div v-else-if="item.type === MsgType.Location">
|
||||||
<wx-location
|
<WxLocation
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:location-y="item.locationY"
|
:location-y="item.locationY"
|
||||||
:location-x="item.locationX"
|
:location-x="item.locationX"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'news'" style="width: 300px">
|
<div v-else-if="item.type === MsgType.News" style="width: 300px">
|
||||||
<!-- TODO 芋艿:待测试;详情页也存在类似的情况 -->
|
<!-- TODO 芋艿:待测试;详情页也存在类似的情况 -->
|
||||||
<wx-news :articles="item.articles" />
|
<WxNews :articles="item.articles" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type === 'music'">
|
<div v-else-if="item.type === MsgType.Music">
|
||||||
<wx-music
|
<WxMusic
|
||||||
:title="item.title"
|
:title="item.title"
|
||||||
:description="item.description"
|
:description="item.description"
|
||||||
:thumb-media-url="item.thumbMediaUrl"
|
:thumb-media-url="item.thumbMediaUrl"
|
||||||
@ -125,100 +125,126 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="msg-send" v-loading="sendLoading">
|
<div class="msg-send" v-loading="sendLoading">
|
||||||
<wx-reply-select ref="replySelect" :objData="objData" />
|
<WxReplySelect ref="replySelectRef" :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>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" name="WxMsg">
|
<script setup lang="ts" name="WxMsg">
|
||||||
import { getMessagePage, sendMessage } from '@/api/mp/message'
|
|
||||||
import WxReplySelect from '@/views/mp/components/wx-reply/main.vue'
|
import WxReplySelect from '@/views/mp/components/wx-reply/main.vue'
|
||||||
import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'
|
import WxVideoPlayer from '@/views/mp/components/wx-video-play/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 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 { getMessagePage, sendMessage } from '@/api/mp/message'
|
||||||
import { getUser } from '@/api/mp/user'
|
import { getUser } from '@/api/mp/user'
|
||||||
import { defineComponent } from 'vue'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
|
||||||
import profile from '@/assets/imgs/profile.jpg'
|
import profile from '@/assets/imgs/profile.jpg'
|
||||||
import wechat from '@/assets/imgs/wechat.png'
|
import wechat from '@/assets/imgs/wechat.png'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { MsgType } from './types'
|
||||||
|
|
||||||
export default defineComponent({
|
const message = useMessage() // 消息弹窗
|
||||||
components: {
|
|
||||||
WxReplySelect,
|
const props = defineProps({
|
||||||
WxVideoPlayer,
|
|
||||||
WxVoicePlayer,
|
|
||||||
WxNews,
|
|
||||||
WxLocation,
|
|
||||||
WxMusic
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
userId: {
|
userId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
setup(props) {
|
|
||||||
const nowStr = ref(new Date().getTime()) // 当前的时间戳,用于每次消息加载后,回到原位置;具体见 :id="'msg-div' + nowStr" 处
|
const nowStr = ref(new Date().getTime()) // 当前的时间戳,用于每次消息加载后,回到原位置;具体见 :id="'msg-div' + nowStr" 处
|
||||||
const loading = ref(false) // 消息列表是否正在加载中
|
const loading = ref(false) // 消息列表是否正在加载中
|
||||||
const loadMore = ref(true) // 是否可以加载更多
|
const loadMore = ref(true) // 是否可以加载更多
|
||||||
const list = ref<any[]>([]) // 消息列表
|
const list = ref<any[]>([]) // 消息列表
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
pageNo: 1, // 当前页数
|
pageNo: 1, // 当前页数
|
||||||
pageSize: 14, // 每页显示多少条
|
pageSize: 14, // 每页显示多少条
|
||||||
accountId: undefined
|
accountId: undefined
|
||||||
})
|
})
|
||||||
const user = reactive({
|
|
||||||
// 由于微信不再提供昵称,直接使用“用户”展示
|
interface User {
|
||||||
|
nickname: string
|
||||||
|
avatar: string
|
||||||
|
accountId: number
|
||||||
|
}
|
||||||
|
// 由于微信不再提供昵称,直接使用“用户”展示
|
||||||
|
const user: User = reactive({
|
||||||
nickname: '用户',
|
nickname: '用户',
|
||||||
avatar: profile,
|
avatar: profile,
|
||||||
accountId: 0 // 公众号账号编号
|
accountId: 0 // 公众号账号编号
|
||||||
})
|
})
|
||||||
const mp = reactive({
|
|
||||||
|
interface Mp {
|
||||||
|
nickname: string
|
||||||
|
avatar: string
|
||||||
|
}
|
||||||
|
const mp: Mp = reactive({
|
||||||
nickname: '公众号',
|
nickname: '公众号',
|
||||||
avatar: wechat
|
avatar: wechat
|
||||||
})
|
})
|
||||||
|
|
||||||
// ========= 消息发送 =========
|
// ========= 消息发送 =========
|
||||||
const sendLoading = ref(false) // 发送消息是否加载中
|
const sendLoading = ref(false) // 发送消息是否加载中
|
||||||
const objData = reactive({
|
interface ObjData {
|
||||||
// 微信发送消息
|
type: MsgType
|
||||||
type: 'text',
|
accountId: number | null
|
||||||
|
articles: any[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 微信发送消息
|
||||||
|
const objData: ObjData = reactive({
|
||||||
|
type: MsgType.Text,
|
||||||
accountId: null,
|
accountId: null,
|
||||||
articles: []
|
articles: []
|
||||||
})
|
})
|
||||||
|
|
||||||
const replySelect = ref(null)
|
const replySelectRef = ref<InstanceType<typeof WxReplySelect> | null>(null)
|
||||||
// 执行发送
|
|
||||||
const sendMsg = async () => {
|
/** 完成加载 */
|
||||||
|
onMounted(async () => {
|
||||||
|
const data = await getUser(props.userId)
|
||||||
|
user.nickname = data.nickname?.length > 0 ? data.nickname : user.nickname
|
||||||
|
user.avatar = user.avatar?.length > 0 ? data.avatar : user.avatar
|
||||||
|
user.accountId = data.accountId
|
||||||
|
queryParams.accountId = data.accountId
|
||||||
|
objData.accountId = data.accountId
|
||||||
|
|
||||||
|
refreshChange()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 执行发送
|
||||||
|
const sendMsg = async () => {
|
||||||
if (!objData) {
|
if (!objData) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// // 公众号限制:客服消息,公众号只允许发送一条
|
// 公众号限制:客服消息,公众号只允许发送一条
|
||||||
if (objData.type === 'news' && objData.articles.length > 1) {
|
if (objData.type === MsgType.News && objData.articles.length > 1) {
|
||||||
objData.articles = [objData.articles[0]]
|
objData.articles = [objData.articles[0]]
|
||||||
message.success('图文消息条数限制在 1 条以内,已默认发送第一条')
|
message.success('图文消息条数限制在 1 条以内,已默认发送第一条')
|
||||||
}
|
}
|
||||||
let data = await sendMessage(Object.assign({ userId: props.userId }, { ...objData }))
|
|
||||||
|
const data = await sendMessage(Object.assign({ userId: props.userId }, { ...objData }))
|
||||||
sendLoading.value = false
|
sendLoading.value = false
|
||||||
|
|
||||||
list.value = [...list.value, ...[data]]
|
list.value = [...list.value, ...[data]]
|
||||||
scrollToBottom()
|
scrollToBottom()
|
||||||
//ts檢查的時候會判斷這個組件可能是空的,所以需要進行斷言。
|
|
||||||
|
//ts检查的時候会判断这个组件可能是空的,所以需要进行断言。
|
||||||
//避免 tab 的数据未清理
|
//避免 tab 的数据未清理
|
||||||
const deleteObj = (replySelect.value as any).deleteObj
|
const deleteObj = replySelectRef.value?.deleteObj
|
||||||
if (deleteObj) {
|
if (deleteObj) {
|
||||||
deleteObj()
|
deleteObj()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const loadingMore = () => {
|
|
||||||
|
const loadingMore = () => {
|
||||||
queryParams.pageNo++
|
queryParams.pageNo++
|
||||||
getPage(queryParams, null)
|
getPage(queryParams, null)
|
||||||
}
|
}
|
||||||
const getPage = async (page, params) => {
|
|
||||||
|
const getPage = async (page, params) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
let dataTemp = await getMessagePage(
|
let dataTemp = await getMessagePage(
|
||||||
Object.assign(
|
Object.assign(
|
||||||
@ -231,13 +257,14 @@ export default defineComponent({
|
|||||||
params
|
params
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
const msgDiv = document.getElementById('msg-div' + nowStr.value)
|
const msgDiv = document.getElementById('msg-div' + nowStr.value)
|
||||||
let scrollHeight = 0
|
let scrollHeight = 0
|
||||||
if (msgDiv) {
|
if (msgDiv) {
|
||||||
scrollHeight = msgDiv.scrollHeight
|
scrollHeight = msgDiv.scrollHeight
|
||||||
}
|
}
|
||||||
// 处理数据
|
// 处理数据
|
||||||
let data = dataTemp.list.reverse()
|
const data = dataTemp.list.reverse()
|
||||||
list.value = [...data, ...list.value]
|
list.value = [...data, ...list.value]
|
||||||
loading.value = false
|
loading.value = false
|
||||||
if (data.length < queryParams.pageSize || data.length === 0) {
|
if (data.length < queryParams.pageSize || data.length === 0) {
|
||||||
@ -260,47 +287,23 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const refreshChange = () => {
|
|
||||||
|
const refreshChange = () => {
|
||||||
getPage(queryParams, null)
|
getPage(queryParams, null)
|
||||||
}
|
}
|
||||||
/** 定位到消息底部 */
|
|
||||||
const scrollToBottom = () => {
|
/** 定位到消息底部 */
|
||||||
|
const scrollToBottom = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
let div = document.getElementById('msg-div' + nowStr.value)
|
let div = document.getElementById('msg-div' + nowStr.value)
|
||||||
if (div) {
|
if (div) {
|
||||||
div.scrollTop = div.scrollHeight
|
div.scrollTop = div.scrollHeight
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
let data = await getUser(props.userId)
|
|
||||||
user.nickname = data.nickname && data.nickname.length > 0 ? data.nickname : user.nickname
|
|
||||||
user.avatar = data.avatar && user.avatar.length > 0 ? data.avatar : user.avatar
|
|
||||||
user.accountId = data.accountId
|
|
||||||
queryParams.accountId = data.accountId
|
|
||||||
objData.accountId = data.accountId
|
|
||||||
refreshChange()
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
sendMsg,
|
|
||||||
loadingMore,
|
|
||||||
formatDate,
|
|
||||||
scrollToBottom,
|
|
||||||
objData,
|
|
||||||
mp,
|
|
||||||
user,
|
|
||||||
queryParams,
|
|
||||||
list,
|
|
||||||
loadMore,
|
|
||||||
loading,
|
|
||||||
nowStr,
|
|
||||||
sendLoading
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
/* 因为 joolun 实现依赖 avue 组件,该页面使用了 comment.scss、card.scc */
|
/* 因为 joolun 实现依赖 avue 组件,该页面使用了 comment.scss、card.scc */
|
||||||
@import './comment.scss';
|
@import './comment.scss';
|
||||||
|
11
src/views/mp/components/wx-msg/types.ts
Normal file
11
src/views/mp/components/wx-msg/types.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export enum MsgType {
|
||||||
|
Event = 'event',
|
||||||
|
Text = 'text',
|
||||||
|
Voice = 'voice',
|
||||||
|
Image = 'image',
|
||||||
|
Video = 'video',
|
||||||
|
Link = 'link',
|
||||||
|
Location = 'location',
|
||||||
|
Music = 'music',
|
||||||
|
News = 'news'
|
||||||
|
}
|
@ -9,14 +9,7 @@
|
|||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
<el-form-item label="公众号" prop="accountId">
|
<el-form-item label="公众号" prop="accountId">
|
||||||
<el-select v-model="queryParams.accountId" placeholder="请选择公众号" class="!w-240px">
|
<WxMpSelect @change="onAccountChanged" />
|
||||||
<el-option
|
|
||||||
v-for="item in accountList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="消息类型" prop="type">
|
<el-form-item label="消息类型" prop="type">
|
||||||
<el-select v-model="queryParams.type" placeholder="请选择消息类型" class="!w-240px">
|
<el-select v-model="queryParams.type" placeholder="请选择消息类型" class="!w-240px">
|
||||||
@ -84,70 +77,76 @@
|
|||||||
<el-table-column label="内容" prop="content">
|
<el-table-column label="内容" prop="content">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- 【事件】区域 -->
|
<!-- 【事件】区域 -->
|
||||||
<div v-if="scope.row.type === 'event' && scope.row.event === 'subscribe'">
|
<div v-if="scope.row.type === MsgType.Event && scope.row.event === 'subscribe'">
|
||||||
<el-tag type="success">关注</el-tag>
|
<el-tag type="success">关注</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'unsubscribe'">
|
<div v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'unsubscribe'">
|
||||||
<el-tag type="danger">取消关注</el-tag>
|
<el-tag type="danger">取消关注</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'CLICK'">
|
<div v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'CLICK'">
|
||||||
<el-tag>点击菜单</el-tag>
|
<el-tag>点击菜单</el-tag>
|
||||||
【{{ scope.row.eventKey }}】
|
【{{ scope.row.eventKey }}】
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'VIEW'">
|
<div v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'VIEW'">
|
||||||
<el-tag>点击菜单链接</el-tag>
|
<el-tag>点击菜单链接</el-tag>
|
||||||
【{{ scope.row.eventKey }}】
|
【{{ scope.row.eventKey }}】
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'scancode_waitmsg'">
|
<div
|
||||||
|
v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'scancode_waitmsg'"
|
||||||
|
>
|
||||||
<el-tag>扫码结果</el-tag>
|
<el-tag>扫码结果</el-tag>
|
||||||
【{{ scope.row.eventKey }}】
|
【{{ scope.row.eventKey }}】
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'scancode_push'">
|
<div v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'scancode_push'">
|
||||||
<el-tag>扫码结果</el-tag>
|
<el-tag>扫码结果</el-tag>
|
||||||
【{{ scope.row.eventKey }}】
|
【{{ scope.row.eventKey }}】
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'pic_sysphoto'">
|
<div v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'pic_sysphoto'">
|
||||||
<el-tag>系统拍照发图</el-tag>
|
<el-tag>系统拍照发图</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'pic_photo_or_album'">
|
<div
|
||||||
|
v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'pic_photo_or_album'"
|
||||||
|
>
|
||||||
<el-tag>拍照或者相册</el-tag>
|
<el-tag>拍照或者相册</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'pic_weixin'">
|
<div v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'pic_weixin'">
|
||||||
<el-tag>微信相册</el-tag>
|
<el-tag>微信相册</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event' && scope.row.event === 'location_select'">
|
<div
|
||||||
|
v-else-if="scope.row.type === MsgType.Event && scope.row.event === 'location_select'"
|
||||||
|
>
|
||||||
<el-tag>选择地理位置</el-tag>
|
<el-tag>选择地理位置</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'event'">
|
<div v-else-if="scope.row.type === MsgType.Event">
|
||||||
<el-tag type="danger">未知事件类型</el-tag>
|
<el-tag type="danger">未知事件类型</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<!-- 【消息】区域 -->
|
<!-- 【消息】区域 -->
|
||||||
<div v-else-if="scope.row.type === 'text'">{{ scope.row.content }}</div>
|
<div v-else-if="scope.row.type === MsgType.Text">{{ scope.row.content }}</div>
|
||||||
<div v-else-if="scope.row.type === 'voice'">
|
<div v-else-if="scope.row.type === MsgType.Voice">
|
||||||
<wx-voice-player :url="scope.row.mediaUrl" :content="scope.row.recognition" />
|
<wx-voice-player :url="scope.row.mediaUrl" :content="scope.row.recognition" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'image'">
|
<div v-else-if="scope.row.type === MsgType.Image">
|
||||||
<a target="_blank" :href="scope.row.mediaUrl">
|
<a target="_blank" :href="scope.row.mediaUrl">
|
||||||
<img :src="scope.row.mediaUrl" style="width: 100px" />
|
<img :src="scope.row.mediaUrl" style="width: 100px" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'video' || scope.row.type === 'shortvideo'">
|
<div v-else-if="scope.row.type === MsgType.Video || scope.row.type === 'shortvideo'">
|
||||||
<wx-video-player :url="scope.row.mediaUrl" style="margin-top: 10px" />
|
<wx-video-player :url="scope.row.mediaUrl" style="margin-top: 10px" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'link'">
|
<div v-else-if="scope.row.type === MsgType.Link">
|
||||||
<el-tag>链接</el-tag>
|
<el-tag>链接</el-tag>
|
||||||
:
|
:
|
||||||
<a :href="scope.row.url" target="_blank">{{ scope.row.title }}</a>
|
<a :href="scope.row.url" target="_blank">{{ scope.row.title }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'location'">
|
<div v-else-if="scope.row.type === MsgType.Location">
|
||||||
<wx-location
|
<WxLocation
|
||||||
:label="scope.row.label"
|
:label="scope.row.label"
|
||||||
:location-y="scope.row.locationY"
|
:location-y="scope.row.locationY"
|
||||||
:location-x="scope.row.locationX"
|
:location-x="scope.row.locationX"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'music'">
|
<div v-else-if="scope.row.type === MsgType.Music">
|
||||||
<wx-music
|
<WxMusic
|
||||||
:title="scope.row.title"
|
:title="scope.row.title"
|
||||||
:description="scope.row.description"
|
:description="scope.row.description"
|
||||||
:thumb-media-url="scope.row.thumbMediaUrl"
|
:thumb-media-url="scope.row.thumbMediaUrl"
|
||||||
@ -155,8 +154,8 @@
|
|||||||
:hq-music-url="scope.row.hqMusicUrl"
|
:hq-music-url="scope.row.hqMusicUrl"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.type === 'news'">
|
<div v-else-if="scope.row.type === MsgType.News">
|
||||||
<wx-news :articles="scope.row.articles" />
|
<WxNews :articles="scope.row.articles" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<el-tag type="danger">未知消息类型</el-tag>
|
<el-tag type="danger">未知消息类型</el-tag>
|
||||||
@ -177,7 +176,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<!-- 分页组件 -->
|
<!-- 分页组件 -->
|
||||||
<pagination
|
<Pagination
|
||||||
v-show="total > 0"
|
v-show="total > 0"
|
||||||
:total="total"
|
:total="total"
|
||||||
v-model:page="queryParams.pageNo"
|
v-model:page="queryParams.pageNo"
|
||||||
@ -186,9 +185,14 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 发送消息的弹窗 -->
|
<!-- 发送消息的弹窗 -->
|
||||||
<el-dialog title="粉丝消息列表" v-model="open" @click="openDialog()" width="50%">
|
<el-dialog
|
||||||
|
title="粉丝消息列表"
|
||||||
|
v-model="showMessageBox"
|
||||||
|
@click="showMessageBox = true"
|
||||||
|
width="50%"
|
||||||
|
>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<wx-msg :user-id="userId" v-if="open" />
|
<WxMsg :user-id="userId" v-if="showMessageBox" />
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
@ -200,17 +204,27 @@ import WxMsg from '@/views/mp/components/wx-msg/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 WxNews from '@/views/mp/components/wx-news/main.vue'
|
import WxNews from '@/views/mp/components/wx-news/main.vue'
|
||||||
import * as MpAccountApi from '@/api/mp/account'
|
import WxMpSelect from '@/views/mp/components/WxMpSelect.vue'
|
||||||
import * as MpMessageApi from '@/api/mp/message'
|
import * as MpMessageApi from '@/api/mp/message'
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
|
||||||
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import { MsgType } from '@/views/mp/components/wx-msg/types'
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
|
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref<any[]>([]) // 列表的数据
|
||||||
const queryParams = reactive({
|
|
||||||
|
// 搜索参数
|
||||||
|
interface QueryParams {
|
||||||
|
pageNo: number
|
||||||
|
pageSize: number
|
||||||
|
openid: string | null
|
||||||
|
accountId: number | null
|
||||||
|
type: MsgType | null
|
||||||
|
createTime: string[] | []
|
||||||
|
}
|
||||||
|
const queryParams: QueryParams = reactive({
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
openid: null,
|
openid: null,
|
||||||
@ -218,19 +232,18 @@ const queryParams = reactive({
|
|||||||
type: null,
|
type: null,
|
||||||
createTime: []
|
createTime: []
|
||||||
})
|
})
|
||||||
const queryFormRef = ref() // 搜索的表单
|
const queryFormRef = ref<FormInstance | null>(null) // 搜索的表单
|
||||||
// TODO 芋艿:下面应该移除
|
const showMessageBox = ref(false) // 是否显示弹出层
|
||||||
const open = ref(false) // 是否显示弹出层
|
|
||||||
const userId = ref(0) // 操作的用户编号
|
const userId = ref(0) // 操作的用户编号
|
||||||
const accountList = ref<MpAccountApi.AccountVO[]>([]) // 公众号账号列表
|
|
||||||
|
/** 侦听accountId */
|
||||||
|
const onAccountChanged = (id?: number) => {
|
||||||
|
queryParams.accountId = id as number
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
/** 查询列表 */
|
/** 查询列表 */
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
// 如果没有选中公众号账号,则进行提示。
|
|
||||||
if (!queryParams.accountId) {
|
|
||||||
await message.error('未选中公众号,无法查询消息')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const data = await MpMessageApi.getMessagePage(queryParams)
|
const data = await MpMessageApi.getMessagePage(queryParams)
|
||||||
@ -249,34 +262,15 @@ const handleQuery = () => {
|
|||||||
|
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
const resetQuery = async () => {
|
const resetQuery = async () => {
|
||||||
queryFormRef.value.resetFields()
|
const accountId = queryParams.accountId
|
||||||
// 默认选中第一个
|
queryFormRef.value?.resetFields()
|
||||||
if (accountList.value.length > 0) {
|
queryParams.accountId = accountId
|
||||||
// @ts-ignore
|
|
||||||
queryParams.accountId = accountList.value[0].id
|
|
||||||
}
|
|
||||||
handleQuery()
|
handleQuery()
|
||||||
}
|
}
|
||||||
const handleSend = async (row) => {
|
|
||||||
|
/** 打开消息发送窗口 */
|
||||||
|
const handleSend = async (row: any) => {
|
||||||
userId.value = row.userId
|
userId.value = row.userId
|
||||||
open.value = true
|
showMessageBox.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const openDialog = () => {
|
|
||||||
open.value = true
|
|
||||||
}
|
|
||||||
// const closeDiaLog = () => {
|
|
||||||
// open.value = false
|
|
||||||
// }
|
|
||||||
|
|
||||||
/** 初始化 **/
|
|
||||||
onMounted(async () => {
|
|
||||||
accountList.value = await MpAccountApi.getSimpleAccountList()
|
|
||||||
// 选中第一个
|
|
||||||
if (accountList.value.length > 0) {
|
|
||||||
// @ts-ignore
|
|
||||||
queryParams.accountId = accountList.value[0].id
|
|
||||||
}
|
|
||||||
await getList()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user