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.
569 lines
15 KiB
569 lines
15 KiB
<!--聊天记录-列表-->
|
|
<template>
|
|
<view class="main_box">
|
|
|
|
<view class="main_section">
|
|
<scroll-view
|
|
class="section_1"
|
|
scroll-y="true"
|
|
:scroll-top="scrollTop"
|
|
:lower-threshold="lowerThreshold"
|
|
style="height: 78vh;"
|
|
>
|
|
<view class="ul">
|
|
<view class="item_box" v-for="(v,k) in tableList" :key="k" :id="'item_' + v.id">
|
|
<view class="time_section" v-if="v.created_at">{{v.created_at}}</view>
|
|
|
|
<view class="li" v-if="v.direction == `left`">
|
|
<view class="item left_item" :style="{ backgroundColor: v.message_type === 'text' ? '#f4f6f9' : '' }">
|
|
<!--文本内容-->
|
|
<view class="text_box" v-if="v.message_type == 'text'">{{v.content}}</view>
|
|
<!-- 图片内容 -->
|
|
<view class="img_box" v-if="v.message_type == 'img'" @click="previewImage(v.content)">
|
|
<image class="chat_img" :src="v.content" mode="aspectFill"></image>
|
|
</view>
|
|
</view>
|
|
<view class="item"></view>
|
|
</view>
|
|
|
|
<view class="li" v-if="v.direction == `right`">
|
|
<view class="item"></view>
|
|
<view class="item right_item" :style="{ backgroundColor: v.message_type === 'text' ? '#1684fc' : '' }">
|
|
<view class="text_box" v-if="v.message_type == 'text'">{{v.content}}</view>
|
|
<!-- 图片内容 -->
|
|
<view class="img_box" v-if="v.message_type == 'img'" @click="previewImage(v.content)">
|
|
<image class="chat_img" :src="v.content" mode="aspectFill"></image>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<view class="input_section">
|
|
<view class="left_box">
|
|
<input class="input" v-model="formData.content" type="text" placeholder="请输入">
|
|
</view>
|
|
<view class="right_box">
|
|
<!--发送-->
|
|
<view class="img_box">
|
|
<image @click="submitTextForm()" class="send_img" src="@/static/images/common/fa_song.png"></image>
|
|
</view>
|
|
|
|
<!--更多选择-->
|
|
<view class="img_box">
|
|
<image @click="openMore()" class="send_img" src="@/static/images/common/jia_hao.png"></image>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!--更多选择-->
|
|
<fui-bottom-popup :show="moreShow" @close="closeMore">
|
|
<view class="more_section">
|
|
<view class="fui-scroll__wrap">
|
|
<scroll-view scroll-y class="fui-scroll__view">
|
|
<view class="ul">
|
|
<view class="li" @click="">
|
|
<AQUplodeImage
|
|
:uploadUrl=uploadUrl
|
|
:extraData="{ input_name: 'img_uplode', formData:{} }"
|
|
@uplodeImageRes="uplodeImageRes"
|
|
>
|
|
<view class="icon_box">
|
|
<fui-icon name="picture-fill" :size="80"></fui-icon>
|
|
</view>
|
|
<view class="title">相册</view>
|
|
</AQUplodeImage>
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</fui-bottom-popup>
|
|
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import apiRoute from '@/api/apiRoute.js';
|
|
|
|
import {
|
|
Api_url
|
|
} from "@/common/config.js";
|
|
import AQUplodeImage from '@/components/AQ/AQUplodeImage';//单图上传组件
|
|
import AQTabber from "@/components/AQ/AQTabber"
|
|
|
|
|
|
export default {
|
|
components: {
|
|
AQTabber,
|
|
AQUplodeImage,
|
|
},
|
|
data() {
|
|
return {
|
|
uploadUrl: `${Api_url}/uploadImage`,
|
|
|
|
|
|
scrollTop:'',//滚动条位置,用于加载第一页后滚动到底部
|
|
loading:false,//加载状态
|
|
lowerThreshold: 100,//距离底部多远触发
|
|
isReachedBottom: false,//防止重复加载|true=不可加载|false=可加载
|
|
|
|
//筛选条件
|
|
filteredData:{
|
|
page:1,//当前页码
|
|
limit:10,//每页返回数据条数
|
|
total:10,//数据总条数
|
|
friend_id: '',//chat_friends表id
|
|
},
|
|
tableList:[],//聊天数据列表
|
|
|
|
from_id:'',//发送者ID
|
|
to_id:'',//接收者ID
|
|
from_type:'',//发送者类型|personnel=员工,customer=学生(客户)
|
|
|
|
//请求参数
|
|
chatFriendsInfoParams:{
|
|
personnel_id:'',
|
|
customer_resources_id:'',
|
|
},
|
|
chatFriendsInfo:{},//好友关系详情
|
|
|
|
//聊天表单信息
|
|
formData: {
|
|
from_type:'',//发送者类型|personnel=员工,customer=学生(客户)
|
|
from_id:'',//发送者ID
|
|
to_id:'',//接收者ID
|
|
friend_id:'',//关联chat_friends表id
|
|
message_type: 'text',//消息类型|text=文本,img=图片
|
|
content: '',//文本内容(JSON 格式扩展字段),文本类型=纯文字,图片类型=绝对路径
|
|
},
|
|
|
|
//更多选项相关
|
|
moreShow:false,
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
this.from_id = options.from_id//发送者的id
|
|
this.to_id = options.to_id//接收者的id
|
|
},
|
|
onShow(){
|
|
this.init()
|
|
},
|
|
//下拉刷新
|
|
async onPullDownRefresh() {
|
|
//加载更多(下一页)
|
|
await this.loadMoreData()
|
|
},
|
|
methods: {
|
|
|
|
//初始化
|
|
async init(){
|
|
//获取用户类型
|
|
let userType = uni.getStorageSync('userType')
|
|
//1=教练,2=销售,3=学员
|
|
if (['1', '2'].includes(String(userType))) {
|
|
//
|
|
this.from_type = 'personnel'//员工
|
|
this.chatFriendsInfoParams.personnel_id = this.from_id//员工资源的id
|
|
this.chatFriendsInfoParams.customer_resources_id = this.to_id//学生资源的id
|
|
|
|
this.formData.from_type = 'personnel'//员工
|
|
this.formData.from_id = this.from_id//发送者的id(员工)
|
|
this.formData.to_id = this.to_id//接收者的id(学生)
|
|
|
|
} else {
|
|
//
|
|
this.from_type = 'customer'//学生
|
|
this.chatFriendsInfoParams.personnel_id = this.to_id//员工资源的id
|
|
this.chatFriendsInfoParams.customer_resources_id = this.from_id//学生资源的id
|
|
|
|
this.formData.from_type = 'customer'//学生
|
|
this.formData.from_id = this.to_id//发送者的id(学生)
|
|
this.formData.to_id = this.from_id//接收者的id(员工)
|
|
}
|
|
//获取好友关系详情
|
|
await this.getChatFriendsInfo()
|
|
//获取聊天记录列表
|
|
await this.getList();
|
|
|
|
// 首次加载后滚动到底部
|
|
if (this.filteredData.page == 2) {
|
|
this.scrollToBottom()
|
|
}
|
|
},
|
|
|
|
//获取好友关系详情
|
|
async getChatFriendsInfo(){
|
|
let params = {
|
|
personnel_id: this.chatFriendsInfoParams.personnel_id,//员工资源ID
|
|
customer_resources_id: this.chatFriendsInfoParams.customer_resources_id,//学生资源ID
|
|
}
|
|
let res = await apiRoute.xs_chatGetChatFriendsInfo(params)
|
|
if (res.code != 1){
|
|
uni.showToast({
|
|
title: res.msg,
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
this.chatFriendsInfo = res.data
|
|
|
|
this.filteredData.friend_id = res.data.id
|
|
|
|
this.formData.friend_id = res.data.id
|
|
},
|
|
|
|
//加载更多(下一页)
|
|
loadMoreData() {
|
|
//判断是否加载
|
|
if (!this.isReachedBottom) {
|
|
this.isReachedBottom = true;//设置为不可请求状态
|
|
this.getList();
|
|
}
|
|
},
|
|
//重置为第一页
|
|
async resetFilteredData() {
|
|
this.isReachedBottom = false; // 重置状态,以便下次触发加载更多
|
|
|
|
this.filteredData.page = 1//当前页码
|
|
this.filteredData.limit = 10//每页返回数据条数
|
|
this.filteredData.total = 10//数据总条数
|
|
},
|
|
|
|
//获取聊天记录列表
|
|
async getList(){
|
|
this.loading = true
|
|
|
|
let data = {...this.filteredData}
|
|
|
|
// 判断是否还有数据可加载
|
|
if ((this.filteredData.page - 1) * this.filteredData.limit >= this.filteredData.total) {
|
|
this.loading = false;
|
|
uni.showToast({
|
|
title: '暂无更多',
|
|
icon: 'none'
|
|
});
|
|
return;
|
|
}
|
|
|
|
if(data.page == 1){
|
|
this.tableList = []
|
|
}
|
|
|
|
let res = await apiRoute.xs_chatGetChatMessagesList(data)//获取消息列表
|
|
this.loading = false
|
|
this.isReachedBottom = false;
|
|
if (res.code != 1){
|
|
uni.showToast({
|
|
title: res.msg,
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
// this.tableList = this.tableList.concat(res.data.data); // 使用 concat 方法 将新数据追加到数组中
|
|
|
|
let list = res.data.data
|
|
|
|
list.forEach((v, k) => {
|
|
|
|
if (this.from_type == 'personnel') {
|
|
//当前是员工登陆聊天页面时
|
|
if (v.from_type == 'personnel') {
|
|
v.direction = 'right'//是员工发的消息
|
|
} else {
|
|
v.direction = 'left'//是学生发的消息
|
|
}
|
|
} else if (this.from_type == 'customer') {
|
|
//当前是学生登陆聊天页面时
|
|
if (v.from_type == 'customer') {
|
|
v.direction = 'right'//是员工发的消息
|
|
} else {
|
|
v.direction = 'left'//是学生发的消息
|
|
}
|
|
}
|
|
})
|
|
|
|
list.reverse()
|
|
this.tableList.unshift(...list); // 将新数据插入到数组头部
|
|
|
|
console.log('列表',res.data.total)
|
|
this.filteredData.total = res.data.total
|
|
this.filteredData.page++
|
|
},
|
|
|
|
|
|
//######AQ上传文件组件相关######
|
|
// 上传文件回调
|
|
AQUploadSuccess(res) {
|
|
console.log('接收AQ上传回调xxx1', res)
|
|
// 使用 split 方法分割字符串
|
|
let _inputValue = []
|
|
if (res.filePathArr.length) {
|
|
_inputValue = res.filePathArr
|
|
}
|
|
this.formData[res.inputName] = _inputValue
|
|
// console.log('接收AQ上传回调xxx1',res)
|
|
// console.log('接收AQ上传回调xxx2',this.formData.member_store_certification_arr)
|
|
},
|
|
|
|
|
|
//发送文本信息
|
|
submitTextForm(){
|
|
this.formData.message_type = 'text'
|
|
this.submitForm()
|
|
},
|
|
//发送站内信
|
|
async submitForm() {
|
|
let data = {...this.formData}
|
|
if (!data.content) {
|
|
//反馈内容为必填项
|
|
uni.showToast({
|
|
title: '请输入内容',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
let res = await apiRoute.xs_chatSendChatMessages(data)
|
|
if (res.code != 1) {
|
|
uni.showToast({
|
|
title: res.msg,
|
|
icon: 'none'
|
|
})
|
|
} else {
|
|
let content = this.formData.content
|
|
this.formData.content = ''//清空输入框
|
|
|
|
|
|
|
|
let msgData = {
|
|
id:'',
|
|
from_type:data.from_type,//发送者类型|personnel=员工,customer=学生(客户)
|
|
from_id:data.from_id,//发送者ID
|
|
to_id:data.to_id,//接收者ID
|
|
friend_id:data.friend_id,//关联chat_friends表id
|
|
message_type: data.message_type,//消息类型|text=文本,img=图片
|
|
content: data.content,//文本内容(JSON 格式扩展字段),文本类型=纯文字,图片类型=绝对路径
|
|
direction:'right'
|
|
}
|
|
//将发送的消息放在最下方
|
|
this.tableList = this.tableList.concat(msgData);
|
|
}
|
|
},
|
|
|
|
//页面滚动到底部
|
|
scrollToBottom() {
|
|
this.$nextTick(() => {
|
|
this.scrollTop = 999999 // 足够大的值确保滚动到底部
|
|
})
|
|
},
|
|
|
|
//打开更多选择弹窗
|
|
openMore(){
|
|
this.moreShow = true
|
|
},
|
|
//关闭更多选择弹窗
|
|
closeMore(){
|
|
this.moreShow = false
|
|
},
|
|
|
|
//但文件上传回调
|
|
uplodeImageRes(resData,extraData){
|
|
console.log('上传成功回调',resData,extraData)
|
|
//判断是不是上传相册图片
|
|
if(extraData.input_name == 'img_uplode'){
|
|
this.closeMore()//关闭更多选择弹窗
|
|
this.formData.content = resData.url
|
|
this.formData.message_type = 'img'
|
|
this.submitForm()
|
|
}
|
|
},
|
|
|
|
//图片预览
|
|
previewImage(url){
|
|
uni.previewImage({
|
|
current: url, // 当前图片地址
|
|
urls: [url] // 所有图片列表(可以是多个)
|
|
});
|
|
},
|
|
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.main_box {
|
|
background: #292929;
|
|
}
|
|
|
|
//自定义导航栏
|
|
.navbar_section {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background: #29d3b4;
|
|
|
|
.title {
|
|
padding: 20rpx 0;
|
|
font-size: 30rpx;
|
|
color: #315d55;
|
|
}
|
|
}
|
|
|
|
.main_section {
|
|
min-height: 100vh;
|
|
background: #292929 100%;
|
|
padding: 0 0rpx;
|
|
padding-top: 120rpx;
|
|
padding-bottom: 120rpx;
|
|
font-size: 28rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20rpx;
|
|
|
|
.section {
|
|
background-color: #434544;
|
|
padding: 40rpx 40rpx;
|
|
}
|
|
|
|
.section_1{
|
|
color: #FFFFFF;
|
|
font-size: 28rpx;
|
|
padding: 0 24rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 40rpx;
|
|
.ul{
|
|
.time_section{
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
color: #989898;
|
|
}
|
|
.li{
|
|
margin: 40rpx 0;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
.item{
|
|
max-width: 70%;
|
|
padding: 32rpx;
|
|
border-radius: 32rpx;
|
|
word-wrap: break-word; /* 允许长单词或 URL 换行 */
|
|
word-break: break-all; /* 强制所有字符换行 */
|
|
.text_box{}
|
|
.img_box {
|
|
.chat_img {
|
|
width: 200rpx;
|
|
height: 200rpx;
|
|
border-radius: 16rpx;
|
|
}
|
|
}
|
|
}
|
|
.left_item{
|
|
//background-color: #f4f6f9;
|
|
color: #343434;
|
|
}
|
|
.right_item{
|
|
//background-color: #1684fc;
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//输入框板块
|
|
.input_section{
|
|
width: 100%;
|
|
position: fixed;
|
|
bottom: 0;
|
|
|
|
padding: 30rpx;
|
|
padding-bottom: 50rpx;
|
|
display: flex;
|
|
justify-content:space-between;
|
|
align-items: center;
|
|
gap: 20rpx;
|
|
.left_box{
|
|
.input{
|
|
background-color: #f4f6f9;
|
|
height: 88rpx;
|
|
padding: 28rpx;
|
|
font-size: 28rpx;
|
|
border-radius: 32rpx;
|
|
|
|
width: 480rpx;
|
|
color: #292929;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
.right_box{
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
.img_box{
|
|
width: 88rpx;
|
|
height: 88rpx;
|
|
border-radius: 50%;
|
|
background-color: #a2cefe;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
.send_img{
|
|
width: 36rpx;
|
|
height: 36rpx;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
.describe {
|
|
color: #999999;
|
|
padding-left: 30rpx;
|
|
}
|
|
|
|
|
|
/* 更多选项相关 自定义内容区样式需自行控制 */
|
|
.more_section{
|
|
.fui-scroll__wrap {
|
|
padding-top: 30rpx;
|
|
position: relative;
|
|
}
|
|
.fui-title {
|
|
font-size: 30rpx;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
padding-bottom: 24rpx;
|
|
}
|
|
.fui-icon__close {
|
|
position: absolute;
|
|
top: 24rpx;
|
|
left: 24rpx;
|
|
}
|
|
.fui-scroll__view {
|
|
width: 100%;
|
|
height: 350rpx;
|
|
}
|
|
|
|
.ul{
|
|
padding: 10rpx 40rpx;
|
|
display: flex;
|
|
.li{
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
.icon_box{
|
|
}
|
|
.title{
|
|
font-size: 28rpx;
|
|
text-align: center;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|