From 12f54fb7e96673968294a8c55f08767bdd9b79f1 Mon Sep 17 00:00:00 2001 From: zhouhefeng Date: Tue, 29 Apr 2025 15:53:56 +0800 Subject: [PATCH 1/2] commit --- .../controller/ClientGroupController.java | 68 +++- .../controller/ClientItemController.java | 38 ++- .../service/impl/ClientItemServiceImpl.java | 14 +- .../activity/vo/ClientItemSignUpVO.java | 2 +- .../app/module/activity/models/Activity.java | 10 + .../platform/activity/manage/addOrUpdate.js | 24 +- .../src/pages/activity/team-form/index.vue | 116 ++++--- frontend/src/pages/activity/team/index.vue | 313 +++++++++--------- 8 files changed, 368 insertions(+), 217 deletions(-) diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientGroupController.java b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientGroupController.java index d74a123..cea7cd9 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientGroupController.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientGroupController.java @@ -4,15 +4,21 @@ import cn.dev33.satoken.annotation.SaCheckLogin; import com.budwk.app.base.result.Result; import com.budwk.app.client.module.activity.service.ClientActivityService; import com.budwk.app.module.activity.models.ActGroup; +import com.budwk.app.module.activity.models.ActGroupUser; import com.budwk.app.module.activity.models.ActUser; +import com.budwk.app.module.activity.models.ActivityItem; import com.budwk.app.web.commons.auth.satoken.StpClientUtil; +import org.nutz.dao.Chain; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Lang; import org.nutz.lang.util.NutMap; +import org.nutz.mvc.adaptor.JsonAdaptor; +import org.nutz.mvc.annotation.AdaptBy; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; @@ -37,11 +43,12 @@ public class ClientGroupController { /** * 查询我的活动 + * * @return */ @At("/list-act") @SaCheckLogin(type = StpClientUtil.TYPE) - public Result listAct(){ + public Result listAct() { Sql sql = Sqls.create(""" SELECT t1.id, @@ -64,19 +71,60 @@ public class ClientGroupController { @At("/info/?") @SaCheckLogin(type = StpClientUtil.TYPE) - public Result info(Long activityId){ - ActGroup group = dao.fetch(ActGroup.class, Cnd.where(ActGroup::getActivityId, "=", activityId)); + public Result info(Long activityId) { + Sql sql = Sqls.create("select * from act_group where activityId=@activityId").setParam("activityId", activityId); + sql.setCallback(Sqls.callback.map()); + NutMap map = (NutMap) dao.execute(sql).getResult(); + Sql sqlGroupUser = Sqls.create(""" + SELECT + t1.*, + t2.userName, + t2.unitName, + t2.sex + FROM + `act_group_user` t1 + LEFT JOIN act_user t2 ON t1.userId = t2.userId + WHERE t1.groupId=@groupId + """).setParam("groupId", map.getString("id")); + List groupUsers = clientActivityService.listMap(sqlGroupUser); + map.put("groupUsers", groupUsers); + NutMap leader = groupUsers.stream().filter(nutMap -> nutMap.getBoolean("isLeader")).findFirst().orElse(null); + map.put("isSelfLeader", ""); + if (Lang.isNotEmpty(leader)) { + map.put("isSelfLeader", leader.getString("userId").equals(StpClientUtil.STP.getLoginIdAsString())); + } + + return Result.success(map); + } + + + @At("/apply-leader/?") + @AdaptBy(type = JsonAdaptor.class) + @SaCheckLogin(type = StpClientUtil.TYPE) + public Result applyLeader(Long groupId) { + clientActivityService.dao().update(ActGroupUser.class, + Chain.make("isLeader", true), + Cnd.where(ActGroupUser::getGroupId, "=", groupId) + .and(ActGroupUser::getUserId, "=", StpClientUtil.STP.getLoginIdAsLong())); return Result.success(); } - - /** - * 查询团队成员 - */ - @At("/list-team-user/?") + @At("/list-team/?") @SaCheckLogin(type = StpClientUtil.TYPE) - public Result listTeamUser(Long activityId){ - List list = dao.query(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(ActUser::getIsSignIn, "=", 1)); + public Result listTeam(Long activityId){ + Sql sql = Sqls.create(""" + SELECT + t1.*, + COUNT( t2.id ) isSignUp + FROM + activity_item t1 + LEFT JOIN act_item_user t2 ON t1.id = t2.itemId + WHERE + t1.activityId = @activityId + GROUP BY + t1.id + """).setParam("activityId",activityId); + List list = clientActivityService.listMap(sql); return Result.success(list); } } diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientItemController.java b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientItemController.java index 855a93c..dbc5dd4 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientItemController.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientItemController.java @@ -5,14 +5,18 @@ import com.budwk.app.base.result.Result; import com.budwk.app.client.module.activity.service.ClientItemService; import com.budwk.app.client.module.activity.vo.ClientActivitySignVO; import com.budwk.app.client.module.activity.vo.ClientItemSignUpVO; +import com.budwk.app.module.activity.models.ActGroup; import com.budwk.app.module.activity.models.ActUser; import com.budwk.app.module.activity.models.ActivityItem; import com.budwk.app.module.activity.models.ActivityItemUser; import com.budwk.app.web.commons.auth.satoken.StpClientUtil; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; import org.nutz.mvc.adaptor.JsonAdaptor; import org.nutz.mvc.annotation.AdaptBy; import org.nutz.mvc.annotation.At; @@ -41,6 +45,19 @@ public class ClientItemController { return Result.success(); } + + /** + * 查询出这个活动所有报名的人 + * @param activityId + * @return + */ + @At("/list-apply-user/?") + @SaCheckLogin(type = StpClientUtil.TYPE) + public Result listApplyUser(String activityId){ + List userList = dao.query(ActivityItemUser.class, Cnd.where(ActivityItemUser::getActivityId, "=", activityId)); + return Result.success(userList); + } + /** * 获取项目列表 */ @@ -56,8 +73,23 @@ public class ClientItemController { */ @At("/list-team-user/?") @SaCheckLogin(type = StpClientUtil.TYPE) - public Result listTeamUser(Long activityId){ - List list = dao.query(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(ActUser::getIsSignIn, "=", 1)); + public Result listTeamUser(Long activityId) { + Sql sql = Sqls.create(""" + SELECT + t1.groupId, + t1.userId, + t2.activityId, + t3.userName, + t3.unitName, + t3.sex + FROM + `act_group_user` t1 + LEFT JOIN act_group t2 ON t2.id = t1.groupId + LEFT JOIN act_user t3 ON t3.userId = t1.userId + WHERE + t2.activityId = @activityId + """).setParam("activityId", activityId); + List list = clientItemService.listMap(sql); return Result.success(list); } @@ -66,7 +98,7 @@ public class ClientItemController { */ @At("/list-signup-user") @SaCheckLogin - public Result listSignUpUser(Long activityId,Long itemId) { + public Result listSignUpUser(Long activityId, Long itemId) { List itemUsers = dao.query(ActivityItemUser.class, Cnd.where(ActivityItemUser::getActivityId, "=", activityId).and(ActivityItemUser::getItemId, "=", itemId)); return Result.success(itemUsers); } diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientItemServiceImpl.java b/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientItemServiceImpl.java index 7201e99..515808c 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientItemServiceImpl.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientItemServiceImpl.java @@ -3,6 +3,7 @@ package com.budwk.app.client.module.activity.service.impl; import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.client.module.activity.service.ClientItemService; import com.budwk.app.client.module.activity.vo.ClientItemSignUpVO; +import com.budwk.app.module.activity.models.Activity; import com.budwk.app.module.activity.models.ActivityItemUser; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Cnd; @@ -10,6 +11,8 @@ import org.nutz.dao.Dao; import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.IocBean; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; @IocBean(args = {"refer:dao"}) @@ -21,17 +24,24 @@ public class ClientItemServiceImpl extends BaseServiceImpl imp @Override @Aop(TransAop.READ_COMMITTED) public void signUp(ClientItemSignUpVO signVO) { + Activity activity = dao().fetch(Activity.class, Cnd.where(Activity::getId, "=", signVO.getActivityId())); + if (activity.getItemEndTime().isBefore(LocalDateTime.now())){ + throw new RuntimeException("项目报名已结束!"); + } // 删除掉之前的 clear(Cnd.where(ActivityItemUser::getActivityId, "=", signVO.getActivityId()) .and(ActivityItemUser::getGroupId, "=", signVO.getGroupId()) .and(ActivityItemUser::getItemId, "=", signVO.getItemId()) ); - List userList = signVO.getUserList(); - for (ActivityItemUser itemUser : userList) { + List userList = new ArrayList<>(); + for (Long userId : signVO.getUserList()) { + ActivityItemUser itemUser = new ActivityItemUser(); itemUser.setActivityId(signVO.getActivityId()); itemUser.setItemId(signVO.getItemId()); itemUser.setGroupId(signVO.getGroupId()); + itemUser.setUserId(userId); + userList.add(itemUser); } insert(userList); } diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/vo/ClientItemSignUpVO.java b/backend/src/main/java/com/budwk/app/client/module/activity/vo/ClientItemSignUpVO.java index 0392944..711d5b0 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/vo/ClientItemSignUpVO.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/vo/ClientItemSignUpVO.java @@ -14,6 +14,6 @@ public class ClientItemSignUpVO { private Long groupId; - private List userList; + private List userList; } diff --git a/backend/src/main/java/com/budwk/app/module/activity/models/Activity.java b/backend/src/main/java/com/budwk/app/module/activity/models/Activity.java index cb6c2a9..1e79c50 100644 --- a/backend/src/main/java/com/budwk/app/module/activity/models/Activity.java +++ b/backend/src/main/java/com/budwk/app/module/activity/models/Activity.java @@ -50,6 +50,16 @@ public class Activity extends BaseModel { @ColDefine(type = ColType.DATETIME) private LocalDateTime signEndTime; + @Comment("项目报名开始时间") + @Column + @ColDefine(type = ColType.DATETIME) + private LocalDateTime itemStartTime; + + @Comment("项目报名结束时间") + @Column + @ColDefine(type = ColType.DATETIME) + private LocalDateTime itemEndTime; + @Comment("主办单位") @Column @ColDefine(type = ColType.VARCHAR, width = 255) diff --git a/backend/src/main/resources/views/platform/activity/manage/addOrUpdate.js b/backend/src/main/resources/views/platform/activity/manage/addOrUpdate.js index eb03b96..5e27579 100644 --- a/backend/src/main/resources/views/platform/activity/manage/addOrUpdate.js +++ b/backend/src/main/resources/views/platform/activity/manage/addOrUpdate.js @@ -6,7 +6,7 @@ const addOrUpdate = { - + @@ -43,6 +43,22 @@ const addOrUpdate = { + + + + + + + + + + + + @@ -95,6 +111,12 @@ const addOrUpdate = { signEndTime: [ {required: true, message: '请选择报名结束时间', trigger: ['blur', 'change']} ], + itemStartTime: [ + {required: true, message: '请选择项目报名开始时间', trigger: ['blur', 'change']} + ], + itemEndTime: [ + {required: true, message: '请选择项目报名结束时间', trigger: ['blur', 'change']} + ], hostUnit: [{required: true, message: '请输入主办单位', trigger: ['blur', 'change']}], coHostUnit: [{required: true, message: '请输入承办单位', trigger: ['blur', 'change']}], contact: [{required: true, message: '请输入联系人', trigger: ['blur', 'change']}], diff --git a/frontend/src/pages/activity/team-form/index.vue b/frontend/src/pages/activity/team-form/index.vue index bf28c77..79340b5 100644 --- a/frontend/src/pages/activity/team-form/index.vue +++ b/frontend/src/pages/activity/team-form/index.vue @@ -16,7 +16,7 @@ v-for="project in itemOptions" :key="project.id" class="project-card" - :class="{'project-card--registered': registrationStatus[project.id]?.length}" + :class="{'project-card--registered': registrationStatus.get(project.id)?.length}" @click="selectProject(project.id)" > @@ -24,14 +24,14 @@ {{ project.description }} - - 已报名 {{ registrationStatus[project.id]?.length }}人 + + 已报名 {{ registrationStatus.get(project.id)?.length }}人 - + @@ -53,24 +53,19 @@ - - 已报名 - - - + 确认报名 ({{ selectedMemberIds.length }}人) @@ -116,14 +111,15 @@ const teamMembers = ref([]); onLoad((option) => { if (option.id) { - selectActId.value = option.id; + selectActId.value = Number(option.id); } }); onMounted(async () => { await listActs() await listItems(); - listTeamUser() - // fetchRegistrationStatus(); + await listTeamUser(); + await getApplyUsers(); + fetchRegistrationStatus(); }); // 选中的团队成员 @@ -132,8 +128,7 @@ const selectedMemberIds = ref([]); // 成员选择弹窗显示状态 const showMemberPicker = ref(false); -// 当前项目的报名状态 -const registrationStatus = ref({}); + // 获取活动列表 async function listActs() { @@ -146,9 +141,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) } @@ -171,61 +166,80 @@ async function listItems() { } // 获取团队成员 -async function listTeamUser(){ +async function listTeamUser() { try { - const {code, data, msg} = await request.get('/client/item/list-team-user/'+selectActId.value) + const {code, data, msg} = await request.get('/client/item/list-team-user/' + selectActId.value) if (code === 0) { teamMembers.value = data; - }else{ + } else { Toast.error(msg) } - }catch (e){ + } catch (e) { Toast.error(msg) console.error(e) } } +// 当前项目的报名状态 +const registrationStatus = ref(new Map()); // 获取报名状态 - 使用静态数据 -const fetchRegistrationStatus = async () => { +const fetchRegistrationStatus = () => { + const resultMap = selectedMemberList.value.reduce((acc, item) => { + const key = item.itemId; + if (!acc.has(key)) { + acc.set(key, []); + } + acc.get(key).push(item); + return acc; + }, new Map()); + registrationStatus.value = resultMap; }; // 选择项目 const selectProject = (projectId) => { selectedItemId.value = projectId; - selectedMemberIds.value = []; + selectedMemberIds.value = selectedMemberList.value.filter(v => v.itemId === projectId).map(v => v.userId) + showMemberPicker.value = true; }; +const selectedMemberList = ref([]) +// 每个项目报名的user +const getApplyUsers = async () => { + try { + const {code, data, msg} = await useRequest().post('/client/item/list-apply-user/' + selectActId.value) + if (code === 0) { + selectedMemberList.value = data + } else { + Toast.error(msg) + } + } catch (e) { + Toast.error(e.message) + } +} + + // 提交报名 - 使用静态数据模拟 const submitRegistration = async () => { - if (!selectedMemberIds.value.length) { - Toast.warning('请选择团队成员'); - return; - } try { - console.log(selectedMemberIds.value) - console.log(selectedItemId.value) - console.log(selectActId.value) - - const teamUser = teamMembers.value.filter(v=>selectedMemberIds.value.includes(v.id)) - - // const {code, msg} = await request.post('/client/item/sign-up', { - // activityId: selectActId.value, - // itemId: selectedItemId.value, - // userList: selectedMemberIds.value - // }) - // if (code === 0) { - // Toast.success('报名成功') - // showMemberPicker.value = false; - // selectedMemberIds.value = [] - // }else{ - // Toast.error(msg) - // } - }catch (e){ + let data = {} + data.activityId = selectActId.value + data.itemId = selectedItemId.value + data.userList = selectedMemberIds.value + const {code, msg} = await useRequest().post('/client/item/sign-up', {...data}) + if (code === 0) { + Toast.success('报名成功') + showMemberPicker.value = false; + selectedMemberIds.value = [] + await getApplyUsers(); + fetchRegistrationStatus(); + } else { + Toast.error(msg) + } + } catch (e) { Toast.error(e.message) - console.error(e) } }; diff --git a/frontend/src/pages/activity/team/index.vue b/frontend/src/pages/activity/team/index.vue index 9a6a119..9176656 100644 --- a/frontend/src/pages/activity/team/index.vue +++ b/frontend/src/pages/activity/team/index.vue @@ -1,118 +1,109 @@ + +