feat: 语言切换和布局配置

This commit is contained in:
hzj 2025-10-29 21:23:23 +08:00
parent 92b0e65a85
commit 620dca97b0
3 changed files with 336 additions and 180 deletions

View File

@ -16,7 +16,12 @@
<!-- 返回键 -->
<div style="width: 10%; display: flex; align-items: center">
<button v-if="showBack" class="back-btn" @click="handleBack">
<img :src="backImg" alt="" style="width: 100%; aspect-ratio: 1/1; display: block" />
<img
class="flipImg"
:src="backImg"
alt=""
style="width: 100%; aspect-ratio: 1/1; display: block"
/>
</button>
</div>
@ -75,6 +80,7 @@
border-radius: 10px;
margin-top: 5px;
backdrop-filter: blur(8px);
z-index: 999999;
"
v-show="visibleList"
class="extraList"
@ -235,6 +241,10 @@ onMounted(() => {
transform: scale(0.9);
}
[dir='rtl'] .flipImg {
transform: scaleX(-1);
}
@media screen and (max-width: 360px) {
* {
font-size: 10px;

View File

@ -1,21 +1,7 @@
<template>
<div style="position: relative; width: 100%">
<img :src="whiteBox" alt="" width="100%" style="display: block" />
<div
style="
width: 48%;
height: 46%;
border-radius: 12px;
margin: 2.5%;
position: absolute;
top: 0;
right: 0;
z-index: -1;
display: flex;
justify-content: flex-end;
"
:style="{ backgroundImage }"
>
<img class="flipImg" :src="whiteBox" alt="" width="100%" style="display: block" />
<div :style="{ backgroundImage }" class="status-background">
<div
style="width: 50%; height: 50%; display: flex; justify-content: center; align-items: center"
>
@ -28,12 +14,12 @@
>
<div class="contentTime">{{ date }}</div>
<div style="display: grid; grid-template-columns: repeat(2, 1fr)">
<div class="contentText">Target: {{ target }}</div>
<div class="contentText">Salary: ${{ salary }}</div>
<div class="contentText">{{ t('target') }}: {{ target }}</div>
<div class="contentText">{{ t('salary') }}: ${{ salary }}</div>
</div>
<div style="display: grid; grid-template-columns: repeat(2, 1fr)">
<div class="contentText">Time(Days):{{ days }}</div>
<div class="contentText" v-if="income">Total income:{{ income }}</div>
<div class="contentText">{{ t('time_days') }}: {{ days }}</div>
<div class="contentText" v-if="income">{{ t('total_income') }}: {{ income }}</div>
</div>
</div>
<div
@ -42,7 +28,7 @@
style="position: absolute; bottom: 8%; right: 4%; color: #bb92ff; font-weight: 500"
@click="btMore"
>
More >
{{ t('more') }} >
</div>
</div>
</div>
@ -50,6 +36,9 @@
<script setup>
import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const whiteBox = new URL('../../assets/images/HostCenter/whitebox.png', import.meta.url).href
const props = defineProps({
@ -100,19 +89,19 @@ const fontSize = ref('')
watch(
() => props.type,
(newType) => {
if (newType == 'In Progress') {
if (newType == t('in_progress')) {
backgroundImage.value = 'linear-gradient(112deg, #759CFF 5.66%, #3D73FF 42.49%)'
fontSize.value = '0.9em'
}
if (newType == 'Pending') {
if (newType == t('pending')) {
backgroundImage.value = 'linear-gradient(112deg, #FF7578 5.66%, #FF3D40 42.49%)'
fontSize.value = '1em'
}
if (newType == 'Completed') {
if (newType == t('completed')) {
backgroundImage.value = 'linear-gradient(112deg, #75FF98 5.66%, #3DFF54 42.49%)'
fontSize.value = '1em'
}
if (newType == 'Out Of Account') {
if (newType == t('out_of_account')) {
backgroundImage.value = 'linear-gradient(112deg, #BDBDBD 5.66%, #AEAEAE 42.49%)'
fontSize.value = '0.7em'
}
@ -146,6 +135,43 @@ watch(
font-size: 1em;
}
.flipImg {
width: 100%;
height: auto;
}
.status-background {
width: 48%;
height: 46%;
border-radius: 12px;
margin: 2.5%;
position: absolute;
top: 0;
right: 0;
z-index: -1;
display: flex;
justify-content: flex-end;
}
[dir='rtl'] .flipImg {
transform: scaleX(-1);
}
[dir='rtl'] .status-background {
right: auto;
left: 0;
}
/* RTL支持 */
[dir='rtl'] .contentText {
text-align: right;
}
[dir='rtl'] .moreBt {
right: auto;
left: 4%;
}
@media screen and (max-width: 360px) {
* {
font-size: 10px;

View File

@ -1,41 +1,27 @@
<template>
<div class="host-center gradient-background-circles">
<!-- 顶部导航 -->
<MobileHeader title="Host Center" :isHomePage="true" />
<GeneralHeader
:title="t('host_center')"
:isHomePage="true"
:showLanguageList="true"
color="black"
style="border-bottom: 1px solid #e5e5e5; z-index: 999"
@help="goToHelp"
/>
<!-- 主要内容 -->
<div class="content">
<!-- 身份 -->
<div
style="
margin: 0 1%;
margin-bottom: 12px;
font-weight: 600;
display: flex;
align-items: center;
font-size: 1.3em;
"
>
My account
<img src="../assets/icon/host.png" alt="" height="20px" style="margin-left: 10px" />
<div class="section-title">
{{ t('my_account') }}
<img src="../assets/icon/host.png" alt="" class="title-icon" />
</div>
<!-- 用户信息卡片 -->
<div
style="
background-color: white;
padding: 16px;
border-radius: 12px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
margin: 0 1%;
margin-bottom: 12px;
display: flex;
flex-direction: column;
justify-content: space-between;
"
>
<div class="user-card">
<!-- 头像信息 -->
<div style="display: flex; align-items: center; margin-bottom: 12px">
<div class="user-header">
<div class="avatar">
<img
v-if="userInfo.userAvatar"
@ -45,126 +31,64 @@
/>
<span v-else class="avatar-placeholder">{{ getAvatarPlaceholder() }}</span>
</div>
<div style="flex: 1">
<div style="margin: 0 0 4px 0; font-size: 16px; font-weight: 600; color: #333">
{{ userInfo.userNickname || userInfo.name }}
</div>
<div style="margin: 0; font-size: 14px; color: #666">ID: {{ userInfo.id }}</div>
<div class="user-info">
<div class="user-name">{{ userInfo.userNickname || userInfo.name }}</div>
<div class="user-id">ID: {{ userInfo.id }}</div>
</div>
<button
style="width: 32px; height: 32px; border: none; background: none; font-size: 16px"
@click="goToNotification"
>
<img src="../assets/icon/edit.png" alt="" width="70%" />
<button class="edit-btn" @click="goToNotification">
<img src="../assets/icon/edit.png" alt="" class="edit-icon" />
</button>
</div>
<!-- 我的薪资 -->
<div>
<div style="display: flex; justify-content: space-between; margin-bottom: 5px">
<div style="font-weight: 600">My salary:</div>
<button
style="
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
border: 0;
background-color: transparent;
"
@click="showDatePicker"
>
Personal Salary >
<div class="salary-section">
<div class="salary-header">
<div class="salary-title">{{ t('my_salary') }}</div>
<button class="salary-link" @click="showDatePicker">
{{ t('personal_salary') }}
</button>
</div>
</div>
<!-- 历史薪资 -->
<div style="display: grid; grid-template-columns: repeat(2, 1fr)">
<div>
<div style="font-weight: 500; color: rgba(0, 0, 0, 0.4); margin-bottom: 5px">
History Salary:
</div>
<div style="font-weight: 600">${{ salaryInfo.hostSalary }}</div>
<div class="salary-grid">
<div class="salary-item">
<div class="salary-label">{{ t('history_salary') }}</div>
<div class="salary-value">${{ salaryInfo.hostSalary }}</div>
</div>
<div>
<div style="font-weight: 500; color: rgba(0, 0, 0, 0.4); margin-bottom: 5px">
Current Salary:
</div>
<div style="font-weight: 600">${{ salaryInfo.currentSalary }}</div>
<div class="salary-item">
<div class="salary-label">{{ t('current_salary') }}</div>
<div class="salary-value">${{ salaryInfo.currentSalary }}</div>
</div>
</div>
</div>
<!-- 今日任务 -->
<div
style="
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 5px;
background-color: white;
padding: 3%;
border-radius: 12px;
margin: 0 1%;
margin-bottom: 12px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
"
>
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 600">Today's Task:</div>
<button
style="
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
border: 0;
background-color: transparent;
"
@click="goToPlatformPolicy"
>
Platform Policy >
<div class="task-card">
<div class="task-header">
<div class="task-title">{{ t('todays_task') }}</div>
<button class="policy-link" @click="goToPlatformPolicy">
{{ t('platform_policy') }}
</button>
</div>
<div style="display: flex">
<div style="flex: 1">
<div
style="
width: max-content;
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
"
>
<div style="font-weight: 600">Anchor Type</div>
<div style="font-weight: 600">{{ taskInfo.anchorType }}</div>
</div>
<div class="task-content">
<div class="task-item">
<div class="task-label">{{ t('host_type') }}</div>
<div class="task-value">{{ taskInfo.anchorType }}</div>
</div>
<div
style="flex: 1; display: flex; flex-direction: column; align-items: center; gap: 5px"
>
<div style="font-weight: 600">Minutes</div>
<div style="font-weight: 600">
{{ taskInfo.minutesProgress }}/{{ taskInfo.minutesTotal }}
</div>
<div class="task-item">
<div class="task-label">{{ t('minutes') }}</div>
<div class="task-value">{{ taskInfo.minutesProgress }}/{{ taskInfo.minutesTotal }}</div>
</div>
<div style="flex: 1; 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">Gift Task</div>
<div style="font-weight: 600">{{ taskInfo.giftTask }}</div>
</div>
<div class="task-item">
<div class="task-label">{{ t('gift_task') }}</div>
<div class="task-value">{{ taskInfo.giftTask }}</div>
</div>
</div>
</div>
<!-- 进度信息 -->
<workReportBox
style="margin-bottom: 10px"
class="work-report"
:type="progressInfo.status"
:date="progressInfo.date"
:target="progressInfo.target"
@ -175,13 +99,12 @@
<!-- 操作按钮 -->
<div class="action-buttons">
<button class="action-btn exchange-btn" @click="exchangeGoldCoins">Exchange</button>
<button class="action-btn transfer-btn" @click="transfer">Transfer</button>
<!--
<button class="action-btn withdraw-btn" @click="cashWithdraw">
Cash<br>Withdraw
<button class="action-btn exchange-btn" @click="exchangeGoldCoins">
{{ t('exchange') }}
</button>
<button class="action-btn transfer-btn" @click="transfer">
{{ t('transfer') }}
</button>
-->
</div>
</div>
</div>
@ -189,8 +112,9 @@
<script setup>
import { onMounted, reactive } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import MobileHeader from '../components/MobileHeader.vue'
import GeneralHeader from '@/components/GeneralHeader.vue'
import { usePageInitializationWithConfig } from '@/utils/pageConfig.js'
import { isInApp } from '@/utils/appBridge.js'
import { getTeamMemberWork } from '@/api/teamBill.js'
@ -198,9 +122,14 @@ import { getUserId } from '@/utils/userStore.js'
import { getUserIdentity } from '@/api/wallet.js'
import { clearSelectedPayee } from '../utils/payeeStore.js'
import workReportBox from '@/components/HostCenter/workReportBox.vue'
import { setDocumentDirection } from '@/locales/i18n'
const { t, locale } = useI18n()
const router = useRouter()
//
locale.value && setDocumentDirection(locale.value)
//
const progressInfo = reactive({
date: '',
@ -241,10 +170,10 @@ const fetchMemberWorkData = async () => {
//
const formatStatus = (status) => {
const statusMap = {
SETTLED: 'Completed',
UNPAID: 'In Progress',
HANG_UP: 'Out of Account',
PAY_OUT: 'Completed',
SETTLED: t('completed'),
UNPAID: t('in_progress'),
HANG_UP: t('out_of_account'),
PAY_OUT: t('completed'),
}
return statusMap[status] || status
}
@ -304,6 +233,11 @@ const goToNotification = () => {
router.push('/host-setting')
}
const goToHelp = () => {
//
console.log('Help clicked')
}
const exchangeGoldCoins = () => {
router.push('/exchange-gold-coins')
}
@ -331,20 +265,50 @@ onMounted(() => {
font-family: 'SF Pro Text';
}
.host-center {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
width: 100vw;
min-height: 100vh;
background-color: #ffffff;
background-image: url(../assets/images/secondBg.png);
}
.content {
padding: 16px;
position: relative;
z-index: 2;
}
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
.section-title {
margin: 0 1%;
margin-bottom: 12px;
font-weight: 600;
display: flex;
align-items: center;
font-size: 1.3em;
}
.title-icon {
height: 20px;
margin-left: 10px;
}
.user-card {
background-color: white;
padding: 16px;
border-radius: 12px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
margin: 0 1%;
margin-bottom: 12px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.user-header {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.avatar {
@ -376,27 +340,132 @@ onMounted(() => {
font-weight: 600;
}
/* 任务区域头部样式 */
.task-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.user-info {
flex: 1;
}
.task-header h3 {
margin: 0;
.user-name {
margin: 0 0 4px 0;
font-size: 16px;
font-weight: 600;
color: #333;
}
/* 任务表格 */
.task-table {
border: 1px solid #e5e7eb;
border-radius: 8px;
overflow: hidden;
.user-id {
margin: 0;
font-size: 14px;
color: #666;
}
.edit-btn {
width: 32px;
height: 32px;
border: none;
background: none;
font-size: 16px;
}
.edit-icon {
width: 70%;
}
.salary-section {
margin-bottom: 10px;
}
.salary-header {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
.salary-title {
font-weight: 600;
}
.salary-link {
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
border: 0;
background-color: transparent;
cursor: pointer;
}
.salary-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.salary-item {
display: flex;
flex-direction: column;
}
.salary-label {
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
margin-bottom: 5px;
}
.salary-value {
font-weight: 600;
}
.task-card {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 5px;
background-color: white;
padding: 3%;
border-radius: 12px;
margin: 0 1%;
margin-bottom: 12px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
}
.task-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.task-title {
font-weight: 600;
}
.policy-link {
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
border: 0;
background-color: transparent;
cursor: pointer;
}
.task-content {
display: flex;
justify-content: space-between;
}
.task-item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.task-label {
font-weight: 600;
margin-bottom: 5px;
}
.task-value {
font-weight: 600;
}
.work-report {
margin-bottom: 10px;
}
/* 操作按钮 */
@ -404,6 +473,7 @@ onMounted(() => {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin: 0 1%;
}
.action-btn {
@ -416,6 +486,7 @@ onMounted(() => {
line-height: 1.2;
transition: all 0.2s;
width: 100%;
cursor: pointer;
}
.action-btn:active {
@ -438,6 +509,16 @@ onMounted(() => {
color: white;
}
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
@media screen and (max-width: 360px) {
* {
font-size: 10px;
@ -455,4 +536,43 @@ onMounted(() => {
font-size: 24px;
}
}
/* RTL支持 */
[dir='rtl'] .section-title {
text-align: right;
}
[dir='rtl'] .avatar {
margin-right: 0;
margin-left: 12px;
}
[dir='rtl'] .title-icon {
margin-left: 0;
margin-right: 10px;
}
[dir='rtl'] .user-header {
/* flex-direction: row-reverse; */
}
[dir='rtl'] .user-info {
text-align: right;
}
[dir='rtl'] .salary-header {
/* flex-direction: row-reverse; */
}
[dir='rtl'] .task-header {
/* flex-direction: row-reverse; */
}
[dir='rtl'] .task-content {
/* flex-direction: row-reverse; */
}
[dir='rtl'] .action-buttons {
grid-template-columns: 1fr 1fr;
}
</style>