This commit is contained in:
那些花儿
2025-05-06 20:15:51 +08:00
parent 178da5f9df
commit c21ba7b426
13 changed files with 120 additions and 137 deletions
@@ -47,6 +47,9 @@ public class ClientActivityServiceImpl extends BaseServiceImpl<Activity> impleme
public void signUp(ClientActivitySignVO signVO) {
LocalDateTime now = LocalDateTime.now();
Client_user selfUser = dao().fetch(Client_user.class, StpClientUtil.STP.getLoginIdAsLong());
dao().fetchLinks(selfUser, "unit");
List<ActUser> userList = signVO.getUserList();
// 首先检查报名人员是否已经在用户表中
for (ActUser user : userList) {
@@ -58,6 +61,7 @@ public class ClientActivityServiceImpl extends BaseServiceImpl<Activity> impleme
clientUser.setSex(user.getSex());
clientUser.setPhone(user.getPhone());
clientUser.setIdCard(user.getIdCard());
clientUser.setUnitId(selfUser.getUnitId());
dao().insert(clientUser);
} else {
// 验证用户之前是不是已经报名 别人帮报 自己报 管理员报
@@ -71,6 +75,7 @@ public class ClientActivityServiceImpl extends BaseServiceImpl<Activity> impleme
user.setActivityId(signVO.getActivityId());
user.setUserId(clientUser.getId());
user.setUnitId(selfUser.getUnitId());
user.setUnitName(signVO.getUnitName());
user.setSignUpContacts(signVO.getContactName());
user.setSignUpMobile(signVO.getContactPhone());
@@ -12,6 +12,7 @@ import java.util.List;
public class ClientActivitySignVO {
private Long activityId;
private Long itemId;
private String unitId;
@@ -40,13 +40,13 @@ const actQrCode = {
width: 150,
height: 150
})
signUpCode.makeCode("/pages/activity/detail/index?id=" + this.actId)
signUpCode.makeCode("https://192.168.41.118:5173" + "/pages/activity/detail/index?id=" + this.actId)
let signInCode = new QRCode(document.getElementById("signInCode"), {
width: 150,
height: 150
})
signInCode.makeCode("/pages/activity/scan-sign/index?id=" + this.actId)
signInCode.makeCode("https://192.168.41.118:5173" + "/pages/activity/scan-sign/index?id=" + this.actId)
},
download() {
// 获取base64
+2 -2
View File
@@ -131,8 +131,8 @@
"pagePath": "pages/activity/rank/index",
"text": "排行榜",
"iconfont": {
"text": "\ue64d",
"selectedText": "\ue64d",
"text": "\ue8b3",
"selectedText": "\ue8b3",
"fontSize": "17px",
"color": "#333",
"selectedColor": "#f45a5a"
@@ -8,6 +8,7 @@
show-error-message
label-align="left"
scroll-to-first-error="auto"
labelWidth="90px"
>
<!-- <view class="form-block">-->
<!-- <view class="form-block-title">-->
@@ -69,9 +70,9 @@
<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-form-item label="是否联系人" :name="`userList[${index}].isContacts`"
: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>
@@ -161,9 +162,9 @@ onLoad((option) => {
listSignUpUser()
getIsSignUp()
// 没报名进行引导
if(formData.userList.length === 0){
if(formData.value.userList.length === 0){
guideCurrent.value = 0
formData.value.unitName = userStore.userInfo?.unit.name
//formData.value.unitName = userStore.userInfo?.unit.name
}
} else {
Toast({message: 'ID不存在', theme: 'error'});
@@ -255,6 +256,7 @@ async function submitForm() {
title: '提交中...',
mask: true,
})
console.log(formData.value)
try {
const {code, data, msg} = await request.post('/client/activity/sign-up', formData.value)
if (code === 0) {
@@ -14,25 +14,25 @@
</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">
<t-button theme="default" shape="round" @click="navigateToHome">返回首页</t-button>
<t-button theme="primary" shape="round" @click="viewRegistrationDetails">查看报名详情</t-button>
<t-button theme="primary" shape="round" @click="navigateToEdit">修改报名信息</t-button>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { Toast } from 'tdesign-mobile-vue';
import { useRequest } from '@/utils/request';
import {ref} from 'vue';
import {onLoad} from '@dcloudio/uni-app';
import {Toast} from 'tdesign-mobile-vue';
import {useRequest} from '@/utils/request';
const request = useRequest();
const actId = ref(null);
@@ -69,9 +69,9 @@ const navigateToHome = () => {
};
// 查看报名详情
const viewRegistrationDetails = () => {
uni.navigateTo({
url: '/pages/activity/registration-details/index?id=' + actId.value
const navigateToEdit = () => {
uni.redirectTo({
url: '/pages/activity/registration-form/index?id=' + actId.value
});
};
</script>
+42 -51
View File
@@ -69,32 +69,10 @@
</view>
</view>
</view>
<div class="bg-decoration">
<svg class="wave" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320">
<path fill="#f45a5a" fill-opacity="0.1" d="M0,160L48,154.7C96,149,192,139,288,144C384,149,480,171,576,176C672,181,768,171,864,154.7C960,139,1056,117,1152,128C1248,139,1344,181,1392,202.7L1440,224L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"></path>
</svg>
<svg class="dots" width="100" height="100" viewBox="0 0 100 100">
<circle fill="#f45a5a" fill-opacity="0.2" cx="10" cy="10" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="30" cy="10" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="50" cy="10" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="70" cy="10" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="90" cy="10" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="10" cy="30" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="30" cy="30" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="50" cy="30" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="70" cy="30" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="90" cy="30" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="10" cy="50" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="30" cy="50" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="50" cy="50" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="70" cy="50" r="3" />
<circle fill="#f45a5a" fill-opacity="0.2" cx="90" cy="50" r="3" />
</svg>
</div>
</template>
<view style="flex: 1;display: flex;justify-content: center;align-items: center">
<t-empty v-if="actOptions && actOptions.length === 0"
<view v-if="actOptions && actOptions.length === 0" style="flex: 1;display: flex;justify-content: center;align-items: center">
<t-empty
image="/static/img/empty.png"
description="报名活动后才能扫码签到"
style="flex: 1">
@@ -114,12 +92,14 @@
<script setup>
import {ref, computed, onMounted} from 'vue';
import {onBackPress, onLoad} from "@dcloudio/uni-app";
import {useRequest} from '@/utils/request';
import {useUserStore} from "@/store";
import {Dialog, Toast} from 'tdesign-mobile-vue';
import moment from 'moment';
import ScanQRCode from '@/components/scanQrCode.vue'
const request = useRequest()
const userStore = useUserStore()
const list = ref([])
const signInfo = ref({})
@@ -138,6 +118,20 @@ onMounted(() => {
listMineAct();
});
onLoad((options)=>{
if(options.id){
selectActId.value = Number(options.id)
signIn()
}
})
// 返回按钮
onBackPress(()=>{
uni.redirectTo({
url: '/pages/index/index'
})
})
// 获取活动列表
async function listMineAct() {
try {
@@ -175,6 +169,10 @@ async function getSignInfo(val) {
// 扫码签到
function handleScan() {
if(signInfo.value.isSignIn){
Toast('您已签到')
return
}
qrScannerRef.value.startScan()
}
@@ -185,6 +183,20 @@ function handleScanSuccess(val) {
Toast.error("请扫描合法的二维码")
return
}
if(val.indexOf('http')!== -1){
const url = new URL(val)
const id = url.searchParams.get('id')
if(id){
val = id
signIn()
return;
}else{
Toast.error("请扫描合法的二维码")
return
}
}
if (String(val) !== String(selectActId.value)) {
Toast.error('请扫码签到当前活动,扫描成功,活动ID为' + val + ",当前选择活动ID为" + selectActId.value)
return
@@ -195,6 +207,11 @@ function handleScanSuccess(val) {
// 签到
async function signIn() {
try {
if(signInfo.value.isSignIn){
Toast.error('您已签到')
return
}
await uni.showLoading({
title: '签到中...',
mask: true,
@@ -538,32 +555,6 @@ function navigateToSignUp(){
color: #999999;
}
.bg-decoration {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
overflow: hidden;
}
.wave {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 200px;
}
.dots {
position: absolute;
bottom: 5%;
right: 5%;
animation: float 4s ease-in-out infinite;
}
/* 导入Animate.css的部分动画 */
.animate__animated {
animation-duration: 1s;
+18 -18
View File
@@ -1,9 +1,10 @@
<template>
<view class="page-container">
<template v-if="actOptions && actOptions.length>0">
<t-dropdown-menu class="top-dropdown">
<t-dropdown-item :options="actOptions" :value="selectActId"/>
</t-dropdown-menu>
<t-dropdown-menu class="top-dropdown">
<t-dropdown-item :options="actOptions" :value="selectActId"/>
</t-dropdown-menu>
<template v-if="actOptions && actOptions.length > 0 && teamMembers.length > 0">
<view class="content-container">
<!-- <view class="page-header">-->
<!-- <text class="page-title">团队报名</text>-->
@@ -25,8 +26,11 @@
<view class="project-card__title">{{ project.name }}</view>
<div style="display: flex;justify-content: flex-end;margin-top: 10px;">
<t-button size="small" class="project-card__button" @click="openDesc(project)">项目介绍</t-button>
<t-button size="small" @click="selectProject(project)" class="project-card__button"> 活动报名 {{
<t-button theme="primary" size="small" class="project-card__button" @click="openDesc(project)">
项目介绍
</t-button>
<t-button theme="primary" size="small" @click="selectProject(project)" class="project-card__button">
活动报名 {{
registrationStatus.get(project.id)?.length ? registrationStatus.get(project.id)?.length : 0
}}人
</t-button>
@@ -41,10 +45,10 @@
</view>
</template>
<view v-else style="flex: 1;display: flex;justify-content: center;align-items: center">
<t-empty v-if="actOptions && actOptions.length === 0"
image="/static/img/empty.png"
description="您没有任何团队信息,无法进行项目报名"
style="flex: 1">
<t-empty
image="/static/img/empty.png"
description="您没有任何团队信息,无法进行项目报名"
style="flex: 1">
</t-empty>
</view>
@@ -205,9 +209,9 @@ async function listActs() {
label: item.title
}
})
// if(selectActId.value === null && data.length){
// selectActId.value = data[0].id
// }
if (selectActId.value === null && data.length) {
selectActId.value = data[0].id
}
} else {
Toast.error(msg)
}
@@ -240,7 +244,6 @@ async function listTeamUser() {
teamMembers.value = data;
isSelfLeader.value = data.find(t => t.userId === userStore?.userInfo.id)?.isLeader
} else {
Toast.error(msg)
}
} catch (e) {
Toast.error(e)
@@ -285,7 +288,6 @@ const getApplyUsers = async () => {
if (code === 0) {
selectedMemberList.value = data
} else {
Toast.error(msg)
}
} catch (e) {
Toast.error(e.message)
@@ -297,7 +299,7 @@ const cancelRegistration = async () => {
let data = {}
data.activityId = selectActId.value
data.itemId = selectedItemId.value
const {code, msg} = await useRequest().post('/client/item/cancel-team-sign-up/' ,{...data})
const {code, msg} = await useRequest().post('/client/item/cancel-team-sign-up/', {...data})
if (code === 0) {
Toast.success('取消报名成功')
showMemberPicker.value = false;
@@ -461,8 +463,6 @@ const submitRegistration = async () => {
.project-card__button {
margin-left: 10px;
background-color: #0052D9;
color: #ffffff;
}
+8 -8
View File
@@ -1,11 +1,11 @@
<template>
<view class="page-container">
<t-sticky>
<t-dropdown-menu class="top-dropdown-menu">
<t-dropdown-item :options="actOptions" :value="pageForm.actId" @change="actChange"/>
</t-dropdown-menu>
</t-sticky>
<view v-if="team">
<t-sticky>
<t-dropdown-menu class="top-dropdown-menu">
<t-dropdown-item :options="actOptions" :value="pageForm.actId" @change="actChange"/>
</t-dropdown-menu>
</t-sticky>
<!-- 团队卡片 -->
<div class="content-area">
<div class="team-card">
@@ -118,8 +118,7 @@
</div>
</view>
<view v-else style="flex: 1;display: flex;justify-content: center;align-items: center">
<t-empty v-if="actOptions && actOptions.length === 0"
image="/static/img/empty.png"
<t-empty image="/static/img/empty.png"
description="您没有任何团队信息"
style="flex: 1">
</t-empty>
@@ -265,7 +264,8 @@ const getListAct = async () => {
// 点击查看成绩排名
const queryRank = () => {
uni.navigateTo({url: '/pages/activity/rank/index?id=' + pageForm.actId})
// uni.navigateTo({url: '/pages/activity/rank/index?id=' + pageForm.actId})
uni.switchTab({url: '/pages/activity/rank/index?id=' + pageForm.actId})
}
// 初始化
+18 -31
View File
@@ -136,6 +136,7 @@ import {ref, reactive, computed, onMounted, onBeforeUnmount} from 'vue'
import {Toast} from 'tdesign-mobile-vue';
import {useRequest} from "@/utils/request";
import {useUserStore} from "@/store";
import {onLoad} from "@dcloudio/uni-app";
const request = useRequest()
const userStore = useUserStore()
@@ -287,44 +288,30 @@ async function handleLogin() {
userStore.smsLogin(loginForm).then(() => {
userStore.getUserInfo().then(() => {
Toast({message: '登录成功', theme: 'success'})
uni.switchTab({
url: '/pages/index/index'
})
const redirect = uni.getStorageSync("REDIRECT_URL")
if(redirect){
if(redirect.startsWith('/pages/index/index') || redirect.startsWith('/pages/profile/index')){
uni.switchTab({
url: redirect
})
}else{
uni.navigateTo({
url: redirect
})
}
}else{
uni.switchTab({
url: '/pages/index/index'
})
}
}).catch(e => {
console.log(e)
Toast({message: e.message, theme: 'error'})
})
}).catch(e => {
console.log(e)
Toast({message: e.message, theme: 'error'})
})
// const {data, code, msg} = await request.post('/client/auth/sms-login', loginForm)
// if (code === 0) {
// Toast({message: '登录成功', theme: 'success'})
// // 保存token
// uni.setStorageSync('token', data)
//
// // 获取之前保存的重定向URL
// const redirectUrl = uni.getStorageSync('REDIRECT_URL') || '/pages/index/index'
// uni.removeStorageSync('REDIRECT_URL') // 使用后删除
//
// // 延迟跳转,让用户看到成功提示
// setTimeout(() => {
// if (redirectUrl.startsWith('/pages/index/') || redirectUrl.startsWith('/pages/profile/')) {
// // 主页和个人中心,使用switchTab
// uni.switchTab({
// url: redirectUrl
// })
// } else {
// // 其他页面使用reLaunch
// uni.reLaunch({
// url: redirectUrl
// })
// }
// }, 1000)
// } else {
// Toast({message: msg, theme: 'error'})
// }
} catch (e) {
console.error(e)
Toast({message: e.message, theme: 'error'})
Binary file not shown.
+2 -5
View File
@@ -19,6 +19,7 @@ export const checkAuth = async () => {
if (token) {
await useUserStore().getUserInfo()
} else {
uni.setStorageSync('REDIRECT_URL', window.location.pathname + window.location.search)
await uni.redirectTo({
url: '/pages/login/index'
})
@@ -88,12 +89,8 @@ async function routeInterceptor(args, whiteList) {
return args
} else {
console.log('拦截导航,跳转到登录页')
// 保存用户尝试访问的页面,以便登录后跳回
try {
uni.setStorageSync('REDIRECT_URL', targetUrl)
} catch (e) {
}
uni.setStorageSync('REDIRECT_URL', targetUrl + args.query)
Dialog.confirm({
title: '提示',
+3 -3
View File
@@ -28,13 +28,13 @@ export default defineConfig({
}
},
server: {
/* https: {
https: {
cert: fs.readFileSync(path.join(__dirname, 'src/ssl/localhost+2.pem')),
key: fs.readFileSync(path.join(__dirname, 'src/ssl/localhost+2-key.pem'))
},*/
},
proxy: {
'/api': {
target: 'http://localhost:9090',
target: 'http://192.168.41.118:9090',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}