123
This commit is contained in:
parent
fb9d83b2a6
commit
a3984facfe
@ -28,3 +28,11 @@ export const uploadFile = (data) => {
|
||||
data,
|
||||
})
|
||||
}
|
||||
export const competitionWorks = (data) => {
|
||||
return request({
|
||||
isFormData:true,
|
||||
url: '/api/children/competition/works',
|
||||
method: 'POST',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
BIN
src/assets/image/zu3222@2x.png
Normal file
BIN
src/assets/image/zu3222@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
src/assets/image/zu3316@2x.png
Normal file
BIN
src/assets/image/zu3316@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
@ -4,9 +4,13 @@ import App from './App.vue'
|
||||
import '@unocss/reset/sanitize/sanitize.css'
|
||||
import '@unocss/reset/sanitize/assets.css'
|
||||
import 'virtual:uno.css'
|
||||
import { ImagePreview } from 'vant';
|
||||
|
||||
import router from "./router/index.js";
|
||||
const app = createApp(App);
|
||||
app.use(router);
|
||||
app.use(ImagePreview);
|
||||
|
||||
app.directive('no-space', {
|
||||
mounted(el) {
|
||||
el.addEventListener('input', (e) => {
|
||||
|
@ -20,6 +20,11 @@ const routes = [
|
||||
name: 'confirm',
|
||||
component: () => import('@/views/confirm/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/details',
|
||||
name: 'details',
|
||||
component: () => import('@/views/details/index.vue')
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import Request from '@/service/request/index.js'
|
||||
import {message} from "@/utils/message.js";
|
||||
const request = new Request({
|
||||
baseURL: import.meta.env.VITE_BASEURL,
|
||||
timeout: 1000 * 60 * 5,
|
||||
@ -20,6 +21,9 @@ const request = new Request({
|
||||
},
|
||||
//实例的响应拦截器
|
||||
responseInterceptors: async (response) => {
|
||||
if (response.data.status===1){
|
||||
message.warning(response.data.msg)
|
||||
}
|
||||
if ([200, 201, 204].includes(response.status)) {
|
||||
return response.config.responseType === 'blob' ? response : response;
|
||||
} else {
|
||||
|
@ -1,16 +1,16 @@
|
||||
import {ref,computed} from 'vue'
|
||||
import {createGlobalState,useStorage} from '@vueuse/core'
|
||||
import {competitionApply, loginRegister, sendCode} from '@/api/auth/index.js'
|
||||
import {competitionApply, competitionWorks, loginRegister, sendCode} from '@/api/auth/index.js'
|
||||
import {message} from "@/utils/message.js"
|
||||
import { useRouter } from 'vue-router';
|
||||
export const useAuth=createGlobalState(()=>{
|
||||
|
||||
const router = useRouter();
|
||||
const token = useStorage('token', '', localStorage)
|
||||
const telNum =ref('')
|
||||
const telNum =useStorage('telNum', '', localStorage)
|
||||
const code=ref('')
|
||||
const countdown = ref(0);
|
||||
const isCountingDown = ref(false);
|
||||
const countdown = ref(0)
|
||||
const isCountingDown = ref(false)
|
||||
const showTextCode=computed(()=>{
|
||||
return isCountingDown.value ? `${countdown.value}s` : '获取验证码'
|
||||
})
|
||||
@ -18,20 +18,38 @@ export const useAuth=createGlobalState(()=>{
|
||||
{text:'男',value:'男'},
|
||||
{text:'女',value:'女'}
|
||||
])
|
||||
|
||||
const formData=ref({
|
||||
// 验证 formData 中的字段
|
||||
function validateFormData() {
|
||||
// 验证基本信息
|
||||
const baseFields = ['name', 'age', 'gender'];
|
||||
if (baseFields.some(field => !Boolean(formData.value[field]))) {
|
||||
return false;
|
||||
}
|
||||
// 验证 works 数组中的每一个作品
|
||||
if (formData.value.works.some(work =>
|
||||
!Boolean(work.picUrl) ||
|
||||
!Boolean(work.workName) ||
|
||||
!Boolean(work.length) ||
|
||||
!Boolean(work.wide))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const detailData=useStorage('detailData', {}, localStorage)
|
||||
const formData=useStorage('formData',{
|
||||
name:'',
|
||||
age:'',
|
||||
gender:'',
|
||||
works:[
|
||||
{
|
||||
imgList:[],
|
||||
picUrl: "", //作品图片url
|
||||
workName: "", //作品名称
|
||||
length: undefined, //长度
|
||||
wide:undefined//宽度
|
||||
}
|
||||
]
|
||||
})
|
||||
},localStorage)
|
||||
const clickAddWorks=()=>{
|
||||
formData.value.works.push({
|
||||
picUrl: "", //作品图片url
|
||||
@ -44,15 +62,32 @@ export const useAuth=createGlobalState(()=>{
|
||||
formData.value.works.splice(index,1)
|
||||
}
|
||||
const clickApply=async ()=>{
|
||||
const isValid = validateFormData();
|
||||
if (!isValid){
|
||||
message.warning('作品信息不全,请补充')
|
||||
return
|
||||
}
|
||||
const data={
|
||||
...formData.value
|
||||
}
|
||||
const res=await competitionApply(data)
|
||||
if(res.status===0){
|
||||
message.success('报名成功')
|
||||
router.push('/confirm')
|
||||
}
|
||||
}
|
||||
let timer = null;
|
||||
const getDetail=async ()=>{
|
||||
if (!telNum.value){
|
||||
message.error('获取手机号失败')
|
||||
return
|
||||
}
|
||||
const res=await competitionWorks({telNum:telNum.value})
|
||||
if (res.status===0){
|
||||
console.log(res.data,'getDetail')
|
||||
detailData.value=res.data
|
||||
}
|
||||
}
|
||||
const clickLogin=async ()=>{
|
||||
const data={
|
||||
telNum:telNum.value,
|
||||
@ -60,9 +95,16 @@ export const useAuth=createGlobalState(()=>{
|
||||
}
|
||||
const res=await loginRegister(data)
|
||||
if(res.status===0){
|
||||
message.success('登录成功')
|
||||
token.value=res.data.token
|
||||
router.push('/signup')
|
||||
if (res.data.status===1){
|
||||
message.warning('您已经报名')
|
||||
await getDetail()
|
||||
router.push('/details')
|
||||
}else {
|
||||
message.success('登录成功')
|
||||
token.value=res.data.token
|
||||
router.push('/signup')
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
const clickSendCode=async ()=>{
|
||||
@ -94,6 +136,7 @@ export const useAuth=createGlobalState(()=>{
|
||||
}
|
||||
}
|
||||
return {
|
||||
detailData,
|
||||
removeWorks,
|
||||
clickAddWorks,
|
||||
genderOptions,
|
||||
|
30
src/views/details/index.vue
Normal file
30
src/views/details/index.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<script setup>
|
||||
import {useAdaptation} from "@/utils/self-adaption.js";
|
||||
import {sizes} from "@/dict/index.js";
|
||||
import size375 from '@/views/details/size375/index.vue'
|
||||
import {computed} from "vue";
|
||||
import size768 from "@/views/details/size768/index.vue";
|
||||
/*import size1440 from "@/views/details/size1440/index.vue";
|
||||
import size1920 from "@/views/details/size1920/index.vue";*/
|
||||
const {currentRange }= useAdaptation(sizes)
|
||||
const viewComponent = computed(()=>{
|
||||
switch (currentRange.value?.minWidth){
|
||||
case '0px':
|
||||
return size375
|
||||
case '768px':
|
||||
return size768
|
||||
/* case '1440px':
|
||||
return size1440
|
||||
case '1920px':
|
||||
return size1920*/
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component :is="viewComponent"></component>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
330
src/views/details/size375/index.vue
Normal file
330
src/views/details/size375/index.vue
Normal file
@ -0,0 +1,330 @@
|
||||
<script setup>
|
||||
import {useAuth} from "@/store/auth/index.js";
|
||||
const {detailData} =useAuth()
|
||||
|
||||
import "vant/es/image-preview/style";
|
||||
import { showImagePreview } from 'vant';
|
||||
|
||||
|
||||
console.log(detailData,'detailData')
|
||||
const openMask=(src)=>{
|
||||
showImagePreview({
|
||||
images:[src],
|
||||
closeable: true,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="box-border relative w-[1920px] h-screen bg-no-repeat bg-cover bg-[url('@/assets/image/zu3237.png')] flex items-center flex-col container">
|
||||
<div class="content1"></div>
|
||||
<div class="content2">
|
||||
<div class="wrap1" style="margin-top: 0">
|
||||
<div class="wrap1_1">姓名</div>
|
||||
<div class="wrap1_2">
|
||||
{{detailData.name}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">年龄</div>
|
||||
<div class="wrap1_2">
|
||||
{{detailData.age}} 岁
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap1">
|
||||
<div class="wrap1_1">性别</div>
|
||||
<div class="wrap1_2">
|
||||
{{detailData.gender}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="package1">
|
||||
<div class="package1_1" v-for="(item,index) of detailData?.worksInfo">
|
||||
<div class="package1_1_1">作品{{index+1}}</div>
|
||||
<div class="package1_1_2 relative">
|
||||
<img class="package1_1_2_1" @click="openMask(item.picUrl.replace('https','http'))" :src="item.picUrl.replace('https','http')" alt="">
|
||||
<img src="@/assets/image/zu3222@2x.png" class="w-404px h-404px absolute top-0 right-0" alt="">
|
||||
<div class="package1_1_2_2">
|
||||
<div class="package1_1_2_2_1">作品名称</div>
|
||||
<div class="package1_1_2_2_2">{{item.workName}}</div>
|
||||
</div>
|
||||
<div class="package1_1_2_3">
|
||||
<div class="package1_1_2_3_1">
|
||||
<div class="package1_1_2_3_1_1">长度</div>
|
||||
<div class="package1_1_2_3_1_2">{{item.length}} cm</div>
|
||||
</div>
|
||||
<div class="package1_1_2_3_2">
|
||||
<div class="package1_1_2_3_2_1">宽度</div>
|
||||
<div class="package1_1_2_3_2_2">{{item.wide}} cm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content3">
|
||||
<img src="@/assets/image/gdz27.png" alt="">
|
||||
</div>
|
||||
<div class="content4">
|
||||
<img src="@/assets/image/zu733@2x.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
|
||||
.content4 {
|
||||
position: absolute;
|
||||
bottom: 200px;
|
||||
|
||||
img {
|
||||
width: 1270px;
|
||||
height: 145px;
|
||||
|
||||
}
|
||||
}
|
||||
.content3 {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-size: cover;
|
||||
|
||||
img {
|
||||
width: 671px;
|
||||
height: 728px;
|
||||
}
|
||||
}
|
||||
.content1 {
|
||||
margin-top: 143px;
|
||||
background-size: cover;
|
||||
width: 1074px;
|
||||
height: 178px;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/image/zu3316@2x.png");
|
||||
}
|
||||
.content2 {
|
||||
margin-top: 123px;
|
||||
background-size: cover;
|
||||
width: 1654px;
|
||||
height: 2729px;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("@/assets/image/zu3186@2x.png");
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 200px 82px 92px;
|
||||
|
||||
.package2{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin-top: 60px;
|
||||
justify-content: space-between;
|
||||
.package2_1{
|
||||
background-color:#fff;
|
||||
width: 512px;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 100px;
|
||||
box-shadow: 0 16px 16px rgba(0, 0, 0, 0.1); /* X轴偏移, Y轴偏移, 模糊半径, 阴影颜色 */
|
||||
|
||||
}
|
||||
.package2_2{
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
width: 866px;
|
||||
height: 200px;
|
||||
background-image: url("@/assets/image/zu3189@2x1.png");
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
font-size: 82px;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
.package1{
|
||||
overflow-y: auto;
|
||||
|
||||
padding-top: 46px;
|
||||
padding-left: 31px;
|
||||
width: 1490px;
|
||||
|
||||
background-color: #F5F5F5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.package1_2 {
|
||||
margin-bottom: 46px;
|
||||
margin-top: 51px;
|
||||
width: 184px; /* 按照图片的实际尺寸调整 */
|
||||
height: 184px; /* 按照图片的实际尺寸调整 */
|
||||
background-color: #336699; /* 蓝色背景颜色 */
|
||||
border-radius: 50%; /* 圆形 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 可选的阴影效果 */
|
||||
}
|
||||
.package1_2::before,
|
||||
.package1_2::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-color: white; /* 加号的颜色 */
|
||||
}
|
||||
|
||||
.package1_2::before {
|
||||
width: 88px; /* 加号横线的宽度 */
|
||||
height: 6px; /* 加号横线的高度 */
|
||||
}
|
||||
|
||||
.package1_2::after {
|
||||
width: 6px; /* 加号竖线的宽度 */
|
||||
height: 88px; /* 加号竖线的高度 */
|
||||
}
|
||||
.package1_1{
|
||||
margin-bottom: 92px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
.package1_1_2{
|
||||
.x_c2{
|
||||
margin-top: 20px;
|
||||
width: 1174px;
|
||||
padding-left: 61px;
|
||||
height: 174px;
|
||||
background-color: #DCE5E9;
|
||||
border: none;
|
||||
&:focus{
|
||||
outline: none;
|
||||
}
|
||||
&::placeholder {
|
||||
font-size: 72px;
|
||||
color: #2B69A1;
|
||||
}
|
||||
}
|
||||
.x_c3{
|
||||
margin-top: 41px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.x_c3_1{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.x_c3_1_2{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.x_c3_1_2_2{
|
||||
color: #2B69A1;
|
||||
font-size: 72px;
|
||||
}
|
||||
.x_c3_1_2_1{
|
||||
margin-right: 51px;
|
||||
padding-left: 61px;
|
||||
width: 379px;
|
||||
height: 174px;
|
||||
background-color: #DCE5E9;
|
||||
border: none;
|
||||
&:focus{
|
||||
outline: none;
|
||||
}
|
||||
&::placeholder {
|
||||
font-size: 72px;
|
||||
color: #2B69A1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.x_c3_1_1{
|
||||
|
||||
color: #2B69A1;
|
||||
font-size: 61px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.x_c1{
|
||||
margin-top: 41px;
|
||||
color: #2B69A1;
|
||||
font-size: 61px;
|
||||
}
|
||||
.package1_1_2_3{
|
||||
display: flex;
|
||||
.package1_1_2_3_2{
|
||||
display: flex;
|
||||
.package1_1_2_3_2_1{
|
||||
margin-right: 51px;
|
||||
font-weight:bold;
|
||||
color: #2B69A1;
|
||||
font-size: 61px;
|
||||
}
|
||||
.package1_1_2_3_2_2{
|
||||
color: #2B69A1;
|
||||
font-size: 61px;
|
||||
}
|
||||
}
|
||||
.package1_1_2_3_1{
|
||||
display: flex;
|
||||
.package1_1_2_3_1_1{
|
||||
margin-right: 51px;
|
||||
font-weight:bold;
|
||||
color: #2B69A1;
|
||||
font-size: 61px;
|
||||
}
|
||||
.package1_1_2_3_1_2{
|
||||
margin-right: 251px;
|
||||
color: #2B69A1;
|
||||
font-size: 61px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.package1_1_2_2{
|
||||
margin-top:56px;
|
||||
display: flex;
|
||||
.package1_1_2_2_2{
|
||||
color: #2B69A1;
|
||||
font-size:61px;
|
||||
}
|
||||
.package1_1_2_2_1{
|
||||
margin-right:51px;
|
||||
font-weight:bold;
|
||||
color: #2B69A1;
|
||||
font-size:61px;
|
||||
}
|
||||
}
|
||||
.package1_1_2_1{
|
||||
width: 1147px;
|
||||
height: 691px;
|
||||
}
|
||||
}
|
||||
|
||||
.package1_1_1{
|
||||
width: 256px;
|
||||
color: #2B69A1;
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrap1 {
|
||||
padding-left: 31px;
|
||||
margin-top: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
.wrap1_2 {
|
||||
color: #2B69A1;
|
||||
font-size: 72px;
|
||||
}
|
||||
|
||||
.wrap1_1 {
|
||||
width: 256px;
|
||||
font-weight: bold;
|
||||
color: #2B69A1;
|
||||
font-size: 72px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
45
src/views/details/size768/index.vue
Normal file
45
src/views/details/size768/index.vue
Normal file
@ -0,0 +1,45 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="box-border relative w-[1920px] h-screen bg-no-repeat bg-cover bg-[url('@/assets/image/zu3237.png')] flex items-center flex-col">
|
||||
<div class="mb-[90px]">
|
||||
<img class="w-[525px] h-[87px] mt-[303px]" src="@/assets/image/zu3314@2x.png" alt="">
|
||||
</div>
|
||||
<div class="absolute top-0 left-[70px]">
|
||||
<img class="w-[610px] h-[668px]" src="@/assets/image/gdz47@2x.png" alt="">
|
||||
</div>
|
||||
<div class="bg-[url('@/assets/image/z3327@2x1.png')] w-[1173px] h-[1489px] bg-no-repeat bg-cover pt-[98px] pr-[54px] pl-[54px]">
|
||||
<div class="flex">
|
||||
<div class="text-primary text-[35px] w-[200px] font-bold">姓名</div>
|
||||
<div class="text-primary text-[35px]">王小五</div>
|
||||
</div>
|
||||
<div class="flex mt-[26.74px]">
|
||||
<div class="text-primary text-[35px] w-[200px] font-bold">*年龄</div>
|
||||
<div class="text-primary text-[35px]">10 岁</div>
|
||||
</div>
|
||||
<div class="flex mt-[26.74px]">
|
||||
<div class="text-primary text-[35px] w-[200px] font-bold">*性别</div>
|
||||
<div class="text-primary text-[35px]">女</div>
|
||||
</div>
|
||||
<div class="w-[1065px] h-[980px] bg-#F5F5F5 mt-[8.26px] flex pt-[21.74px]">
|
||||
<div class="flex">
|
||||
<div class="text-primary font-bold shrink-0 w-[200px]">*作品1</div>
|
||||
<div>
|
||||
<img class="w-[738px] h-[353px]" src="@/assets/image/dfbackground@2.png" alt="">
|
||||
<div class="flex text-primary text-[30px] font-bold">
|
||||
<div>作品名称</div>
|
||||
<div>盛夏光年</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
@ -8,11 +8,18 @@ function onConfirm(data){
|
||||
formData.value.gender=data.selectedValues?.[0]
|
||||
showPicker.value=false
|
||||
}
|
||||
const afterRead=(file)=>{
|
||||
const formData = new FormData()
|
||||
formData.append("file", file.file)
|
||||
formData.append("type", 'image')
|
||||
uploadFile(formData)
|
||||
const afterRead=async (file,item)=>{
|
||||
const formData1 = new FormData()
|
||||
formData1.append("file", file.file)
|
||||
formData1.append("type", 'image')
|
||||
const res=await uploadFile(formData1)
|
||||
if (res.status===0){
|
||||
item.picUrl=res.data
|
||||
}
|
||||
}
|
||||
const deleteImg=(item)=>{
|
||||
item.picUrl=''
|
||||
item.imgList=[]
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
@ -50,7 +57,7 @@ const afterRead=(file)=>{
|
||||
<div class="w-265px shrink-0 font-bold text-[#2B69A1]">*作品{{index+1}}</div>
|
||||
<div>
|
||||
<div class="flex items-end">
|
||||
<van-uploader :after-read="afterRead">
|
||||
<van-uploader v-model="item.imgList" @delete="deleteImg(item)" :max-count="1" :after-read="(e)=>{afterRead(e,item)}">
|
||||
<div class="w-410px h-410px bg-[#D6E0E9] rounded-20px flex flex-col items-center justify-center">
|
||||
<img class="w-88px h-88px" src="@/assets/image/zu3264@2x.png" alt="">
|
||||
<div class="mt-36px text-[#2B69A1] text-72px">上传作品</div>
|
||||
@ -86,7 +93,7 @@ const afterRead=(file)=>{
|
||||
<div class="absolute w-6px h-88px bg-white"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-60px w-866px h-200px bg-contain bg-no-repeat bg-[url('@/assets/image/zu3189@2x1.png')] flex justify-center items-center text-white text-82px">
|
||||
<div @click="clickApply" class="mt-60px w-866px h-200px bg-contain bg-no-repeat bg-[url('@/assets/image/zu3189@2x1.png')] flex justify-center items-center text-white text-82px">
|
||||
确定
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user