commit
This commit is contained in:
+17
-1
@@ -88,10 +88,26 @@ public class ClientActivityController {
|
|||||||
@At("/list-signup-user/?")
|
@At("/list-signup-user/?")
|
||||||
@SaCheckLogin(type = StpClientUtil.TYPE)
|
@SaCheckLogin(type = StpClientUtil.TYPE)
|
||||||
public Result listSignUpUser(Long activityId) {
|
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);
|
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 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.Sqls;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@@ -49,7 +50,7 @@ public class ClientActivityServiceImpl extends BaseServiceImpl<Activity> impleme
|
|||||||
List<ActUser> userList = signVO.getUserList();
|
List<ActUser> userList = signVO.getUserList();
|
||||||
// 首先检查报名人员是否已经在用户表中
|
// 首先检查报名人员是否已经在用户表中
|
||||||
for (ActUser user : userList) {
|
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) {
|
if (clientUser == null) {
|
||||||
// 创建用户
|
// 创建用户
|
||||||
clientUser = new Client_user();
|
clientUser = new Client_user();
|
||||||
@@ -100,4 +101,13 @@ public class ClientActivityServiceImpl extends BaseServiceImpl<Activity> impleme
|
|||||||
actUser.setSignInTime(LocalDateTime.now());
|
actUser.setSignInTime(LocalDateTime.now());
|
||||||
dao().update(actUser, "isSignIn|signInTime");
|
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 lombok.EqualsAndHashCode;
|
||||||
import org.nutz.dao.entity.annotation.*;
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @Author zzr
|
* @Author zzr
|
||||||
@@ -14,7 +16,7 @@ import org.nutz.dao.entity.annotation.*;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Comment("活动队伍")
|
@Comment("活动队伍")
|
||||||
//@Table("act_group")
|
@Table("act_group")
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||||
public class ActGroup extends BaseModel {
|
public class ActGroup extends BaseModel {
|
||||||
@@ -23,18 +25,24 @@ public class ActGroup extends BaseModel {
|
|||||||
@Comment("ID")
|
@Comment("ID")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("活动ID")
|
||||||
|
@ColDefine(customType = "bigint")
|
||||||
|
private Long activityId;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("队伍名称")
|
@Comment("队伍名称")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||||
private String groupName;
|
private String groupName;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("领队Id")
|
@Comment("队伍总得分")
|
||||||
@ColDefine(customType = "bigint")
|
@ColDefine(customType = "decimal", width = 10, precision = 2)
|
||||||
private Long groupLeaderId;
|
private BigDecimal totalScore;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("领队名称")
|
@Comment("队伍总排名")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 128)
|
@ColDefine(type = ColType.INT)
|
||||||
private Long groupLeaderName;
|
private Integer totalRank;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,7 @@ package com.budwk.app.module.activity.models;
|
|||||||
import com.budwk.app.base.model.BaseModel;
|
import com.budwk.app.base.model.BaseModel;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.nutz.dao.entity.annotation.Comment;
|
import org.nutz.dao.entity.annotation.*;
|
||||||
import org.nutz.dao.entity.annotation.Id;
|
|
||||||
import org.nutz.dao.entity.annotation.Table;
|
|
||||||
import org.nutz.dao.entity.annotation.TableMeta;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
@@ -17,7 +14,7 @@ import org.nutz.dao.entity.annotation.TableMeta;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Comment("活动队伍人员")
|
@Comment("活动队伍人员")
|
||||||
//@Table("act_group_user")
|
@Table("act_group_user")
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||||
public class ActGroupUser extends BaseModel {
|
public class ActGroupUser extends BaseModel {
|
||||||
@@ -25,4 +22,19 @@ public class ActGroupUser extends BaseModel {
|
|||||||
@Id
|
@Id
|
||||||
@Comment("ID")
|
@Comment("ID")
|
||||||
private Long 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 lombok.EqualsAndHashCode;
|
||||||
import org.nutz.dao.entity.annotation.*;
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Table("act_item_user")
|
@Table("act_item_user")
|
||||||
@Comment("项目报名人员")
|
@Comment("项目报名人员")
|
||||||
|
|||||||
@@ -20,7 +20,9 @@
|
|||||||
<t-icon name="calendar" size="20px"/>
|
<t-icon name="calendar" size="20px"/>
|
||||||
<view class="info-text-container">
|
<view class="info-text-container">
|
||||||
<text class="info-text-title">报名时间</text>
|
<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>
|
</view>
|
||||||
|
|
||||||
@@ -29,7 +31,10 @@
|
|||||||
<t-icon name="alarm" size="20px"/>
|
<t-icon name="alarm" size="20px"/>
|
||||||
<view class="info-text-container">
|
<view class="info-text-container">
|
||||||
<text class="info-text-title">活动时间</text>
|
<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>
|
</view>
|
||||||
|
|
||||||
@@ -59,7 +64,8 @@
|
|||||||
:navigation="{ type: 'fraction', paginationPosition: 'bottom-right' }"
|
:navigation="{ type: 'fraction', paginationPosition: 'bottom-right' }"
|
||||||
height="500px"
|
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>
|
||||||
<view class="event-item-header">
|
<view class="event-item-header">
|
||||||
<view class="event-item-index">{{ index + 1 }}</view>
|
<view class="event-item-index">{{ index + 1 }}</view>
|
||||||
@@ -142,7 +148,10 @@
|
|||||||
|
|
||||||
<!-- 底部操作栏 -->
|
<!-- 底部操作栏 -->
|
||||||
<view class="footer-bar">
|
<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>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -157,13 +166,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue';
|
import {ref, onMounted, computed} from 'vue';
|
||||||
import {onLoad} from '@dcloudio/uni-app';
|
import {onLoad} from '@dcloudio/uni-app';
|
||||||
import {Toast} from 'tdesign-mobile-vue';
|
import {Toast} from 'tdesign-mobile-vue';
|
||||||
import {useRequest} from "@/utils/request";
|
import {useRequest} from "@/utils/request";
|
||||||
|
|
||||||
const request = useRequest();
|
const request = useRequest();
|
||||||
const actId = ref(null);
|
const actId = ref(null);
|
||||||
|
const isSignUp = ref(null);
|
||||||
const detailData = 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 = () => {
|
const navigateToSignUp = () => {
|
||||||
if (!actId.value) return;
|
if (!actId.value) return;
|
||||||
@@ -208,11 +249,26 @@ const getActivityDetail = async (id) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 判断是否报名
|
||||||
|
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) => {
|
onLoad((option) => {
|
||||||
if (option.id) {
|
if (option.id) {
|
||||||
actId.value = option.id;
|
actId.value = option.id;
|
||||||
getActivityDetail(option.id);
|
getActivityDetail(option.id);
|
||||||
|
getIsSignUp();
|
||||||
} else {
|
} else {
|
||||||
Toast({message: '未找到活动ID', theme: 'error'});
|
Toast({message: '未找到活动ID', theme: 'error'});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
<view style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||||
<t-icon name="castle-7"></t-icon>
|
<t-icon name="castle-7"></t-icon>
|
||||||
{{ item.address }}
|
{{ item.coHostUnit }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -63,9 +63,6 @@
|
|||||||
<view>
|
<view>
|
||||||
100人已报名
|
100人已报名
|
||||||
</view>
|
</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>
|
<t-button theme="primary" shape="round" size="small">立即报名</t-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -74,8 +74,8 @@
|
|||||||
<t-form-item label="是否住宿" :name="`userList[${index}].isStay`"
|
<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-group v-model="user.isStay" class="radio-box">
|
||||||
<t-radio :block="false" name="radio" value="1" label="是"/>
|
<t-radio :block="false" name="radio" :value="true" label="是"/>
|
||||||
<t-radio :block="false" name="radio" value="0" label="否"/>
|
<t-radio :block="false" name="radio" :value="false" label="否"/>
|
||||||
</t-radio-group>
|
</t-radio-group>
|
||||||
</t-form-item>
|
</t-form-item>
|
||||||
</view>
|
</view>
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
shape="round"
|
shape="round"
|
||||||
@click="onSubmit"
|
@click="onSubmit"
|
||||||
>
|
>
|
||||||
提交报名
|
{{ isSignUp ? '重新提交报名信息' : '提交报名'}}
|
||||||
</t-button>
|
</t-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -115,6 +115,7 @@ import {onLoad} from "@dcloudio/uni-app";
|
|||||||
|
|
||||||
const request = useRequest()
|
const request = useRequest()
|
||||||
const actId = ref(null)
|
const actId = ref(null)
|
||||||
|
const isSignUp = ref(null)
|
||||||
const agreementChecked = ref(false)
|
const agreementChecked = ref(false)
|
||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
@@ -127,7 +128,7 @@ const formData = ref({
|
|||||||
position: "测试",
|
position: "测试",
|
||||||
idCard: "421087200004040010",
|
idCard: "421087200004040010",
|
||||||
phone: "18899998888",
|
phone: "18899998888",
|
||||||
isStay: "1"
|
isStay: true
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -136,6 +137,7 @@ onLoad((option) => {
|
|||||||
actId.value = option.id
|
actId.value = option.id
|
||||||
formData.value.activityId = option.id
|
formData.value.activityId = option.id
|
||||||
listSignUpUser()
|
listSignUpUser()
|
||||||
|
getIsSignUp()
|
||||||
} else {
|
} else {
|
||||||
Toast({message: 'ID不存在', theme: 'error'});
|
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() {
|
async function validaForm() {
|
||||||
return new Promise((resolve, reject) => {
|
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
|
<t-cell
|
||||||
title="已报名活动"
|
title="已报名活动"
|
||||||
arrow
|
arrow
|
||||||
@click="navigateTo('/pages/activity/list/index?type=enrolled')"
|
@click="navigateTo('/pages/profile/act')"
|
||||||
hover
|
hover
|
||||||
>
|
>
|
||||||
<template #leftIcon>
|
<template #leftIcon>
|
||||||
<t-icon name="calendar" size="24"/>
|
<t-icon name="calendar" size="24"/>
|
||||||
</template>
|
</template>
|
||||||
<template #rightIcon>
|
|
||||||
<view class="badge">{{ activities.enrolled }}</view>
|
|
||||||
</template>
|
|
||||||
</t-cell>
|
</t-cell>
|
||||||
|
|
||||||
<t-cell
|
<t-cell
|
||||||
|
|||||||
Reference in New Issue
Block a user