活跃作者推荐
This commit is contained in:
parent
a949996907
commit
56b1d23b8a
11
src/api/centre_maps.js
Normal file
11
src/api/centre_maps.js
Normal file
@ -0,0 +1,11 @@
|
||||
import axiosInstance from './axiosConfig';
|
||||
|
||||
|
||||
export const getMapEditors = async () => {
|
||||
try {
|
||||
const response = await axiosInstance.get('/map/editors');
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
@ -1,6 +1,7 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { hasValidToken, getUserInfo, logoutUser } from '../utils/jwt';
|
||||
import { justLoggedIn } from '../utils/authSessionState';
|
||||
import EditorsMaps from '@/views/index/EditorsMaps.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@ -70,6 +71,11 @@ const routes = [
|
||||
name: 'CompetitionSignUp',
|
||||
component: () => import('@/views/index/CompetitionSignUp.vue'),
|
||||
meta: { requiresAuth: true }
|
||||
},
|
||||
{
|
||||
path: 'editors-maps',
|
||||
name: 'EditorsMaps',
|
||||
component: () => import('@/views/index/EditorsMaps.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1,61 +1,166 @@
|
||||
<template>
|
||||
<div class="weekly-recommend">
|
||||
<div class="maps">
|
||||
<div class="page-header">
|
||||
<h1>活跃作者推荐</h1>
|
||||
<div class="header-subtitle">
|
||||
<span class="date-range">{{ currentWeekRange }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table class="maps-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>预览图</th>
|
||||
<th>地图名称</th>
|
||||
<th>作者</th>
|
||||
<th>下载次数</th>
|
||||
<th>收藏次数</th>
|
||||
<th>玩家数量</th>
|
||||
<th>创建时间</th>
|
||||
<th>标签</th>
|
||||
<th class="rank-column">排名</th>
|
||||
<th>作者名称</th>
|
||||
<th>积分</th>
|
||||
<th>最近三个月活跃</th>
|
||||
<th>最近一个月活跃</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(map, index) in recommendedMaps" :key="map.id" @click="goToMapDetail(map.id)" class="table-row">
|
||||
<td class="rank-number">{{ index + 1 }}</td>
|
||||
<td class="preview-cell">
|
||||
<img :src="map.thumbnail" :alt="map.chinese_name">
|
||||
</td>
|
||||
<td class="map-name">{{ map.chinese_name }}</td>
|
||||
<td>{{ map.user }}</td>
|
||||
<td>{{ map.download_count }}</td>
|
||||
<td>{{ map.favourite_count }}</td>
|
||||
<td>{{ map.player_count }}</td>
|
||||
<td>{{ formatDate(map.create_time) }}</td>
|
||||
<tr v-for="(editor, index) in displayedEditors" :key="editor.update_editor" class="table-row" @click="goToAuthorMaps(editor.update_editor)">
|
||||
<td class="rank-column">{{ index + 1 }}</td>
|
||||
<td class="author-name">{{ editor.update_editor }}</td>
|
||||
<td>{{ editor.credits }}</td>
|
||||
<td>
|
||||
<div class="tags">
|
||||
<span v-for="tag in map.tags" :key="tag" class="tag">{{ tag }}</span>
|
||||
</div>
|
||||
<span :class="['status-badge', editor.three_month_live ? 'active' : 'inactive']">
|
||||
{{ editor.three_month_live ? '是' : '否' }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span :class="['status-badge', editor.one_month_live ? 'active' : 'inactive']">
|
||||
{{ editor.one_month_live ? '是' : '否' }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="expand-button" @click="toggleExpand">
|
||||
{{ isExpanded ? '收起' : '展开更多' }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, computed, onMounted} from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { getMapEditors } from '@/api/centre_maps.js'
|
||||
import '../../assets/styles/common.css'
|
||||
import '../../assets/styles/Maps.css'
|
||||
|
||||
const router = useRouter()
|
||||
const sortedEditors = ref([])
|
||||
const isExpanded = ref(false)
|
||||
|
||||
// 计算要显示的作者列表
|
||||
const displayedEditors = computed(() => {
|
||||
return isExpanded.value ? sortedEditors.value : sortedEditors.value.slice(0, 10)
|
||||
})
|
||||
|
||||
// 跳转到作者地图列表
|
||||
const goToAuthorMaps = (authorName) => {
|
||||
router.push({
|
||||
name: 'EditorsMaps',
|
||||
query: {
|
||||
author: authorName
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const editorsList = async () => {
|
||||
try {
|
||||
// 获取作者列表并按积分排序
|
||||
const editorsData = await getMapEditors();
|
||||
sortedEditors.value = editorsData.sort((a, b) => b.credits - a.credits);
|
||||
console.log('排序后的作者列表:', sortedEditors.value);
|
||||
} catch (error) {
|
||||
console.error('获取列表失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 切换展开状态
|
||||
const toggleExpand = () => {
|
||||
isExpanded.value = !isExpanded.value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
editorsList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.rank-number {
|
||||
.maps-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.maps-table th,
|
||||
.maps-table td {
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.maps-table th {
|
||||
background-color: #f5f5f5;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rank-column {
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
color: #1a237e;
|
||||
text-align: center;
|
||||
width: 50px;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.table-row:hover {
|
||||
background-color: #f5f5f5;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.author-name {
|
||||
font-weight: bold;
|
||||
color: #1a237e;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 0.9em;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-badge.active {
|
||||
background-color: #e8f5e9;
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
.status-badge.inactive {
|
||||
background-color: #ffebee;
|
||||
color: #c62828;
|
||||
}
|
||||
|
||||
.expand-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 20px 0;
|
||||
padding: 10px 20px;
|
||||
background-color: #1a237e;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
width: fit-content;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.expand-button:hover {
|
||||
background-color: #283593;
|
||||
}
|
||||
</style>
|
@ -113,6 +113,23 @@
|
||||
<span class="label">发布时间:</span>
|
||||
<span class="value">{{ formatDate(selectedDemand?.date) }}</span>
|
||||
</div>
|
||||
<div class="reply-section">
|
||||
<h3>回复内容</h3>
|
||||
<div class="reply-list">
|
||||
<div v-if="selectedDemand?.replies && selectedDemand.replies.length > 0">
|
||||
<div v-for="reply in selectedDemand.replies" :key="reply.id" class="reply-item">
|
||||
<div class="reply-header">
|
||||
<span class="reply-author">{{ reply.author || '匿名用户' }}</span>
|
||||
<span class="reply-time">{{ formatDate(reply.time) }}</span>
|
||||
</div>
|
||||
<div class="reply-content">{{ reply.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="no-reply">
|
||||
暂无回复
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -427,7 +444,7 @@ function autoResize() {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
width: 90%;
|
||||
max-width: 600px;
|
||||
max-width: 800px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
@ -588,4 +605,57 @@ function autoResize() {
|
||||
line-height: 1.6;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.reply-section {
|
||||
margin-top: 20px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.reply-section h3 {
|
||||
color: #1a237e;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.reply-list {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.reply-item {
|
||||
background: #f7faff;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.reply-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.reply-author {
|
||||
font-weight: 600;
|
||||
color: #1a237e;
|
||||
}
|
||||
|
||||
.reply-time {
|
||||
color: #666;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.reply-content {
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.no-reply {
|
||||
text-align: center;
|
||||
color: #666;
|
||||
padding: 20px;
|
||||
background: #f7faff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
@ -256,5 +256,74 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
.page-btn {
|
||||
padding: 6px 16px;
|
||||
border: none;
|
||||
background: #e3f0ff;
|
||||
color: #2563eb;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.page-btn:disabled {
|
||||
background: #f5f5f5;
|
||||
color: #aaa;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.page-numbers {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
.page-number {
|
||||
padding: 6px 12px;
|
||||
border: none;
|
||||
background: #f5f5f5;
|
||||
color: #2563eb;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.page-number.active {
|
||||
background: #2563eb;
|
||||
color: #fff;
|
||||
}
|
||||
.page-ellipsis {
|
||||
padding: 6px 8px;
|
||||
color: #aaa;
|
||||
font-size: 14px;
|
||||
}
|
||||
.page-jump {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.jump-input {
|
||||
width: 50px;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.jump-btn {
|
||||
padding: 4px 10px;
|
||||
background: #2563eb;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.jump-btn:hover {
|
||||
background: #1a237e;
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user