提交 f106bfc2 authored 作者: lhh's avatar lhh

update

上级 59333994
......@@ -8,7 +8,7 @@ import AppAside from './Aside.vue'
import AppMain from './Main.vue'
import AppFooter from './Footer.vue'
withDefaults(defineProps<{ sidebar?: boolean; footer?: boolean }>(), {
withDefaults(defineProps<{ sidebar?: boolean; footer?: boolean; header?: boolean }>(), {
sidebar: false,
footer: false
})
......@@ -16,7 +16,7 @@ withDefaults(defineProps<{ sidebar?: boolean; footer?: boolean }>(), {
<template>
<div class="app-layout">
<AppHeader></AppHeader>
<AppHeader v-if="header"></AppHeader>
<div class="app-layout-container">
<AppAside v-if="sidebar"></AppAside>
<AppMain></AppMain>
......
import httpRequest from '@/utils/axios'
import type { ContestJoinParams } from './types'
// 获取学员可以报名的所有赛项
export function getContestList() {
return httpRequest.get('/api/lab/v1/student/competition/list')
}
// 获取学员已报名的赛项列表
export function getMyContestList() {
return httpRequest.get('/api/lab/v1/student/competition/my-list')
}
// 获取赛项详情
export function getContest(params: { id: string }) {
return httpRequest.get('/api/lab/v1/student/competition/detail', { params })
}
// 获取学员详情
export function getStudentInfo() {
return httpRequest.get('/api/lab/v1/student/competition/student-detail')
}
// 分发参赛短信
export function sendApplySMS(data: { competition_id: string; mobile: string }) {
return httpRequest.post('/api/lab/v1/student/competition/send-apply-sms', data)
}
// 大赛报名
export function joinContest(data: ContestJoinParams) {
return httpRequest.post('/api/lab/v1/student/competition/apply', data)
}
export function joinContest2(data: any) {
return httpRequest.post('/api/lab/v1/student/competition/apply2', data)
}
// 获取实验指导书
export function getExperimentBook(params: { competition_id: string }) {
return httpRequest.get('/api/lab/v1/student/competition/book', { params })
}
// 获取实验视频
export function getExperimentVideoList(params: { competition_id: string }) {
return httpRequest.get('/api/lab/v1/student/competition/videos', { params })
}
// 获取实验视频播放信息
export function getExperimentVideoPlayInfo(params: { source_id: string }) {
return httpRequest.get('/api/lab/v1/student/competition/replay-list', { params })
}
// 获取实验讨论交流
export function getExperimentDiscussList(params: {
competition_id: string
tag: number
page?: number
'per-page'?: number
}) {
return httpRequest.get('/api/lab/v1/student/competition/discussion-list', { params })
}
// 发表新话题
export function addExperimentDiscuss(data: { competition_id: string; title: string; content: string }) {
return httpRequest.post('/api/lab/v1/student/competition/discussion-create', data)
}
// 发表回复
export function addExperimentDiscussComment(data: { discussion_id: string; content: string }) {
return httpRequest.post('/api/lab/v1/student/competition/discussion-reply-create', data)
}
// 获取实验截图记录
export function getExperimentRecord(params: { competition_id: string }) {
return httpRequest.get('/api/lab/v1/student/competition/pictures', { params })
}
// 截图
export function uploadExperimentPicture(data: { competition_id: string; pictures: string }) {
return httpRequest.post('/api/lab/v1/student/competition/save-pictures', data)
}
// 参赛选手训练计数
export function updateTrainCount(data: { competition_id: string }) {
return httpRequest.post('/api/lab/v1/student/competition/train-count', data)
}
import type { RouteRecordRaw } from 'vue-router'
import AppLayout from '@/components/layout/Index.vue'
import { useAppConfig } from '@/composables/useAppConfig'
const appConfig = useAppConfig()
export const routes: Array<RouteRecordRaw> = [
{
path: '/register',
component: AppLayout,
props: { sidebar: false, footer: false, header: false },
children: [{ path: '', component: () => import('./views/Index.vue') }]
}
]
import type { SystemDictionary } from '@/types'
export interface Contest {
apply_expiration_date: string
competition_uri: string
cover: string
end_at: string
end_range: string
host_unit: SystemDictionary
id: string
login_id: string
logo: string
name: string
org_name: string
organizers: SystemDictionary[]
start_at: string
start_range: string
student_id: string
student_name: string
technical_support_unit: SystemDictionary
train_platform_uri: string
type: string
mode: string
}
export type ContestJoinParams = {
competition_id: string
mode: string
picture: string
grade: string
teacher_name: string
sms_code: string
}
export type ExperimentBookType = {
id: string
name: string
competition_id: string
type: string
url: string
}
export interface ExperimentVideoType {
id: string
name: string
size: string
type: string
source_id: string
length: number
cover: string
}
export interface PlayInfo {
BitDepth: number
Bitrate: string
CreationTime: string
Definition: string
Duration: string
Encrypt: number
Format: string
Fps: string
HDRType: string
Height: number
JobId: string
ModificationTime: string
NarrowBandType: string
PlayURL: string
PreprocessStatus: string
Size: number
Specification: string
Status: string
StreamType: string
Width: number
}
export interface ExperimentDiscussType {
content: string
created_operator: string
created_time: string
id: string
is_reply: string
competitionDiscussionReplies: ExperimentDiscussCommentType[]
reply_count: number
sso_user: UserType
student_id: string
title: string
updated_time: string
}
export interface ExperimentDiscussCommentType {
content: string
created_time: string
discussion_id: string
id: string
role: string
sso_id: string
sso_user: UserType
}
export interface UserType {
avatar: string
id: string
nickname: string
real_name: string
username: string
}
export type ExperimentRecord = {
competition_id: string
created_time: string
id: string
pictures: ExperimentRecordFile[]
student_id: string
updated_time: string
}
export interface ExperimentRecordFile {
url: string
name: string
upload_time: string
size?: number
}
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import AppUpload from '@/components/base/AppUpload.vue'
import { useCountdown } from '@/composables/useCountdown'
import { joinContest2, sendApplySMS } from '../api'
const { second, disabled, start } = useCountdown()
const countdownText = $computed(() => {
return disabled.value ? `(${second.value})秒` : '点击获取'
})
// 发送验证码
function sendSMS() {
if (form.mobile) {
start()
sendApplySMS({ competition_id: form.competition_id, mobile: form.mobile }).catch(() => {
stop()
})
} else {
ElMessage({
showClose: true,
message: '请输入手机号',
type: 'warning'
})
new Error('请输入手机号')
}
}
const router = useRouter()
const formRef = $ref<FormInstance>()
const form = reactive({
competition_name: '2023年全国大学生商业数据分析与应用大赛',
competition_id: '999',
competition_type: '团队赛',
name: '',
gender: '男',
id_type: '身份证',
id_number: '',
mobile: '',
school: '',
subject: '',
grade: '',
class_name: '',
teacher_name: '',
photo: '',
code: '',
protocol: false,
team_name: ''
})
const checkProtocol = (rule: any, value: any, callback: any) => {
if (!value) {
return callback(new Error('请确认'))
} else {
callback()
}
}
const rules = ref<FormRules>({
subject: [{ required: true, message: '请输入', trigger: 'blur' }],
school: [{ required: true, message: '请输入', trigger: 'blur' }],
mobile: [{ required: true, message: '请正确输入联系电话,报名结果将发送此手机号码。', trigger: 'blur' }],
id_type: [{ required: true, message: '请输入', trigger: 'blur' }],
id_number: [{ required: true, message: '请输入', trigger: 'blur' }],
name: [{ required: true, message: '请输入', trigger: 'blur' }],
gender: [{ required: true, message: '请输入', trigger: 'blur' }],
team_name: [{ required: true, message: '请输入', trigger: 'blur' }],
competition_type: [{ required: true, message: '请选择', trigger: 'blur' }],
grade: [{ required: true, message: '请输入年级' }],
teacher_name: [{ required: true, message: '请输入指导教师' }],
photo: [{ required: true, message: '请上传证件照' }],
// code: [{ required: true, message: '请输入验证码' }],
protocol: [{ validator: checkProtocol, trigger: 'change' }]
})
let dialogVisible = $ref(false)
// 提交
function handleSubmit() {
formRef?.validate().then(handleJoin)
}
// 报名
function handleJoin() {
const params: any = form
joinContest2(params).then(() => {
dialogVisible = true
})
}
function handleCancel() {
router.go(0)
}
const step = ref(0)
const goPage = function () {
window.open('https://mp.weixin.qq.com/s/YCrp7zFbmurfNr5JDOBlAQ')
}
</script>
<template>
<div class="register-home" v-if="step === 0">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/pages/assa/register-logo.png" class="logo" />
<div class="pop">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/pages/assa/register-pop.png" />
<div class="btn-box">
<div class="btn1" @click="step = 1">立即报名</div>
<div class="btn2" @click="goPage">赛事通知</div>
</div>
</div>
</div>
<div class="register-form" v-if="step === 1">
<AppCard>
<h1>2023年全国大学生商业数据分析与应用大赛</h1>
<el-form ref="formRef" :model="form" :rules="rules" label-width="124px" style="width: 600px; margin: 0 auto">
<!-- <el-form-item label="报名赛项">
<el-input v-model="form.name" disabled />
</el-form-item> -->
<el-form-item label="参赛类型" prop="competition_type">
<el-radio-group v-model="form.competition_type">
<el-radio label="团队赛">团队赛</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="团队名称" prop="team_name">
<el-input v-model="form.team_name" />
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-radio-group v-model="form.gender">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="证件类型" prop="id_type">
<el-radio-group v-model="form.id_type">
<el-radio label="身份证">身份证</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="证件号码" prop="id_number">
<el-input v-model="form.id_number" />
</el-form-item>
<el-form-item label="联系电话" prop="mobile">
<el-input v-model="form.mobile" />
</el-form-item>
<el-form-item label="学校名称" prop="school">
<el-input v-model="form.school" />
</el-form-item>
<el-form-item label="专业名称" prop="subject">
<el-input v-model="form.subject" />
</el-form-item>
<el-form-item label="年级" prop="grade">
<el-input v-model="form.grade" />
</el-form-item>
<el-form-item label="班级">
<el-input v-model="form.class_name" />
</el-form-item>
<el-form-item label="指导教师" prop="teacher_name">
<el-input v-model="form.teacher_name" />
</el-form-item>
<el-form-item label="证件照" prop="photo">
<AppUpload v-model="form.photo" accept="image/*">
<template #tip>证件照说明:请上传蓝底1寸或蓝底2寸证件照,照片大小控制在500kb以内。</template>
</AppUpload>
</el-form-item>
<!-- <el-form-item label="验证码" prop="code">
<el-input v-model="form.code">
<template #append>
<el-button type="primary" :disabled="disabled" @click="sendSMS">{{ countdownText }}</el-button>
</template>
</el-input>
</el-form-item> -->
<el-form-item prop="protocol">
<el-checkbox label="我已确认上述信息输入无误,并对上述信息填写内容负责。" v-model="form.protocol" />
</el-form-item>
<el-row justify="center">
<el-button type="primary" round auto-insert-space @click="handleSubmit">点击提交</el-button>
<!-- <el-button round auto-insert-space @click="handleCancel">取消</el-button> -->
</el-row>
</el-form>
</AppCard>
</div>
<div class="register-success" v-if="dialogVisible">
<div class="content">
<img src="https://webapp-pub.oss-cn-beijing.aliyuncs.com/pages/assa/register-cg.png" />
<div class="text-box">
<h2>资料提交成功</h2>
<p>工作人员将会审核您的提交,请留意短信通知!</p>
</div>
<div class="btn" @click="handleCancel">我知道了</div>
</div>
</div>
</template>
<style lang="scss">
.register-home {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/pages/assa/register-bg.png);
background-size: cover;
.logo {
position: absolute;
top: 10%;
left: 50%;
transform: translateX(-50%);
width: 202px;
}
.pop {
position: absolute;
top: 25%;
left: 50%;
transform: translateX(-50%);
width: 366px;
img {
width: 100%;
}
.btn-box {
position: absolute;
top: 330px;
left: 50%;
transform: translateX(-50%);
.btn1 {
width: 170px;
line-height: 50px;
background: #e92d55;
border-radius: 40px;
text-align: center;
color: #fff;
font-size: 20px;
cursor: pointer;
}
.btn2 {
width: 170px;
line-height: 50px;
border: 1px solid #e92d55;
border-radius: 40px;
text-align: center;
color: #e92d55;
font-size: 20px;
cursor: pointer;
margin-top: 20px;
}
}
}
}
.register-form {
h1 {
font-size: 36px;
font-weight: bold;
color: #a21935;
text-align: center;
line-height: 120px;
margin-bottom: 20px;
}
}
.register-success {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.39);
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 450px;
background: #fff;
border-radius: 40px;
img {
position: absolute;
top: -25px;
left: 50%;
transform: translateX(-50%);
width: 276px;
}
.text-box {
width: 300px;
padding-top: 187px;
margin: 0 auto;
text-align: center;
h2 {
font-size: 26px;
line-height: 100%;
color: #333333;
}
p {
font-size: 16px;
line-height: 26px;
color: #999999;
margin-top: 20px;
}
}
.btn {
text-align: center;
margin: 0 auto;
width: 240px;
line-height: 88px;
background: #e92d55;
box-shadow: 0px 20px 30px #ffd3dc;
opacity: 1;
border-radius: 44px;
margin-top: 33px;
color: #fff;
font-size: 32px;
cursor: pointer;
}
}
}
.app-layout {
background: #fff !important;
}
</style>
......@@ -19,6 +19,21 @@ router.beforeEach(async (to, from, next) => {
return
}
next()
// if (to.path !== '/register') {
// const user = useUserStore()
// if (!user.isLogin && !whiteList.includes(to.path)) {
// try {
// await user.getUser()
// } catch (e) {
// console.error(e)
// }
// user.isLogin ? next() : next('/401')
// return
// }
// next()
// } else {
// next()
// }
})
export default router
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论