fix: rating
This commit is contained in:
@@ -9,7 +9,7 @@ export const topicItemScore = async (data) => {
|
||||
});
|
||||
};
|
||||
|
||||
// 获取主题下的评分项
|
||||
// 获取评分项详情
|
||||
export const fetchTopicRatingItems = async (itemId) => {
|
||||
return request({
|
||||
url: `/api/rating/topic/item/detail/${itemId}`,
|
||||
|
||||
168
components/AttitudePanel/AttitudePanel.vue
Normal file
168
components/AttitudePanel/AttitudePanel.vue
Normal file
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<view class="attitude-panel card">
|
||||
<text class="section-title">你的态度</text>
|
||||
<view class="action-group">
|
||||
<view
|
||||
class="action-item"
|
||||
v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
:class="{ active: currentAction === action.label }"
|
||||
@tap="handleAction(action)"
|
||||
>
|
||||
<view class="emoji-wrap">
|
||||
<text class="emoji">{{ action.emoji }}</text>
|
||||
</view>
|
||||
<text class="action-name">{{ action.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="quick-comment">
|
||||
<input
|
||||
class="comment-input"
|
||||
type="text"
|
||||
v-model="commentText"
|
||||
placeholder="说点什么吧..."
|
||||
placeholder-class="input-placeholder"
|
||||
/>
|
||||
<button class="send-btn" @tap="handleSend">发送</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
initialAction: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['action-change', 'send-comment']);
|
||||
|
||||
const currentAction = ref(props.initialAction);
|
||||
|
||||
// 监听父组件传入的 initialAction 的变化
|
||||
watch(() => props.initialAction, (newVal) => {
|
||||
currentAction.value = newVal;
|
||||
});
|
||||
|
||||
const commentText = ref('');
|
||||
|
||||
const actions = [
|
||||
{ label: '拉', value: 'terrible', emoji: '👎', score: 2, scoreType:1 },
|
||||
{ label: 'NPC', value: 'bad', emoji: '😐', score: 4, scoreType: 2},
|
||||
{ label: '人上人', value: 'ok', emoji: '🙂', score: 6, scoreType: 3},
|
||||
{ label: '顶级', value: 'good', emoji: '🔥', score: 8, scoreType: 4},
|
||||
{ label: '夯', value: 'god', emoji: '👑', score: 10, scoreType: 5 }
|
||||
];
|
||||
|
||||
const handleAction = (action) => {
|
||||
emit('action-change', action);
|
||||
};
|
||||
|
||||
const handleSend = () => {
|
||||
if (!commentText.value.trim()) {
|
||||
uni.showToast({
|
||||
title: '请输入评论内容',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
emit('send-comment', {
|
||||
action: currentAction.value,
|
||||
content: commentText.value
|
||||
});
|
||||
commentText.value = ''; // 发送后清空
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card {
|
||||
background-color: #fff;
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #111;
|
||||
margin-bottom: 32rpx;
|
||||
display: block;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
|
||||
}
|
||||
|
||||
.action-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.emoji-wrap {
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
font-size: 56rpx;
|
||||
filter: grayscale(100%);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.action-name {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.action-item.active .emoji {
|
||||
filter: grayscale(0%);
|
||||
opacity: 1;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.action-item.active .action-name {
|
||||
color: #2953ff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.quick-comment {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f0f2f7;
|
||||
border-radius: 16rpx;
|
||||
padding: 8rpx 8rpx 8rpx 32rpx;
|
||||
}
|
||||
|
||||
.comment-input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.input-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
background-color: #4d44f1;
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 40rpx;
|
||||
height: 64rpx;
|
||||
line-height: 64rpx;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.send-btn::after {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
@@ -27,7 +27,8 @@
|
||||
</view>
|
||||
<view class="hero-meta">
|
||||
<text class="meta-rank">🥇 No.1</text>
|
||||
<text class="meta-heat">🔥 98.2w 热度</text>
|
||||
<text class="meta-heat">🔥 {{ detailData.hotScore }} 热度</text>
|
||||
<text class="meta-count" style="margin-left: 20rpx; color: #999;">{{ detailData.ratingCount }} 人评分</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -42,27 +43,11 @@
|
||||
</view>
|
||||
|
||||
<!-- 你的态度 -->
|
||||
<view class="attitude-panel card">
|
||||
<text class="section-title">你的态度</text>
|
||||
<view class="action-group">
|
||||
<view
|
||||
class="action-item"
|
||||
v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
:class="{ active: currentAction === action.value }"
|
||||
@tap="handleAction(action.value)"
|
||||
>
|
||||
<view class="emoji-wrap">
|
||||
<text class="emoji">{{ action.emoji }}</text>
|
||||
</view>
|
||||
<text class="action-name">{{ action.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="quick-comment">
|
||||
<input class="comment-input" type="text" placeholder="说点什么吧..." placeholder-class="input-placeholder" />
|
||||
<button class="send-btn">发送</button>
|
||||
</view>
|
||||
</view>
|
||||
<AttitudePanel
|
||||
:initial-action="currentAction"
|
||||
@action-change="handleActionChange"
|
||||
@send-comment="handleSendComment"
|
||||
/>
|
||||
|
||||
<!-- 大家都在 PK -->
|
||||
<view class="pk-panel card">
|
||||
@@ -137,82 +122,122 @@
|
||||
import { ref } from 'vue';
|
||||
import { getStatusBarHeight } from "@/utils/system";
|
||||
import { onLoad, onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
|
||||
import AttitudePanel from "@/components/AttitudePanel/AttitudePanel.vue";
|
||||
import { fetchTopicRatingItems } from "@/api/topicItem";
|
||||
import { FILE_BASE_URL } from "@/utils/constants";
|
||||
import { topicItemScore } from "@/api/topicItem";
|
||||
|
||||
const statusBarHeight = ref(getStatusBarHeight() || 44);
|
||||
const loading = ref(false);
|
||||
const hasMore = ref(true);
|
||||
const currentAction = ref('god');
|
||||
const currentAction = ref('');
|
||||
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
|
||||
const detailData = ref({
|
||||
id: 1,
|
||||
name: '李世民',
|
||||
score: '9.8',
|
||||
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=11',
|
||||
aiSummary: '多数用户认为李世民综合能力最强,尤其在文治武功方面优势明显。关于玄武门事件的争议依然存在。'
|
||||
id: '',
|
||||
name: '',
|
||||
score: '0.0',
|
||||
avatar: '',
|
||||
aiSummary: '加载中...',
|
||||
userAction: "",
|
||||
topicId: ''
|
||||
});
|
||||
|
||||
const actions = [
|
||||
{ label: '离谱', value: 'terrible', emoji: '👎' },
|
||||
{ label: '一般', value: 'bad', emoji: '😐' },
|
||||
{ label: '不错', value: 'ok', emoji: '🙂' },
|
||||
{ label: '很强', value: 'good', emoji: '🔥' },
|
||||
{ label: '封神', value: 'god', emoji: '👑' }
|
||||
];
|
||||
const comments = ref([]);
|
||||
const itemId = ref('');
|
||||
|
||||
const mockComments = [
|
||||
{
|
||||
id: 1,
|
||||
name: '历史课代表',
|
||||
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=u1',
|
||||
time: '2小时前',
|
||||
content: '李世民唯一缺点是儿子太抽象。',
|
||||
likes: '2.3k',
|
||||
badge: '封神',
|
||||
badgeIcon: '👑'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '贞观长歌',
|
||||
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=u2',
|
||||
time: '5小时前',
|
||||
content: '不管怎么说,六边形战士在历史上是真罕见。',
|
||||
likes: '856',
|
||||
badge: '很强',
|
||||
badgeIcon: '🔥'
|
||||
const handleActionChange = async (action) => {
|
||||
const originAction = detailData.value.userAction;
|
||||
const originScore = detailData.value.score;
|
||||
try {
|
||||
detailData.value.userAction = detailData.value.userAction === action.label ? '' : action.label;
|
||||
currentAction.value = action.label;
|
||||
|
||||
const res = await topicItemScore({
|
||||
topicId: detailData.value.topicId,
|
||||
itemId: itemId.value,
|
||||
scoreType: action.scoreType
|
||||
});
|
||||
detailData.value.score = res?.scoreAvg || originScore;
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: '评分失败',
|
||||
icon: 'none'
|
||||
});
|
||||
detailData.value.userAction = originAction;
|
||||
detailData.value.score = originScore;
|
||||
currentAction.value = originAction;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
const comments = ref([...mockComments]);
|
||||
const handleSendComment = (payload) => {
|
||||
console.log('发送评论:', payload);
|
||||
uni.showToast({
|
||||
title: '发送成功',
|
||||
icon: 'success'
|
||||
});
|
||||
// TODO: 调用接口发送评论,然后更新评论列表
|
||||
};
|
||||
|
||||
const handleAction = (val) => {
|
||||
currentAction.value = val;
|
||||
const getDetailData = async () => {
|
||||
if (!itemId.value) return;
|
||||
try {
|
||||
uni.showLoading({ title: '加载中' });
|
||||
const res = await fetchTopicRatingItems(itemId.value);
|
||||
const data = res?.data || res || {};
|
||||
|
||||
detailData.value = {
|
||||
id: itemId.value,
|
||||
name: data.name || '未知',
|
||||
score: data.scoreAvg ? Number(data.scoreAvg).toFixed(1) : '0.0',
|
||||
avatar: data.avatarUrl ? `${FILE_BASE_URL}${data.avatarUrl}` : '',
|
||||
aiSummary: data.description || '暂无总结',
|
||||
hotScore: data.hotScore || '0.00',
|
||||
topicId: data.topicId || '',
|
||||
ratingCount: data.scoreCount || 0,
|
||||
userAction: data.userAction || ""
|
||||
};
|
||||
|
||||
// 如果接口返回了当前用户的态度,初始化它
|
||||
if (data.userAction) {
|
||||
currentAction.value = data.userAction;
|
||||
}
|
||||
|
||||
// 如果有评论数据,更新评论
|
||||
if (data.comments && Array.isArray(data.comments)) {
|
||||
comments.value = data.comments;
|
||||
} else {
|
||||
comments.value = [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取详情失败:', error);
|
||||
uni.showToast({
|
||||
title: '获取详情失败',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
uni.stopPullDownRefresh();
|
||||
}
|
||||
};
|
||||
|
||||
onLoad((options) => {
|
||||
console.log('Received itemId:', options.itemId);
|
||||
if (options.itemId) {
|
||||
itemId.value = options.itemId;
|
||||
getDetailData();
|
||||
}
|
||||
});
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
setTimeout(() => {
|
||||
comments.value = [...mockComments];
|
||||
hasMore.value = true;
|
||||
uni.stopPullDownRefresh();
|
||||
}, 1000);
|
||||
getDetailData();
|
||||
});
|
||||
|
||||
onReachBottom(() => {
|
||||
if (!hasMore.value || loading.value) return;
|
||||
loading.value = true;
|
||||
setTimeout(() => {
|
||||
const more = mockComments.map(c => ({...c, id: c.id + comments.value.length}));
|
||||
comments.value.push(...more);
|
||||
loading.value = false;
|
||||
if (comments.value.length >= 10) hasMore.value = false;
|
||||
}, 1000);
|
||||
// TODO: 评论分页加载逻辑
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -384,6 +409,8 @@ onReachBottom(() => {
|
||||
}
|
||||
|
||||
/* 你的态度面板 */
|
||||
|
||||
/* 大家都在 PK */
|
||||
.section-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
@@ -393,79 +420,6 @@ onReachBottom(() => {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
|
||||
}
|
||||
|
||||
.action-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.emoji-wrap {
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
font-size: 56rpx;
|
||||
filter: grayscale(100%);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.action-name {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.action-item.active .emoji {
|
||||
filter: grayscale(0%);
|
||||
opacity: 1;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.action-item.active .action-name {
|
||||
color: #2953ff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.quick-comment {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f0f2f7;
|
||||
border-radius: 16rpx;
|
||||
padding: 8rpx 8rpx 8rpx 32rpx;
|
||||
}
|
||||
|
||||
.comment-input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.input-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
background-color: #4d44f1;
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 40rpx;
|
||||
height: 64rpx;
|
||||
line-height: 64rpx;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.send-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 大家都在 PK */
|
||||
.pk-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
Reference in New Issue
Block a user