feat: 配置语言翻译功能
This commit is contained in:
parent
1c9bec1543
commit
cb8bee31e4
@ -162,14 +162,7 @@ const handleLanguageChange = (item) => {
|
|||||||
const isInAppEnvironment = ref(false)
|
const isInAppEnvironment = ref(false)
|
||||||
|
|
||||||
// 定义首页路由列表
|
// 定义首页路由列表
|
||||||
const homeRoutes = [
|
const homeRoutes = ['/host-center', '/coin-seller', '/invitation-to-register', '/lottery', '/']
|
||||||
'/host-center',
|
|
||||||
'/agency-center',
|
|
||||||
'/coin-seller',
|
|
||||||
'/invitation-to-register',
|
|
||||||
'/lottery',
|
|
||||||
'/',
|
|
||||||
]
|
|
||||||
|
|
||||||
// 计算是否为首页
|
// 计算是否为首页
|
||||||
const isCurrentlyHomePage = computed(() => {
|
const isCurrentlyHomePage = computed(() => {
|
||||||
|
|||||||
@ -13,7 +13,9 @@
|
|||||||
>
|
>
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<div style="display: flex; justify-content: center; align-items: center">
|
<div style="display: flex; justify-content: center; align-items: center">
|
||||||
<div style="margin: 0; font-size: 18px; font-weight: 600; color: #333">Member income</div>
|
<div style="margin: 0; font-size: 18px; font-weight: 600; color: #333">
|
||||||
|
{{ t('team_member') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 日期和类型 -->
|
<!-- 日期和类型 -->
|
||||||
@ -52,7 +54,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
name=""
|
name=""
|
||||||
id=""
|
id=""
|
||||||
placeholder="Please enter the host lD"
|
:placeholder="t('enter_host_id')"
|
||||||
style="
|
style="
|
||||||
width: 100%;
|
width: 100%;
|
||||||
outline: none;
|
outline: none;
|
||||||
@ -64,13 +66,13 @@
|
|||||||
v-model="targetUserId"
|
v-model="targetUserId"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style="font-weight: 600">Cancel</div>
|
<div style="font-weight: 600" @click="$emit('close')">{{ t('cancel') }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 加载成员 -->
|
<!-- 加载成员 -->
|
||||||
<div v-if="loading" class="loading-container">
|
<div v-if="loading" class="loading-container">
|
||||||
<div class="loading-spinner"></div>
|
<div class="loading-spinner"></div>
|
||||||
<p>Loading members...</p>
|
<p>{{ t('loading') }}...</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 成员列表 -->
|
<!-- 成员列表 -->
|
||||||
@ -142,7 +144,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ member.memberProfile?.userNickname || 'Unknown User' }}
|
{{ member.memberProfile?.userNickname || t('unknown_user') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
@ -209,7 +211,7 @@
|
|||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
Time (Days):{{ Math.floor(member.target.onlineTime / 60 / 2, 0) }}
|
{{ t('time_days') }}:{{ Math.floor(member.target.onlineTime / 60 / 2, 0) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -218,15 +220,24 @@
|
|||||||
|
|
||||||
<div v-else class="empty-state">
|
<div v-else class="empty-state">
|
||||||
<div class="empty-icon">👥</div>
|
<div class="empty-icon">👥</div>
|
||||||
<p>No members data available</p>
|
<p>{{ t('no_data_available') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted, watch } from 'vue'
|
import { ref, computed, onMounted, watch } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
import { formatBillStatus, getTeamReleasePolicy } from '../../api/teamBill.js'
|
import { formatBillStatus, getTeamReleasePolicy } from '../../api/teamBill.js'
|
||||||
import { getTeamId } from '../../utils/userStore.js'
|
import { getTeamId } from '../../utils/userStore.js'
|
||||||
|
import { setDocumentDirection } from '@/locales/i18n'
|
||||||
|
|
||||||
|
const { t, locale } = useI18n()
|
||||||
|
|
||||||
|
// 监听语言变化并设置文档方向
|
||||||
|
locale.value && setDocumentDirection(locale.value)
|
||||||
|
|
||||||
|
defineEmits(['close'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
billData: {
|
billData: {
|
||||||
@ -305,17 +316,29 @@ const getTargetLevel = (giftValue) => {
|
|||||||
// 格式化Target显示
|
// 格式化Target显示
|
||||||
const formatTargetDisplay = (giftValue) => {
|
const formatTargetDisplay = (giftValue) => {
|
||||||
if (loadingPolicy.value) {
|
if (loadingPolicy.value) {
|
||||||
return 'Loading...'
|
return t('loading') + '...'
|
||||||
}
|
}
|
||||||
|
|
||||||
const level = getTargetLevel(giftValue)
|
const level = getTargetLevel(giftValue)
|
||||||
return `Target: ${level}`
|
return `${t('target')}: ${level}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化状态文本
|
// 格式化状态文本
|
||||||
const getStatusText = (status) => {
|
const getStatusText = (status) => {
|
||||||
const statusInfo = formatBillStatus(status)
|
const statusInfo = formatBillStatus(status)
|
||||||
return statusInfo.text
|
// 使用翻译键而不是直接文本
|
||||||
|
switch (statusInfo.textKey) {
|
||||||
|
case 'Completed':
|
||||||
|
return t('completed')
|
||||||
|
case 'Pending':
|
||||||
|
return t('pending')
|
||||||
|
case 'Out of account':
|
||||||
|
return t('out_of_account')
|
||||||
|
case 'In Progress':
|
||||||
|
return t('in_progress')
|
||||||
|
default:
|
||||||
|
return statusInfo.textKey
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取状态样式类
|
// 获取状态样式类
|
||||||
@ -370,19 +393,19 @@ watch(
|
|||||||
console.log('status:', status)
|
console.log('status:', status)
|
||||||
|
|
||||||
let newStatus = getStatusText(status)
|
let newStatus = getStatusText(status)
|
||||||
if (newStatus == 'In Progress') {
|
if (newStatus == t('in_progress')) {
|
||||||
boxShadow.value = '0 0 1px 0 #6085FF'
|
boxShadow.value = '0 0 1px 0 #6085FF'
|
||||||
color.value = 'rgba(61, 115, 255, 1)'
|
color.value = 'rgba(61, 115, 255, 1)'
|
||||||
}
|
}
|
||||||
if (newStatus == 'Pending') {
|
if (newStatus == t('pending')) {
|
||||||
boxShadow.value = '0 0 1px 0 #FF6062'
|
boxShadow.value = '0 0 1px 0 #FF6062'
|
||||||
color.value = 'rgba(255, 61, 64, 1)'
|
color.value = 'rgba(255, 61, 64, 1)'
|
||||||
}
|
}
|
||||||
if (newStatus == 'Completed') {
|
if (newStatus == t('completed')) {
|
||||||
boxShadow.value = '0 0 1px 0 #60FF65'
|
boxShadow.value = '0 0 1px 0 #60FF65'
|
||||||
color.value = 'rgba(61, 255, 84, 1)'
|
color.value = 'rgba(61, 255, 84, 1)'
|
||||||
}
|
}
|
||||||
if (newStatus == 'Out Of Account') {
|
if (newStatus == t('out_of_account')) {
|
||||||
boxShadow.value = '0 0 1px 0 #6A6161'
|
boxShadow.value = '0 0 1px 0 #6A6161'
|
||||||
color.value = 'rgba(174, 174, 174, 1)'
|
color.value = 'rgba(174, 174, 174, 1)'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
<!-- 使用 GeneralHeader 替换 MobileHeader -->
|
<!-- 使用 GeneralHeader 替换 MobileHeader -->
|
||||||
<GeneralHeader
|
<GeneralHeader
|
||||||
:title="t('team_bill')"
|
:title="t('team_bill')"
|
||||||
:isHomePage="false"
|
|
||||||
:showLanguageList="true"
|
:showLanguageList="true"
|
||||||
color="black"
|
color="black"
|
||||||
style="box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 999"
|
style="box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); z-index: 999"
|
||||||
@ -69,7 +68,7 @@
|
|||||||
<workReportBox
|
<workReportBox
|
||||||
v-for="bill in billList"
|
v-for="bill in billList"
|
||||||
:key="bill.id"
|
:key="bill.id"
|
||||||
:type="getStatusText(bill.status)"
|
:type="bill.status"
|
||||||
:date="bill.date"
|
:date="bill.date"
|
||||||
:target="bill.target"
|
:target="bill.target"
|
||||||
:salary="bill.salary"
|
:salary="bill.salary"
|
||||||
@ -187,6 +186,17 @@ const loadingPolicy = ref(false)
|
|||||||
const billList = ref([])
|
const billList = ref([])
|
||||||
const selectedBillMembers = ref([])
|
const selectedBillMembers = ref([])
|
||||||
|
|
||||||
|
// 格式化状态
|
||||||
|
const formatStatus = (status) => {
|
||||||
|
const statusMap = {
|
||||||
|
SETTLED: 'Completed',
|
||||||
|
UNPAID: 'In Progress',
|
||||||
|
HANG_UP: 'Out of account',
|
||||||
|
PAY_OUT: 'Completed',
|
||||||
|
}
|
||||||
|
return statusMap[status] || status
|
||||||
|
}
|
||||||
|
|
||||||
// 获取团队账单列表
|
// 获取团队账单列表
|
||||||
const fetchTeamBill = async (teamId) => {
|
const fetchTeamBill = async (teamId) => {
|
||||||
try {
|
try {
|
||||||
@ -202,6 +212,7 @@ const fetchTeamBill = async (teamId) => {
|
|||||||
.toString()
|
.toString()
|
||||||
.substring(4, 6)}`,
|
.substring(4, 6)}`,
|
||||||
target: getTargetLevel(bill.target?.acceptGiftValue), // 使用政策数据计算等级
|
target: getTargetLevel(bill.target?.acceptGiftValue), // 使用政策数据计算等级
|
||||||
|
status: formatStatus(bill.status),
|
||||||
salary:
|
salary:
|
||||||
formatSalaryValue(
|
formatSalaryValue(
|
||||||
userIdentity.body?.agent
|
userIdentity.body?.agent
|
||||||
@ -300,7 +311,19 @@ const fetchBillWorkMembers = async (billId) => {
|
|||||||
// 格式化状态文本
|
// 格式化状态文本
|
||||||
const getStatusText = (status) => {
|
const getStatusText = (status) => {
|
||||||
const statusInfo = formatBillStatus(status)
|
const statusInfo = formatBillStatus(status)
|
||||||
return statusInfo.textKey // 使用翻译键而不是直接文本
|
// 使用翻译键而不是直接文本
|
||||||
|
switch (statusInfo.textKey) {
|
||||||
|
case 'Completed':
|
||||||
|
return t('completed')
|
||||||
|
case 'Pending':
|
||||||
|
return t('pending')
|
||||||
|
case 'Out of account':
|
||||||
|
return t('out_of_account')
|
||||||
|
case 'In Progress':
|
||||||
|
return t('in_progress')
|
||||||
|
default:
|
||||||
|
return statusInfo.textKey
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取状态样式类
|
// 获取状态样式类
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user