You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
WeChat/src/views/modules/wx/wx-msg.vue

209 lines
7.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="mod-config">
<!-- 搜索表单 -->
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-form-item>
<!-- 时间选择器 -->
<el-select v-model="dataForm.startTime" placeholder="时间">
<el-option v-for="(name,key) in timeSelections" :key="key" :value="name" :label="key"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<!-- 消息类型选择器 -->
<el-select v-model="dataForm.msgTypes" placeholder="消息类型">
<el-option value="" label="不限类型"></el-option>
<el-option value="text,image,voice,shortvideo,video,news,music,location,link" label="消息"></el-option>
<el-option value="event,transfer_customer_service" label="事件"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<!-- 查询按钮 -->
<el-button @click="getDataList()">查询</el-button>
</el-form-item>
</el-form>
<!-- 消息回复提示 -->
<div class="text-gray">
24小时内消息可回复。此后台展示消息有一分钟左右延迟如需畅聊请使用
<a href="https://mpkf.weixin.qq.com/" target="_blank">公众平台客服</a>
</div>
<!-- 消息列表使用v-loading显示加载状态 -->
<div v-loading="dataListLoading">
<div class="msg-item" v-for="(msg,index) in dataList" :key="index">
<!-- -->
<div class="avatar"><el-avatar shape="square" :size="60" :src="getUserInfo(msg.openid).headimgurl"></el-avatar></div>
<!-- 消息内容 -->
<div class="item-content">
<div class="flex justify-between margin-bottom">
<div class="text-cut">{{getUserInfo(msg.openid).nickname || '--'}}</div>
<div>{{$moment(msg.createTime).calendar()}}</div>
<div class="reply-btn">
<!-- 回复按钮如果消息在24小时内可点击 -->
<div v-if="canReply(msg.createTime)" @click="replyHandle(msg.openid)" class="el-icon-s-promotion">回复</div>
</div>
</div>
<!-- 消息预览组件 -->
<wx-msg-preview :msg="msg" singleLine></wx-msg-preview>
</div>
</div>
</div>
<!-- 分页组件 -->
<el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" :current-page="pageIndex" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" :total="totalCount" layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
<!-- 弹窗, 消息回复 -->
<wx-msg-reply ref="wxMsgReply" @success="onReplyed"></wx-msg-reply>
</div>
</template>
<script>
const TIME_FORMAT = 'YYYY/MM/DD hh:mm:ss'
export default {
data() {
return {
// 时间选项
timeSelections:{
'近24小时':this.$moment().subtract(1, 'days').format(TIME_FORMAT),
'近3天': this.$moment().subtract(3, 'days').format(TIME_FORMAT),
'近7天': this.$moment().subtract(7, 'days').format(TIME_FORMAT),
'近30天': this.$moment().subtract(30, 'days').format(TIME_FORMAT),
},
// 表单数据
dataForm: {
startTime: this.$moment().subtract(1, 'days').format(TIME_FORMAT),
msgTypes: ''
},
// 消息列表
dataList: [],
// 用户数据列表
userDataList:[],
// 分页参数
pageIndex: 1,
pageSize: 20,
totalCount: 0,
// 加载状态
dataListLoading: false,
// 选中的消息(用于多选操作,但当前代码未使用)
dataListSelections: []
}
},
components: {
// 异步加载组件
WxMsgReply:()=>import('./wx-msg-reply'),
WxMsgPreview:()=>import('@/components/wx-msg-preview')
},
// 激活时获取数据列表
activated() {
this.getDataList()
},
methods: {
// 获取数据列表
getDataList() {
this.dataListLoading = true
this.$http({
url: this.$http.adornUrl('/manage/wxMsg/list'),
method: 'get',
params: this.$http.adornParams({
'page': this.pageIndex,
'limit': this.pageSize,
'msgTypes': this.dataForm.msgTypes,
'startTime':this.dataForm.startTime,
'sidx': 'create_time',
'order': 'desc'
})
}).then(({ data }) => {
if (data && data.code === 200) {
this.dataList = data.page.list
this.totalCount = data.page.totalCount
this.refreshUserList(this.dataList)
} else {
this.dataList = []
this.totalCount = 0
}
this.dataListLoading = false
})
},
// 根据消息列表刷新用户数据列表
refreshUserList(msgList){
let openidList=msgList.map(msg=>msg.openid).filter(openid=>!this.userDataList.some(u=>u.openid==openid))
if(!openidList.length)return
openidList = Array.from(new Set(openidList))//去重
this.$http({
url: this.$http.adornUrl('/manage/wxUser/listByIds'),
method: 'post',
data: this.$http.adornParams(openidList,false)
}).then(({ data }) => {
if (data && data.code === 200) {
this.userDataList = this.userDataList.concat(data.data)
}
})
},
// 根据openid获取用户信息
getUserInfo(openid){
return this.userDataList.find(u=>u.openid==openid) || {nickname:'--',headimgurl:''}
},
// 判断消息是否在24小时内可回复
canReply(time){
return new Date(time).getTime()>new Date().getTime()-24*60*60*1000
},
// 每页显示数量改变时的处理
sizeChangeHandle(val) {
this.pageSize = val
this.pageIndex = 1
this.getDataList()
},
// 当前页码改变时的处理
currentChangeHandle(val) {
this.pageIndex = val
this.getDataList()
},
// 多选操作(当前代码未使用此方法)
selectionChangeHandle(val) {
this.dataListSelections = val
},
// 回复消息
replyHandle(openid) {
this.$nextTick(() => {
this.$refs.wxMsgReply.init(openid)
})
},
// 回复成功后的处理
onReplyed(replyMsg){
this.dataList.unshift({
openid : replyMsg.openid,
msgType : replyMsg.replyType,
detail : {
content : replyMsg.replyContent
},
inOut : 1,
createTime : new Date()
})
}
}
}
</script>
<style scoped>
.msg-item{
border: 1px solid #DCDFE6;
display: flex;
justify-content: flex-start;
align-items: top;
margin-top: 20px;
padding: 10px 20px;
}
.avatar{
flex: 0;
display: inline-block;
min-width: 60px;
margin-right: 20px;
}
.item-content{
flex: 1;
line-height: 20px;
max-width: 100%;
overflow: hidden;
}
.reply-btn{
width: 50px;
}
</style>