aslan-h5/src/views/PlatformPolicyView.vue

427 lines
8.6 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="platform-policy gradient-background-circles">
<!-- 使用 GeneralHeader 组件替换 MobileHeader -->
<GeneralHeader
:title="t('platform_policy')"
:showBack="true"
:showLanguageList="true"
color="black"
style="box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 999"
/>
<div class="content">
<!-- 政策列表 -->
<div v-if="policies.length > 0" style="display: flex; flex-direction: column; gap: 16px">
<div
style="
background-color: white;
padding: 16px;
border-radius: 12px;
margin-bottom: 12px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 5px;
"
v-for="policy in policies"
:key="policy.level"
>
<div style="font-weight: 600; font-size: 1.2em">Lv.{{ policy.level }}</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px">
<div
style="
width: max-content;
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
"
>
<div style="font-weight: 600">{{ t('time') }} ({{ t('hours') }})</div>
<div style="font-weight: 500">{{ policy.onlineTime || 0 }}</div>
</div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 5px">
<div style="font-weight: 600">{{ t('target') }}</div>
<div style="font-weight: 500">
{{ formatTarget(policy.target) }}
</div>
</div>
<div style="display: flex; justify-content: flex-end">
<div
style="
width: max-content;
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
"
>
<div style="font-weight: 600">{{ t('host_salary') }}</div>
<div style="font-weight: 500">${{ policy.memberSalary || 0 }}</div>
</div>
</div>
<!-- 第二行 -->
<div
style="
width: max-content;
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
"
>
<div style="font-weight: 600">{{ t('agent_salary') }}</div>
<div style="font-weight: 500">${{ policy.ownSalary || 0 }}</div>
</div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 5px">
<div style="font-weight: 600">{{ t('total_salary') }}</div>
<div style="font-weight: 500">${{ policy.totalSalary || 0 }}</div>
</div>
</div>
</div>
</div>
<!-- 空状态 -->
<div v-else class="empty-state">
<div class="empty-icon">📋</div>
<p>{{ t('no_policy_data_available') }}</p>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import GeneralHeader from '@/components/GeneralHeader.vue'
import { get } from '../utils/http.js'
import { getTeamId } from '@/utils/userStore.js'
import { setDocumentDirection } from '@/locales/i18n'
const { t, locale } = useI18n()
// 监听语言变化并设置文档方向
locale.value && setDocumentDirection(locale.value)
const loading = ref(false)
const policies = ref([])
const role = ref('')
// 获取团队政策数据
const fetchTeamPolicy = async () => {
try {
loading.value = true
// 从路由参数获取 teamId 和 role如果没有则使用默认值
const teamId = getTeamId()
const response = await get(`/team/release/policy?id=${teamId}`)
if (response.status && response.body && response.body.policy) {
policies.value = response.body.policy || []
} else {
policies.value = []
}
} catch (error) {
console.error('Failed to fetch team policy:', error)
policies.value = []
} finally {
loading.value = false
}
}
// 格式化目标值显示
const formatTarget = (target) => {
if (!target) return '0'
const numTarget = parseFloat(target)
if (isNaN(numTarget)) return target
if (numTarget >= 1000000) {
return `${(numTarget / 1000000).toFixed(1)}M`
} else if (numTarget >= 1000) {
return `${(numTarget / 1000).toFixed(1)}K`
}
return numTarget.toString()
}
// 格式化奖励类型
const formatRewardType = (type) => {
const typeMap = {
AVATAR_FRAME: t('avatar_frame'),
RIDE: t('ride_effect'),
THEME: t('theme'),
BADGE: t('badge'),
GIFT: t('gift'),
}
return typeMap[type] || type
}
// 组件挂载时获取数据
onMounted(() => {
fetchTeamPolicy()
})
</script>
<style scoped>
* {
color: rgba(0, 0, 0, 0.8);
font-family: 'SF Pro Text';
}
.platform-policy {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
min-height: 100vh;
background-color: #f1f2f3;
}
.content {
padding: 16px;
position: relative;
z-index: 2;
}
/* 加载状态 */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
padding: 60px 20px;
color: #666;
}
.loading-spinner {
width: 32px;
height: 32px;
border: 3px solid #f3f3f3;
border-top: 3px solid #8b5cf6;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 12px;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 政策列表 */
.policy-list {
display: flex;
flex-direction: column;
gap: 16px;
}
.policy-item {
background-color: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.policy-header {
padding: 16px 16px 8px 16px;
background-color: #f8f9fa;
border-bottom: 1px solid #e9ecef;
}
.policy-header h3 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #333;
}
.policy-details {
padding: 16px;
}
.policy-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
margin-bottom: 16px;
}
.policy-grid.bottom-row {
margin-bottom: 0;
}
.policy-cell {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 12px 8px;
background-color: #f1f2f3;
border-radius: 8px;
}
.policy-cell.empty {
visibility: hidden;
}
.cell-label {
font-size: 12px;
color: #666;
margin-bottom: 8px;
line-height: 1.3;
}
.cell-value {
font-size: 14px;
font-weight: 600;
color: #333;
}
.cell-value.salary {
color: #ff6600;
font-weight: 700;
}
/* 奖励区域 */
.rewards-section {
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid #e9ecef;
}
.rewards-divider {
height: 2px;
background: linear-gradient(90deg, #c2d9f0 0%, #03dbb8 100%);
margin-bottom: 12px;
border-radius: 1px;
}
.rewards-header {
margin-bottom: 12px;
}
.rewards-title {
font-size: 14px;
font-weight: 600;
color: #333;
}
.rewards-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.reward-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
background: linear-gradient(135deg, #c2d9f0 0%, #03dbb8 100%);
border-radius: 8px;
color: white;
}
.reward-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.reward-name {
font-size: 14px;
font-weight: 600;
}
.reward-type {
font-size: 12px;
opacity: 0.9;
}
.reward-amount {
font-size: 14px;
font-weight: 700;
color: white;
}
/* 空状态 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: #666;
text-align: center;
}
.empty-icon {
font-size: 48px;
margin-bottom: 16px;
}
.empty-state p {
margin: 0;
font-size: 16px;
}
/* 响应式调整 */
@media (max-width: 480px) {
.policy-grid {
gap: 12px;
}
.cell-label {
font-size: 11px;
}
.cell-value {
font-size: 13px;
}
.policy-cell {
padding: 8px 4px;
}
.reward-item {
padding: 10px;
}
.reward-name {
font-size: 13px;
}
.reward-type {
font-size: 11px;
}
.reward-amount {
font-size: 13px;
}
}
@media screen and (max-width: 360px) {
* {
font-size: 10px;
}
}
@media screen and (min-width: 360px) {
* {
font-size: 12px;
}
}
@media screen and (min-width: 768px) {
* {
font-size: 24px;
}
}
/* RTL支持 */
[dir='rtl'] .policy-grid {
direction: rtl;
}
</style>