This commit is contained in:
2025-09-19 08:34:51 +08:00
parent ed1d417785
commit 0c0811f0f9
13 changed files with 225 additions and 117 deletions
@@ -18,11 +18,11 @@
<scroll-view scroll-x="true" class="tabs-scroll-view" show-scrollbar="false">
<view class="tabs">
<view
v-for="(user, index) in formData.userList"
:key="index"
class="tab"
:class="{ active: activeTabIndex === index }"
@click="switchTab(index)"
v-for="(user, index) in formData.userList"
:key="index"
class="tab"
:class="{ active: activeTabIndex === index }"
@click="switchTab(index)"
>
<view class="tab-content">
<view class="tab-icon" v-if="activeTabIndex === index">
@@ -47,22 +47,21 @@
labelWidth="90px"
:requiredMark="true"
>
<!-- <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">-->
<!-- <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">
@@ -78,9 +77,10 @@
</view>
<!-- 所有人员的表单,使用v-show控制显示 -->
<view v-for="(user, index) in formData.userList" :key="index" class="form-fields-container" v-show="activeTabIndex === index">
<view v-for="(user, index) in formData.userList" :key="index" class="form-fields-container"
v-show="activeTabIndex === index">
<t-form-item label="姓名" :name="`userList[${index}].userName`"
:rules="[{required:true,message: '请输入姓名'}]">
:rules="[{required:true,message: '请输入姓名'}]">
<t-input v-model="user.userName" borderless placeholder="请输入内容"></t-input>
</t-form-item>
<t-form-item label="性别" :name="`userList[${index}].sex`" :rules="[{required:true,message: '请选择性别'}]">
@@ -89,74 +89,83 @@
<t-radio :block="false" label="女" value="女"/>
</t-radio-group>
</t-form-item>
<t-form-item label="体重" :name="`userList[${index}].weight`"
:rules="[{required:true,message: '请输入体重'}]">
<t-input placeholder="0.00" suffix="KG" type="number" borderless v-model="user.weight"></t-input>
</t-form-item>
<t-form-item label="单位名称">
<t-input v-model="user.unitName" borderless placeholder="请输入单位名称" readonly></t-input>
</t-form-item>
<t-form-item label="职务" :name="`userList[${index}].position`"
requiredMark
:rules="[{required:true,message: '请输入职务'}]">
:rules="[{required:true,message: '请输入职务'}]">
<t-input v-model="user.position" borderless placeholder="请输入职务"></t-input>
</t-form-item>
<t-form-item label="身份证号" :name="`userList[${index}].idCard`"
:rules="[{required:true,message: '请输入身份证号码'},{idcard:true, message: '请输入正确的身份证号码'}]">
:rules="[{required:true,message: '请输入身份证号码'},{idcard:true, message: '请输入正确的身份证号码'}]">
<t-input v-model="user.idCard" borderless placeholder="请输入身份证号码"></t-input>
</t-form-item>
<t-form-item label="联系电话" :name="`userList[${index}].phone`"
:rules="[{required:true,message: '请输入联系电话'},{telnumber:true, message: '请输入正确的联系电话'}]">
:rules="[{required:true,message: '请输入联系电话'},{telnumber:true, message: '请输入正确的联系电话'}]">
<t-input v-model="user.phone" borderless placeholder="请输入联系电话"></t-input>
</t-form-item>
<t-form-item label="是否住宿" :name="`userList[${index}].isStay`"
:rules="[{required:true,message: '请选择是否住宿'}]">
: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>
<t-form-item label="是否联系人" :name="`userList[${index}].isContacts`"
:rules="[{required:true,message: '请选择是否为联系人'}]">
:rules="[{required:true,message: '请选择是否为联系人'}]">
<t-radio-group v-model="user.isContacts" 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>
<t-form-item label="交通方式" :name="`userList[${index}].traffic`" :rules="[{required:true,message: '请选择交通方式'}]">
<t-form-item label="交通方式" :name="`userList[${index}].traffic`"
:rules="[{required:true,message: '请选择交通方式'}]">
<t-radio-group v-model="user.traffic" class="radio-box">
<t-radio :block="false" name="radio" :value="'自驾'" label="自驾"/>
<t-radio :block="false" name="radio" :value="'公共交通'" label="公共交通"/>
</t-radio-group>
</t-form-item>
<t-form-item v-if="user.traffic === '自驾'" label="车牌号" :name="`userList[${index}].carNo`" :rules="[{required:true,message: '请输入车牌号'}]">
<t-form-item v-if="user.traffic === '自驾'" label="车牌号" :name="`userList[${index}].carNo`"
:rules="[{required:true,message: '请输入车牌号'}]">
<t-input v-model="user.carNo" borderless placeholder="请输入车牌号"></t-input>
</t-form-item>
<t-form-item v-if="user.traffic === '公共交通'" label="是否接站" :name="`userList[${index}].isStation`" :rules="[{required:true,message: '请选择是否接站'}]">
<t-form-item v-if="user.traffic === '公共交通'" label="是否接站" :name="`userList[${index}].isStation`"
:rules="[{required:true,message: '请选择是否接站'}]">
<t-radio-group v-model="user.isStation" 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>
<t-form-item v-if="user.isStation" label="接站地址" :name="`userList[${index}].stationAddress`" :rules="[{required:true,message: '请输入接站地址'}]">
<t-form-item v-if="user.isStation" label="接站地址" :name="`userList[${index}].stationAddress`"
:rules="[{required:true,message: '请输入接站地址'}]">
<t-input v-model="user.stationAddress" borderless placeholder="请输入接站地址" maxlength="50"></t-input>
</t-form-item>
<!-- <t-form-item label="展示才艺" :name="`userList[${index}].isShowSkill`" :rules="[{required:true,message: '请选择是否展示才艺'}]">-->
<!-- <t-radio-group v-model="user.isShowSkill" 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>-->
<!-- <template v-if="formData.userList[index]?.isShowSkill">-->
<!-- <t-form-item label="才艺名称" :name="`userList[${index}].skillName`" :rules="[{required:user.isShowSkill===true,message: '请填写才艺名称'}]">-->
<!-- <t-input v-model="user.skillName" borderless placeholder="请输入才艺名称"></t-input>-->
<!-- </t-form-item>-->
<!-- <t-form-item label="所需器材" :name="`userList[${index}].equip`" :rules="[{required:user.isShowSkill===true,message: '请填写才艺所需器材'}]">-->
<!-- <t-input v-model="user.equip" borderless placeholder="请填写才艺所需器材"></t-input>-->
<!-- </t-form-item>-->
<!-- </template>-->
<t-form-item label="参加茶叙会" :name="`userList[${index}].isParty`" :rules="[{required:true,message: '请选择是否参加茶叙会'}]">
<!-- <t-form-item label="展示才艺" :name="`userList[${index}].isShowSkill`" :rules="[{required:true,message: '请选择是否展示才艺'}]">-->
<!-- <t-radio-group v-model="user.isShowSkill" 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>-->
<!-- <template v-if="formData.userList[index]?.isShowSkill">-->
<!-- <t-form-item label="才艺名称" :name="`userList[${index}].skillName`" :rules="[{required:user.isShowSkill===true,message: '请填写才艺名称'}]">-->
<!-- <t-input v-model="user.skillName" borderless placeholder="请输入才艺名称"></t-input>-->
<!-- </t-form-item>-->
<!-- <t-form-item label="所需器材" :name="`userList[${index}].equip`" :rules="[{required:user.isShowSkill===true,message: '请填写才艺所需器材'}]">-->
<!-- <t-input v-model="user.equip" borderless placeholder="请填写才艺所需器材"></t-input>-->
<!-- </t-form-item>-->
<!-- </template>-->
<t-form-item label="参加茶叙会" :name="`userList[${index}].isParty`"
:rules="[{required:true,message: '请选择是否参加茶叙会'}]">
<t-radio-group v-model="user.isParty" class="radio-box">
<t-radio :block="false" name="radio" :value="true" label="是"/>
<t-radio :block="false" name="radio" :value="false" label="否"/>
@@ -182,7 +191,7 @@
shape="round"
@click="onSubmit"
>
{{ isSignUp ? '重新提交报名信息' : '提交报名'}}
{{ isSignUp ? '重新提交报名信息' : '提交报名' }}
</t-button>
</view>
@@ -202,13 +211,14 @@
</view>
<view class="agreement-popup-content">
<view class="agreement-popup-text">
<!-- 阅读并同意本承诺书内容,点击"确定并报名"即表示您已充分理解并接受所有条款,承担相应法律责任。-->
<!-- 阅读并同意本承诺书内容,点击"确定并报名"即表示您已充分理解并接受所有条款,承担相应法律责任。-->
<rich-text :nodes="agreementContent"></rich-text>
</view>
</view>
<view class="agreement-popup-footer">
<t-button variant="outline" block @click="closeAgreementPopup" class="agreement-btn">取消</t-button>
<t-button theme="primary" block :disabled="!canConfirmAgreement" @click="confirmAgreement" class="agreement-btn">
<t-button theme="primary" block :disabled="!canConfirmAgreement" @click="confirmAgreement"
class="agreement-btn">
{{ canConfirmAgreement ? '确定并报名' : `请阅读(${agreementCountdown}秒)` }}
</t-button>
</view>
@@ -225,7 +235,9 @@
<text class="notice-popup-title">重要提醒</text>
</view>
<view class="notice-popup-content">
<text class="notice-popup-text">请务必准确填写手机号码和身份证号码,信息有误将导致现场签到失败,影响您的正常使用。</text>
<text class="notice-popup-text">
请务必准确填写手机号码和身份证号码,信息有误将导致现场签到失败,影响您的正常使用。
</text>
</view>
<view class="notice-popup-footer">
<t-button theme="primary" block @click="closeNoticePopup" class="notice-btn">
@@ -244,7 +256,7 @@ import {onLoad} from "@dcloudio/uni-app";
import {useUserStore} from "@/store";
const request = useRequest()
const userStore= useUserStore()
const userStore = useUserStore()
// 当前选中的选项卡索引
const activeTabIndex = ref(0)
@@ -339,16 +351,16 @@ function scrollFormToTop() {
// 引导部分
const guideCurrent = ref(-1)
const guideSteps = [
{
element:()=> document.querySelector('.header-add-btn'),
title: '添加活动报名人员',
placement: 'top'
},
{
element:()=> document.querySelector('.footer'),
title: '提交报名信息',
placement: 'top'
}
{
element: () => document.querySelector('.header-add-btn'),
title: '添加活动报名人员',
placement: 'top'
},
{
element: () => document.querySelector('.footer'),
title: '提交报名信息',
placement: 'top'
}
]
// 报名信息
@@ -377,7 +389,7 @@ onLoad(async (option) => {
await getIsSignUp()
await getAgreement()
// 没报名进行引导
if(!formData.value.userList || formData.value.userList.length === 0){
if (!formData.value.userList || formData.value.userList.length === 0) {
guideCurrent.value = 0
// 默认是本人的信息
formData.value.userList.push({
@@ -406,7 +418,7 @@ async function getAgreement() {
if (code === 0 && data) {
agreementContent.value = data
}
}catch (e){
} catch (e) {
console.error(e)
}
}
@@ -905,8 +917,12 @@ function closeNoticePopup() {
}
@keyframes fadeIn {
from { opacity: 0.6; }
to { opacity: 1; }
from {
opacity: 0.6;
}
to {
opacity: 1;
}
}
.user-actions {
@@ -1023,7 +1039,7 @@ function closeNoticePopup() {
height: 44px;
}
::v-deep .t-form__label--required::before{
::v-deep .t-form__label--required::before {
position: absolute;
left: 8px;
color: #ee0a24;
@@ -47,7 +47,7 @@
<view v-else style="flex: 1;display: flex;justify-content: center;align-items: center">
<t-empty
image="/static/img/empty.png"
description="活动还没有自由组队,组队后方项目报名!"
description="活动还没有自由组队,组队后方可项目报名!"
style="flex: 1">
</t-empty>
</view>
+67 -29
View File
@@ -10,10 +10,10 @@
<div class="content-area">
<div class="team-card">
<div class="team-header">
<!-- <div class="team-logo">-->
<!-- <i class="bi bi-people-fill" v-if="!team.logoUrl"></i>-->
<!-- <img :src="team.logoUrl" alt="团队logo" v-if="team.logoUrl">-->
<!-- </div>-->
<!-- <div class="team-logo">-->
<!-- <i class="bi bi-people-fill" v-if="!team.logoUrl"></i>-->
<!-- <img :src="team.logoUrl" alt="团队logo" v-if="team.logoUrl">-->
<!-- </div>-->
<div class="team-basic-info">
<div class="team-name">{{ team.groupName }}</div>
@@ -24,23 +24,23 @@
<div class="team-stats">
<div class="stat-item">
<div class="stat-icon">
<!-- <i class="bi bi-people"></i>-->
<!-- <i class="bi bi-people"></i>-->
<t-icon name="chart-ring-1"></t-icon>
</div>
<div class="stat-content">
<div class="stat-value">成员:{{ team.groupUsers?.length }}</div>
<!-- <div class="stat-label">成员</div>-->
<!-- <div class="stat-label">成员</div>-->
</div>
</div>
<div class="stat-divider"></div>
<div class="stat-item" @click="queryRank">
<div class="stat-icon">
<!-- <i class="bi bi-trophy"></i>-->
<!-- <i class="bi bi-trophy"></i>-->
<t-icon name="chart-bar"></t-icon>
</div>
<div class="stat-content">
<div class="stat-value">排名:{{ team.totalRank ? team.totalRank : '--' }}</div>
<!-- <div class="stat-label">点击查看排行榜</div>-->
<!-- <div class="stat-label">点击查看排行榜</div>-->
</div>
</div>
</div>
@@ -80,19 +80,29 @@
<!-- 当前角色与申请队长 -->
<div class="role-section">
<div class="role-card" v-if="team.isSelfLeader">
<div class="role-icon">
<i class="bi bi-trophy"></i>
</div>
<div class="role-info">
<div class="role-title">您是队长</div>
<div class="role-desc">拥有团队所有管理权限</div>
<div v-if="team.isSelfLeader">
<div class="role-card">
<div class="role-icon">
<t-icon name="user-safety"></t-icon>
</div>
<div class="role-info">
<div class="role-title">您是队长</div>
<div class="role-desc">拥有团队所有管理权限</div>
</div>
</div>
<t-button block
class="leader-apply-btn"
theme="danger"
variant="outline"
@click="cancelLeader">
取消成为队长
</t-button>
</div>
<div v-if="team.teamIsLeader&&!team.isSelfLeader">
<div class="role-card">
<div class="role-icon">
<i class="bi bi-person"></i>
<t-icon name="face-retouching"></t-icon>
</div>
<div class="role-info">
<div class="role-title">您是普通成员</div>
@@ -104,7 +114,7 @@
<div v-if="!team.teamIsLeader&&!team.isSelfLeader">
<div class="role-card">
<div class="role-icon">
<i class="bi bi-person"></i>
<t-icon name="face-retouching"></t-icon>
</div>
<div class="role-info">
<div class="role-title">您是普通成员</div>
@@ -125,7 +135,7 @@
</view>
<view v-else style="flex: 1;display: flex;justify-content: center;align-items: center">
<t-empty image="/static/img/empty.png"
description="活动还没未开始,请耐心等待!"
description="活动还未开始,请耐心等待!"
style="flex: 1">
</t-empty>
</view>
@@ -161,10 +171,10 @@
<view class="member-list">
<t-cell-group bordered>
<t-cell title="姓名" hover>{{ userInfo.userName }}</t-cell>
<t-cell title="性别" hover>{{userInfo.sex}}</t-cell>
<t-cell title="联系方式" hover>{{userInfo.phone}}</t-cell>
<t-cell title="职务" hover>{{userInfo.position}}</t-cell>
<t-cell title="所属单位" hover>{{userInfo.unitName}}</t-cell>
<t-cell title="性别" hover>{{ userInfo.sex }}</t-cell>
<t-cell title="联系方式" hover>{{ userInfo.phone }}</t-cell>
<t-cell title="职务" hover>{{ userInfo.position }}</t-cell>
<t-cell title="所属单位" hover>{{ userInfo.unitName }}</t-cell>
</t-cell-group>
</view>
</view>
@@ -214,6 +224,35 @@ const actChange = (val) => {
getListAct()
}
// 取消成为队长
const cancelLeader = async () => {
// 弹出确认框
Dialog.confirm({
title: '温馨提示',
content: '确定要取消队长身份吗?',
confirmBtn: '确认取消',
cancelBtn: '再想想',
onConfirm: async () => {
try {
const {code, msg} = await useRequest().post('/client/group/cancel-leader/' + team.value.id);
if (code === 0) {
await getTeamInfo();
Toast({message: '取消成功', theme: 'success'});
} else {
await getTeamInfo();
Toast({message: msg, theme: 'error'});
}
} catch (e) {
Toast({message: e.message || '操作失败', theme: 'error'});
}
},
onCancel: () => {
// 用户取消,可选提示或什么都不做
// Toast({ message: '已取消操作', theme: 'warning' });
},
});
};
// 申请成为队长
const onLeaderConfirm = async () => {
try {
@@ -224,6 +263,7 @@ const onLeaderConfirm = async () => {
Toast({message: '申请成功', theme: 'success'});
leaderConfirmVisible.value = false
} else {
await getTeamInfo();
Toast({message: msg, theme: 'error'});
}
} catch (e) {
@@ -241,7 +281,7 @@ const getTeamInfo = async () => {
try {
const {code, msg, data} = await useRequest().post('/client/group/info/' + pageForm.actId);
if (code === 0) {
if(data){
if (data) {
team.value = data
team.value.teamIsLeader = !!team.value.groupUsers.find(t => t.isLeader)
}
@@ -618,18 +658,16 @@ onLoad(() => {
width: 40px;
height: 40px;
border-radius: 20px;
background: linear-gradient(120deg, #ff5f5c, #ff8c8a);
//background: linear-gradient(120deg, #ff5f5c, #ff8c8a);
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
box-shadow: 0 4px 12px rgba(255, 95, 92, 0.2);
//box-shadow: 0 4px 12px rgba(255, 95, 92, 0.2);
color: #ff5f5c;
font-size: 22px;
}
.role-icon i {
font-size: 20px;
color: white;
}
.role-info {
flex: 1;