commit
This commit is contained in:
+17
-1
@@ -88,10 +88,26 @@ public class ClientActivityController {
|
||||
@At("/list-signup-user/?")
|
||||
@SaCheckLogin(type = StpClientUtil.TYPE)
|
||||
public Result listSignUpUser(Long activityId) {
|
||||
List<ActUser> list = dao.query(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(ActUser::getSignUpUserId, "=", StpClientUtil.STP.getLoginIdAsLong()));
|
||||
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||
group.or(ActUser::getUserId, "=", StpClientUtil.STP.getLoginIdAsLong());
|
||||
group.or(ActUser::getSignUpUserId, "=", StpClientUtil.STP.getLoginIdAsLong());
|
||||
List<ActUser> list = dao.query(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(group));
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否报名
|
||||
*/
|
||||
@At("/is-sign-up/?")
|
||||
@SaCheckLogin(type = StpClientUtil.TYPE)
|
||||
public Result isSignUp(Long activityId) {
|
||||
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||
group.or(ActUser::getUserId, "=", StpClientUtil.STP.getLoginIdAsLong());
|
||||
group.or(ActUser::getSignUpUserId, "=", StpClientUtil.STP.getLoginIdAsLong());
|
||||
int count = dao.count(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(group));
|
||||
return Result.success().addData(count > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我报名的活动
|
||||
*/
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.budwk.app.client.module.activity.controller;
|
||||
|
||||
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.ActUser;
|
||||
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.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zhf
|
||||
* @date 2025/4/28 17:35
|
||||
* @description 我的团队
|
||||
*/
|
||||
@IocBean
|
||||
@At("/client/group")
|
||||
@Ok("json:full")
|
||||
public class ClientGroupController {
|
||||
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private ClientActivityService clientActivityService;
|
||||
|
||||
|
||||
/**
|
||||
* 查询我的活动
|
||||
* @return
|
||||
*/
|
||||
@At("/list-act")
|
||||
@SaCheckLogin(type = StpClientUtil.TYPE)
|
||||
public Result listAct(){
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
t1.id,
|
||||
t1.title,
|
||||
t1.address,
|
||||
t1.startTime,
|
||||
t1.endTime,
|
||||
t1.signStartTime,
|
||||
t1.signEndTime
|
||||
FROM
|
||||
activity t1
|
||||
LEFT JOIN act_user t2 ON t1.id = t2.activityId
|
||||
WHERE
|
||||
t2.userId = @userId
|
||||
AND t2.isSignIn =1
|
||||
""").setParam("userId", StpClientUtil.STP.getLoginIdAsLong());
|
||||
List<NutMap> list = clientActivityService.listMap(sql);
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@At("/info/?")
|
||||
@SaCheckLogin(type = StpClientUtil.TYPE)
|
||||
public Result info(Long activityId){
|
||||
ActGroup group = dao.fetch(ActGroup.class, Cnd.where(ActGroup::getActivityId, "=", activityId));
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询团队成员
|
||||
*/
|
||||
@At("/list-team-user/?")
|
||||
@SaCheckLogin(type = StpClientUtil.TYPE)
|
||||
public Result listTeamUser(Long activityId){
|
||||
List<ActUser> list = dao.query(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(ActUser::getIsSignIn, "=", 1));
|
||||
return Result.success(list);
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package com.budwk.app.client.module.activity.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import com.budwk.app.base.page.PageForm;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.client.module.activity.service.ClientActivityService;
|
||||
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.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.adaptor.JsonAdaptor;
|
||||
import org.nutz.mvc.annotation.AdaptBy;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
/**
|
||||
* @author zhf
|
||||
* @date 2025/4/28 15:59
|
||||
* @description 我的
|
||||
*/
|
||||
@IocBean
|
||||
@At("/client/profile")
|
||||
@Ok("json:full")
|
||||
public class ClientProfileController {
|
||||
|
||||
@Inject
|
||||
private ClientActivityService clientActivityService;
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@At("/list-act")
|
||||
@AdaptBy(type = JsonAdaptor.class)
|
||||
@SaCheckLogin(type = StpClientUtil.TYPE)
|
||||
public Result listAct(PageForm pageForm) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
t1.id,
|
||||
t1.title,
|
||||
t1.address,
|
||||
t1.startTime,
|
||||
t1.endTime,
|
||||
t1.signStartTime,
|
||||
t1.signEndTime,
|
||||
t1.cover,
|
||||
t1.coHostUnit
|
||||
FROM
|
||||
activity t1
|
||||
LEFT JOIN act_user t2 ON t1.id=t2.activityId
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||
group.or("t2.userId", "=", StpClientUtil.STP.getLoginIdAsLong());
|
||||
group.or("t2.signUpUserId", "=", StpClientUtil.STP.getLoginIdAsLong());
|
||||
cnd.groupBy("t1.id");
|
||||
cnd.and(group);
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = clientActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消报名
|
||||
*/
|
||||
@At("/cancel-sign-up/?")
|
||||
@SaCheckLogin(type = StpClientUtil.TYPE)
|
||||
public Result cancelSignUp(Long activityId) {
|
||||
clientActivityService.cancelSignUp(activityId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
||||
+4
@@ -25,4 +25,8 @@ public interface ClientActivityService extends BaseService<Activity> {
|
||||
void signIn(Long activityId);
|
||||
|
||||
|
||||
/**
|
||||
* 取消报名
|
||||
*/
|
||||
void cancelSignUp(Long activityId);
|
||||
}
|
||||
|
||||
+11
-1
@@ -14,6 +14,7 @@ import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.time.LocalDate;
|
||||
@@ -49,7 +50,7 @@ public class ClientActivityServiceImpl extends BaseServiceImpl<Activity> impleme
|
||||
List<ActUser> userList = signVO.getUserList();
|
||||
// 首先检查报名人员是否已经在用户表中
|
||||
for (ActUser user : userList) {
|
||||
Client_user clientUser = dao().fetch(Client_user.class, Cnd.where(Client_user::getIdCard, "=", user.getIdCard()));
|
||||
Client_user clientUser = dao().fetch(Client_user.class, Cnd.where(Client_user::getIdCard, "=", user.getIdCard()).or(Client_user::getPhone, "=", user.getPhone()));
|
||||
if (clientUser == null) {
|
||||
// 创建用户
|
||||
clientUser = new Client_user();
|
||||
@@ -100,4 +101,13 @@ public class ClientActivityServiceImpl extends BaseServiceImpl<Activity> impleme
|
||||
actUser.setSignInTime(LocalDateTime.now());
|
||||
dao().update(actUser, "isSignIn|signInTime");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelSignUp(Long activityId) {
|
||||
ActUser actUser = dao().fetch(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(ActUser::getSignUpUserId, "=", StpClientUtil.STP.getLoginIdAsLong()));
|
||||
if (Lang.isEmpty(actUser)) {
|
||||
throw new BaseException("请联系报名人取消报名!");
|
||||
}
|
||||
dao().clear(ActUser.class, Cnd.where(ActUser::getActivityId, "=", activityId).and(ActUser::getSignUpUserId, "=", StpClientUtil.STP.getLoginIdAsLong()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author zzr
|
||||
@@ -14,7 +16,7 @@ import org.nutz.dao.entity.annotation.*;
|
||||
*/
|
||||
@Data
|
||||
@Comment("活动队伍")
|
||||
//@Table("act_group")
|
||||
@Table("act_group")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||
public class ActGroup extends BaseModel {
|
||||
@@ -23,18 +25,24 @@ public class ActGroup extends BaseModel {
|
||||
@Comment("ID")
|
||||
private Long id;
|
||||
|
||||
@Column
|
||||
@Comment("活动ID")
|
||||
@ColDefine(customType = "bigint")
|
||||
private Long activityId;
|
||||
|
||||
@Column
|
||||
@Comment("队伍名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
private String groupName;
|
||||
|
||||
@Column
|
||||
@Comment("领队Id")
|
||||
@ColDefine(customType = "bigint")
|
||||
private Long groupLeaderId;
|
||||
@Comment("队伍总得分")
|
||||
@ColDefine(customType = "decimal", width = 10, precision = 2)
|
||||
private BigDecimal totalScore;
|
||||
|
||||
@Column
|
||||
@Comment("领队名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 128)
|
||||
private Long groupLeaderName;
|
||||
@Comment("队伍总排名")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer totalRank;
|
||||
|
||||
}
|
||||
|
||||
@@ -3,10 +3,7 @@ package com.budwk.app.module.activity.models;
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.Comment;
|
||||
import org.nutz.dao.entity.annotation.Id;
|
||||
import org.nutz.dao.entity.annotation.Table;
|
||||
import org.nutz.dao.entity.annotation.TableMeta;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
@@ -17,7 +14,7 @@ import org.nutz.dao.entity.annotation.TableMeta;
|
||||
*/
|
||||
@Data
|
||||
@Comment("活动队伍人员")
|
||||
//@Table("act_group_user")
|
||||
@Table("act_group_user")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||
public class ActGroupUser extends BaseModel {
|
||||
@@ -25,4 +22,19 @@ public class ActGroupUser extends BaseModel {
|
||||
@Id
|
||||
@Comment("ID")
|
||||
private Long id;
|
||||
|
||||
@Column
|
||||
@Comment("队伍Id")
|
||||
@ColDefine(customType = "bigint")
|
||||
private Long groupId;
|
||||
|
||||
@Column
|
||||
@Comment("用户id")
|
||||
@ColDefine(customType = "bigint")
|
||||
private Long userId;
|
||||
|
||||
@Column
|
||||
@Comment("是否领队")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
private Boolean isLeader;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.budwk.app.module.activity.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author zhf
|
||||
* @date 2025/4/28 17:55
|
||||
* @description
|
||||
*/
|
||||
@Data
|
||||
@Comment("活动项目队伍得分表")
|
||||
@Table("act_item_group_score")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||
public class ActItemGroupScore extends BaseModel {
|
||||
|
||||
@Id
|
||||
@Comment("ID")
|
||||
private Long id;
|
||||
|
||||
@Column
|
||||
@Comment("活动ID")
|
||||
@ColDefine(customType = "bigint")
|
||||
private Long activityId;
|
||||
|
||||
@Column
|
||||
@Comment("活动项目ID")
|
||||
@ColDefine(customType = "bigint")
|
||||
private Long itemId;
|
||||
|
||||
@Column
|
||||
@Comment("队伍ID")
|
||||
@ColDefine(customType = "bigint")
|
||||
private Long groupId;
|
||||
|
||||
@Column
|
||||
@Comment("队伍得分")
|
||||
@ColDefine(customType = "decimal", width = 10, precision = 2)
|
||||
private BigDecimal score;
|
||||
|
||||
@Column
|
||||
@Comment("队伍排名")
|
||||
private Integer rank;
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Table("act_item_user")
|
||||
@Comment("项目报名人员")
|
||||
|
||||
@@ -17,25 +17,30 @@
|
||||
<view class="event-info-section">
|
||||
<!-- 报名时间 -->
|
||||
<view class="info-item">
|
||||
<t-icon name="calendar" size="20px" />
|
||||
<t-icon name="calendar" size="20px"/>
|
||||
<view class="info-text-container">
|
||||
<text class="info-text-title">报名时间</text>
|
||||
<text class="info-text">{{ formatDate(detailData.signStartTime) }} 至 {{ formatDate(detailData.signEndTime) }}</text>
|
||||
<text class="info-text">{{ formatDate(detailData.signStartTime) }} 至
|
||||
{{ formatDate(detailData.signEndTime) }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 活动时间 -->
|
||||
<view class="info-item">
|
||||
<t-icon name="alarm" size="20px" />
|
||||
<t-icon name="alarm" size="20px"/>
|
||||
<view class="info-text-container">
|
||||
<text class="info-text-title">活动时间</text>
|
||||
<text class="info-text">{{ formatDate(detailData.startTime) }} 至 {{ formatDate(detailData.endTime) }}</text>
|
||||
<text class="info-text">{{ formatDate(detailData.startTime) }} 至 {{
|
||||
formatDate(detailData.endTime)
|
||||
}}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 活动地点 -->
|
||||
<view class="info-item">
|
||||
<t-icon name="location" size="20px" />
|
||||
<t-icon name="location" size="20px"/>
|
||||
<view class="info-text-container">
|
||||
<text class="info-text-title">活动地点</text>
|
||||
<text class="info-text">{{ detailData.address }}</text>
|
||||
@@ -59,7 +64,8 @@
|
||||
:navigation="{ type: 'fraction', paginationPosition: 'bottom-right' }"
|
||||
height="500px"
|
||||
>
|
||||
<t-swiper-item v-for="(item, index) in detailData.items" :key="index" style="height: 192px" class="event-item">
|
||||
<t-swiper-item v-for="(item, index) in detailData.items" :key="index" style="height: 192px"
|
||||
class="event-item">
|
||||
<view>
|
||||
<view class="event-item-header">
|
||||
<view class="event-item-index">{{ index + 1 }}</view>
|
||||
@@ -80,7 +86,7 @@
|
||||
<view class="event-item-info">
|
||||
<view class="event-item-section">
|
||||
<view class="event-item-section-title">
|
||||
<t-icon name="flag" size="16px" color="var(--td-brand-color-5)" />
|
||||
<t-icon name="flag" size="16px" color="var(--td-brand-color-5)"/>
|
||||
<text>活动形式</text>
|
||||
</view>
|
||||
<view class="event-item-section-content">{{ item.form }}</view>
|
||||
@@ -88,7 +94,7 @@
|
||||
|
||||
<view class="event-item-section">
|
||||
<view class="event-item-section-title">
|
||||
<t-icon name="chart-bar" size="16px" color="var(--td-brand-color-5)" />
|
||||
<t-icon name="chart-bar" size="16px" color="var(--td-brand-color-5)"/>
|
||||
<text>评分规则</text>
|
||||
</view>
|
||||
<view class="event-item-section-content">{{ item.rule }}</view>
|
||||
@@ -99,57 +105,60 @@
|
||||
</t-swiper-item>
|
||||
</t-swiper>
|
||||
|
||||
<!-- <view class="event-items">-->
|
||||
<!-- <view v-for="(item, index) in detailData.items" :key="item.id" class="event-item">-->
|
||||
<!-- <view class="event-item-header">-->
|
||||
<!-- <view class="event-item-index">{{ index + 1 }}</view>-->
|
||||
<!-- <text class="event-item-name">{{ item.name }}</text>-->
|
||||
<!-- </view>-->
|
||||
<!-- -->
|
||||
<!-- <view class="event-item-content">-->
|
||||
<!-- <!– 项目图片区域 –>-->
|
||||
<!-- <!– v-if="item.img"–>-->
|
||||
<!-- <!– :src="item.img"–>-->
|
||||
<!-- <image-->
|
||||
<!-- src="https://api.zzzmh.cn/v2/bz/v3/getUrl/c9d3deb2880411ebb6edd017c2d2eca220"-->
|
||||
<!-- mode="aspectFill" -->
|
||||
<!-- class="event-item-image"-->
|
||||
<!-- />-->
|
||||
<!-- -->
|
||||
<!-- <!– 项目信息区域 –>-->
|
||||
<!-- <view class="event-item-info">-->
|
||||
<!-- <view class="event-item-section">-->
|
||||
<!-- <view class="event-item-section-title">-->
|
||||
<!-- <t-icon name="flag" size="16px" color="var(--td-brand-color-5)" />-->
|
||||
<!-- <text>活动形式</text>-->
|
||||
<!-- </view>-->
|
||||
<!-- <view class="event-item-section-content">{{ item.form }}</view>-->
|
||||
<!-- </view>-->
|
||||
<!-- -->
|
||||
<!-- <view class="event-item-section">-->
|
||||
<!-- <view class="event-item-section-title">-->
|
||||
<!-- <t-icon name="chart-bar" size="16px" color="var(--td-brand-color-5)" />-->
|
||||
<!-- <text>评分规则</text>-->
|
||||
<!-- </view>-->
|
||||
<!-- <view class="event-item-section-content">{{ item.rule }}</view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<!-- <view class="event-items">-->
|
||||
<!-- <view v-for="(item, index) in detailData.items" :key="item.id" class="event-item">-->
|
||||
<!-- <view class="event-item-header">-->
|
||||
<!-- <view class="event-item-index">{{ index + 1 }}</view>-->
|
||||
<!-- <text class="event-item-name">{{ item.name }}</text>-->
|
||||
<!-- </view>-->
|
||||
<!-- -->
|
||||
<!-- <view class="event-item-content">-->
|
||||
<!-- <!– 项目图片区域 –>-->
|
||||
<!-- <!– v-if="item.img"–>-->
|
||||
<!-- <!– :src="item.img"–>-->
|
||||
<!-- <image-->
|
||||
<!-- src="https://api.zzzmh.cn/v2/bz/v3/getUrl/c9d3deb2880411ebb6edd017c2d2eca220"-->
|
||||
<!-- mode="aspectFill" -->
|
||||
<!-- class="event-item-image"-->
|
||||
<!-- />-->
|
||||
<!-- -->
|
||||
<!-- <!– 项目信息区域 –>-->
|
||||
<!-- <view class="event-item-info">-->
|
||||
<!-- <view class="event-item-section">-->
|
||||
<!-- <view class="event-item-section-title">-->
|
||||
<!-- <t-icon name="flag" size="16px" color="var(--td-brand-color-5)" />-->
|
||||
<!-- <text>活动形式</text>-->
|
||||
<!-- </view>-->
|
||||
<!-- <view class="event-item-section-content">{{ item.form }}</view>-->
|
||||
<!-- </view>-->
|
||||
<!-- -->
|
||||
<!-- <view class="event-item-section">-->
|
||||
<!-- <view class="event-item-section-title">-->
|
||||
<!-- <t-icon name="chart-bar" size="16px" color="var(--td-brand-color-5)" />-->
|
||||
<!-- <text>评分规则</text>-->
|
||||
<!-- </view>-->
|
||||
<!-- <view class="event-item-section-content">{{ item.rule }}</view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="footer-bar">
|
||||
<t-button theme="primary" block @click="navigateToSignUp">立即报名</t-button>
|
||||
<!-- <t-button theme="primary" block @click="navigateToSignUp">立即报名</t-button>-->
|
||||
<t-button theme="primary" block :disabled="bottomButton.disabled" @click="bottomButton.onClick">
|
||||
{{ bottomButton.text }}
|
||||
</t-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- 加载中状态 -->
|
||||
<template v-else>
|
||||
<view class="loading-container">
|
||||
<t-loading theme="dots" size="40rpx" />
|
||||
<t-loading theme="dots" size="40rpx"/>
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
</template>
|
||||
@@ -157,13 +166,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { Toast } from 'tdesign-mobile-vue';
|
||||
import { useRequest } from "@/utils/request";
|
||||
import {ref, onMounted, computed} 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);
|
||||
const isSignUp = ref(null);
|
||||
const detailData = ref(null);
|
||||
|
||||
// 格式化日期
|
||||
@@ -177,6 +187,37 @@ const formatDate = (dateStr) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 底部按钮文字
|
||||
const bottomButton = computed(() => {
|
||||
const {signStartTime, signEndTime} = detailData.value
|
||||
if (signStartTime && signEndTime) {
|
||||
const now = new Date();
|
||||
const startTime = new Date(signStartTime);
|
||||
const endTime = new Date(signEndTime);
|
||||
if (now >= startTime && now <= endTime) {
|
||||
return {
|
||||
text: isSignUp.value ? '修改报名信息' : '立即报名',
|
||||
disabled: false,
|
||||
onClick: navigateToSignUp
|
||||
}
|
||||
} else if (now < startTime) {
|
||||
return {
|
||||
text: `报名开始时间:${formatDate(signStartTime)}`,
|
||||
disabled: true,
|
||||
onClick: () => {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
text: `报名结束时间:${formatDate(signEndTime)}`,
|
||||
disabled: true,
|
||||
onClick: () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 跳转到报名页面
|
||||
const navigateToSignUp = () => {
|
||||
if (!actId.value) return;
|
||||
@@ -194,27 +235,42 @@ const getActivityDetail = async (id) => {
|
||||
duration: 0
|
||||
});
|
||||
|
||||
const { code, data } = await request.get(`/client/activity/get/${id}`);
|
||||
const {code, data} = await request.get(`/client/activity/get/${id}`);
|
||||
if (code === 0 && data) {
|
||||
detailData.value = data;
|
||||
} else {
|
||||
Toast({ message: '获取活动详情失败', theme: 'error' });
|
||||
Toast({message: '获取活动详情失败', theme: 'error'});
|
||||
}
|
||||
|
||||
loading.clear();
|
||||
} catch (error) {
|
||||
console.error('获取活动详情错误', error);
|
||||
Toast({ message: '获取活动详情失败', theme: 'error' });
|
||||
Toast({message: '获取活动详情失败', theme: 'error'});
|
||||
}
|
||||
};
|
||||
|
||||
// 判断是否报名
|
||||
async function getIsSignUp() {
|
||||
try {
|
||||
const {code, data} = await request.get('/client/activity/is-sign-up/' + actId.value)
|
||||
if (code === 0) {
|
||||
isSignUp.value = data
|
||||
} else {
|
||||
Toast({message: '判断是否报名失败', theme: 'error'});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载
|
||||
onLoad((option) => {
|
||||
if (option.id) {
|
||||
actId.value = option.id;
|
||||
getActivityDetail(option.id);
|
||||
getIsSignUp();
|
||||
} else {
|
||||
Toast({ message: '未找到活动ID', theme: 'error' });
|
||||
Toast({message: '未找到活动ID', theme: 'error'});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -461,14 +517,14 @@ onLoad((option) => {
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .t-swiper__container{
|
||||
::v-deep .t-swiper__container {
|
||||
//min-height: 300rpx!important;
|
||||
height: unset;
|
||||
}
|
||||
|
||||
::v-deep .t-swiper-item{
|
||||
::v-deep .t-swiper-item {
|
||||
//height: 100%!important;
|
||||
height: unset!important;
|
||||
height: unset !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</view>
|
||||
<view style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
<t-icon name="castle-7"></t-icon>
|
||||
{{ item.address }}
|
||||
{{ item.coHostUnit }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -63,9 +63,6 @@
|
||||
<view>
|
||||
100人已报名
|
||||
</view>
|
||||
<!-- <image src="https://assets.cumen.fun/upload/017cdaf1-c5fa-788e-eea2-d0ee249f902b/01892580-5db0-be0b-5643-35d6c5a83591"-->
|
||||
<!-- style="width: 105px;height: 40px"-->
|
||||
<!-- ></image>-->
|
||||
<t-button theme="primary" shape="round" size="small">立即报名</t-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -74,8 +74,8 @@
|
||||
<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="1" label="是"/>
|
||||
<t-radio :block="false" name="radio" value="0" label="否"/>
|
||||
<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>
|
||||
@@ -101,7 +101,7 @@
|
||||
shape="round"
|
||||
@click="onSubmit"
|
||||
>
|
||||
提交报名
|
||||
{{ isSignUp ? '重新提交报名信息' : '提交报名'}}
|
||||
</t-button>
|
||||
</view>
|
||||
</view>
|
||||
@@ -115,6 +115,7 @@ import {onLoad} from "@dcloudio/uni-app";
|
||||
|
||||
const request = useRequest()
|
||||
const actId = ref(null)
|
||||
const isSignUp = ref(null)
|
||||
const agreementChecked = ref(false)
|
||||
const formRef = ref(null)
|
||||
const formData = ref({
|
||||
@@ -127,7 +128,7 @@ const formData = ref({
|
||||
position: "测试",
|
||||
idCard: "421087200004040010",
|
||||
phone: "18899998888",
|
||||
isStay: "1"
|
||||
isStay: true
|
||||
}]
|
||||
})
|
||||
|
||||
@@ -136,6 +137,7 @@ onLoad((option) => {
|
||||
actId.value = option.id
|
||||
formData.value.activityId = option.id
|
||||
listSignUpUser()
|
||||
getIsSignUp()
|
||||
} else {
|
||||
Toast({message: 'ID不存在', theme: 'error'});
|
||||
}
|
||||
@@ -158,6 +160,20 @@ async function listSignUpUser() {
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否报名
|
||||
async function getIsSignUp() {
|
||||
try {
|
||||
const {code, data} = await request.get('/client/activity/is-sign-up/' + actId.value)
|
||||
if (code === 0) {
|
||||
isSignUp.value = data
|
||||
} else {
|
||||
Toast({message: '判断是否报名失败', theme: 'error'});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
// 表单验证
|
||||
async function validaForm() {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<view class="header">
|
||||
<view class="search-container">
|
||||
<t-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
placeholder="搜索活动名称"
|
||||
shape="round"
|
||||
class="search-input"
|
||||
@onSearch="handleSearch"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="list-scroll-view"
|
||||
@scrolltolower="handleScrollToBottom"
|
||||
refresher-enabled
|
||||
:refresher-triggered="refresherTriggered"
|
||||
@refresherrefresh="handleRefresh"
|
||||
refresher-background="#f2f3f5"
|
||||
>
|
||||
<view class="list-container">
|
||||
<view
|
||||
class="card-item"
|
||||
v-for="item in dataList"
|
||||
:key="item.id"
|
||||
@click="navigateToDetail(item.id)"
|
||||
>
|
||||
|
||||
<view>
|
||||
<view style="display: flex;align-items: center;margin-bottom: 10px">
|
||||
<image
|
||||
src="https://assets.cumen.fun/upload/017cdaf1-c5fa-788e-eea2-d0ee249f902b/0187376a-3cfa-07b3-3cd6-7479bf463865?x-oss-process=style/720-jpg"
|
||||
style="width: 30px;height: 30px;flex-shrink: 0"
|
||||
></image>
|
||||
<view
|
||||
style="margin-left: 10px;font-weight: 600;white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
{{ item.title }}
|
||||
</view>
|
||||
</view>
|
||||
<view style="display: flex;">
|
||||
<image :src="item.cover" mode="aspectFill"
|
||||
style="flex-shrink:0;width: 120px;height: 90px;border-radius: 5px;"></image>
|
||||
<view
|
||||
style="margin-left:10px;flex:1;overflow:hidden;display: flex;flex-direction: column;justify-content:space-around;color: #534d4d;">
|
||||
<view
|
||||
style="display: flex; align-items: center; column-gap: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
<t-icon name="time"></t-icon>
|
||||
{{ moment(item.startTime).format('MM-DD') }}
|
||||
</view>
|
||||
<view style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
<t-icon name="location"></t-icon>
|
||||
{{ item.address }}
|
||||
</view>
|
||||
<view style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
<t-icon name="castle-7"></t-icon>
|
||||
{{ item.coHostUnit }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
style="border-top: 1px solid #f0f0f0;margin-top: 10px;padding-top: 12px;display: flex;align-items: center;justify-content: space-between">
|
||||
<view>
|
||||
</view>
|
||||
<t-button theme="primary" shape="round" size="small" v-if="canCancelSignUp(item)"
|
||||
@click.stop="cancelSignUp(item)">取消报名
|
||||
</t-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-container">
|
||||
<t-loading v-if="loading" text="加载中..." layout="vertical" theme="circular" size="40rpx"/>
|
||||
<t-divider v-else-if="!hasMore && dataList.length > 0" content="没有更多活动了"/>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<t-empty
|
||||
v-if="!loading && dataList.length === 0"
|
||||
description="暂无活动信息"
|
||||
/>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, reactive, onMounted} from 'vue';
|
||||
import {Dialog, Toast} from 'tdesign-mobile-vue';
|
||||
import {useRequest} from "@/utils/request";
|
||||
import moment from "moment";
|
||||
|
||||
// 活动状态筛选选项
|
||||
const statusOptions = [
|
||||
{value: '', label: '全部'},
|
||||
{value: 'notStartSign', label: '未开始报名'},
|
||||
{value: 'signing', label: '报名中'},
|
||||
{value: 'notStartActivity', label: '活动未开始'},
|
||||
{value: 'activitying', label: '活动进行中'},
|
||||
{value: 'ended', label: '已结束'}
|
||||
];
|
||||
|
||||
// 页面表单数据
|
||||
const pageForm = reactive({
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
status: '' // 全部
|
||||
});
|
||||
|
||||
// 数据与状态
|
||||
const dataList = ref([]);
|
||||
const loading = ref(false);
|
||||
const hasMore = ref(true);
|
||||
const refresherTriggered = ref(false);
|
||||
|
||||
// 选择状态筛选
|
||||
const selectStatusFilter = (status) => {
|
||||
pageForm.status = status;
|
||||
handleSearch();
|
||||
};
|
||||
|
||||
// 获取列表数据
|
||||
const getListData = async (isRefresh = false) => {
|
||||
if (loading.value) return;
|
||||
|
||||
loading.value = true;
|
||||
|
||||
if (isRefresh) {
|
||||
pageForm.pageNumber = 1;
|
||||
}
|
||||
|
||||
// 延时1秒,模拟网络请求
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
try {
|
||||
const response = await useRequest().post('/client/profile/list-act', {
|
||||
...pageForm
|
||||
});
|
||||
|
||||
if (response.code === 0) {
|
||||
const {list, totalCount} = response.data;
|
||||
|
||||
if (isRefresh) {
|
||||
dataList.value = list;
|
||||
} else {
|
||||
dataList.value = [...dataList.value, ...list];
|
||||
}
|
||||
|
||||
pageForm.totalCount = totalCount;
|
||||
hasMore.value = dataList.value.length < totalCount;
|
||||
pageForm.pageNumber++;
|
||||
} else {
|
||||
Toast({message: '获取活动列表失败', theme: 'error'});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取活动列表失败', error);
|
||||
Toast({message: '获取活动列表失败', theme: 'error'});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
|
||||
// 重置下拉刷新状态
|
||||
if (refresherTriggered.value) {
|
||||
refresherTriggered.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//下拉刷新
|
||||
const handleRefresh = () => {
|
||||
if (loading.value) {
|
||||
refresherTriggered.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
refresherTriggered.value = true;
|
||||
pageForm.pageNumber = 1;
|
||||
getListData(true);
|
||||
};
|
||||
|
||||
// 搜索处理
|
||||
const handleSearch = () => {
|
||||
pageForm.pageNumber = 1;
|
||||
hasMore.value = true;
|
||||
dataList.value = [];
|
||||
getListData(true);
|
||||
};
|
||||
|
||||
// 触底加载更多
|
||||
const handleScrollToBottom = () => {
|
||||
if (loading.value || !hasMore.value) return;
|
||||
getListData();
|
||||
};
|
||||
|
||||
// 能否取消报名
|
||||
const canCancelSignUp = (item) => {
|
||||
const {signStartTime, signEndTime} = item;
|
||||
return moment().isBetween(signStartTime, signEndTime);
|
||||
};
|
||||
|
||||
// 取消报名
|
||||
const cancelSignUp = async (item) => {
|
||||
Dialog.confirm({
|
||||
title: '提示',
|
||||
content: '确定要取消报名吗?',
|
||||
confirmBtn: '确定',
|
||||
cancelBtn: '取消',
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
const {code, msg} = await useRequest().post('/client/profile/cancel-sign-up/' + item.id);
|
||||
if (code === 0) {
|
||||
Toast({message: '取消报名成功', theme: 'success'});
|
||||
getListData(true);
|
||||
} else {
|
||||
Toast({message: msg, theme: 'error'});
|
||||
}
|
||||
} catch (error) {
|
||||
Toast({message: '取消报名失败', theme: 'error'});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 跳转详情
|
||||
const navigateToDetail = (id) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/activity/detail/index?id=${id}`
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
getListData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.header {
|
||||
background-color: #fff;
|
||||
padding: 16rpx 0;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.list-scroll-view {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.list-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20rpx 24rpx;
|
||||
}
|
||||
|
||||
.card-item {
|
||||
width: 100%;
|
||||
margin-bottom: 24rpx;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||||
transition: transform 0.3s;
|
||||
//background: url("https://assets.cumen.fun/upload/017cdaf1-c5fa-788e-eea2-d0ee249f902b/0189257e-fc75-5b89-b900-104c706f2d63") top / 100% auto no-repeat,
|
||||
//linear-gradient(to right, white, #ecb5b5);
|
||||
//background: no-repeat, linear-gradient(to right, white, #f6d4d4);
|
||||
background: #ffffff;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
padding: 40rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -87,15 +87,12 @@ onMounted(() => {
|
||||
<t-cell
|
||||
title="已报名活动"
|
||||
arrow
|
||||
@click="navigateTo('/pages/activity/list/index?type=enrolled')"
|
||||
@click="navigateTo('/pages/profile/act')"
|
||||
hover
|
||||
>
|
||||
<template #leftIcon>
|
||||
<t-icon name="calendar" size="24"/>
|
||||
</template>
|
||||
<template #rightIcon>
|
||||
<view class="badge">{{ activities.enrolled }}</view>
|
||||
</template>
|
||||
</t-cell>
|
||||
|
||||
<t-cell
|
||||
|
||||
Reference in New Issue
Block a user