爆灯
This commit is contained in:
parent
cf0b4e6ea9
commit
47763fea17
|
@ -16,7 +16,7 @@ const install = (Vue, vm) => {
|
|||
// },
|
||||
// });
|
||||
Vue.prototype.$u.http.setConfig({
|
||||
// baseUrl: 'http://192.168.2.18:4301',
|
||||
// baseUrl: 'http://192.168.2.84:4301',
|
||||
baseUrl: 'https://bao.chuangtewl.com/prod-api',
|
||||
loadingText: '努力加载中~',
|
||||
loadingTime: 800,
|
||||
|
|
|
@ -16,8 +16,14 @@
|
|||
</view>
|
||||
</view>
|
||||
<!-- 右侧商品列表 -->
|
||||
<view class="product-list">
|
||||
<view class="product-item" v-for="(product, index) in filteredProducts" :key="index">
|
||||
<scroll-view class="product-list" scroll-y="true"
|
||||
@scroll="onProductScroll"
|
||||
:scroll-top="isScrolling ? scrollTop : ''"
|
||||
scroll-with-animation="true">
|
||||
<view class="product-item" v-for="(product, index) in filteredProducts" :key="index"
|
||||
:id="`product-${product.categoryName}`"
|
||||
:data-category-name="product.categoryName"
|
||||
:data-category-id="product.categoryId">
|
||||
<image class="product-image-placeholder" :src="product.image" mode="aspectFill"></image>
|
||||
<view class="product-info">
|
||||
<view class="product-name">{{ product.name }}</view>
|
||||
|
@ -34,7 +40,7 @@
|
|||
<view class="" style="width: 100%;text-align: center;margin-top: 50rpx;">
|
||||
当前没有更多商品咯...
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="jiesuan">
|
||||
<view class="bot">
|
||||
|
@ -119,7 +125,7 @@
|
|||
{{shopobj.name}}
|
||||
</view>
|
||||
<view style="max-height: 46vh; overflow: scroll;">
|
||||
<view v-for="(specGroup, index) in shopobj.specVO" :key="specGroup.id">
|
||||
<view v-for="specGroup in shopobj.specVO" :key="specGroup.id">
|
||||
<!-- 规格组名称 -->
|
||||
<view class="ts">{{specGroup.name}}</view>
|
||||
<!-- 规格选项 -->
|
||||
|
@ -185,12 +191,15 @@ import { number } from 'echarts'
|
|||
totalPrice: 0,
|
||||
boothId:'',
|
||||
skuList:[],
|
||||
xiadanflag:true
|
||||
xiadanflag:true,
|
||||
scrollTop: 0,
|
||||
isScrolling: false,
|
||||
scrollTimer: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredProducts() {
|
||||
// 这里可以根据currentCategoryIndex进行分类过滤,示例中暂不区分
|
||||
// 显示所有商品,不进行过滤,以便滚动联动功能正常工作
|
||||
return this.products
|
||||
}
|
||||
},
|
||||
|
@ -201,6 +210,9 @@ import { number } from 'echarts'
|
|||
onShow() {
|
||||
this.xiadanflag = true
|
||||
},
|
||||
onReady() {
|
||||
// 页面渲染完成后的初始化
|
||||
},
|
||||
methods: {
|
||||
// 获取购物车中商品的数量
|
||||
getCartItemQuantity(productId) {
|
||||
|
@ -235,17 +247,54 @@ import { number } from 'echarts'
|
|||
this.$u.get(`/app/goodsCategory/list?pageNum=1&pageSize=999`).then(res =>{
|
||||
if(res.code == 200){
|
||||
this.categories = res.data
|
||||
// 清理分类名称
|
||||
this.categories.forEach(category => {
|
||||
if (category.name) {
|
||||
category.name = category.name.trim()
|
||||
}
|
||||
})
|
||||
this.categoryId = res.data[0].id
|
||||
console.log('分类数据加载完成:', this.categories)
|
||||
// 分类加载完成后再加载商品
|
||||
this.getshoplist()
|
||||
}
|
||||
})
|
||||
},
|
||||
// 请求商品列表
|
||||
getshoplist(){
|
||||
this.$u.get(`/app/goods/list?pageNum=1&pageSize=999&categoryId=${this.categoryId}`).then(res =>{
|
||||
this.$u.get(`/app/goods/list?pageNum=1&pageSize=999`).then(res =>{
|
||||
if(res.code == 200){
|
||||
this.products = res.data
|
||||
// 确保每个商品都有categoryId和categoryName属性
|
||||
this.products.forEach((product, index) => {
|
||||
// 如果商品没有categoryId,使用当前选中的分类ID
|
||||
if (!product.categoryId && this.categoryId) {
|
||||
product.categoryId = this.categoryId
|
||||
}
|
||||
// 确保categoryId是数字类型
|
||||
product.categoryId = parseInt(product.categoryId) || this.categoryId
|
||||
|
||||
// 如果商品没有categoryName,从分类列表中查找
|
||||
if (!product.categoryName) {
|
||||
const category = this.categories.find(cat => cat.id === product.categoryId)
|
||||
if (category) {
|
||||
product.categoryName = category.name
|
||||
}
|
||||
}
|
||||
|
||||
// 清理分类名称,移除空格和特殊字符
|
||||
if (product.categoryName) {
|
||||
product.categoryName = product.categoryName.trim()
|
||||
}
|
||||
|
||||
console.log(`商品${index}:`, product.name, '分类ID:', product.categoryId, '分类名称:', product.categoryName)
|
||||
})
|
||||
console.log('商品列表:', this.products)
|
||||
console.log('分类列表:', this.categories)
|
||||
console.log('当前分类ID:', this.categoryId)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('获取商品列表失败:', err)
|
||||
})
|
||||
},
|
||||
// 点击我已选好
|
||||
|
@ -398,11 +447,91 @@ import { number } from 'echarts'
|
|||
chooseSeat() {
|
||||
this.addmenflag = true
|
||||
},
|
||||
// 点击分类请求商品列表
|
||||
selectCategory(item,index) {
|
||||
this.categoryId = item.id
|
||||
this.currentCategoryIndex = index
|
||||
this.getshoplist()
|
||||
// 点击分类滚动到对应商品
|
||||
selectCategory(item, index) {
|
||||
console.log('点击分类:', item.name, '分类ID:', item.id, '索引:', index)
|
||||
|
||||
// 更新当前分类
|
||||
this.currentCategoryIndex = index
|
||||
this.categoryId = item.id
|
||||
|
||||
// 设置滚动标志,防止用户滚动事件干扰
|
||||
this.isScrolling = true
|
||||
|
||||
// 如果是第一个分类,直接回到顶部
|
||||
if (index === 0) {
|
||||
console.log('点击第一个分类,直接回到顶部')
|
||||
this.scrollTop = 0
|
||||
setTimeout(() => {
|
||||
this.isScrolling = false
|
||||
}, 500)
|
||||
return
|
||||
}
|
||||
|
||||
// 查找该分类下的第一个商品
|
||||
const firstProductOfCategory = this.products.find(product =>
|
||||
product.categoryName === item.name
|
||||
)
|
||||
|
||||
if (firstProductOfCategory) {
|
||||
// 先回到顶部,再滚动到目标位置
|
||||
this.scrollToCategoryWithReset(item.name)
|
||||
} else {
|
||||
console.log('未找到分类商品:', item.name)
|
||||
// 即使没找到商品也要重置滚动状态
|
||||
setTimeout(() => {
|
||||
this.isScrolling = false
|
||||
}, 500)
|
||||
}
|
||||
},
|
||||
// 先回到顶部,再滚动到指定分类
|
||||
scrollToCategoryWithReset(categoryName) {
|
||||
// 先回到顶部
|
||||
this.scrollTop = 0
|
||||
|
||||
// 延迟执行滚动到目标位置,确保回到顶部的动画完成
|
||||
setTimeout(() => {
|
||||
this.scrollToCategory(categoryName)
|
||||
}, 300)
|
||||
},
|
||||
// 滚动到指定分类
|
||||
scrollToCategory(categoryName) {
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query.selectAll('.product-item').boundingClientRect()
|
||||
query.select('.product-list').boundingClientRect()
|
||||
query.exec((res) => {
|
||||
if (res && res[0] && res[1]) {
|
||||
const items = res[0] // 商品项列表
|
||||
const container = res[1] // 滚动容器
|
||||
|
||||
// 找到该分类的第一个商品
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i]
|
||||
if (item.dataset.categoryName === categoryName) {
|
||||
// 计算正确的滚动位置
|
||||
// 由于已经回到顶部,现在item.top就是相对于容器的位置
|
||||
const targetScrollTop = Math.max(0, item.top - 20)
|
||||
|
||||
console.log('滚动到分类:', categoryName, '位置:', targetScrollTop)
|
||||
|
||||
// 设置滚动位置
|
||||
this.scrollTop = targetScrollTop
|
||||
|
||||
// 延迟重置滚动状态
|
||||
// setTimeout(() => {
|
||||
// this.isScrolling = false
|
||||
// }, 1000)
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('获取元素位置失败,重置滚动状态')
|
||||
setTimeout(() => {
|
||||
this.isScrolling = false
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 选择规格
|
||||
selectSpec(groupId, optionId) {
|
||||
|
@ -554,7 +683,64 @@ import { number } from 'echarts'
|
|||
// 点击显示购物车列表商品
|
||||
btngw(){
|
||||
this.gouwuflag = true
|
||||
}
|
||||
},
|
||||
// 商品列表滚动事件
|
||||
onProductScroll(event) {
|
||||
// 如果正在程序滚动,不处理用户滚动
|
||||
if (this.isScrolling) {
|
||||
return
|
||||
}
|
||||
|
||||
const scrollTop = event.detail.scrollTop
|
||||
|
||||
// 清除之前的定时器
|
||||
if (this.scrollTimer) {
|
||||
clearTimeout(this.scrollTimer)
|
||||
}
|
||||
|
||||
// 延迟执行,避免频繁触发
|
||||
this.scrollTimer = setTimeout(() => {
|
||||
this.updateCurrentCategoryByScroll(scrollTop)
|
||||
}, 200)
|
||||
},
|
||||
// 根据滚动位置更新当前分类
|
||||
updateCurrentCategoryByScroll(scrollTop) {
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query.selectAll('.product-item').boundingClientRect()
|
||||
query.select('.product-list').boundingClientRect()
|
||||
query.exec((res) => {
|
||||
if (res && res[0] && res[1]) {
|
||||
const items = res[0]
|
||||
const container = res[1]
|
||||
|
||||
// 找到当前可见的商品分类
|
||||
let currentCategoryName = null
|
||||
const threshold = 100 // 可视区域阈值
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i]
|
||||
// 计算商品相对于容器的位置
|
||||
const itemTop = item.top - container.top
|
||||
const itemBottom = itemTop + item.height
|
||||
|
||||
// 如果商品在可视区域内
|
||||
if (itemTop <= threshold && itemBottom > threshold) {
|
||||
currentCategoryName = item.dataset.categoryName
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 更新当前分类索引
|
||||
if (currentCategoryName !== null) {
|
||||
const categoryIndex = this.categories.findIndex(cat => cat.name === currentCategoryName)
|
||||
if (categoryIndex !== -1 && categoryIndex !== this.currentCategoryIndex) {
|
||||
this.currentCategoryIndex = categoryIndex
|
||||
this.categoryId = this.categories[categoryIndex].id
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -699,7 +885,6 @@ import { number } from 'echarts'
|
|||
.area-list {
|
||||
width: 200rpx;
|
||||
background: #1A1A1A;
|
||||
// padding: 20rpx 0;
|
||||
|
||||
.area-item {
|
||||
height: 80rpx;
|
||||
|
@ -916,7 +1101,7 @@ import { number } from 'echarts'
|
|||
}
|
||||
|
||||
.category-item {
|
||||
padding: 15rpx 20rpx;
|
||||
padding: 30rpx 20rpx;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -932,8 +1117,9 @@ import { number } from 'echarts'
|
|||
.product-list {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
overflow-y: auto;
|
||||
background-color: #1A1A1A;
|
||||
padding-bottom: 200rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.product-item {
|
||||
|
@ -998,4 +1184,5 @@ import { number } from 'echarts'
|
|||
.product-actions button:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
|
|
|
@ -41,23 +41,51 @@
|
|||
<view style="width: 300rpx;color: #fff;text-align: center;background-color: #999;margin: auto;border-radius: 10rpx;opacity: .7;padding: 20rpx;box-sizing: border-box;">
|
||||
倡导聊天过程文明善意~ 谨慎判断切勿私下交易,谨防网络诈骗,切勿违法乱纪!!!</view>
|
||||
<view v-for="(messages, index) in messages" :key="index" class="message-item">
|
||||
<view style="width: 100%;color: #666;text-align: center;font-size: 20rpx;margin-top: 20rpx;margin-bottom: 10rpx;">{{ messages.createTime }}</view>
|
||||
<view v-if="messages.sendId == userId" class="message-self">
|
||||
<view class="message-content" v-if="messages.type == 1">
|
||||
{{ messages.content }}
|
||||
<view class="message-status" v-if="messages.status">
|
||||
<image v-if="messages.status === 'sending'" src="https://api.ccttiot.com/smartmeter/img/static/loading" class="status-icon sending"></image>
|
||||
<image v-else-if="messages.status === 'failed'" src="https://api.ccttiot.com/smartmeter/img/static/failed" class="status-icon failed" @click="resendMessage(messages)"></image>
|
||||
<view class="message-header">
|
||||
<view class="message-status" v-if="messages.status">
|
||||
<image v-if="messages.status === 'sending'" src="https://api.ccttiot.com/smartmeter/img/static/uO9UFjzbzS9YlabzL4HV" class="status-icon sending"></image>
|
||||
<image v-else-if="messages.status === 'failed'" src="https://api.ccttiot.com/smartmeter/img/static/ualrWMTB5pPYR8UvkCv6" class="status-icon failed" @click="resendMessage(messages)"></image>
|
||||
<text v-else-if="messages.status === 'sent'" class="status-text">已发送</text>
|
||||
</view>
|
||||
<text class="message-time">{{ messages.createTime }}</text>
|
||||
</view>
|
||||
<text class="message-text">{{ messages.content }}</text>
|
||||
</view>
|
||||
<view class="message-content" v-if="messages.type == 2">
|
||||
<view class="message-header">
|
||||
<view class="message-status" v-if="messages.status">
|
||||
<image v-if="messages.status === 'sending'" src="https://api.ccttiot.com/smartmeter/img/static/uO9UFjzbzS9YlabzL4HV" class="status-icon sending"></image>
|
||||
<image v-else-if="messages.status === 'failed'" src="https://api.ccttiot.com/smartmeter/img/static/ualrWMTB5pPYR8UvkCv6" class="status-icon failed" @click="resendMessage(messages)"></image>
|
||||
<text v-else-if="messages.status === 'sent'" class="status-text">已发送</text>
|
||||
</view>
|
||||
<text class="message-time">{{ messages.createTime }}</text>
|
||||
</view>
|
||||
<image class="message-image" :src="messages.content" mode="widthFix" @click="previewImage(messages.content)"></image>
|
||||
</view>
|
||||
<view class="message-content" v-if="messages.type == 3">
|
||||
<view class="message-header">
|
||||
<view class="message-status" v-if="messages.status">
|
||||
<image v-if="messages.status === 'sending'" src="https://api.ccttiot.com/smartmeter/img/static/uO9UFjzbzS9YlabzL4HV" class="status-icon sending"></image>
|
||||
<image v-else-if="messages.status === 'failed'" src="https://api.ccttiot.com/smartmeter/img/static/ualrWMTB5pPYR8UvkCv6" class="status-icon failed" @click="resendMessage(messages)"></image>
|
||||
<text v-else-if="messages.status === 'sent'" class="status-text">已发送</text>
|
||||
</view>
|
||||
<text class="message-time">{{ messages.createTime }}</text>
|
||||
</view>
|
||||
<video class="message-video" :src="messages.content" object-fit="contain" :id="'video-' + index"></video>
|
||||
</view>
|
||||
<image class="message-image" v-if="messages.type == 2" :src="messages.content" mode="widthFix" @click="previewImage(messages.content)"></image>
|
||||
<video class="message-video" v-if="messages.type == 3" :src="messages.content" object-fit="contain" :id="'video-' + index"></video>
|
||||
<image class="avatar" :src="messages.senderAvatar" v-if="messages.type != 4" mode=""></image>
|
||||
</view>
|
||||
<view v-else class="message-other">
|
||||
<image class="avatar" :src="messages.senderAvatar" v-if="messages.type != 4" mode=""></image>
|
||||
<view v-if="messages.type == 4" style="width: 100%;color: #666;text-align: center;">{{ messages.content }}</view>
|
||||
<view class="message-content" v-if="messages.type == 1">{{ messages.content }}</view>
|
||||
<view class="message-content" v-if="messages.type == 1">
|
||||
<view class="message-header">
|
||||
<text class="message-time">{{ messages.createTime }}</text>
|
||||
</view>
|
||||
<text class="message-text">{{ messages.content }}</text>
|
||||
</view>
|
||||
<image class="message-image" v-if="messages.type == 2" :src="messages.content" mode="widthFix" @click="previewImage(messages.content)"></image>
|
||||
<video class="message-video" v-if="messages.type == 3" :src="messages.content" object-fit="contain" :id="'video-' + index"></video>
|
||||
</view>
|
||||
|
@ -240,11 +268,42 @@
|
|||
})
|
||||
this.socketTask.onMessage((res) => {
|
||||
const message = JSON.parse(res.data)
|
||||
this.$nextTick(() => {
|
||||
this.messages.push(message)
|
||||
console.log(message,this.messages,'asdasdasdas')
|
||||
// this.scrollToBottom()
|
||||
})
|
||||
console.log('收到WebSocket消息:', message)
|
||||
console.log('当前用户ID:', this.userId)
|
||||
console.log('消息发送者ID:', message.sendId)
|
||||
|
||||
// 检查是否是自己发送的消息,如果是则不重复添加
|
||||
const isOwnMessage = this.messages.some(msg =>
|
||||
msg.tempId &&
|
||||
msg.sendId == this.userId &&
|
||||
message.sendId == this.userId &&
|
||||
msg.content === message.content &&
|
||||
msg.type === message.type
|
||||
)
|
||||
|
||||
console.log('是否为自己的消息:', isOwnMessage)
|
||||
|
||||
if (!isOwnMessage) {
|
||||
this.$nextTick(() => {
|
||||
this.messages.push(message)
|
||||
console.log('添加新消息:', message)
|
||||
// this.scrollToBottom()
|
||||
})
|
||||
} else {
|
||||
// 如果是自己的消息,更新状态为已发送
|
||||
const index = this.messages.findIndex(msg =>
|
||||
msg.tempId &&
|
||||
msg.sendId == this.userId &&
|
||||
msg.content === message.content &&
|
||||
msg.type === message.type
|
||||
)
|
||||
console.log('找到匹配的消息索引:', index)
|
||||
if (index !== -1) {
|
||||
console.log('更新消息状态为已发送')
|
||||
this.messages[index].status = 'sent'
|
||||
this.sendingMessages.delete(this.messages[index].tempId)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.socketTask.onClose(() => {
|
||||
console.log('WebSocket连接已关闭')
|
||||
|
@ -306,12 +365,18 @@
|
|||
type: type,
|
||||
status: 'sending',
|
||||
tempId: tempId,
|
||||
senderAvatar: uni.getStorageSync('user').avatar || 'https://api.ccttiot.com/smartmeter/img/static/default-avatar'
|
||||
senderAvatar: uni.getStorageSync('user').avatar || 'https://api.ccttiot.com/smartmeter/img/static/default-avatar',
|
||||
createTime: this.$u.timeFormat(new Date(), 'yyyy-mm-dd hh:MM:ss')
|
||||
}
|
||||
|
||||
// 立即将消息添加到聊天列表中
|
||||
this.messages.push(tempMessage)
|
||||
this.sendingMessages.add(tempId)
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.scrollToBottom()
|
||||
})
|
||||
|
||||
let data = {
|
||||
teamId: this.teamId,
|
||||
content: this.inputContent,
|
||||
|
@ -319,11 +384,17 @@
|
|||
}
|
||||
this.$u.post(`/app/chat/sendMessage`, data).then(res => {
|
||||
if (res.code == 200) {
|
||||
const index = this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
this.messages[index].status = 'sent'
|
||||
}
|
||||
this.sendingMessages.delete(tempId)
|
||||
// 状态更新由WebSocket处理,这里不需要重复更新
|
||||
console.log('消息发送成功')
|
||||
// 备用机制:如果3秒后WebSocket没有更新状态,则手动更新
|
||||
setTimeout(() => {
|
||||
const index = this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1 && this.messages[index].status === 'sending') {
|
||||
console.log('WebSocket未响应,手动更新状态为已发送')
|
||||
this.messages[index].status = 'sent'
|
||||
this.sendingMessages.delete(tempId)
|
||||
}
|
||||
}, 3000)
|
||||
} else {
|
||||
const index = this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
|
@ -403,35 +474,67 @@
|
|||
if (index !== -1) {
|
||||
this.messages[index].status = 'sending'
|
||||
this.sendingMessages.add(message.tempId)
|
||||
let data = {
|
||||
teamId: this.teamId,
|
||||
content: message.content,
|
||||
type: message.type
|
||||
}
|
||||
this.$u.post(`/app/chat/sendMessage`, data).then(res => {
|
||||
if (res.code == 200) {
|
||||
this.messages[index].status = 'sent'
|
||||
this.sendingMessages.delete(message.tempId)
|
||||
} else {
|
||||
|
||||
// 根据消息类型处理重发
|
||||
if (message.type === 2 || message.type === 3) {
|
||||
// 图片或视频消息,需要重新上传
|
||||
this.reuploadMedia(message, index)
|
||||
} else {
|
||||
// 文本消息,直接发送
|
||||
let data = {
|
||||
teamId: this.teamId,
|
||||
content: message.content,
|
||||
type: message.type
|
||||
}
|
||||
this.$u.post(`/app/chat/sendMessage`, data).then(res => {
|
||||
if (res.code == 200) {
|
||||
this.messages[index].status = 'sent'
|
||||
this.sendingMessages.delete(message.tempId)
|
||||
} else {
|
||||
this.messages[index].status = 'failed'
|
||||
this.sendingMessages.delete(message.tempId)
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
this.messages[index].status = 'failed'
|
||||
this.sendingMessages.delete(message.tempId)
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
title: '发送失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
this.messages[index].status = 'failed'
|
||||
this.sendingMessages.delete(message.tempId)
|
||||
uni.showToast({
|
||||
title: '发送失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
// 重新上传媒体文件
|
||||
reuploadMedia(message, index) {
|
||||
// 这里需要根据实际情况处理,可能需要用户重新选择文件
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '媒体文件重发需要重新选择文件,是否重新选择?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
if (message.type === 2) {
|
||||
this.chooseImage()
|
||||
} else if (message.type === 3) {
|
||||
this.takeVideo()
|
||||
}
|
||||
// 移除失败的消息
|
||||
this.messages.splice(index, 1)
|
||||
this.sendingMessages.delete(message.tempId)
|
||||
} else {
|
||||
// 取消重发,恢复失败状态
|
||||
this.messages[index].status = 'failed'
|
||||
this.sendingMessages.delete(message.tempId)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取七牛云token
|
||||
gettoken(){
|
||||
this.$u.get(`/common/qiniuToken`).then(res => {
|
||||
|
@ -465,6 +568,24 @@
|
|||
type: 'all',
|
||||
success(res) {
|
||||
const tempFilePaths = res.tempFiles
|
||||
// 立即添加一个发送中的消息
|
||||
const tempId = Date.now().toString()
|
||||
const tempMessage = {
|
||||
sendId: _this.userId,
|
||||
content: tempFilePaths[0].path, // 临时路径
|
||||
type: 2,
|
||||
status: 'sending',
|
||||
tempId: tempId,
|
||||
senderAvatar: uni.getStorageSync('user').avatar || 'https://api.ccttiot.com/smartmeter/img/static/default-avatar',
|
||||
createTime: _this.$u.timeFormat(new Date(), 'yyyy-mm-dd hh:MM:ss')
|
||||
}
|
||||
_this.messages.push(tempMessage)
|
||||
_this.sendingMessages.add(tempId)
|
||||
|
||||
_this.$nextTick(() => {
|
||||
_this.scrollToBottom()
|
||||
})
|
||||
|
||||
wx.uploadFile({
|
||||
url: 'https://up-z2.qiniup.com',
|
||||
name: 'file',
|
||||
|
@ -476,9 +597,68 @@
|
|||
success: function(res) {
|
||||
console.log(res, 'resres')
|
||||
let str = JSON.parse(res.data)
|
||||
_this.inputContent = 'https://api.ccttiot.com/' + str.key
|
||||
console.log(_this.inputContent)
|
||||
_this.sendMessage(2)
|
||||
const imageUrl = 'https://api.ccttiot.com/' + str.key
|
||||
|
||||
// 更新消息内容为真实URL
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
_this.messages[index].content = imageUrl
|
||||
}
|
||||
|
||||
// 发送消息到服务器
|
||||
let data = {
|
||||
teamId: _this.teamId,
|
||||
content: imageUrl,
|
||||
type: 2
|
||||
}
|
||||
_this.$u.post(`/app/chat/sendMessage`, data).then(res => {
|
||||
if (res.code == 200) {
|
||||
console.log('图片消息发送成功')
|
||||
// 备用机制:如果3秒后WebSocket没有更新状态,则手动更新
|
||||
setTimeout(() => {
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1 && _this.messages[index].status === 'sending') {
|
||||
console.log('WebSocket未响应,手动更新图片状态为已发送')
|
||||
_this.messages[index].status = 'sent'
|
||||
_this.sendingMessages.delete(tempId)
|
||||
}
|
||||
}, 3000)
|
||||
} else {
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
_this.messages[index].status = 'failed'
|
||||
}
|
||||
_this.sendingMessages.delete(tempId)
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
_this.messages[index].status = 'failed'
|
||||
}
|
||||
_this.sendingMessages.delete(tempId)
|
||||
uni.showToast({
|
||||
title: '发送失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
_this.messages[index].status = 'failed'
|
||||
}
|
||||
_this.sendingMessages.delete(tempId)
|
||||
uni.showToast({
|
||||
title: '上传失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -496,6 +676,25 @@
|
|||
compressed: true, // 压缩视频
|
||||
success(res) {
|
||||
const tempFilePath = res.tempFilePath
|
||||
|
||||
// 立即添加一个发送中的消息
|
||||
const tempId = Date.now().toString()
|
||||
const tempMessage = {
|
||||
sendId: _this.userId,
|
||||
content: tempFilePath, // 临时路径
|
||||
type: 3,
|
||||
status: 'sending',
|
||||
tempId: tempId,
|
||||
senderAvatar: uni.getStorageSync('user').avatar || 'https://api.ccttiot.com/smartmeter/img/static/default-avatar',
|
||||
createTime: _this.$u.timeFormat(new Date(), 'yyyy-mm-dd hh:MM:ss')
|
||||
}
|
||||
_this.messages.push(tempMessage)
|
||||
_this.sendingMessages.add(tempId)
|
||||
|
||||
_this.$nextTick(() => {
|
||||
_this.scrollToBottom()
|
||||
})
|
||||
|
||||
// 显示上传loading
|
||||
uni.showLoading({
|
||||
title: '视频上传中...',
|
||||
|
@ -512,15 +711,69 @@
|
|||
success: function(uploadRes) {
|
||||
uni.hideLoading()
|
||||
let responseData = JSON.parse(uploadRes.data);
|
||||
_this.inputContent = 'https://api.ccttiot.com/' + responseData.key
|
||||
const videoUrl = 'https://api.ccttiot.com/' + responseData.key
|
||||
|
||||
// 更新消息内容为真实URL
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
_this.messages[index].content = videoUrl
|
||||
}
|
||||
|
||||
// 视频特殊处理:保存缩略图
|
||||
if(res.thumbTempFilePath){
|
||||
_this.uploadThumb(res.thumbTempFilePath)
|
||||
}
|
||||
_this.sendMessage(3); // 类型改为3表示视频
|
||||
|
||||
// 发送消息到服务器
|
||||
let data = {
|
||||
teamId: _this.teamId,
|
||||
content: videoUrl,
|
||||
type: 3
|
||||
}
|
||||
_this.$u.post(`/app/chat/sendMessage`, data).then(res => {
|
||||
if (res.code == 200) {
|
||||
console.log('视频消息发送成功')
|
||||
// 备用机制:如果3秒后WebSocket没有更新状态,则手动更新
|
||||
setTimeout(() => {
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1 && _this.messages[index].status === 'sending') {
|
||||
console.log('WebSocket未响应,手动更新视频状态为已发送')
|
||||
_this.messages[index].status = 'sent'
|
||||
_this.sendingMessages.delete(tempId)
|
||||
}
|
||||
}, 3000)
|
||||
} else {
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
_this.messages[index].status = 'failed'
|
||||
}
|
||||
_this.sendingMessages.delete(tempId)
|
||||
uni.showToast({
|
||||
title: res.msg,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
_this.messages[index].status = 'failed'
|
||||
}
|
||||
_this.sendingMessages.delete(tempId)
|
||||
uni.showToast({
|
||||
title: '发送失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
uni.hideLoading()
|
||||
const index = _this.messages.findIndex(msg => msg.tempId === tempId)
|
||||
if (index !== -1) {
|
||||
_this.messages[index].status = 'failed'
|
||||
}
|
||||
_this.sendingMessages.delete(tempId)
|
||||
uni.showToast({
|
||||
title: '上传失败',
|
||||
icon: 'none'
|
||||
|
@ -604,27 +857,51 @@
|
|||
padding: 15rpx 20rpx;
|
||||
border-radius: 10rpx;
|
||||
max-width: 70%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
|
||||
.message-status {
|
||||
position: absolute;
|
||||
right: -40rpx;
|
||||
bottom: 0;
|
||||
.message-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
flex-shrink: 0;
|
||||
|
||||
.status-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
.message-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&.sending {
|
||||
animation: rotate 1s linear infinite;
|
||||
.status-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
|
||||
&.sending {
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
|
||||
&.failed {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
&.failed {
|
||||
opacity: 0.7;
|
||||
.status-text {
|
||||
font-size: 18rpx;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: 18rpx;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.message-text {
|
||||
word-break: break-all;
|
||||
line-height: 1.4;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
}
|
||||
.message-image {
|
||||
|
@ -655,6 +932,28 @@
|
|||
padding: 15rpx 20rpx;
|
||||
border-radius: 10rpx;
|
||||
max-width: 70%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
|
||||
.message-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
flex-shrink: 0;
|
||||
|
||||
.message-time {
|
||||
font-size: 18rpx;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.message-text {
|
||||
word-break: break-all;
|
||||
line-height: 1.4;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
}
|
||||
.message-image {
|
||||
max-width: 400rpx;
|
||||
|
|
|
@ -13,10 +13,6 @@
|
|||
<view class="boxpic">
|
||||
<image class="bd" @click="btnbd(1)" src="https://api.ccttiot.com/smartmeter/img/static/uQdax0INyCWNnNqWXerD"
|
||||
mode=""></image>
|
||||
<!-- <view class="bdpic" @click="btnwu">
|
||||
<image src="https://api.ccttiot.com/smartmeter/img/static/uop0H6ZZWbHH600RkbsA" mode=""></image>
|
||||
<image src="https://api.ccttiot.com/smartmeter/img/static/uE714dLumBXvTz7EPOFR" mode=""></image>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
@ -32,9 +28,7 @@
|
|||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
console.log(option, uni.getStorageSync('type'));
|
||||
if (uni.getStorageSync('type')) {
|
||||
console.log(1);
|
||||
uni.removeStorageSync('type')
|
||||
} else {
|
||||
xBlufi.initXBlufi(1)
|
||||
|
|
|
@ -28,14 +28,12 @@
|
|||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- 充值记录 -->
|
||||
<template v-if="tabindex == 1">
|
||||
<!-- 空状态 -->
|
||||
<view style="width: 480rpx;height: 373rpx;margin: auto;margin-top: 390rpx;" v-if="chonzghilist.length == 0">
|
||||
<image class="empty-image" src="https://api.ccttiot.com/smartmeter/img/static/uEiNJh8Rfurw9ORQzlit" mode="aspectFit"></image>
|
||||
</view>
|
||||
|
||||
<!-- 列表内容 -->
|
||||
<view class="list_item" v-for="(item,index) in chonzghilist" :key="index">
|
||||
<view class="lt">
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #111111;
|
||||
background-color: #010000;
|
||||
}
|
||||
.list{
|
||||
width: 100%;
|
||||
|
@ -137,12 +137,12 @@
|
|||
color: #808080;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 36rpx;
|
||||
margin-top: 36rpx;
|
||||
}
|
||||
.list_item{
|
||||
width: 702rpx;
|
||||
height: 288rpx;
|
||||
background: #010000;
|
||||
background: #211f1f;
|
||||
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
||||
margin: auto;
|
||||
margin-top: 26rpx;
|
||||
|
|
|
@ -10,7 +10,7 @@ const store = new Vuex.Store({
|
|||
token:"",
|
||||
appid:'1',
|
||||
storeId:'8',
|
||||
// wsUrl:'192.168.2.204:4301',
|
||||
// wsUrl:'192.168.2.61:4301',
|
||||
wsUrl:'wss://bao.chuangtewl.com/prod-api'
|
||||
},
|
||||
mutations:{
|
||||
|
|
Loading…
Reference in New Issue
Block a user