Merge branch 'dev_vite' of ssh://18.167.251.121:10002/aidlab/aida_front into dev_vite

This commit is contained in:
X1627315083
2026-02-02 13:48:09 +08:00
4 changed files with 168 additions and 84 deletions

View File

@@ -0,0 +1 @@
<svg focusable="false" class="" data-icon="paper-clip" width="1em" height="1em" fill="#00000073" aria-hidden="true" viewBox="64 64 896 896"><path d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 00174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"></path></svg>

After

Width:  |  Height:  |  Size: 985 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -13,7 +13,10 @@
<div class="desc">AiDA Users Only</div>
</div>
</div>
<Success :isExpired="isExpired" v-if="isCompleted || isExpired" />
<Success
:isExpired="isExpired"
v-if="isCompleted || isExpired"
/>
<div
class="form-container"
v-if="!isCompleted && !isExpired"
@@ -36,6 +39,7 @@
<div class="email-wrapper flex align-center">
<a-input v-model:value="form.email" />
<div
v-if="!hasValidEmail"
class="code-btn"
:class="{ disabled: isCountingDown }"
@click="handleSendCode"
@@ -157,19 +161,15 @@
:validate-trigger="[]"
label="How will you use AiDA in your design process?"
>
<div
v-if="
pdfUploadStatus === 'idle' ||
pdfUploadStatus === 'error'
"
>
<div>
<a-upload-dragger
v-model:fileList="pdfList"
:disabled="readOnly"
:showUploadList="false"
:maxCount="1"
@change="info => handleFileChange(info, 'pdf')"
:customRequest="handleUploadPdf"
:beforeUpload="beforeUploadPdf"
@remove="handleRemoveFile('pdf')"
accept=".pdf"
>
<img
@@ -179,25 +179,48 @@
/>
<p class="desc">Click to upload or drag and drop</p>
<p class="limit">PDF file, max 20MB</p>
<template #itemRender="{ file, actions }">
<div
class="custom-upload-list flex align-center space-between"
>
<div class="flex align-center">
<SvgIcon name="CFile" />
{{ file.name }}
</div>
<div
@click="actions.remove"
class="delete-file"
title="delete file"
>
<SvgIcon
name="CDelete"
color="red"
/>
</div>
</div>
</template>
</a-upload-dragger>
</div>
<div
v-else
v-show="
pdfUploadStatus === 'uploading' ||
pdfUploadStatus === 'success'
"
class="uploading-container"
>
<UploadStatus
:status="pdfUploadStatus"
type="pdf"
/>
</div>
<div
class="progress-bar-container"
v-if="pdfUploadStatus === 'uploading'"
>
<div
class="progress-bar"
:style="{ width: `${uploadProgressPdf}%` }"
></div>
class="progress-bar-container"
v-if="pdfUploadStatus === 'uploading'"
>
<div
class="progress-bar"
:style="{ width: `${uploadProgressPdf}%` }"
></div>
</div>
</div>
</a-form-item>
</div>
@@ -209,23 +232,19 @@
:validate-trigger="[]"
label="How will you use AiDA in your design process?"
>
<div
v-if="
videoUploadStatus === 'idle' ||
videoUploadStatus === 'error'
"
>
<div>
<a-upload-dragger
v-model:fileList="videoList"
:showUploadList="false"
:disabled="readOnly"
:maxCount="1"
@change="info => handleFileChange(info, 'video')"
:customRequest="handleUploadVideo"
:beforeUpload="beforeUploadVideo"
@remove="handleRemoveFile('video')"
accept=".mp4,.mov"
>
<img
src="@/assets/images/award/upload.png"
src="@/assets/images/award/upload_video_icon.png"
alt=""
class="upload-icon"
/>
@@ -233,25 +252,48 @@
<p class="limit">
Video file (MP4, MOV), 1080p, max 100MB
</p>
<template #itemRender="{ file, actions }">
<div
class="custom-upload-list flex align-center space-between"
>
<div class="flex align-center">
<SvgIcon name="CFile" />
{{ file.name }}
</div>
<div
@click="actions.remove"
class="delete-file"
title="delete file"
>
<SvgIcon
name="CDelete"
color="red"
/>
</div>
</div>
</template>
</a-upload-dragger>
</div>
<div
v-else
v-show="
videoUploadStatus === 'success' ||
videoUploadStatus === 'uploading'
"
class="uploading-container"
>
<UploadStatus
:status="videoUploadStatus"
type="video"
/>
</div>
<div
class="progress-bar-container"
v-if="videoUploadStatus === 'uploading'"
>
<div
class="progress-bar"
:style="{ width: `${uploadProgressVideo}%` }"
></div>
class="progress-bar-container"
v-if="videoUploadStatus === 'uploading'"
>
<div
class="progress-bar"
:style="{ width: `${uploadProgressVideo}%` }"
></div>
</div>
</div>
</a-form-item>
</div>
@@ -342,7 +384,7 @@
import { ref, onUnmounted, onMounted, computed } from 'vue'
import { debounce } from 'lodash-es'
import type { Rule } from 'ant-design-vue/es/form'
import { message } from 'ant-design-vue'
import { message, Upload } from 'ant-design-vue'
import { Https } from '@/tool/https'
import { useRoute } from 'vue-router'
import type { UploadChangeParam } from 'ant-design-vue'
@@ -359,7 +401,7 @@
const route = useRoute()
const isCompleted = ref(false)
const hasValidEmail = ref(false)
const readOnly = computed(() => {
if (route.query.id && !hasValidEmail.value) {
return true
@@ -369,7 +411,7 @@
})
const formRef = ref(null)
const form = ref({
email: '',
email: 'yhzhang@aidlab.hk',
firstName: '',
lastName: '',
gender: '',
@@ -383,7 +425,10 @@
designDescription: '',
pdfPath: '',
videoPath: '',
secureToken: null
secureToken: ''
})
const hasValidEmail = computed(() => {
return !!form.value.secureToken
})
// 验证码输入组件引用
@@ -620,7 +665,6 @@
console.log('coderes', res)
form.value.secureToken = res.data.secureToken
hasValidEmail.value = true
message.success('Verification successful!')
showModal.value = false
@@ -675,7 +719,7 @@
const beforeUploadFile = (type: FileType, file: File) => {
if (!hasValidEmail.value) {
message.error('Please verify your email first')
return false
return Upload.LIST_IGNORE
}
let maxSize: number
let allowedExtensions: string[]
@@ -693,7 +737,7 @@
allowedMimeTypes = ['video/mp4', 'video/quicktime']
errorMessage = 'Please upload a MP4 or MOV file only.'
} else {
return false
return Upload.LIST_IGNORE
}
// 验证文件类型
@@ -705,18 +749,18 @@
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 false // 阻止上传
// 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
}
// 验证文件大小
@@ -726,21 +770,21 @@
`File size exceeds ${sizeLimit} limit. Please upload a smaller file.`
)
// 从文件列表中移除
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 false // 阻止上传
// 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
}
return true // 允许上传
return true
}
// PDF文件上传前验证
@@ -822,18 +866,22 @@
}
const completeChunkUpload = async (type: FileType, file: File) => {
const endpoint =
type === 'pdf'
? Https.httpUrls.uploadPDFComplete
: Https.httpUrls.uploadVideoComplete
try {
const endpoint =
type === 'pdf'
? Https.httpUrls.uploadPDFComplete
: Https.httpUrls.uploadVideoComplete
return Https.axiosPost(endpoint, {
uploadId: chunkUploadState[type].uploadId,
email: form.value.email,
fileName: file.name,
totalSize: file.size,
secureToken: form.value.secureToken
})
return Https.axiosPost(endpoint, {
uploadId: chunkUploadState[type].uploadId,
email: form.value.email,
fileName: file.name,
totalSize: file.size,
secureToken: form.value.secureToken
})
} catch (error) {
console.log('complete错误', error)
}
}
type FileType = 'pdf' | 'video'
@@ -922,10 +970,12 @@
isUploadingPdf.value = false
uploadProgressPdf.value = 0
pdfUploadStatus.value = 'error'
pdfList.value = []
} else {
isUploadingVideo.value = false
uploadProgressVideo.value = 0
videoUploadStatus.value = 'error'
videoList.value = []
}
}
}
@@ -940,6 +990,18 @@
return handleUploadFile(option, 'video')
}
const handleRemoveFile = (type: 'video' | 'pdf') => {
if (type === 'pdf') {
form.value.pdfPath = ''
pdfUploadStatus.value = 'idle'
uploadProgressPdf.value = 0
} else if (type === 'video') {
form.value.videoPath = ''
videoUploadStatus.value = 'idle'
uploadProgressVideo.value = 0
}
}
const conditionsList = ref([
{
check: false,
@@ -1238,9 +1300,10 @@
.upload-container {
margin-top: 6rem;
position: relative;
:deep(.ant-upload-drag) {
height: 32rem;
border-radius: 0.8rem;
.ant-upload-btn {
padding: 0;
@@ -1276,9 +1339,13 @@
display: flex;
align-items: center;
justify-content: center;
border: 0.2rem solid #d5d5d5;
border: 0.2rem dashed #d5d5d5;
border-radius: 0.8rem;
background-color: #fafafa;
position: absolute;
top: 0;
left: 0;
width: 100%;
.uploading-text {
color: #585858;
@@ -1306,7 +1373,20 @@
}
}
}
.custom-upload-list {
padding: 0.4rem 1rem;
margin-top: 1rem;
&:hover {
background-color: #f5f5f5;
border-radius: 0.4rem;
}
.c-svg {
width: fit-content;
}
.delete-file {
cursor: pointer;
}
}
.conditions {
margin-top: 12rem;
@@ -1462,9 +1542,12 @@
</style>
<style lang="less">
.code-modal {
.ant-modal-content .ant-modal-body {
padding: 0;
// width: 60rem;
.ant-modal-content {
width: 60rem;
height: 49.4rem;
.ant-modal-body {
padding: 0;
}
}
}
</style>

View File

@@ -35,7 +35,7 @@
return {
icon: expiredIcon,
title: 'Application Deadline Passed',
desc: 'The submission deadline for AIDA Global Fashion Award 2026 has ended.\nWe are no longer accepting new applications. '
desc: 'The submission deadline for AiDA Global Fashion Award 2026 has ended.\nWe are no longer accepting new applications. '
}
} else {
return {