bugfix: i18n问题

This commit is contained in:
2026-02-04 16:10:10 +08:00
parent 228e3d56b5
commit 3da4a97400
9 changed files with 242 additions and 120 deletions

View File

@@ -9,7 +9,9 @@
class="form-header"
v-if="!isCompleted && !isExpired"
>
<div class="form-title poppins-bold">{{ t('AwardApply.emailVerification') }}</div>
<div class="form-title poppins-bold">
{{ t('AwardApply.emailVerification') }}
</div>
<div class="desc">{{ t('AwardApply.aidaUsersOnly') }}</div>
</div>
</div>
@@ -63,7 +65,9 @@
</a-form-item>
</div>
<div class="form-row full-row">
<div class="form-title poppins-bold">{{ t('AwardApply.personalInformation') }}</div>
<div class="form-title poppins-bold">
{{ t('AwardApply.personalInformation') }}
</div>
<div class="desc">{{ t('AwardApply.tellUsAboutYourself') }}</div>
</div>
<div class="user-info flex">
@@ -109,8 +113,12 @@
</template>
</div>
<div class="form-row full-row">
<div class="form-title poppins-bold">{{ t('AwardApply.designInformation') }}</div>
<div class="desc">{{ t('AwardApply.shareYourCreativeVision') }}</div>
<div class="form-title poppins-bold">
{{ t('AwardApply.designInformation') }}
</div>
<div class="desc">
{{ t('AwardApply.shareYourCreativeVision') }}
</div>
</div>
<a-form-item
class="full-row design-title"
@@ -137,28 +145,30 @@
/>
</a-form-item>
<div class="form-row full-row">
<div class="form-title poppins-bold">{{ t('AwardApply.submissionFiles') }}</div>
<div class="desc">{{ t('AwardApply.uploadYourDesignMaterials') }}</div>
<div class="form-title poppins-bold">
{{ t('AwardApply.submissionFiles') }}
</div>
<div class="desc">
{{ t('AwardApply.uploadYourDesignMaterials') }}
</div>
</div>
<div class="information full-row">
<div class="information-title flex align-center">
<div class="point"></div>
<div class="text poppins-bold">{{ t('AwardApply.submissionRequirements') }}</div>
<div class="text poppins-bold">
{{ t('AwardApply.submissionRequirements') }}
</div>
</div>
<ul class="information-list flex space-between">
<li class="information-item">
{{
t('AwardApply.pdfRequirement')
}}
{{ t('AwardApply.pdfRequirement') }}
</li>
<div class="right">
<li class="information-item">
{{ t('AwardApply.rightContent.format') }}
</li>
<li class="information-item">
{{
t('AwardApply.rightContent.video')
}}
{{ t('AwardApply.rightContent.video') }}
</li>
</div>
</ul>
@@ -187,8 +197,12 @@
alt=""
class="upload-icon"
/>
<p class="desc">{{ t('AwardApply.clickToUploadPdf') }}</p>
<p class="limit">{{ t('AwardApply.pdfFileLimit') }}</p>
<p class="desc">
{{ t('AwardApply.clickToUploadPdf') }}
</p>
<p class="limit">
{{ t('AwardApply.pdfFileLimit') }}
</p>
<template #itemRender="{ file, actions }">
<div
class="custom-upload-list flex align-center space-between"
@@ -258,7 +272,9 @@
alt=""
class="upload-icon"
/>
<p class="desc">{{ t('AwardApply.clickToUploadVideo') }}</p>
<p class="desc">
{{ t('AwardApply.clickToUploadVideo') }}
</p>
<p class="limit">
{{ t('AwardApply.videoFileLimit') }}
</p>
@@ -308,38 +324,40 @@
</a-form-item>
</div>
</a-form>
<div class="conditions">
<div class="confitions-title poppins-bold">{{ t('AwardApply.termsAndConditions') }}</div>
<div class="condition-list flex flex-col">
<div
class="condition-item flex align-center"
v-for="item in conditionsList"
:key="item.id"
>
<a-checkbox v-model:checked="item.check" />
<span>
{{ t('AwardApply.' + item.translationKey) }}
<span
class="required"
v-if="item.required"
>
*
<div class="conditions">
<div class="confitions-title poppins-bold">
{{ t('AwardApply.termsAndConditions') }}
</div>
<div class="condition-list flex flex-col">
<div
class="condition-item flex align-center"
v-for="item in conditionsList"
:key="item.id"
>
<a-checkbox v-model:checked="item.check" />
<span>
{{ t('AwardApply.' + item.translationKey) }}
<span
class="required"
v-if="item.required"
>
*
</span>
</span>
</span>
</div>
</div>
</div>
</div>
<div class="submit-container">
<div
class="submit-btn poppins-bold"
@click="handleSubmitForm"
>
{{ t('AwardApply.submitYourDesign') }}
<div class="submit-container">
<div
class="submit-btn poppins-bold"
@click="handleSubmitForm"
>
{{ t('AwardApply.submitYourDesign') }}
</div>
<div class="desc">
{{ t('AwardApply.unfinishedFormTip') }}
</div>
</div>
<div class="desc">
{{ t('AwardApply.unfinishedFormTip') }}
</div>
</div>
</div>
</div>
<a-modal
@@ -359,7 +377,11 @@
@click="handleCloseModal"
/>
<div class="title poppins-bold">{{ t('AwardApply.checkYourEmail') }}</div>
<div class="desc">{{ t('AwardApply.enterSixDigitCode') }} {{ form.email }}</div>
<div class="desc">
{{ t('AwardApply.enterSixDigitCode') }}
<br />
<span class="email-verify">{{ form.email }}</span>
</div>
<div class="code-box">
<VerifycationCodeInput
:ct="emailCode"
@@ -379,7 +401,9 @@
>
{{
isCountingDown
? `${t('AwardApply.resendCodeIn')} ${formatCountdown(countdown)}`
? `${t('AwardApply.resendCodeIn')} ${formatCountdown(
countdown
)}`
: t('AwardApply.resendCode')
}}
</div>
@@ -436,6 +460,7 @@
designDescription: '',
pdfPath: '',
videoPath: '',
videoDuration: 0,
secureToken: ''
})
const hasValidEmail = computed(() => {
@@ -493,18 +518,36 @@
const rulesRef = {
email: [{ required: true, validator: validEmail }],
firstName: [
{ required: true, message: t('AwardApply.pleaseInputFirstName'), trigger: 'blur' }
{
required: true,
message: t('AwardApply.pleaseInputFirstName'),
trigger: 'blur'
}
],
lastName: [
{ required: true, message: t('AwardApply.pleaseInputLastName'), trigger: 'blur' }
{
required: true,
message: t('AwardApply.pleaseInputLastName'),
trigger: 'blur'
}
],
gender: [
{ required: true, message: t('AwardApply.pleaseSelectGender'), trigger: 'blur' }
{
required: true,
message: t('AwardApply.pleaseSelectGender'),
trigger: 'blur'
}
],
occupation: [
{ required: true, message: t('AwardApply.pleaseInputOccupation'), trigger: 'blur' }
{
required: true,
message: t('AwardApply.pleaseInputOccupation'),
trigger: 'blur'
}
],
age: [
{ required: true, message: t('AwardApply.pleaseInputAge'), trigger: 'blur' }
],
age: [{ required: true, message: t('AwardApply.pleaseInputAge'), trigger: 'blur' }],
countryRegionCity: [
{
required: true,
@@ -515,7 +558,11 @@
phoneNumber: [{ required: true, validator: validatePhone, trigger: 'blur' }],
designTitle: [
{ required: true, message: t('AwardApply.pleaseInputDesignTitle'), trigger: 'blur' }
{
required: true,
message: t('AwardApply.pleaseInputDesignTitle'),
trigger: 'blur'
}
],
designDescription: [
{
@@ -524,9 +571,15 @@
trigger: 'blur'
}
],
pdfPath: [{ required: true, message: t('AwardApply.pleaseUploadPdf'), trigger: 'null' }],
pdfPath: [
{ required: true, message: t('AwardApply.pleaseUploadPdf'), trigger: 'null' }
],
videoPath: [
{ required: true, message: t('AwardApply.pleaseUploadVideo'), trigger: 'null' }
{
required: true,
message: t('AwardApply.pleaseUploadVideo'),
trigger: 'null'
}
]
}
@@ -760,7 +813,24 @@
}
// 统一的文件上传前验证
const beforeUploadFile = (type: FileType, file: File) => {
// 获取视频时长
const getVideoDuration = (file: File): Promise<number> => {
return new Promise((resolve, reject) => {
const video = document.createElement('video')
video.preload = 'metadata'
video.onloadedmetadata = () => {
window.URL.revokeObjectURL(video.src)
resolve(video.duration)
}
video.onerror = () => {
window.URL.revokeObjectURL(video.src)
reject(new Error('Failed to load video'))
}
video.src = window.URL.createObjectURL(file)
})
}
const beforeUploadFile = async (type: FileType, file: File) => {
if (!hasValidEmail.value) {
message.error(t('AwardApply.pleaseVerifyEmailFirst'))
return Upload.LIST_IGNORE
@@ -792,42 +862,33 @@
if (!isValidType) {
message.error(errorMessage)
// 从文件列表中移除
// if (type === 'pdf') {
// const index = pdfList.value.findIndex(item => item.uid === file.uid)
// if (index > -1) {
// pdfList.value.splice(index, 1)
// }
// } else {
// const index = videoList.value.findIndex(item => item.uid === file.uid)
// if (index > -1) {
// videoList.value.splice(index, 1)
// }
// }
return Upload.LIST_IGNORE
}
// 验证文件大小
if (file.size > maxSize) {
const sizeLimit = type === 'pdf' ? '20MB' : '100MB'
message.error(
t('AwardApply.fileSizeExceeds', { sizeLimit })
)
// 从文件列表中移除
// if (type === 'pdf') {
// const index = pdfList.value.findIndex(item => item.uid === file.uid)
// if (index > -1) {
// pdfList.value.splice(index, 1)
// }
// } else {
// const index = videoList.value.findIndex(item => item.uid === file.uid)
// if (index > -1) {
// videoList.value.splice(index, 1)
// }
// }
message.error(t('AwardApply.fileSizeExceeds', { sizeLimit }))
return Upload.LIST_IGNORE
}
// 验证视频时长
let duration = 0
if (type === 'video') {
duration = await getVideoDuration(file)
try {
if (duration > 60) {
message.error(t('AwardApply.videoDurationExceeds'))
return Upload.LIST_IGNORE
}
} catch (error) {
console.error('Failed to get video duration:', error)
}
}
form.value.videoDuration = Math.ceil(duration)
return true
}
@@ -933,7 +994,9 @@
const status = info.file.status
if (status === 'done') {
message.success(t('AwardApply.fileUploadedSuccess', { fileName: info.file.name }))
message.success(
t('AwardApply.fileUploadedSuccess', { fileName: info.file.name })
)
if (type === 'pdf') {
isUploadingPdf.value = false
uploadProgressPdf.value = 0
@@ -957,9 +1020,9 @@
}
}
// 统一的上传处理函数
const handleUploadFile = async (option: any, type: FileType) => {
const file = option.file as File
//
if (!form.value.email) {
message.error(t('AwardApply.pleaseInputEmail'))
@@ -1247,7 +1310,7 @@
}
}
// :deep(.ant-select-arrow) {
// justify-content: center;
// display: flex;
// align-items: center;
@@ -1552,6 +1615,13 @@
font-size: 1.6rem;
line-height: 3.4rem;
margin-top: 1.4rem;
text-align: center;
.email-verify {
color: #232323;
font-family: 'ArialBold';
font-weight: 700;
font-size: 1.6rem;
}
}
.email {

View File

@@ -202,6 +202,9 @@ onBeforeUnmount(() => {
column-gap: 23.22rem;
row-gap: 8rem;
padding: 0 25rem 0 26.6rem;
div{
text-align: center;
}
.judgement-item {
overflow: hidden;
.picture {

View File

@@ -52,6 +52,13 @@
const { t } = useI18n()
const props = defineProps({
isZh: {
type: Boolean,
default: false
}
})
const prizes = [
{
money: 'AwardsPage.grandMoney',
@@ -83,11 +90,8 @@
{
money: 'AwardsPage.awardCertification',
name: 'AwardsPage.finalists',
desc: [
'AwardsPage.TravelAllowance',
'AwardsPage.globalMediaExposure'
],
smaller: true
desc: ['AwardsPage.TravelAllowance', 'AwardsPage.globalMediaExposure'],
smaller: !props.isZh
}
]

View File

@@ -83,12 +83,12 @@
class="close-icon"
@click="handleCloseQRcode"
/>
<div class="code-title">WeChat Official Account</div>
<div class="code-title">{{ $t('AwardsPage.wechatTitle') }}</div>
<img
src="@/assets/images/award/qrcode.jpg"
class="qrcode"
/>
<div class="tips">Scan the QR code in WeChat</div>
<div class="tips">{{ $t('AwardsPage.wechatDesc') }}</div>
</div>
</div>
</div>

View File

@@ -1,8 +1,11 @@
<template>
<div class="award-page">
<div
class="award-page"
:class="{ 'is-zh': isZh }"
>
<div class="banner">
<video
src="@/assets/images/award/banner.mp4"
:src="bannerUrl"
autoplay
muted
loop
@@ -11,32 +14,33 @@
webkit-playsinline
x5-playsinline
></video>
<div
class="submit-btn flex flex-center"
@click="handleSubmitApplication"
>
<div>{{ $t('AwardsPage.submitApplication') }}</div>
<img
src="@/assets/images/award/arrow_right.png"
alt=""
class="arrow"
/>
<div class="ddl">{{ $t('AwardsPage.applicationDeadline') }}</div>
</div>
<div
class="submit-btn flex flex-center"
@click="handleSubmitApplication"
>
<div>{{ $t('AwardsPage.submitApplication') }}</div>
<img
src="@/assets/images/award/arrow_right.png"
alt=""
class="arrow"
/>
<div class="ddl">{{ $t('AwardsPage.applicationDeadline') }}</div>
</div>
</div>
<Slogan />
<Bloom />
<TimeLine />
<JudgesSection />
<PrizesSection />
<PrizesSection :is-zh="isZh" />
<ApplySection />
<SelectionSection />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import JudgesSection from './components/JudgesSection.vue'
import SelectionSection from './components/SelectionSection.vue'
@@ -46,7 +50,19 @@
import Bloom from './components/Bloom.vue'
import Slogan from './components/Slogan.vue'
import banner from '@/assets/images/award/banner.mp4'
import bannerZh from '@/assets/images/award/banner_chinese.mp4'
const router = useRouter()
const { locale } = useI18n()
const isZh = computed(() => {
return locale.value === 'CHINESE_SIMPLIFIED'
})
const bannerUrl = computed(() => {
return isZh.value ? bannerZh : banner
})
const handleSubmitApplication = () => {
router.push('/award/contestants')
@@ -110,4 +126,18 @@
}
}
}
.is-zh {
.submit-btn {
padding: 0 7.5rem;
height: 7.8rem;
border-radius: 7.74rem;
column-gap: 3.8rem;
// justify-content: space-between;
&,
.ddl {
width: 35.4rem;
}
}
}
</style>