Files
api-client/src/views/rating/topicItem/index.vue
2026-06-01 16:18:27 +08:00

319 lines
9.4 KiB
Vue
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>
<div class="rating-topic-item-container">
<vab-query-form>
<vab-query-form-left-panel :span="12">
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
<el-form-item>
<el-select v-model="queryForm.topicId" clearable filterable placeholder="请选择评价主题" @change="handleTopicChange">
<el-option v-for="item in topicList" :key="item.id" :label="item.title" :value="item.id" />
</el-select>
</el-form-item>
</el-form>
</vab-query-form-left-panel>
<vab-query-form-right-panel :span="12">
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
<el-form-item>
<el-input v-model.trim="queryForm.keyword" clearable placeholder="请输入评价项名称" />
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
</el-form-item>
</el-form>
</vab-query-form-right-panel>
</vab-query-form>
<el-alert
v-if="!queryForm.topicId"
show-icon
style="margin-bottom: 20px"
title="请先在左侧选择一个评价主题,或从主题列表点击跳转过来"
type="warning"
/>
<el-table v-loading="listLoading" :data="list" :element-loading-text="elementLoadingText">
<el-table-column align="center" fixed="left" label="操作" width="120">
<template #default="{ row }">
<el-button type="text" @click="handleRating(row)">评价</el-button>
<el-button type="text" @click="handleComment(row)">评论</el-button>
</template>
</el-table-column>
<el-table-column align="left" label="评价项" min-width="200">
<template #default="{ row }">
<div class="item-info-cell">
<el-image v-if="row.avatarUrl" class="item-avatar" :preview-src-list="[row.avatarUrl]" :src="getThumbUrl(row.avatarUrl)" />
<div v-else class="item-avatar-placeholder"><i class="el-icon-picture-outline" /></div>
<div class="item-details">
<div class="item-name">{{ row.name }}</div>
<div v-if="row.description" class="item-desc" :title="row.description">{{ row.description }}</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column align="center" label="状态" width="100">
<template #default="{ row }">
<el-tag v-if="row.status === 1" type="warning">审核中</el-tag>
<el-tag v-else-if="row.status === 2" type="success">已审通过</el-tag>
<el-tag v-else-if="row.status === 3" type="danger">已拒绝</el-tag>
<el-tag v-else-if="row.status === 4" type="info">禁用</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column align="left" label="分数统计">
<template #default="{ row }">
<div class="stat-cell">
<div class="stat-row">
<span class="stat-label">排名分</span>
<span class="stat-value highlight">{{ row.rankScore }}</span>
</div>
<div class="stat-row">
<span class="stat-label">平均分数</span>
<span class="stat-value highlight">{{ row.scoreAvg }}</span>
</div>
<div class="stat-row">
<span class="stat-label">累计总分</span>
<span class="stat-value">{{ row.scoreTotal }}</span>
</div>
<div class="stat-row">
<span class="stat-label">热门分</span>
<span class="stat-value">{{ row.hotScore }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column align="left" label="互动数据" min-width="150">
<template #default="{ row }">
<div class="stat-cell">
<div class="stat-row">
<span class="stat-label">
<i class="el-icon-view" />
浏览数
</span>
<span class="stat-value">{{ row.viewCount }}</span>
</div>
<div class="stat-row">
<span class="stat-label">
<i class="el-icon-chat-dot-round" />
评论数
</span>
<span class="stat-value">{{ row.commentCount }}</span>
</div>
<!-- <div class="stat-row">
<span class="stat-label">
<i class="el-icon-star-off" />
打分次数
</span>
<span class="stat-value">{{ row.ratingCount }}</span>
</div> -->
<div class="stat-row">
<span class="stat-label">
<i class="el-icon-user" />
评价人数
</span>
<span class="stat-value">{{ row.scoreCount }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column align="center" label="排序" prop="sortOrder" width="80" />
<el-table-column align="center" label="创建时间" prop="createdAt" width="160">
<template #default="{ row }">
{{ formatTime(row.createdAt) }}
</template>
</el-table-column>
</el-table>
<el-pagination
background
:current-page="queryForm.pageNo"
:layout="layout"
:page-size="queryForm.pageSize"
:total="total"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
<topic-item-rating-edit ref="ratingEdit" @fetch-data="fetchData" />
<topic-item-comment-edit ref="commentEdit" @fetch-data="fetchData" />
</div>
</template>
<script>
import { getList } from '@/api/rating/topicItem'
import { getList as getTopicList } from '@/api/rating/topic'
import { formatTime } from '@/utils'
import { getThumbUrl } from '@/utils/blessing'
import TopicItemRatingEdit from './components/TopicItemRatingEdit'
import TopicItemCommentEdit from './components/TopicItemCommentEdit'
export default {
name: 'RatingTopicItemIndex',
components: { TopicItemRatingEdit, TopicItemCommentEdit },
data() {
return {
list: [],
topicList: [],
listLoading: false,
layout: 'total, sizes, prev, pager, next, jumper',
total: 0,
elementLoadingText: '正在加载...',
queryForm: {
pageNo: 1,
pageSize: 10,
keyword: '',
topicId: '',
},
}
},
watch: {
'$route.query.topicId': {
handler(newVal) {
if (newVal && newVal !== this.queryForm.topicId) {
this.queryForm.topicId = newVal
this.fetchData()
}
},
immediate: true,
},
},
created() {
this.initData()
},
methods: {
formatTime,
getThumbUrl,
async initData() {
// 先获取下拉列表的主题数据暂时取100条
try {
const { data } = await getTopicList({ pageNo: 1, pageSize: 100 })
this.topicList = data.list || []
} catch (error) {
console.error(error)
}
},
handleTopicChange() {
this.queryForm.pageNo = 1
this.fetchData()
},
handleSizeChange(val) {
this.queryForm.pageSize = val
this.fetchData()
},
handleCurrentChange(val) {
this.queryForm.pageNo = val
this.fetchData()
},
queryData() {
this.queryForm.pageNo = 1
this.fetchData()
},
async fetchData() {
if (!this.queryForm.topicId) {
this.list = []
this.total = 0
return
}
this.listLoading = true
try {
const { data } = await getList(this.queryForm)
this.list = data.list
this.total = data.totalCount
} catch (error) {
console.error(error)
} finally {
this.listLoading = false
}
},
handleRating(row) {
this.$refs['ratingEdit'].showEdit(row, this.queryForm.topicId)
},
handleComment(row) {
this.$refs['commentEdit'].showEdit(row, this.queryForm.topicId)
},
},
}
</script>
<style scoped>
.rating-topic-item-container {
padding: 20px;
}
.item-info-cell {
display: flex;
align-items: center;
}
.item-avatar,
.item-avatar-placeholder {
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 12px;
flex-shrink: 0;
}
.item-avatar-placeholder {
background-color: #f0f2f5;
display: flex;
align-items: center;
justify-content: center;
color: #909399;
font-size: 20px;
}
.item-details {
display: flex;
flex-direction: column;
overflow: hidden;
}
.item-name {
font-weight: bold;
color: #303133;
margin-bottom: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-desc {
font-size: 12px;
color: #909399;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.stat-cell {
display: flex;
flex-direction: column;
gap: 4px;
}
.stat-row {
display: flex;
align-items: center;
font-size: 13px;
}
.stat-label {
color: #909399;
width: 90px;
}
.stat-value {
color: #606266;
}
.stat-value.highlight {
color: #409eff;
font-weight: bold;
}
</style>