mahjong_group/components/com/page/reservation-evaluate.vue
2025-09-13 09:49:10 +08:00

191 lines
4.9 KiB
Vue

<template>
<uni-popup ref="popupRef" type="center">
<view class="popup-container">
<view class="column popup-inner">
<text class="popup-title">牌友评价</text>
<text class="popup-desc">请对每位牌友进行评价</text>
<view class="row panel-box" v-if="currentEvaluate" @click="index = 0, showPicker = true">
{{ currentEvaluate.userName }}
<image src="/static/down.png" class="down-icon" mode=""></image>
</view>
<view class="column panel-box" v-if="currentEvaluate">
<view class="row row-center mt-20 ml-20">
<text class="font-24">牌品</text>
<uni-rate :readonly="currentEvaluate.is_evaluate" class="ml-20"
v-model="currentEvaluate.play_level" />
<text class="font-24">当前评分:{{ currentEvaluate.user_play_level }}</text>
</view>
<view class="row row-center mt-20 ml-20">
<text class="font-24">牌技</text>
<uni-rate :readonly="currentEvaluate.is_evaluate" v-model="currentEvaluate.skills_level"
class="ml-20" />
<text class="font-24">当前评分:{{ currentEvaluate.user_skills_level }}</text>
</view>
</view>
<view class="row action-row" v-if="currentEvaluate">
<view class="center action-btn" v-if="!currentEvaluate.userBlackStatus"
@click="async () => { var f = await addBlack(currentEvaluate.user_id); f ? currentEvaluate.userBlackStatus = true : currentEvaluate.userBlackStatus = false; }">
拉入黑名单
</view>
<view class="center action-btn" v-if="currentEvaluate.userBlackStatus"
@click="async () => { var f = await cancelBlack(currentEvaluate.user_id); f ? currentEvaluate.userBlackStatus = false : currentEvaluate.userBlackStatus = true; }">
移出黑名单
</view>
<view class="center action-btn ml-20" v-if="!currentEvaluate.is_evaluate"
@click="submitEvaluate(currentEvaluate)">
提交
</view>
<view class="center action-btn ml-20" v-if="currentEvaluate.is_evaluate">
已提交
</view>
</view>
<text class="info-tip">加入黑名单后,双方将看不到对方发起的组局</text>
</view>
<view style="height: 5rpx;"></view>
</view>
<up-picker v-if="evaluateList.length > 0" @cancel="closePicker" @confirm="confirmPicker" :show="showPicker"
:columns="[evaluateList]" keyName="userName" valueName="user_id" :defaultIndex="[index]"></up-picker>
</uni-popup>
</template>
<script setup>
import { ref, computed } from 'vue'
import { sqInterface } from '@/common/server/interface/sq.js'
import { cancelBlack, addBlack } from '@/common/server/user.js'
const popupRef = ref(null)
const index = ref(0)
const showPicker = ref(false)
const evaluateList = ref([])
const currentReservation = ref(null)
const currentEvaluate = computed(() => {
if (!evaluateList.value || evaluateList.value.length === 0) return null
return evaluateList.value[index.value]
})
const show = async (reservation) => {
currentReservation.value = reservation
uni.showLoading({ title: '加载中...' })
const data = await sqInterface.getEvaluateServices(reservation.id)
uni.hideLoading()
if (!data || data.length === 0) {
uni.showToast({ title: '暂无评价', icon: 'none' })
return
}
evaluateList.value = []
evaluateList.value.push(...data)
popupRef.value.open()
}
const close = () => {
popupRef.value.close()
}
const closePicker = () => { showPicker.value = false }
const confirmPicker = () => { showPicker.value = false }
const submitEvaluate = async (evaluate) => {
uni.showLoading({ title: '评价提交中...' })
const payload = {
reservation_id: currentReservation.value.id,
to_user_id: evaluate.user_id,
play_level: evaluate.play_level,
skills_level: evaluate.skills_level
}
const ok = await sqInterface.addEvaluateServices(payload)
uni.hideLoading()
if (ok) {
uni.showToast({ title: '评价提交成功', icon: 'success' })
evaluate.is_evaluate = true
} else {
uni.showToast({ title: '评价提交失败', icon: 'none' })
}
}
defineExpose({ show, close })
</script>
<style lang="scss" scoped>
.popup-container {
width: 650rpx;
background-color: #FFFFFF;
border-radius: 20rpx;
}
.popup-inner {
width: 90%;
margin: 0 auto 0;
}
.popup-title {
font-size: 26rpx;
margin-top: 30rpx;
text-align: center;
}
.popup-desc {
font-size: 24rpx;
margin-top: 20rpx;
}
.panel-box {
width: 100%;
background-color: #F2F3F5;
border-radius: 10rpx;
padding-top: 20rpx;
padding-bottom: 20rpx;
margin-top: 20rpx;
}
.down-icon {
width: 40rpx;
height: 40rpx;
margin-left: auto;
margin-right: 20rpx;
}
.font-24 {
font-size: 24rpx;
}
.action-row {
margin-top: 50rpx;
height: 80rpx;
color: #FFFFFF;
font-size: 28rpx;
}
.action-btn {
flex: 1;
background-color: #1989FA;
border-radius: 10rpx;
}
.info-tip {
font-size: 24rpx;
text-align: center;
margin-top: 20rpx;
margin-bottom: 20rpx;
}
.row-center {
align-items: center;
}
.mt-20 {
margin-top: 20rpx;
}
.mt-10 {
margin-top: 10rpx;
}
.ml-20 {
margin-left: 20rpx;
}
</style>