752 lines
21 KiB
JavaScript
752 lines
21 KiB
JavaScript
// pages/companion-chat/companion-chat.js - 陪聊师列表/陪聊聊天页面
|
||
// 对接后端API
|
||
|
||
const api = require('../../utils/api')
|
||
const { getPageAssets } = require('../../utils/assets')
|
||
const app = getApp()
|
||
|
||
Page({
|
||
data: {
|
||
statusBarHeight: 44,
|
||
navBarHeight: 44,
|
||
totalNavHeight: 88,
|
||
stickyHeaderHeight: 150,
|
||
isSticky: false,
|
||
stickyThreshold: 0,
|
||
loading: false,
|
||
showCategoryGrid: true,
|
||
categoryImageLoadCount: 0,
|
||
categoryImageErrorCount: 0,
|
||
// 页面素材
|
||
bannerImage: 'https://ai-c.maimanji.com/images/Header-banner.png',
|
||
categoryImages: [
|
||
'https://ai-c.maimanji.com/images/pb01.png',
|
||
'https://ai-c.maimanji.com/images/pb02.png',
|
||
'https://ai-c.maimanji.com/images/pb03.png',
|
||
'https://ai-c.maimanji.com/images/pb04.png'
|
||
],
|
||
consultButtonImage: '/images/btn-text-consult.png',
|
||
giftIcon: '/images/icon-gift.png',
|
||
locationIcon: '/images/icon-location.png',
|
||
// 页面模式: list(陪聊师列表) / chat(聊天)
|
||
mode: 'list',
|
||
// 列表模式数据
|
||
searchKeyword: '',
|
||
counselorList: [],
|
||
filters: {
|
||
status: '',
|
||
gender: '',
|
||
sortBy: 'rating',
|
||
specialty: ''
|
||
},
|
||
// 筛选条显示文本
|
||
filterLabels: {
|
||
sort: '排序',
|
||
gender: '性别',
|
||
specialty: '类型',
|
||
filter: '筛选'
|
||
},
|
||
page: 1,
|
||
hasMore: true,
|
||
// 聊天模式数据
|
||
orderId: '',
|
||
companionId: '',
|
||
companionName: '',
|
||
messages: [],
|
||
inputText: '',
|
||
serviceEndTime: null,
|
||
remainingTime: '',
|
||
// 未读消息数
|
||
totalUnread: 0,
|
||
// 电话倾诉指南弹窗
|
||
showGuidePopup: false,
|
||
guideData: {
|
||
title: '电话倾诉指南',
|
||
subtitle: '让沟通更有效',
|
||
steps: [
|
||
{ number: 1, title: '选择合适的倾诉师', description: '根据您的需求,浏览倾诉师的擅长方向、服务经验和用户评价,选择最适合您的专业倾诉师。' },
|
||
{ number: 2, title: '预约通话时间', description: '选择您方便的时间段进行预约,确保有充足的时间进行深入交流,建议每次通话30-60分钟。' },
|
||
{ number: 3, title: '准备倾诉内容', description: '提前整理您想要倾诉的问题或困惑,这样能让沟通更有针对性和效果。' },
|
||
{ number: 4, title: '保持真诚开放', description: '在安全私密的环境中,真诚地表达您的感受和想法。倾诉师会为您保密,请放心倾诉。' }
|
||
],
|
||
tips: {
|
||
title: '温馨提示',
|
||
content: '首次通话建议先试听,了解倾诉师的沟通风格。如遇紧急情况,请及时拨打心理危机热线或就医。'
|
||
}
|
||
},
|
||
auditStatus: 0
|
||
},
|
||
|
||
async onLoad(options) {
|
||
const systemInfo = wx.getSystemInfoSync()
|
||
const statusBarHeight = systemInfo.statusBarHeight || 44
|
||
const menuButton = wx.getMenuButtonBoundingClientRect()
|
||
const navBarHeight = menuButton.height + (menuButton.top - statusBarHeight) * 2
|
||
const totalNavHeight = statusBarHeight + navBarHeight
|
||
|
||
// 计算固定头部高度(搜索框 + 筛选条)
|
||
const stickyHeaderHeight = statusBarHeight + 90
|
||
|
||
// 计算吸顶触发阈值:banner高度(400rpx) + 红包条(约80rpx) + 分类按钮(约230rpx) + 标题行(约80rpx)
|
||
// 转换为px:rpx * 屏幕宽度 / 750
|
||
const screenWidth = systemInfo.screenWidth
|
||
const stickyThreshold = (400 + 80 + 230 + 80) * screenWidth / 750
|
||
|
||
this.setData({
|
||
statusBarHeight,
|
||
navBarHeight,
|
||
totalNavHeight,
|
||
stickyHeaderHeight,
|
||
stickyThreshold
|
||
})
|
||
|
||
// 加载页面素材
|
||
await this.loadPageAssets()
|
||
|
||
// 判断页面模式
|
||
if (options.orderId) {
|
||
// 聊天模式
|
||
this.setData({
|
||
mode: 'chat',
|
||
orderId: options.orderId,
|
||
companionId: options.companionId,
|
||
companionName: decodeURIComponent(options.name || '')
|
||
})
|
||
this.loadChatHistory()
|
||
} else {
|
||
// 列表模式
|
||
this.loadCounselorList()
|
||
}
|
||
},
|
||
|
||
onShow() {
|
||
wx.hideTabBar({ animation: false })
|
||
const app = getApp()
|
||
this.setData({
|
||
auditStatus: app.globalData.auditStatus
|
||
})
|
||
this.loadUnreadCount()
|
||
},
|
||
|
||
onUnload() {
|
||
// 清除计时器
|
||
if (this.timer) {
|
||
clearInterval(this.timer)
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 页面滚动监听 - 控制吸顶效果
|
||
*/
|
||
onPageScroll(e) {
|
||
const scrollTop = e.detail.scrollTop
|
||
const { stickyThreshold, isSticky } = this.data
|
||
|
||
// 添加一定的缓冲区,避免在临界点频繁切换
|
||
const buffer = 10 // 10px缓冲区
|
||
|
||
// 当滚动超过阈值+缓冲时显示吸顶,低于阈值-缓冲时隐藏
|
||
let shouldSticky = isSticky
|
||
if (scrollTop > stickyThreshold + buffer) {
|
||
shouldSticky = true
|
||
} else if (scrollTop < stickyThreshold - buffer) {
|
||
shouldSticky = false
|
||
}
|
||
|
||
if (shouldSticky !== isSticky) {
|
||
this.setData({ isSticky: shouldSticky })
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 加载页面素材配置
|
||
*/
|
||
async loadPageAssets() {
|
||
try {
|
||
const assets = await getPageAssets();
|
||
|
||
if (assets) {
|
||
this.setData({
|
||
bannerImage: assets.banners.companion_banner,
|
||
categoryImages: [
|
||
assets.entries.entry_1,
|
||
assets.entries.entry_2,
|
||
assets.entries.entry_3,
|
||
assets.entries.entry_4
|
||
],
|
||
consultButtonImage: assets.icons.consult_button,
|
||
giftIcon: assets.icons.gift,
|
||
locationIcon: assets.icons.location
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('加载页面素材失败:', error);
|
||
// 使用默认值,已在 data 中定义
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 加载未读消息数
|
||
*/
|
||
async loadUnreadCount() {
|
||
if (!app.globalData.isLoggedIn) {
|
||
this.setData({ totalUnread: 0 })
|
||
return
|
||
}
|
||
|
||
try {
|
||
const res = await api.chat.getConversations()
|
||
if (res.success && res.data) {
|
||
const totalUnread = res.data.reduce((sum, conv) => sum + (conv.unread_count || 0), 0)
|
||
this.setData({ totalUnread })
|
||
} else {
|
||
this.setData({ totalUnread: 0 })
|
||
}
|
||
} catch (err) {
|
||
console.log('获取未读消息数失败', err)
|
||
this.setData({ totalUnread: 0 })
|
||
}
|
||
},
|
||
|
||
// ==================== 列表模式 ====================
|
||
|
||
/**
|
||
* 加载陪聊师列表
|
||
*/
|
||
async loadCounselorList() {
|
||
this.setData({ loading: true, page: 1 })
|
||
|
||
try {
|
||
const params = {
|
||
page: 1,
|
||
pageSize: 20,
|
||
...this.data.filters
|
||
}
|
||
|
||
// 过滤掉空值参数
|
||
Object.keys(params).forEach(key => {
|
||
if (params[key] === '' || params[key] === undefined || params[key] === null) {
|
||
delete params[key]
|
||
}
|
||
})
|
||
|
||
if (this.data.searchKeyword.trim()) {
|
||
params.keyword = this.data.searchKeyword.trim()
|
||
}
|
||
|
||
console.log('请求陪聊师列表,参数:', params)
|
||
|
||
const res = await api.companion.getList(params)
|
||
|
||
console.log('陪聊师列表响应:', res)
|
||
|
||
// 兼容两种返回格式
|
||
let list = []
|
||
if (res.success && res.data) {
|
||
// 格式1: { success: true, data: { list: [...] } }
|
||
// 格式2: { success: true, data: [...] }
|
||
list = Array.isArray(res.data) ? res.data : (res.data.list || [])
|
||
}
|
||
|
||
if (list.length > 0) {
|
||
const transformedList = list.map(c => this.transformCounselor(c))
|
||
|
||
this.setData({
|
||
counselorList: transformedList,
|
||
hasMore: list.length >= 20,
|
||
loading: false
|
||
})
|
||
console.log('更新列表成功,数量:', transformedList.length)
|
||
} else {
|
||
// API没有数据时使用模拟数据
|
||
console.log('API返回空数据,使用模拟数据')
|
||
this.setData({
|
||
counselorList: this.getMockCounselorList(),
|
||
loading: false
|
||
})
|
||
}
|
||
} catch (err) {
|
||
console.error('加载陪聊师列表失败', err)
|
||
// 加载失败时使用模拟数据
|
||
this.setData({
|
||
counselorList: this.getMockCounselorList(),
|
||
loading: false
|
||
})
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 获取模拟陪聊师数据
|
||
*/
|
||
getMockCounselorList() {
|
||
return [
|
||
{
|
||
id: 'c001',
|
||
name: '林心怡',
|
||
avatar: '',
|
||
avatarColor: '#e8b4d8',
|
||
avatarColorEnd: '#c984cd',
|
||
type: '文字/语音',
|
||
age: '28岁',
|
||
education: '心理学硕士',
|
||
training: '国家二级心理咨询师',
|
||
certification: '情感咨询专家认证',
|
||
quote: '每一次倾诉,都是心灵的释放',
|
||
tags: ['情感倾诉', '婚姻家庭', '亲密关系'],
|
||
serviceCount: 1286,
|
||
repeatCount: 423,
|
||
rating: 4.96,
|
||
location: '北京',
|
||
online: true
|
||
},
|
||
{
|
||
id: 'c002',
|
||
name: '张明辉',
|
||
avatar: '',
|
||
avatarColor: '#a8d8ea',
|
||
avatarColorEnd: '#6bb3d9',
|
||
type: '文字/语音',
|
||
age: '35岁',
|
||
education: '应用心理学博士',
|
||
training: '高级心理咨询师',
|
||
certification: '职场心理专家',
|
||
quote: '用专业的态度,温暖每一颗心',
|
||
tags: ['职场压力', '人际关系', '情绪管理'],
|
||
serviceCount: 2156,
|
||
repeatCount: 687,
|
||
rating: 4.92,
|
||
location: '上海',
|
||
online: true
|
||
},
|
||
{
|
||
id: 'c003',
|
||
name: '王雨萱',
|
||
avatar: '',
|
||
avatarColor: '#f8c8dc',
|
||
avatarColorEnd: '#e89bb8',
|
||
type: '文字/语音',
|
||
age: '26岁',
|
||
education: '心理学学士',
|
||
training: '情感咨询师',
|
||
certification: '青年心理辅导员',
|
||
quote: '倾听你的故事,陪伴你的成长',
|
||
tags: ['恋爱指导', '分手挽回', '单身脱单'],
|
||
serviceCount: 856,
|
||
repeatCount: 298,
|
||
rating: 4.89,
|
||
location: '深圳',
|
||
online: false
|
||
},
|
||
{
|
||
id: 'c004',
|
||
name: '李思远',
|
||
avatar: '',
|
||
avatarColor: '#b8d4e3',
|
||
avatarColorEnd: '#8ab4cf',
|
||
type: '文字/语音',
|
||
age: '42岁',
|
||
education: '临床心理学硕士',
|
||
training: '资深心理治疗师',
|
||
certification: '家庭治疗师认证',
|
||
quote: '专业倾听,用心陪伴每一刻',
|
||
tags: ['婚姻危机', '家庭矛盾', '亲子教育'],
|
||
serviceCount: 3421,
|
||
repeatCount: 1156,
|
||
rating: 4.98,
|
||
location: '广州',
|
||
online: true
|
||
},
|
||
{
|
||
id: 'c005',
|
||
name: '陈晓琳',
|
||
avatar: '',
|
||
avatarColor: '#d4b8e8',
|
||
avatarColorEnd: '#b088d4',
|
||
type: '文字/语音',
|
||
age: '31岁',
|
||
education: '发展心理学硕士',
|
||
training: '心理咨询师',
|
||
certification: '情绪管理专家',
|
||
quote: '让每一次对话都充满温暖',
|
||
tags: ['焦虑抑郁', '情绪调节', '自我成长'],
|
||
serviceCount: 1567,
|
||
repeatCount: 512,
|
||
rating: 4.94,
|
||
location: '杭州',
|
||
online: true
|
||
},
|
||
{
|
||
id: 'c006',
|
||
name: '赵文博',
|
||
avatar: '',
|
||
avatarColor: '#a8e6cf',
|
||
avatarColorEnd: '#7bc9a6',
|
||
type: '文字/语音',
|
||
age: '38岁',
|
||
education: '社会心理学博士',
|
||
training: '高级心理顾问',
|
||
certification: '企业EAP咨询师',
|
||
quote: '理性分析,感性陪伴',
|
||
tags: ['职业规划', '压力管理', '领导力'],
|
||
serviceCount: 1892,
|
||
repeatCount: 634,
|
||
rating: 4.91,
|
||
location: '成都',
|
||
online: false
|
||
}
|
||
]
|
||
},
|
||
|
||
/**
|
||
* 转换陪聊师数据格式
|
||
*/
|
||
transformCounselor(data) {
|
||
const config = require('../../config/index')
|
||
|
||
// 处理地址,只显示城市名
|
||
let location = data.location || data.city || ''
|
||
if (location) {
|
||
// 如果地址包含多个部分(如"北京 北京市 朝阳区"),只取第一个城市名
|
||
// 或者如果是"XX市"格式,去掉"市"字
|
||
const parts = location.split(/[\s,,]+/).filter(p => p.trim())
|
||
if (parts.length > 0) {
|
||
location = parts[0].replace(/[省市区县]$/, '') || parts[0]
|
||
}
|
||
}
|
||
|
||
// 处理在线状态 - 后端返回 onlineStatus 或 status
|
||
const onlineStatus = data.onlineStatus || data.online_status || data.status || 'offline'
|
||
const isOnline = onlineStatus === 'online'
|
||
const isBusy = onlineStatus === 'busy'
|
||
|
||
// 处理头像URL - 如果是相对路径,拼接完整域名
|
||
let avatar = data.avatar || ''
|
||
if (avatar && avatar.startsWith('/')) {
|
||
// 从 API_BASE_URL 提取域名(去掉 /api 后缀)
|
||
const baseUrl = config.API_BASE_URL.replace(/\/api$/, '')
|
||
avatar = baseUrl + avatar
|
||
}
|
||
|
||
return {
|
||
id: data.id,
|
||
name: data.name || data.displayName || data.nickname,
|
||
avatar: avatar,
|
||
type: data.service_type || '文字/语音',
|
||
age: data.age_group || data.age || '',
|
||
education: data.education || '',
|
||
training: data.training || data.certification || '',
|
||
certification: data.certification || '',
|
||
quote: data.quote || data.bio || data.introduction || '',
|
||
tags: data.tags || data.specialties || [],
|
||
serviceCount: data.serviceCount || data.service_count || data.totalOrders || 0,
|
||
repeatCount: data.repeatCount || data.repeat_count || 0,
|
||
rating: data.rating || 5.0,
|
||
location: location,
|
||
online: isOnline,
|
||
onlineStatus: onlineStatus,
|
||
statusText: data.statusText || (isOnline ? '在线' : isBusy ? '忙碌中' : '离线'),
|
||
// 等级和价格信息
|
||
levelCode: data.levelCode || 'junior',
|
||
levelName: data.levelName || '初级',
|
||
textPrice: data.textPrice || data.pricePerMinute || 0.5,
|
||
voicePrice: data.voicePrice || 1
|
||
}
|
||
},
|
||
|
||
onSearchInput(e) {
|
||
this.setData({ searchKeyword: e.detail.value })
|
||
},
|
||
|
||
/**
|
||
* 搜索
|
||
*/
|
||
onSearch() {
|
||
this.loadCounselorList()
|
||
},
|
||
|
||
onCategoryTap(e) {
|
||
const type = e.currentTarget.dataset.type
|
||
wx.showToast({ title: type, icon: 'none' })
|
||
},
|
||
|
||
/**
|
||
* 分类图片加载成功
|
||
*/
|
||
onCategoryImageLoad() {
|
||
const count = this.data.categoryImageLoadCount + 1
|
||
this.setData({ categoryImageLoadCount: count })
|
||
},
|
||
|
||
/**
|
||
* 分类图片加载失败 - 如果全部失败则隐藏区域
|
||
*/
|
||
onCategoryImageError() {
|
||
const errorCount = this.data.categoryImageErrorCount + 1
|
||
this.setData({ categoryImageErrorCount: errorCount })
|
||
|
||
// 如果4张图片都加载失败,隐藏整个分类区域
|
||
if (errorCount >= 4) {
|
||
this.setData({ showCategoryGrid: false })
|
||
}
|
||
},
|
||
|
||
onFilterTap(e) {
|
||
const filter = e.currentTarget.dataset.filter
|
||
console.log('筛选点击:', filter)
|
||
|
||
const options = this.getFilterOptions(filter)
|
||
console.log('筛选选项:', options)
|
||
|
||
if (!options || options.length === 0) {
|
||
wx.showToast({ title: '暂无筛选选项', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
wx.showActionSheet({
|
||
itemList: options,
|
||
success: (res) => {
|
||
console.log('选择了:', res.tapIndex, options[res.tapIndex])
|
||
const value = this.getFilterValue(filter, res.tapIndex)
|
||
const label = options[res.tapIndex]
|
||
|
||
// 更新筛选值 - 映射筛选类型到正确的参数名
|
||
// sort -> sortBy, filter -> status, 其他保持不变
|
||
const filterKeyMap = {
|
||
sort: 'sortBy',
|
||
filter: 'status', // 筛选选项对应后端的 status 参数
|
||
gender: 'gender',
|
||
specialty: 'specialty'
|
||
}
|
||
const filterKey = filterKeyMap[filter] || filter
|
||
|
||
// 更新筛选标签显示
|
||
const defaultLabels = {
|
||
sort: '排序',
|
||
gender: '性别',
|
||
specialty: '类型',
|
||
filter: '筛选'
|
||
}
|
||
const displayLabel = res.tapIndex === 0 ? defaultLabels[filter] : label
|
||
|
||
console.log('更新筛选参数:', filterKey, '=', value)
|
||
|
||
this.setData({
|
||
[`filters.${filterKey}`]: value,
|
||
[`filterLabels.${filter}`]: displayLabel
|
||
})
|
||
|
||
this.loadCounselorList()
|
||
},
|
||
fail: (err) => {
|
||
console.log('取消选择或失败:', err)
|
||
}
|
||
})
|
||
},
|
||
|
||
getFilterOptions(filter) {
|
||
const options = {
|
||
sort: ['综合排序', '好评优先', '服务人次', '价格从低到高'],
|
||
gender: ['不限', '男', '女'],
|
||
specialty: ['不限', '情感倾诉', '婚姻家庭', '职场压力', '亲子关系'],
|
||
filter: ['在线优先', '有空闲', '全部']
|
||
}
|
||
return options[filter] || []
|
||
},
|
||
|
||
getFilterValue(filter, index) {
|
||
const values = {
|
||
sort: ['', 'rating', 'service_count', 'price'],
|
||
gender: ['', 'male', 'female'],
|
||
specialty: ['', 'emotion', 'marriage', 'work', 'family'],
|
||
filter: ['online', 'available', '']
|
||
}
|
||
return (values[filter] || [])[index] || ''
|
||
},
|
||
|
||
async onGuideClick() {
|
||
// 显示弹窗
|
||
this.setData({ showGuidePopup: true })
|
||
|
||
// 从后台获取协议内容
|
||
try {
|
||
const res = await api.agreement.get('phone-guide')
|
||
if (res.success && res.data && res.data.content) {
|
||
// 解析JSON内容
|
||
let content = res.data.content
|
||
if (typeof content === 'string') {
|
||
try {
|
||
content = JSON.parse(content)
|
||
} catch (e) {
|
||
console.log('协议内容不是JSON格式')
|
||
return
|
||
}
|
||
}
|
||
|
||
// 更新弹窗数据
|
||
this.setData({
|
||
'guideData.subtitle': content.subtitle || '让沟通更有效',
|
||
'guideData.steps': content.steps || this.data.guideData.steps,
|
||
'guideData.tips': content.tips || this.data.guideData.tips
|
||
})
|
||
}
|
||
} catch (err) {
|
||
console.log('获取协议内容失败,使用默认内容', err)
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 关闭指南弹窗
|
||
*/
|
||
onCloseGuidePopup() {
|
||
this.setData({ showGuidePopup: false })
|
||
},
|
||
|
||
/**
|
||
* 阻止弹窗内容区域的点击事件冒泡
|
||
*/
|
||
preventClose() {
|
||
// 空函数,阻止事件冒泡
|
||
},
|
||
|
||
onCounselorTap(e) {
|
||
const id = e.currentTarget.dataset.id
|
||
wx.navigateTo({
|
||
url: `/pages/counselor-detail/counselor-detail?id=${id}`
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 头像加载失败时,清空avatar字段让其显示占位符
|
||
*/
|
||
onAvatarError(e) {
|
||
const index = e.currentTarget.dataset.index
|
||
if (index !== undefined) {
|
||
this.setData({
|
||
[`counselorList[${index}].avatar`]: ''
|
||
})
|
||
}
|
||
},
|
||
|
||
onTrialListen(e) {
|
||
const id = e.currentTarget.dataset.id
|
||
wx.showToast({ title: '正在播放试听...', icon: 'none' })
|
||
},
|
||
|
||
onConsult(e) {
|
||
const id = e.currentTarget.dataset.id
|
||
wx.navigateTo({
|
||
url: `/pages/counselor-detail/counselor-detail?id=${id}`
|
||
})
|
||
},
|
||
|
||
// ==================== 聊天模式 ====================
|
||
|
||
/**
|
||
* 加载聊天历史
|
||
*/
|
||
async loadChatHistory() {
|
||
this.setData({ loading: true })
|
||
|
||
try {
|
||
const res = await api.chat.getChatHistory(this.data.orderId, {
|
||
page: 1,
|
||
limit: 50
|
||
})
|
||
|
||
if (res.success && res.data) {
|
||
const messages = (res.data || []).map(msg => ({
|
||
id: msg.id,
|
||
content: msg.content,
|
||
isMe: msg.sender_type === 'user',
|
||
time: this.formatTime(msg.created_at),
|
||
type: msg.message_type || 'text'
|
||
}))
|
||
|
||
this.setData({ messages, loading: false })
|
||
this.scrollToBottom()
|
||
} else {
|
||
this.setData({ loading: false })
|
||
}
|
||
} catch (err) {
|
||
console.error('加载聊天历史失败', err)
|
||
this.setData({ loading: false })
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 发送消息
|
||
*/
|
||
async sendMessage() {
|
||
const { inputText, orderId } = this.data
|
||
|
||
if (!inputText.trim()) return
|
||
|
||
const messageText = inputText.trim()
|
||
|
||
// 添加到消息列表
|
||
const newMessage = {
|
||
id: Date.now(),
|
||
content: messageText,
|
||
isMe: true,
|
||
time: this.formatTime(new Date()),
|
||
type: 'text'
|
||
}
|
||
|
||
this.setData({
|
||
messages: [...this.data.messages, newMessage],
|
||
inputText: ''
|
||
})
|
||
|
||
this.scrollToBottom()
|
||
|
||
try {
|
||
await api.companion.sendMessage({
|
||
order_id: orderId,
|
||
message: messageText
|
||
})
|
||
} catch (err) {
|
||
console.error('发送消息失败', err)
|
||
wx.showToast({ title: '发送失败', icon: 'none' })
|
||
}
|
||
},
|
||
|
||
onInput(e) {
|
||
this.setData({ inputText: e.detail.value })
|
||
},
|
||
|
||
/**
|
||
* 格式化时间
|
||
*/
|
||
formatTime(dateStr) {
|
||
const date = new Date(dateStr)
|
||
const hour = String(date.getHours()).padStart(2, '0')
|
||
const minute = String(date.getMinutes()).padStart(2, '0')
|
||
return `${hour}:${minute}`
|
||
},
|
||
|
||
scrollToBottom() {
|
||
// 滚动到底部
|
||
},
|
||
|
||
onBack() {
|
||
wx.navigateBack()
|
||
},
|
||
|
||
// Tab bar navigation - 需要登录的页面检查登录状态
|
||
switchTab(e) {
|
||
const path = e.currentTarget.dataset.path
|
||
const app = getApp()
|
||
|
||
// 消息和我的页面需要登录
|
||
if (path === '/pages/chat/chat' || path === '/pages/profile/profile') {
|
||
if (!app.globalData.isLoggedIn) {
|
||
wx.navigateTo({
|
||
url: '/pages/login/login?redirect=' + encodeURIComponent(path)
|
||
})
|
||
return
|
||
}
|
||
}
|
||
wx.switchTab({ url: path })
|
||
}
|
||
})
|