311 lines
7.4 KiB
Plaintext
311 lines
7.4 KiB
Plaintext
<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: #FF4767;
|
||
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> |