baodeng_xcx/page_user/pingzhuo/qunliao.vue

793 lines
23 KiB
Vue
Raw Normal View History

2025-06-06 11:14:06 +08:00
<template>
<view class="page">
<u-navbar title="拼桌群聊" :border-bottom="false" :background="bgc" back-icon-color="#fff" title-color='#fff'
title-size='36' height='44' id="navbar">
</u-navbar>
<view class="tablexx">
<view class="top">
<view class="zhuti">
拼桌主题
</view>
<!-- <button open-type="share"><image src="https://api.ccttiot.com/smartmeter/img/static/uOBU07kcJQjEVSNLyxPC" mode=""></image></button> -->
</view>
<view class="jieshao">
{{pinzhuoobj.topic}}
</view>
<view class="dangqian">
当前桌号{{pinzhuoobj.boothName}}
</view>
<view class="pianhao">
<view class="">
<image style="height:26rpx;" src="https://api.ccttiot.com/smartmeter/img/static/uSFf09L8mtvqhjMOu0RV" mode=""></image>
{{pinzhuoobj.prefer == 1 ? '意向偏好男性' : pinzhuoobj.prefer == 2 ? '意向偏好女性' : '男女不限'}}
</view>
<view class="">
<image src="https://api.ccttiot.com/smartmeter/img/static/uL0SnLLV5kxVrM1dGGsQ" mode=""></image> 已加入{{pinzhuoobj.currentNum}} | 还可以加入{{Number(pinzhuoobj.limitNum == null ? 0 : pinzhuoobj.limitNum) - Number(pinzhuoobj.currentNum == null ? 0 : pinzhuoobj.currentNum)}}
</view>
</view>
</view>
<view class="chat-container" :style="{ transform: `translateY(-${keyboardHeight}px)` }">
<scroll-view
scroll-y="true"
class="message-list"
:scroll-top="scrollTop"
:scroll-with-animation="true"
:scroll-anchoring="false"
:enhanced="true"
:bounces="false"
@scrolltoupper="loadMoreMessages"
refresher-enabled @refresherrefresh="onRefresh" :refresher-triggered="isRefreshing" refresher-default-style="white"
id="messageList">
2025-06-19 17:41:39 +08:00
<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>
2025-06-06 11:14:06 +08:00
<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>
</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>
<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>
</view>
</scroll-view>
<view class="bottom-area">
<view class="input-container">
<input
type="text"
v-model="inputContent"
placeholder="说点什么..."
class="input-box"
:adjust-position="false"
:cursor-spacing="20"
:hold-keyboard="true"
@confirm="sendMessage(1)"
@focus="onInputFocus"
@blur="onInputBlur"
/>
<button @click="sendMessage(1)" class="send-button">发送</button>
</view>
<view class="function-icons">
<view class="icon-item" @click="showMediaActionSheet">
<image src="https://api.ccttiot.com/smartmeter/img/static/uGcE4EknnaOMxnqivQgL" mode="aspectFit"></image>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#010000",
},
messages: [
2025-06-19 17:41:39 +08:00
{ content: '倡导聊天过程文明善意~ 谨慎判断,切勿私下交易,谨防网络诈骗', type: 4 },
2025-06-06 11:14:06 +08:00
],
inputContent: '',
scrollTop: 0,
keyboardHeight: 0,
isKeyboardShow: false,
pinzhuoobj:{},
teamId:'',
total:'',
pageNum:1,
isRefreshing: false,
userId:'',
oldScrollTop: 0,
socketTask: null,
isConnected: false,
sendingMessages: new Set(),
reconnectTimer: null,
reconnectCount: 0,
2025-06-19 17:41:39 +08:00
maxReconnectAttempts: 50,
2025-06-06 11:14:06 +08:00
token:''
}
},
onLoad(option) {
this.userId = uni.getStorageSync('user').userId //获取登录用户id
if(option.teamId){
this.teamId = option.teamId
this.getxq()
}
this.getlist()
2025-06-19 17:41:39 +08:00
console.log('didididididdididi');
2025-06-06 11:14:06 +08:00
this.connectWebSocket()
this.gettoken()
// 监听键盘高度变化
uni.onKeyboardHeightChange(res => {
this.keyboardHeight = res.height;
this.isKeyboardShow = res.height > 0;
if (this.isKeyboardShow) {
this.$nextTick(() => {
this.scrollToBottom();
});
}
});
},
onUnload() {
// 页面卸载时断开WebSocket连接
this.disconnectWebSocket();
uni.offKeyboardHeightChange();
},
methods: {
// 下拉刷新更多历史消息
onRefresh() {
if(this.messages.length < this.total){
this.isRefreshing = true
// 保存当前滚动位置
const query = uni.createSelectorQuery().in(this);
query.select('#messageList').boundingClientRect(data => {
this.oldScrollTop = data.top;
}).exec();
this.pageNum++
2025-06-19 17:41:39 +08:00
this.getlists()
2025-06-06 11:14:06 +08:00
setTimeout(() => {
this.isRefreshing = false
}, 1000)
}else{
this.isRefreshing = true
setTimeout(() => {
this.isRefreshing = false
}, 1000)
}
},
2025-06-19 17:41:39 +08:00
getlists(){
this.$u.get(`/app/chat/receiveList?pageNum=${this.pageNum}&pageSize=20&teamId=${this.teamId}`).then(res =>{
if(res.code == 200){
this.total = res.total
this.messages = [...res.rows.reverse(), ...this.messages] //将获取的信息进行倒转,最新的信息显示最下面
}
})
},
2025-06-06 11:14:06 +08:00
// 查询队伍聊天信息
getlist(){
this.$u.get(`/app/chat/receiveList?pageNum=${this.pageNum}&pageSize=20&teamId=${this.teamId}`).then(res =>{
if(res.code == 200){
this.total = res.total
if(this.pageNum == 1){
this.messages = res.rows.reverse()
this.$nextTick(() => {
this.scrollToBottom()
})
}else{
const oldLength = this.messages.length
this.messages = [...res.rows.reverse(), ...this.messages] //将获取的信息进行倒转,最新的信息显示最下面
this.$nextTick(() => {
// 计算新增内容的高度并设置滚动位置
2025-06-19 17:41:39 +08:00
const query = uni.createSelectorQuery().in(this)
2025-06-06 11:14:06 +08:00
query.selectAll('.message-item').boundingClientRect(items => {
if (items && items.length > oldLength) {
2025-06-19 17:41:39 +08:00
let newHeight = 0
2025-06-06 11:14:06 +08:00
for (let i = 0; i < items.length - oldLength; i++) {
2025-06-19 17:41:39 +08:00
newHeight += items[i].height
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
this.scrollTop = newHeight
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
}).exec()
})
2025-06-06 11:14:06 +08:00
}
}
})
},
// 查询拼桌信息
getxq(){
this.$u.get(`/app/team/getTeamInfo?id=${this.teamId}`).then(res =>{
if(res.code == 200){
this.pinzhuoobj = res.data
}
})
},
// 进行WebSocket连接
connectWebSocket() {
2025-06-19 17:41:39 +08:00
if (this.socketTask) {
2025-06-06 11:14:06 +08:00
this.disconnectWebSocket()
}
const token = uni.getStorageSync('token')
2025-06-19 17:41:39 +08:00
const wsUrl = `${this.$store.state.wsUrl}/ws/user?token=${token}`
2025-06-06 11:14:06 +08:00
this.socketTask = uni.connectSocket({
url: wsUrl,
success: () => {
console.log('WebSocket连接成功')
}
})
this.socketTask.onOpen(() => {
console.log('WebSocket连接已打开')
this.isConnected = true
this.reconnectCount = 0 // 重置重连次数
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer)
this.reconnectTimer = null
}
})
this.socketTask.onMessage((res) => {
const message = JSON.parse(res.data)
this.$nextTick(() => {
2025-06-19 17:41:39 +08:00
this.messages.push(message)
console.log(message,this.messages,'asdasdasdas')
// this.scrollToBottom()
2025-06-06 11:14:06 +08:00
})
})
this.socketTask.onClose(() => {
console.log('WebSocket连接已关闭')
2025-06-19 17:41:39 +08:00
this.isConnected = false
2025-06-06 11:14:06 +08:00
this.handleReconnect()
})
this.socketTask.onError((err) => {
console.error('WebSocket错误:', err)
this.isConnected = false
this.handleReconnect()
})
},
disconnectWebSocket() {
if (this.socketTask) {
this.socketTask.close()
2025-06-19 17:41:39 +08:00
this.socketTask = null
this.isConnected = false
2025-06-06 11:14:06 +08:00
}
},
handleReconnect() {
if (this.reconnectCount >= this.maxReconnectAttempts) {
uni.showToast({
title: '网络连接失败,请检查网络后重试',
icon: 'none',
duration: 2000
})
return
}
if (!this.reconnectTimer) {
this.reconnectTimer = setTimeout(() => {
this.reconnectCount++
console.log(`尝试第${this.reconnectCount}次重连`);
this.connectWebSocket()
}, 3000) // 3秒后重试
}
},
// 点击发送信息
sendMessage(type) {
2025-06-19 17:41:39 +08:00
if(this.isConnected == false){
uni.showModal({
title: '提示',
content: '当前聊天未连接,请退出重试',
showCancel: false,
success: function(res) {
if (res.confirm) {
} else if (res.cancel) {
}
}
})
return
}
2025-06-06 11:14:06 +08:00
if (this.inputContent.trim() !== '') {
2025-06-19 17:41:39 +08:00
const tempId = Date.now().toString()
2025-06-06 11:14:06 +08:00
const tempMessage = {
sendId: this.userId,
content: this.inputContent,
type: type,
status: 'sending',
tempId: tempId,
senderAvatar: uni.getStorageSync('user').avatar || 'https://api.ccttiot.com/smartmeter/img/static/default-avatar'
}
2025-06-19 17:41:39 +08:00
this.sendingMessages.add(tempId)
2025-06-06 11:14:06 +08:00
this.$nextTick(() => {
this.scrollToBottom()
})
let data = {
teamId: this.teamId,
content: this.inputContent,
type: type
}
this.$u.post(`/app/chat/sendMessage`, data).then(res => {
if (res.code == 200) {
2025-06-19 17:41:39 +08:00
const index = this.messages.findIndex(msg => msg.tempId === tempId)
2025-06-06 11:14:06 +08:00
if (index !== -1) {
2025-06-19 17:41:39 +08:00
this.messages[index].status = 'sent'
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
this.sendingMessages.delete(tempId)
2025-06-06 11:14:06 +08:00
} else {
2025-06-19 17:41:39 +08:00
const index = this.messages.findIndex(msg => msg.tempId === tempId)
2025-06-06 11:14:06 +08:00
if (index !== -1) {
2025-06-19 17:41:39 +08:00
this.messages[index].status = 'failed'
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
this.sendingMessages.delete(tempId)
2025-06-06 11:14:06 +08:00
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
2025-06-19 17:41:39 +08:00
})
2025-06-06 11:14:06 +08:00
}
}).catch(err => {
2025-06-19 17:41:39 +08:00
const index = this.messages.findIndex(msg => msg.tempId === tempId)
2025-06-06 11:14:06 +08:00
if (index !== -1) {
2025-06-19 17:41:39 +08:00
this.messages[index].status = 'failed'
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
this.sendingMessages.delete(tempId)
uni.showModal({
title: '提示',
content: '发送失败,请重试',
showCancel: false,
success: function(res) {
if (res.confirm) {
} else if (res.cancel) {
}
}
})
})
this.inputContent = ''
2025-06-06 11:14:06 +08:00
}
},
scrollToBottom() {
2025-06-19 17:41:39 +08:00
const query = uni.createSelectorQuery().in(this)
2025-06-06 11:14:06 +08:00
query.select('#messageList').boundingClientRect(data => {
if (data) {
query.selectAll('.message-item').boundingClientRect(items => {
2025-06-19 17:41:39 +08:00
let totalHeight = 0
2025-06-06 11:14:06 +08:00
items.forEach(item => {
2025-06-19 17:41:39 +08:00
totalHeight += item.height
})
this.scrollTop = totalHeight
}).exec()
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
}).exec()
2025-06-06 11:14:06 +08:00
},
loadMoreMessages() {
2025-06-19 17:41:39 +08:00
2025-06-06 11:14:06 +08:00
},
onInputFocus() {
this.scrollToBottom()
},
onInputBlur() {
2025-06-19 17:41:39 +08:00
this.isKeyboardShow = false
this.keyboardHeight = 0
2025-06-06 11:14:06 +08:00
},
// 预览图片
previewImage(url) {
uni.previewImage({
urls: [url],
current: url,
indicator: 'number',
loop: false
2025-06-19 17:41:39 +08:00
})
2025-06-06 11:14:06 +08:00
},
// 播放视频
playVideo(index) {
2025-06-19 17:41:39 +08:00
const videoContext = uni.createVideoContext('video-' + index, this)
videoContext.requestFullScreen()
videoContext.play()
2025-06-06 11:14:06 +08:00
},
// 重发消息
resendMessage(message) {
2025-06-19 17:41:39 +08:00
const index = this.messages.findIndex(msg => msg.tempId === message.tempId)
2025-06-06 11:14:06 +08:00
if (index !== -1) {
2025-06-19 17:41:39 +08:00
this.messages[index].status = 'sending'
this.sendingMessages.add(message.tempId)
2025-06-06 11:14:06 +08:00
let data = {
teamId: this.teamId,
content: message.content,
type: message.type
2025-06-19 17:41:39 +08:00
}
2025-06-06 11:14:06 +08:00
this.$u.post(`/app/chat/sendMessage`, data).then(res => {
if (res.code == 200) {
2025-06-19 17:41:39 +08:00
this.messages[index].status = 'sent'
this.sendingMessages.delete(message.tempId)
2025-06-06 11:14:06 +08:00
} else {
2025-06-19 17:41:39 +08:00
this.messages[index].status = 'failed'
this.sendingMessages.delete(message.tempId)
2025-06-06 11:14:06 +08:00
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
2025-06-19 17:41:39 +08:00
})
2025-06-06 11:14:06 +08:00
}
}).catch(err => {
2025-06-19 17:41:39 +08:00
this.messages[index].status = 'failed'
this.sendingMessages.delete(message.tempId)
2025-06-06 11:14:06 +08:00
uni.showToast({
title: '发送失败,请重试',
icon: 'none',
duration: 2000
2025-06-19 17:41:39 +08:00
})
})
2025-06-06 11:14:06 +08:00
}
},
// 获取七牛云token
gettoken(){
this.$u.get(`/common/qiniuToken`).then(res => {
if (res.code == 200) {
this.token = res.data
}
})
},
// 显示媒体选择菜单
showMediaActionSheet() {
uni.showActionSheet({
itemList: ['从相册选择', '拍摄视频'],
success: (res) => {
switch (res.tapIndex) {
case 0: // 从相册选择
2025-06-19 17:41:39 +08:00
this.chooseImage()
2025-06-06 11:14:06 +08:00
break;
case 1: // 拍摄视频
2025-06-19 17:41:39 +08:00
this.takeVideo()
2025-06-06 11:14:06 +08:00
break;
}
}
2025-06-19 17:41:39 +08:00
})
2025-06-06 11:14:06 +08:00
},
// 选择图片
chooseImage() {
let _this = this
let math = 'static/' + _this.$u.guid(20)
uni.chooseImage({
count: 9,
type: 'all',
success(res) {
const tempFilePaths = res.tempFiles
wx.uploadFile({
url: 'https://up-z2.qiniup.com',
name: 'file',
filePath: tempFilePaths[0].path,
formData: {
token: _this.token, //后端返回的token
key: 'smartmeter/img/' + math
},
success: function(res) {
2025-06-19 17:41:39 +08:00
console.log(res, 'resres')
2025-06-06 11:14:06 +08:00
let str = JSON.parse(res.data)
_this.inputContent = 'https://api.ccttiot.com/' + str.key
console.log(_this.inputContent)
_this.sendMessage(2)
}
})
}
})
},
// 拍摄视频
takeVideo() {
let _this = this;
2025-06-19 17:41:39 +08:00
let fileKey = 'static/video/' + _this.$u.guid(20) + '.mp4' // 视频文件后缀
2025-06-06 11:14:06 +08:00
uni.chooseVideo({
sourceType: ['camera'], // 只允许拍摄
maxDuration: 60, // 最长60秒
camera: 'back', // 默认后置摄像头
compressed: true, // 压缩视频
success(res) {
2025-06-19 17:41:39 +08:00
const tempFilePath = res.tempFilePath
2025-06-06 11:14:06 +08:00
// 显示上传loading
uni.showLoading({
title: '视频上传中...',
mask: true
2025-06-19 17:41:39 +08:00
})
2025-06-06 11:14:06 +08:00
wx.uploadFile({
url: 'https://up-z2.qiniup.com',
name: 'file',
filePath: tempFilePath,
formData: {
token: _this.token, // 后端返回的token
key: 'smartmeter/video/' + fileKey // 修改存储路径为video目录
},
success: function(uploadRes) {
2025-06-19 17:41:39 +08:00
uni.hideLoading()
2025-06-06 11:14:06 +08:00
let responseData = JSON.parse(uploadRes.data);
2025-06-19 17:41:39 +08:00
_this.inputContent = 'https://api.ccttiot.com/' + responseData.key
2025-06-06 11:14:06 +08:00
// 视频特殊处理:保存缩略图
if(res.thumbTempFilePath){
2025-06-19 17:41:39 +08:00
_this.uploadThumb(res.thumbTempFilePath)
2025-06-06 11:14:06 +08:00
}
_this.sendMessage(3); // 类型改为3表示视频
},
fail(err) {
2025-06-19 17:41:39 +08:00
uni.hideLoading()
2025-06-06 11:14:06 +08:00
uni.showToast({
title: '上传失败',
icon: 'none'
2025-06-19 17:41:39 +08:00
})
console.error('视频上传失败:', err)
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
})
2025-06-06 11:14:06 +08:00
},
fail(err) {
2025-06-19 17:41:39 +08:00
console.log('视频选择失败:', err)
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
})
2025-06-06 11:14:06 +08:00
},
// 上传视频缩略图
uploadThumb(thumbPath) {
2025-06-19 17:41:39 +08:00
let _this = this
let thumbKey = 'static/thumb/' + _this.$u.guid(20) + '.jpg'
2025-06-06 11:14:06 +08:00
wx.uploadFile({
url: 'https://up-z2.qiniup.com',
name: 'file',
filePath: thumbPath,
formData: {
token: _this.token,
key: thumbKey
},
success(res) {
2025-06-19 17:41:39 +08:00
console.log('缩略图上传成功')
2025-06-06 11:14:06 +08:00
}
2025-06-19 17:41:39 +08:00
})
2025-06-06 11:14:06 +08:00
}
}
}
</script>
<style lang="scss">
page {
background: #010000;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.page {
width: 100%;
height: 100%;
}
.chat-container {
display: flex;
flex-direction: column;
height: calc(100vh - 350rpx - 70rpx);
background-color: #010000;
width: 750rpx;
position: relative;
top: 240rpx;
transition: transform 0.3s;
.message-list {
flex: 1;
padding: 20rpx;
width: 100%;
height: calc(100% - 120rpx);
overflow: hidden;
box-sizing: border-box;
.message-item {
margin-bottom: 20rpx;
.avatar {
width: 60rpx;
height: 60rpx;
background-color: #ccc;
border-radius: 50%;
margin-left: 15rpx;
}
.message-self {
display: flex;
justify-content: flex-end;
.message-content {
background-color: #4D3F53;
color: white;
padding: 15rpx 20rpx;
border-radius: 10rpx;
max-width: 70%;
position: relative;
.message-status {
position: absolute;
right: -40rpx;
bottom: 0;
display: flex;
align-items: center;
.status-icon {
width: 32rpx;
height: 32rpx;
&.sending {
animation: rotate 1s linear infinite;
}
&.failed {
opacity: 0.7;
}
}
}
}
.message-image {
max-width: 400rpx;
border-radius: 10rpx;
}
.message-video {
max-width: 400rpx;
border-radius: 10rpx;
}
}
.message-other {
display: flex;
align-items: flex-start;
.avatar {
width: 60rpx;
height: 60rpx;
background-color: #ccc;
border-radius: 50%;
margin-right: 15rpx;
}
.message-content {
background-color: #333;
color: white;
padding: 15rpx 20rpx;
border-radius: 10rpx;
max-width: 70%;
}
.message-image {
max-width: 400rpx;
border-radius: 10rpx;
}
.message-video {
max-width: 400rpx;
border-radius: 10rpx;
}
}
}
}
.bottom-area {
background-color: #010000;
border-top: 1rpx solid #333;
.input-container {
display: flex;
padding: 20rpx;
.input-box {
flex: 1;
height: 80rpx;
background-color: #333;
color: white;
padding: 0 20rpx;
border-radius: 40rpx;
font-size: 28rpx;
}
.send-button {
margin-left: 20rpx;
background-color: #FF8998;
color: white;
border: none;
border-radius: 40rpx;
padding: 0 30rpx;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
}
}
}
}
.tablexx{
width: 730rpx;
height: 266rpx;
background: #010000;
border-radius: 20rpx 20rpx 20rpx 20rpx;
border-image: linear-gradient(226deg, rgba(255, 137.00000703334808, 152.0000061392784, 0.1899999976158142), rgba(255, 137.00000703334808, 152.0000061392784, 0)) 2 2;
padding: 32rpx 36rpx;
box-sizing: border-box;
position: fixed;
top: 150rpx;
left: 50%;
transform: translateX(-50%);
z-index: 99;
.jieshao{
font-size: 24rpx;
color: #FFFFFF;
margin-top: 16rpx;
}
.dangqian{
font-weight: 600;
font-size: 28rpx;
color: #FFFFFF;
margin-top: 26rpx;
}
.pianhao{
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
view{
margin-top: 20rpx;
font-size: 24rpx;
color: #6E7191;
display: flex;
align-items: center;
image{
height: 32rpx;
width: 32rpx;
margin-right: 16rpx;
}
}
}
.top{
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
font-size: 32rpx;
color: #FFFFFF;
button{
background-color: transparent;
margin: 0 !important;
width: 32rpx;
height: 32rpx;
line-height: 32rpx;
position: relative;
image{
width: 32rpx;
height: 32rpx;
position: absolute;
right: 10rpx;
}
}
}
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.function-icons {
display: flex;
padding: 20rpx;
border-top: 1rpx solid #333;
.icon-item {
width: 60rpx;
height: 60rpx;
image {
width: 100%;
height: 100%;
}
}
}
</style>