mrr.sj.front/pages/evaluate/components/evaluationDetail.nvue

311 lines
7.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="evaluation-detail" @click="goDetail">
<!-- 用户信息区域:显式水平排列 -->
<view class="user-section">
<view class="user-info">
<image class="avatar" :src="evaluatorPhoto" mode="aspectFill" />
<text class="username">{{ evaluatorName }}</text>
</view>
<text class="time">{{formattedCreateTime}}</text>
</view>
<view class="user-contant">
<!-- 评分标题:显式水平排列 -->
<view class="rating-header">
<image :src="getComposite" class="tag" mode="heightFix" />
<view class="stars">
<image v-for="n in 5" :key="n" :src="getStar(n)" class="star-icon" mode="aspectFill" />
</view>
<text class="score">{{evaluateObj.composite}}分</text>
</view>
<!-- 评论内容nvue不支持span全部替换为text -->
<view class="comment">
<text class="comment-text">
{{evaluateObj.describe.length > 60 ? evaluateObj.describe.slice(0, 59) : evaluateObj.describe}}
<text v-if="evaluateObj.describe.length > 60">
{{hasShowMore ? evaluateObj.describe.slice(59) : '...'}}
<text class="foot-btn" @click.stop="showMore">
{{hasShowMore ? '收起' : '全文'}}
<image
src="/static/images/evaluate/open.png"
mode="widthFix"
class="foot-btn-img"
:class="{btnImg2:hasShowMore}"
/>
</text>
</text>
</text>
</view>
<!-- 图片展示:显式水平排列+兼容间距 -->
<view class="photos" v-if="isAllImg">
<image
v-for="(photo, index) in photos"
:key="index"
:src="photo"
class="photo"
:class="{ 'photo-third': (index + 1) % 3 === 0 }"
mode="aspectFill"
@tap.stop="imgPreview(index)"
/>
</view>
<view class="photos" v-else>
<image
v-for="(photo, index) in photos.slice(0, 3)"
:key="index"
:src="photo"
class="photo"
:class="{ 'photo-third': (index + 1) % 3 === 0 }"
mode="aspectFill"
@tap.stop="imgPreview(index)"
/>
<view class="more" v-if="photos.length>3">
<image src="/static/images/evaluate/more.png" class="more-img" mode="aspectFill" />
<text class="more-text">{{photos.length}}</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
hasShowMore: false,
compositeStraList: []
};
},
computed: {
evaluatorPhoto() {
if (!this.evaluateObj.evaluator_head_photo) return "";
return this.evaluateObj.anonymity == 1
? "/static/images/evaluate/photo.jpg"
: this.evaluateObj.evaluator_head_photo;
},
evaluatorName() {
if (!this.evaluateObj.evaluator_name) return "";
return this.evaluateObj.anonymity == 1
? "匿名用户"
: this.evaluateObj.evaluator_name;
},
photos() {
if (!this.evaluateObj.images) return [];
return this.evaluateObj.images.split(",");
},
formattedCreateTime() {
if (!this.evaluateObj?.create_time) return '';
const datePart = this.evaluateObj.create_time.split(' ')[0];
if (!datePart) return '';
const compatibleDateStr = datePart.replace(/-/g, '/');
const date = new Date(compatibleDateStr);
if (isNaN(date.getTime())) return '';
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return `${year}年${month}月${day}日`;
},
getComposite() {
if (!this.evaluateObj.composite) return "";
return `/static/images/evaluate/score${Math.floor(this.evaluateObj.composite)}.png`;
}
},
props: {
evaluateObj: {
type: Object,
default: () => ({})
},
isAllImg: {
type: Boolean,
default: false
}
},
methods: {
showMore() {
this.hasShowMore = !this.hasShowMore;
},
imgPreview(index) {
uni.previewImage({
current: index,
urls: this.photos
});
},
getStar(value) {
if (!this.evaluateObj.composite) return "";
const composite = this.evaluateObj.composite;
if (composite >= value) {
return "/static/images/evaluate/star_red.png";
} else if (composite < value && composite > value - 1) {
return "/static/images/evaluate/star2.png";
} else {
return "/static/images/evaluate/star_ash2.png";
}
},
handleDecimal(num) {
const integerPart = Math.sign(num) === -1 ? Math.ceil(num) : Math.floor(num);
const decimalPart = num - integerPart;
return decimalPart > 0.5 ? integerPart + 0.5 : integerPart;
},
goDetail() {
this.$emit("goDetail", this.evaluateObj);
}
}
};
</script>
<style>
/* 基础容器仅保留布局样式字体样式全部下移到text */
.evaluation-detail {
padding: 30rpx 20rpx;
border-radius: 16rpx;
background-color: #fff;
border-bottom: 2rpx solid #FAFAFA;
flex: 1;
}
/* 用户信息区域显式水平排列覆盖nvue默认column */
.user-section {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.user-info {
display: flex;
flex-direction: row;
align-items: center;
}
.avatar {
width: 62rpx;
height: 62rpx;
border-radius: 50%;
margin-right: 6rpx;
}
/* 文字样式直接写在text的class上不继承 */
.username {
font-weight: 500;
font-size: 24rpx;
color: #333333;
line-height: 33rpx;
}
.time {
font-size: 24rpx;
color: #999;
margin-top: 4rpx;
}
/* 内容区域:左侧内边距保留 */
.user-contant {
padding-left: 70rpx;
}
/* 评分头部:显式水平排列 */
.rating-header {
display: flex;
flex-direction: row;
align-items: center;
margin-top: 20rpx;
}
.tag {
height: 40rpx;
margin-right: 10rpx;
}
.stars {
display: flex;
flex-direction: row;
align-items: center;
margin-right: 10rpx;
}
.star-icon {
width: 24rpx;
height: 24rpx;
margin-right: 2rpx;
}
/* 评分文字样式写在text上 */
.score {
font-weight: 400;
font-size: 26rpx;
color: #E8101E;
line-height: 37rpx;
}
/* 评论内容容器仅控制间距文字样式在text上 */
.comment {
margin-top: 12rpx;
}
.comment-text {
font-weight: 400;
font-size: 26rpx;
color: #333333;
line-height: 46rpx;
}
/* 图片区域:显式水平排列+兼容间距nvue不支持column-gap/row-gap */
.photos {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-top: 20rpx;
position: relative;
}
.photo {
width: 194rpx;
height: 194rpx;
border-radius: 6rpx;
/* nvue不支持object-fit靠mode="aspectFill"实现 */
margin-right: 1.1%;
margin-bottom: 6rpx;
}
/* 清除第3个图片的右间距模拟column-gap */
/* .photo:nth-child(3n) {
margin-right: 0;
} */
/* 第3n个元素的特殊样式用动态类名实现 */
.photo-third {
margin-right: 0; /* 原本放在nth-child里的样式 */
/* 其他特殊样式... */
}
/* 更多图片提示:显式水平排列 */
.more {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 59rpx;
height: 28rpx;
background: rgba(51, 51, 51, 0.4);
border-radius: 14rpx;
position: absolute;
bottom: 10rpx;
right: 10rpx;
}
.more-img {
width: 23rpx;
height: 17rpx;
margin-right: 5rpx;
}
.more-text {
font-weight: 400;
font-size: 22rpx;
color: #FFFFFF;
line-height: 30rpx;
}
/* 全文/收起按钮文字样式写在text上 */
.foot-btn {
font-weight: 500;
font-size: 24rpx;
color: #0751ff;
line-height: 33rpx;
}
.foot-btn-img {
width: 18rpx;
height: 18rpx;
margin-left: 10rpx;
}
.btnImg2 {
transform: rotate(180deg);
}
</style>