..
This commit is contained in:
@@ -1,14 +1,5 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
|
||||
<!-- <view class="act-info">-->
|
||||
<!-- <view class="act-title">奋进新征程 运动促健康 2024晴江第六届"牧城之夜"荧光跑</view>-->
|
||||
<!-- <view class="act-meta">-->
|
||||
<!-- <view class="act-meta-item">22222</view>-->
|
||||
<!-- <view class="act-meta-item">22222222222222222222</view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
|
||||
<view class="form-area">
|
||||
<t-form
|
||||
ref="formRef"
|
||||
@@ -18,22 +9,21 @@
|
||||
label-align="left"
|
||||
scroll-to-first-error="auto"
|
||||
>
|
||||
<view class="form-block">
|
||||
<view class="form-block-title">
|
||||
<t-icon name="institution"></t-icon>
|
||||
单位信息
|
||||
</view>
|
||||
<t-form-item label="参加单位" name="unitName" :rules="[{required:true,message: '请输入单位名称'}]">
|
||||
<!-- <t-input v-model="formData.unitName" borderless placeholder="请输入参加单位名称"></t-input>-->
|
||||
<search-picker v-model="formData.unitName" :options="unitOptions" placeholder="请选择单位"></search-picker>
|
||||
</t-form-item>
|
||||
<t-form-item label="联系人" name="contactName" :rules="[{required:true,message: '请输入联系人姓名'}]">
|
||||
<t-input v-model="formData.contactName" borderless placeholder="请输入联系人姓名"></t-input>
|
||||
</t-form-item>
|
||||
<t-form-item label="联系方式" name="contactPhone" :rules="[{required:true,message: '请输入联系电话'}]">
|
||||
<t-input v-model="formData.contactPhone" borderless placeholder="请输入联系电话"></t-input>
|
||||
</t-form-item>
|
||||
</view>
|
||||
<!-- <view class="form-block">-->
|
||||
<!-- <view class="form-block-title">-->
|
||||
<!-- <t-icon name="institution"></t-icon>-->
|
||||
<!-- 单位信息-->
|
||||
<!-- </view>-->
|
||||
<!-- <t-form-item label="参加单位" name="unitName" :rules="[{required:true,message: '请输入单位名称'}]">-->
|
||||
<!-- <t-input v-model="formData.unitName" borderless readonly placeholder="请输入参加单位名称"></t-input>-->
|
||||
<!-- </t-form-item>-->
|
||||
<!-- <t-form-item label="联系人" name="contactName" :rules="[{required:true,message: '请输入联系人姓名'}]">-->
|
||||
<!-- <t-input v-model="formData.contactName" borderless placeholder="请输入联系人姓名"></t-input>-->
|
||||
<!-- </t-form-item>-->
|
||||
<!-- <t-form-item label="联系方式" name="contactPhone" :rules="[{required:true,message: '请输入联系电话'}]">-->
|
||||
<!-- <t-input v-model="formData.contactPhone" borderless placeholder="请输入联系电话"></t-input>-->
|
||||
<!-- </t-form-item>-->
|
||||
<!-- </view>-->
|
||||
|
||||
<view class="form-block">
|
||||
<view class="form-block-title">
|
||||
@@ -79,14 +69,23 @@
|
||||
<t-radio :block="false" name="radio" :value="false" label="否"/>
|
||||
</t-radio-group>
|
||||
</t-form-item>
|
||||
<t-form-item label="是否联系人" :name="`userList[${index}].isStay`"
|
||||
:rules="[{required:true,message: '请选择是否住宿'}]">
|
||||
<t-radio-group v-model="user.isStay" class="radio-box">
|
||||
<t-radio :block="false" name="radio" :value="true" label="是"/>
|
||||
<t-radio :block="false" name="radio" :value="false" label="否"/>
|
||||
</t-radio-group>
|
||||
</t-form-item>
|
||||
</view>
|
||||
</view>
|
||||
</t-form>
|
||||
<view class="add-user" @click="formData.userList.push({})">
|
||||
<t-icon name="plus" size="24px"></t-icon>
|
||||
<text>添加人员</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 悬浮添加按钮 -->
|
||||
<view class="float-add-btn" @click="formData.userList.push({})">
|
||||
<t-icon name="plus" size="24px" color="#fff"></t-icon>
|
||||
</view>
|
||||
|
||||
<view class="footer">
|
||||
<view class="agreement-checkbox">
|
||||
<t-checkbox label="多选" icon="rectangle" v-model:checked="agreementChecked" default-checked>
|
||||
@@ -105,6 +104,14 @@
|
||||
{{ isSignUp ? '重新提交报名信息' : '提交报名'}}
|
||||
</t-button>
|
||||
</view>
|
||||
|
||||
<!-- 引导 -->
|
||||
<t-guide
|
||||
v-model="guideCurrent"
|
||||
:steps="guideSteps"
|
||||
>
|
||||
</t-guide>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -113,9 +120,32 @@ import {ref} from 'vue'
|
||||
import {useRequest} from '@/utils/request';
|
||||
import {Dialog, Toast} from "tdesign-mobile-vue";
|
||||
import {onLoad} from "@dcloudio/uni-app";
|
||||
import SearchPicker from "@/components/SearchPicker.vue";
|
||||
import {useUserStore} from "@/store";
|
||||
|
||||
const request = useRequest()
|
||||
const userStore= useUserStore()
|
||||
|
||||
// 引导部分
|
||||
const guideCurrent = ref(-1)
|
||||
const guideSteps = [
|
||||
{
|
||||
element:()=> document.querySelector('.float-add-btn'),
|
||||
title: '添加活动报名人员',
|
||||
placement: 'top'
|
||||
},
|
||||
{
|
||||
element:()=> document.querySelector('.t-form'),
|
||||
title: '填写报名信息',
|
||||
placement: 'top'
|
||||
},
|
||||
{
|
||||
element:()=> document.querySelector('.footer'),
|
||||
title: '提交报名信息',
|
||||
placement: 'top'
|
||||
}
|
||||
]
|
||||
|
||||
// 报名信息
|
||||
const actId = ref(null)
|
||||
const isSignUp = ref(null)
|
||||
const agreementChecked = ref(false)
|
||||
@@ -124,18 +154,17 @@ const formData = ref({
|
||||
userList: [{}]
|
||||
})
|
||||
|
||||
const unitOptions = ref([
|
||||
{value:'单位1',label:'单位1'},
|
||||
{value:'单位2',label:'单位2'},
|
||||
{value:'单位3',label:'单位3'},
|
||||
])
|
||||
|
||||
onLoad((option) => {
|
||||
if (option.id) {
|
||||
actId.value = option.id
|
||||
formData.value.activityId = option.id
|
||||
listSignUpUser()
|
||||
getIsSignUp()
|
||||
// 没报名进行引导
|
||||
if(formData.userList.length === 0){
|
||||
guideCurrent.value = 0
|
||||
formData.value.unitName = userStore.userInfo?.unit.name
|
||||
}
|
||||
} else {
|
||||
Toast({message: 'ID不存在', theme: 'error'});
|
||||
}
|
||||
@@ -308,7 +337,6 @@ async function removeUser(index) {
|
||||
.form-area {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
//margin-top: 100px;
|
||||
margin-bottom: 130px;
|
||||
}
|
||||
|
||||
@@ -379,16 +407,23 @@ async function removeUser(index) {
|
||||
}
|
||||
}
|
||||
|
||||
.add-user {
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
color: #e74c3c;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
.float-add-btn {
|
||||
position: fixed;
|
||||
right: 32rpx;
|
||||
bottom: 160rpx;
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #e74c3c;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #ffffff;
|
||||
justify-content: center;
|
||||
z-index: 100;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.float-add-btn:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.radio-box {
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
</view>
|
||||
|
||||
<!-- 小提示 -->
|
||||
<view class="success-tips">
|
||||
<t-icon name="info-circle-filled" size="16px" />
|
||||
<text>活动开始前我们将通过短信通知您</text>
|
||||
</view>
|
||||
<!-- <view class="success-tips">-->
|
||||
<!-- <t-icon name="info-circle-filled" size="16px" />-->
|
||||
<!-- <text>活动开始前我们将通过短信通知您</text>-->
|
||||
<!-- </view>-->
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="action-buttons">
|
||||
@@ -106,7 +106,7 @@ const viewRegistrationDetails = () => {
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: float 3s ease-in-out infinite;
|
||||
//animation: float 3s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="formData.name"
|
||||
v-model="formData.userName"
|
||||
placeholder="请输入姓名"
|
||||
maxlength="20"
|
||||
/>
|
||||
@@ -113,7 +113,7 @@
|
||||
<input
|
||||
class="input"
|
||||
type="number"
|
||||
v-model="formData.verificationCode"
|
||||
v-model="formData.smsCode"
|
||||
placeholder="请输入验证码"
|
||||
maxlength="6"
|
||||
/>
|
||||
@@ -145,37 +145,37 @@
|
||||
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-box">
|
||||
<t-icon name="search" size="22px" class="search-icon" />
|
||||
<t-icon name="search" size="22px" class="search-icon"/>
|
||||
<input
|
||||
class="search-input"
|
||||
type="text"
|
||||
v-model="searchKeyword"
|
||||
placeholder="搜索单位"
|
||||
@input="handleSearch"
|
||||
class="search-input"
|
||||
type="text"
|
||||
v-model="searchKeyword"
|
||||
placeholder="搜索单位"
|
||||
@input="handleSearch"
|
||||
/>
|
||||
<t-icon
|
||||
v-if="searchKeyword"
|
||||
name="close-circle-filled"
|
||||
size="22px"
|
||||
class="clear-icon"
|
||||
@click="clearSearch"
|
||||
v-if="searchKeyword"
|
||||
name="close-circle-filled"
|
||||
size="22px"
|
||||
class="clear-icon"
|
||||
@click="clearSearch"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 单位列表 -->
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="units-scroll-view"
|
||||
scroll-with-animation
|
||||
:scroll-into-view="scrollViewId"
|
||||
scroll-y
|
||||
class="units-scroll-view"
|
||||
scroll-with-animation
|
||||
:scroll-into-view="scrollViewId"
|
||||
>
|
||||
<view
|
||||
v-for="unit in filteredUnits"
|
||||
:key="unit.id"
|
||||
:id="'unit-' + unit.id"
|
||||
class="unit-item"
|
||||
:class="{'unit-selected': selectedUnitId === unit.id}"
|
||||
@click="selectUnit(unit)"
|
||||
v-for="unit in filteredUnits"
|
||||
:key="unit.id"
|
||||
:id="'unit-' + unit.id"
|
||||
class="unit-item"
|
||||
:class="{'unit-selected': selectedUnitId === unit.id}"
|
||||
@click="selectUnit(unit)"
|
||||
>
|
||||
<text class="unit-name">{{ unit.name }}</text>
|
||||
<t-icon v-if="selectedUnitId === unit.id" name="check" size="22px" class="check-icon"/>
|
||||
@@ -191,18 +191,21 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onMounted, watch, nextTick, getCurrentInstance } from 'vue';
|
||||
import { Toast } from 'tdesign-mobile-vue';
|
||||
import { useRequest } from "@/utils/request";
|
||||
import {ref, reactive, computed, onMounted, watch, nextTick, getCurrentInstance} from 'vue';
|
||||
import {Dialog, Toast} from 'tdesign-mobile-vue';
|
||||
import {useRequest} from "@/utils/request";
|
||||
import {useUserStore} from "@/store";
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
userName: '',
|
||||
phone: '',
|
||||
unitId: '',
|
||||
unitName: '',
|
||||
idCard: '',
|
||||
verificationCode: ''
|
||||
smsCode: ''
|
||||
});
|
||||
|
||||
// 验证码倒计时
|
||||
@@ -223,21 +226,10 @@ const filteredUnits = computed(() => {
|
||||
return unitList.value;
|
||||
}
|
||||
return unitList.value.filter(unit =>
|
||||
unit.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||
unit.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||
);
|
||||
});
|
||||
|
||||
// 表单验证
|
||||
const isFormValid = computed(() => {
|
||||
return formData.name &&
|
||||
formData.phone &&
|
||||
formData.phone.length === 11 &&
|
||||
formData.unitId &&
|
||||
formData.idCard &&
|
||||
formData.idCard.length === 18 &&
|
||||
formData.verificationCode;
|
||||
});
|
||||
|
||||
// 当选择器打开时,预设选中当前已选单位
|
||||
watch(showUnitPicker, (newVal) => {
|
||||
if (newVal && formData.unitId) {
|
||||
@@ -270,7 +262,7 @@ const selectUnit = (unit) => {
|
||||
// 确认选择
|
||||
const confirmUnitSelection = () => {
|
||||
if (!selectedUnitId.value) {
|
||||
Toast({ message: '请选择单位', theme: 'warning' });
|
||||
Toast({message: '请选择单位', theme: 'warning'});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -285,22 +277,22 @@ const confirmUnitSelection = () => {
|
||||
// 获取单位列表
|
||||
const getUnitList = async () => {
|
||||
try {
|
||||
const { code, data, msg } = await useRequest().get('/open/common/units');
|
||||
const {code, data, msg} = await useRequest().get('/open/common/units');
|
||||
if (code === 0) {
|
||||
unitList.value = data || [];
|
||||
} else {
|
||||
Toast({ message: msg || '获取单位列表失败', theme: 'error' });
|
||||
Toast({message: msg || '获取单位列表失败', theme: 'error'});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取单位列表失败', error);
|
||||
Toast({ message: '获取单位列表失败', theme: 'error' });
|
||||
Toast({message: '获取单位列表失败', theme: 'error'});
|
||||
}
|
||||
};
|
||||
|
||||
// 发送验证码
|
||||
const sendVerificationCode = async () => {
|
||||
if (!formData.phone || formData.phone.length !== 11) {
|
||||
Toast({ message: '请输入正确的手机号', theme: 'error' });
|
||||
Toast({message: '请输入正确的手机号', theme: 'error'});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,20 +300,17 @@ const sendVerificationCode = async () => {
|
||||
|
||||
sendingCode.value = true;
|
||||
try {
|
||||
const { code, msg } = await useRequest().post('/client/auth/send-verification-code', {
|
||||
phone: formData.phone,
|
||||
type: 'register'
|
||||
});
|
||||
const {code, msg} = await useRequest().post('/client/auth//send-reg-code/' + formData.phone);
|
||||
|
||||
if (code === 0) {
|
||||
Toast({ message: '验证码已发送' });
|
||||
Toast({message: '验证码已发送'});
|
||||
startCountdown();
|
||||
} else {
|
||||
Toast({ message: msg || '发送验证码失败', theme: 'error' });
|
||||
Toast({message: msg || '发送验证码失败', theme: 'error'});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('发送验证码失败', error);
|
||||
Toast({ message: '发送验证码失败', theme: 'error' });
|
||||
Toast({message: '发送验证码失败', theme: 'error'});
|
||||
} finally {
|
||||
sendingCode.value = false;
|
||||
}
|
||||
@@ -340,54 +329,67 @@ const startCountdown = () => {
|
||||
|
||||
// 注册
|
||||
const handleRegister = async () => {
|
||||
if (!isFormValid.value) {
|
||||
Toast({ message: '请完善注册信息', theme: 'error' });
|
||||
return;
|
||||
if (!formData.userName) {
|
||||
Toast('请输入姓名');
|
||||
return
|
||||
}
|
||||
if (!formData.phone) {
|
||||
Toast('请输入手机号码');
|
||||
return
|
||||
}
|
||||
if (!formData.phone.match(/^1[3456789]\d{9}$/)) {
|
||||
Toast('请输入正确的手机号码');
|
||||
return
|
||||
}
|
||||
if (!formData.idCard) {
|
||||
Toast('请输入身份证号');
|
||||
return
|
||||
}
|
||||
if (!formData.unitId) {
|
||||
Toast('请选择单位');
|
||||
return
|
||||
}
|
||||
if (!formData.idCard.match(/^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/)) {
|
||||
Toast('请输入正确的身份证号');
|
||||
return
|
||||
}
|
||||
if (!formData.smsCode) {
|
||||
Toast('请输入验证码');
|
||||
return
|
||||
}
|
||||
|
||||
registering.value = true;
|
||||
try {
|
||||
const { code, msg } = await useRequest().post('/client/auth/register', {
|
||||
name: formData.name,
|
||||
phone: formData.phone,
|
||||
unitId: formData.unitId,
|
||||
idCard: formData.idCard,
|
||||
verificationCode: formData.verificationCode
|
||||
});
|
||||
const {code, msg, data} = await useRequest().post('/client/auth/register', formData);
|
||||
|
||||
if (code === 0) {
|
||||
Toast({ message: '注册成功' });
|
||||
// 注册成功后跳转到登录页
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/login/index'
|
||||
});
|
||||
}, 1500);
|
||||
Dialog.confirm({
|
||||
title: '注册成功',
|
||||
content: '是否立即进入系统?',
|
||||
confirmBtn: '确定',
|
||||
cancelBtn: '取消',
|
||||
onConfirm: () => {
|
||||
userStore.setToken(data)
|
||||
userStore.getUserInfo().then(() => {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}).catch(e => {
|
||||
Toast({message: e.message, theme: 'error'})
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Toast({ message: msg || '注册失败', theme: 'error' });
|
||||
Toast({message: msg || '注册失败', theme: 'error'});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('注册失败', error);
|
||||
Toast({ message: '注册失败', theme: 'error' });
|
||||
Toast({message: '注册失败', theme: 'error'});
|
||||
} finally {
|
||||
registering.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 显示协议
|
||||
const showAgreement = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/agreement/index'
|
||||
});
|
||||
};
|
||||
|
||||
// 显示隐私政策
|
||||
const showPrivacy = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/privacy/index'
|
||||
});
|
||||
};
|
||||
|
||||
// 跳转登录页面
|
||||
const goToLogin = () => {
|
||||
uni.navigateTo({
|
||||
|
||||
Reference in New Issue
Block a user