diff --git a/backend/application.yaml b/backend/application.yaml index 4ac4425..1a845b5 100644 --- a/backend/application.yaml +++ b/backend/application.yaml @@ -27,7 +27,7 @@ jetty: security: tokenName: token - timeout: 3600 + timeout: 36000 # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) # 允许同一账号并发登录,则系统参数 SessionOnlyOne 有效,亦可踢人下线并多了弹框提示功能 isConcurrent: true diff --git a/backend/src/main/java/com/budwk/app/client/auth/controller/ClientAuthController.java b/backend/src/main/java/com/budwk/app/client/auth/controller/ClientAuthController.java index ec37e6f..68c861b 100644 --- a/backend/src/main/java/com/budwk/app/client/auth/controller/ClientAuthController.java +++ b/backend/src/main/java/com/budwk/app/client/auth/controller/ClientAuthController.java @@ -7,6 +7,7 @@ import com.budwk.app.base.result.Result; import com.budwk.app.client.auth.models.Client_user; import com.budwk.app.client.auth.service.ClientAuthService; import com.budwk.app.client.auth.vo.ClientLoginBody; +import com.budwk.app.client.auth.vo.ClientRegisterBody; import com.budwk.app.sys.services.SysMsgService; import com.budwk.app.sys.services.SysUserService; import com.budwk.app.web.commons.auth.satoken.StpClientUtil; @@ -59,6 +60,22 @@ public class ClientAuthController { public void login(HttpServletRequest req, HttpSession session) { } + + @At("/register") + @Ok("json") + @AdaptBy(type = JsonAdaptor.class) + @ApiOperation(value = "注册", nickname = "/register", httpMethod = "POST") + public Result register(ClientRegisterBody registerBody) { + try { +// String token = clientAuthService.doRegister(registerBody); +// return Result.success().addData(token); + return Result.success(); + } catch (Exception e) { + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + } + /** * 短信登录 */ @@ -68,7 +85,7 @@ public class ClientAuthController { @ApiOperation(value = "短信登录", nickname = "/sms-login", httpMethod = "POST") public Object doSmsLogin(ClientLoginBody loginBody, HttpServletRequest req) { try { - String token = clientAuthService.doSmsLogin(loginBody); + String token = clientAuthService.doLogin(loginBody); return Result.success().addData(token); } catch (Exception e) { log.error(e.getMessage(), e); @@ -76,6 +93,23 @@ public class ClientAuthController { } } + + @At("/send-reg-code/?") + @Ok("json") + @ApiOperation(value = "发送注册验证码", nickname = "/send-reg-code", httpMethod = "POST") + public Result sendRegCode(String phone) { + try { + int count = dao.count(Client_user.class, Cnd.where("phone", "=", phone)); + if (count > 0) { + return Result.error("手机号码已注册,请直接登录"); + } + validateService.getSmsCode(phone); + return Result.success(NutMap.NEW().addv("key", RedisConstant.UCENTER_SMSCODE + phone)).addMsg("发送成功"); + } catch (BaseException e) { + return Result.error(e.getMessage()); + } + } + /** * 发送短信验证码 */ diff --git a/backend/src/main/java/com/budwk/app/client/auth/models/Client_user.java b/backend/src/main/java/com/budwk/app/client/auth/models/Client_user.java index d2dfbb5..89b3545 100644 --- a/backend/src/main/java/com/budwk/app/client/auth/models/Client_user.java +++ b/backend/src/main/java/com/budwk/app/client/auth/models/Client_user.java @@ -43,6 +43,21 @@ public class Client_user extends BaseModel implements Serializable { @Comment("头像") private String avatar; + @Column + @ColDefine(type = ColType.VARCHAR, width = 32) + @Comment("单位ID") + private String unitId; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 255) + @Comment("密码") + private String password; + + @Column + @ColDefine(type = ColType.VARCHAR, width = 255) + @Comment("盐") + private String salt; + @Column @ColDefine(type = ColType.VARCHAR, width = 255) @Comment("openId") diff --git a/backend/src/main/java/com/budwk/app/client/auth/service/ClientAuthService.java b/backend/src/main/java/com/budwk/app/client/auth/service/ClientAuthService.java index cd68c13..67ac60a 100644 --- a/backend/src/main/java/com/budwk/app/client/auth/service/ClientAuthService.java +++ b/backend/src/main/java/com/budwk/app/client/auth/service/ClientAuthService.java @@ -1,6 +1,7 @@ package com.budwk.app.client.auth.service; import com.budwk.app.client.auth.vo.ClientLoginBody; +import com.budwk.app.client.auth.vo.ClientRegisterBody; public interface ClientAuthService { @@ -9,6 +10,12 @@ public interface ClientAuthService { * @param loginBody 登录信息 * @return token */ - String doSmsLogin(ClientLoginBody loginBody); + String doLogin(ClientLoginBody loginBody); + /** + * 注册 + * @param registerBody 注册信息 + * @return token + */ + String doRegister(ClientRegisterBody registerBody); } diff --git a/backend/src/main/java/com/budwk/app/client/auth/service/ClientAuthServiceImpl.java b/backend/src/main/java/com/budwk/app/client/auth/service/ClientAuthServiceImpl.java index 625393c..c12d31f 100644 --- a/backend/src/main/java/com/budwk/app/client/auth/service/ClientAuthServiceImpl.java +++ b/backend/src/main/java/com/budwk/app/client/auth/service/ClientAuthServiceImpl.java @@ -1,14 +1,21 @@ package com.budwk.app.client.auth.service; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; import com.budwk.app.base.exception.BaseException; +import com.budwk.app.base.utils.PwdUtil; import com.budwk.app.client.auth.vo.ClientLoginBody; import com.budwk.app.client.auth.models.Client_user; +import com.budwk.app.client.auth.vo.ClientRegisterBody; import com.budwk.app.web.commons.auth.satoken.StpClientUtil; import com.budwk.app.web.commons.auth.service.ValidateService; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Strings; + +import java.util.List; @IocBean public class ClientAuthServiceImpl implements ClientAuthService { @@ -19,22 +26,50 @@ public class ClientAuthServiceImpl implements ClientAuthService { private ValidateService validateService; @Override - public String doSmsLogin(ClientLoginBody loginBody) { + public String doLogin(ClientLoginBody loginBody) { Client_user user = null; int count = dao.count(Client_user.class, Cnd.where(Client_user::getPhone, "=", loginBody.getPhone())); if (count == 0) { - // 自动注册 - user = new Client_user(); - user.setPhone(loginBody.getPhone()); - user.setUserName("用户" + loginBody.getPhone()); - dao.insert(user); + throw new BaseException("手机号码不存在"); } - validateService.checkSMSCode(loginBody.getPhone(), loginBody.getSmsCode()); user = dao.fetch(Client_user.class, Cnd.where(Client_user::getPhone, "=", loginBody.getPhone())); + if (user == null) { - throw new BaseException("用户登录失败"); + throw new BaseException("用户不存在"); } + + if (StrUtil.isBlank(loginBody.getLoginMethod()) || !List.of("sms", "password").contains(loginBody.getLoginMethod())) { + throw new BaseException("登录方式不正确"); + } + + if (loginBody.getLoginMethod().equals("sms")) { + validateService.checkSMSCode(loginBody.getPhone(), loginBody.getSmsCode()); + } + + if (loginBody.getLoginMethod().equals("password")) { + String hashedPassword = PwdUtil.getPassword(loginBody.getPassword(), user.getSalt()); + if (!Strings.sNull(hashedPassword).equalsIgnoreCase(user.getPassword())) { + throw new BaseException("密码不正确"); + } + } + + StpClientUtil.STP.login(user.getId()); + StpClientUtil.STP.checkLogin(); + return StpClientUtil.STP.getTokenValue(); + } + + @Override + public String doRegister(ClientRegisterBody registerBody) { + int count = dao.count(Client_user.class, Cnd.where(Client_user::getPhone, "=", registerBody.getPhone())); + if (count > 0) { + throw new BaseException("手机号码已注册,请直接登录"); + } + + validateService.checkSMSCode(registerBody.getPhone(), registerBody.getSmsCode()); + + Client_user user = BeanUtil.copyProperties(registerBody, Client_user.class); + dao.insert(user); StpClientUtil.STP.login(user.getId()); StpClientUtil.STP.checkLogin(); return StpClientUtil.STP.getTokenValue(); diff --git a/backend/src/main/java/com/budwk/app/client/auth/vo/ClientLoginBody.java b/backend/src/main/java/com/budwk/app/client/auth/vo/ClientLoginBody.java index f192016..41b39a3 100644 --- a/backend/src/main/java/com/budwk/app/client/auth/vo/ClientLoginBody.java +++ b/backend/src/main/java/com/budwk/app/client/auth/vo/ClientLoginBody.java @@ -9,4 +9,8 @@ public class ClientLoginBody { private String smsCode; + private String password; + + private String loginMethod; + } diff --git a/backend/src/main/java/com/budwk/app/client/auth/vo/ClientRegisterBody.java b/backend/src/main/java/com/budwk/app/client/auth/vo/ClientRegisterBody.java new file mode 100644 index 0000000..bfc5fe4 --- /dev/null +++ b/backend/src/main/java/com/budwk/app/client/auth/vo/ClientRegisterBody.java @@ -0,0 +1,21 @@ +package com.budwk.app.client.auth.vo; + +import lombok.Data; + +@Data +public class ClientRegisterBody { + + private String userName; + + private String sex; + + private String phone; + + private String idCard; + + private String avatar; + + private String unitId; + + private String smsCode; +} diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java index 46a63ca..13d4df1 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java @@ -81,6 +81,7 @@ public class ClientActivityController { return Result.success(); } + /** * 查询报名人员 * 报名人不见得参加活动 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 112b4b4..80d6ca5 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 @@ -117,4 +117,18 @@ public class ClientItemController { } + /** + * 取消项目报名 + * @param signVO + * @return + */ + @At("/cancel-team-sign-up") + @AdaptBy(type = JsonAdaptor.class) + @SaCheckLogin(type = StpClientUtil.TYPE) + public synchronized Result cancelTeamSignUp(ClientActivitySignVO signVO) { + clientItemService.cancelTeamSignUp(signVO); + return Result.success(); + } + + } diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientItemService.java b/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientItemService.java index 4747296..1c20e27 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientItemService.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientItemService.java @@ -1,9 +1,12 @@ package com.budwk.app.client.module.activity.service; import com.budwk.app.base.service.BaseService; +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.ActivityItemUser; public interface ClientItemService extends BaseService { void signUp(ClientItemSignUpVO signVO); + + void cancelTeamSignUp(ClientActivitySignVO signVO); } 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 7e19ac4..e9703a3 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 @@ -2,6 +2,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.ClientActivitySignVO; import com.budwk.app.client.module.activity.vo.ClientItemSignUpVO; import com.budwk.app.module.activity.models.ActGroupUser; import com.budwk.app.module.activity.models.Activity; @@ -59,4 +60,10 @@ public class ClientItemServiceImpl extends BaseServiceImpl imp } insert(userList); } + + @Override + public void cancelTeamSignUp(ClientActivitySignVO signVO) { + clear(Cnd.where(ActivityItemUser::getActivityId, "=", signVO.getActivityId()) + .and(ActivityItemUser::getItemId, "=", signVO.getItemId())); + } } diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/vo/ClientActivitySignVO.java b/backend/src/main/java/com/budwk/app/client/module/activity/vo/ClientActivitySignVO.java index fc7c3ed..5846284 100644 --- a/backend/src/main/java/com/budwk/app/client/module/activity/vo/ClientActivitySignVO.java +++ b/backend/src/main/java/com/budwk/app/client/module/activity/vo/ClientActivitySignVO.java @@ -12,6 +12,7 @@ import java.util.List; public class ClientActivitySignVO { private Long activityId; + private Long itemId; private String unitName; diff --git a/backend/src/main/java/com/budwk/app/web/commons/auth/service/ValidateService.java b/backend/src/main/java/com/budwk/app/web/commons/auth/service/ValidateService.java index 763b2e9..12a1f06 100644 --- a/backend/src/main/java/com/budwk/app/web/commons/auth/service/ValidateService.java +++ b/backend/src/main/java/com/budwk/app/web/commons/auth/service/ValidateService.java @@ -50,8 +50,8 @@ public class ValidateService { if (Strings.isNotBlank(codeFromRedis)) { // throw new BaseException("请1分钟之后再试"); } - ThreadUtil.execute(()->{ - smsSendServer.sendMsg(mobile, "验证码为:"+text); + ThreadUtil.execute(() -> { + smsSendServer.sendCode(mobile, "验证码为:" + text); log.debug("sms code:::" + text); redisService.setex(RedisConstant.UCENTER_SMSCODE + mobile, 300, text); redisService.setex(RedisConstant.UCENTER_SMSCODE + mobile + ":LOCK", 60, text); diff --git a/backend/src/main/java/com/budwk/app/web/commons/ext/sms/SmsService.java b/backend/src/main/java/com/budwk/app/web/commons/ext/sms/SmsService.java index 4a39c16..3976ad9 100644 --- a/backend/src/main/java/com/budwk/app/web/commons/ext/sms/SmsService.java +++ b/backend/src/main/java/com/budwk/app/web/commons/ext/sms/SmsService.java @@ -1,7 +1,14 @@ package com.budwk.app.web.commons.ext.sms; import com.budwk.app.base.exception.BaseException; -import com.budwk.app.base.service.BaseService; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.exception.TencentCloudSDKException; +import com.tencentcloudapi.common.profile.ClientProfile; +import com.tencentcloudapi.common.profile.HttpProfile; +import com.tencentcloudapi.sms.v20190711.SmsClient; +import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest; +import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse; +import lombok.extern.slf4j.Slf4j; import org.nutz.ioc.impl.PropertiesProxy; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; @@ -14,27 +21,124 @@ import org.nutz.log.Logs; * @author wizzer@qq.com */ @IocBean +@Slf4j public class SmsService { - private static final Log log = Logs.get(); + @Inject private PropertiesProxy conf; - @Inject - private BaseService baseService; + /** + * 发送短信验证码 + * + * @param mobile 手机号 + * @param text 验证码 + * @return true发送成功 + * @throws BaseException + */ + public boolean sendCode(String mobile, String text) throws BaseException { + try { + if (!conf.getBoolean("sms.enabled")) { + return true; + } + Credential cred = new Credential(conf.get("sms.tencent.secret-id"), conf.get("sms.tencent.secret-key")); + + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint("sms.tencentcloudapi.com"); + + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + + SmsClient client = new SmsClient(cred, "", clientProfile); + + SendSmsRequest req = new SendSmsRequest(); + String[] phoneNumberSet1 = {"+86" + mobile}; + req.setPhoneNumberSet(phoneNumberSet1); + String[] templateParamSet1 = {text, "5"}; + req.setTemplateParamSet(templateParamSet1); + req.setTemplateID(conf.get("sms.tencent.tpl.login_code")); + req.setSmsSdkAppid(conf.get("sms.tencent.appid")); + req.setSign(conf.get("sms.tencent.sign")); + SendSmsResponse resp = client.SendSms(req); + log.debug(SendSmsResponse.toJsonString(resp)); + return true; + } catch (TencentCloudSDKException tencentCloudSDKException) { + throw new BaseException(tencentCloudSDKException.getMessage()); + } + } + + /** + * 发送注册验证码 + * @param mobile 手机号码 + * @param text 验证码 + * @return true发送成功 + * @throws BaseException + */ + public boolean sendRegCode(String mobile,String text) throws BaseException { + try { + if (!conf.getBoolean("sms.enabled")) { + return true; + } + Credential cred = new Credential(conf.get("sms.tencent.secret-id"), conf.get("sms.tencent.secret-key")); + + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint("sms.tencentcloudapi.com"); + + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + + SmsClient client = new SmsClient(cred, "", clientProfile); + + SendSmsRequest req = new SendSmsRequest(); + String[] phoneNumberSet1 = {"+86" + mobile}; + req.setPhoneNumberSet(phoneNumberSet1); + String[] templateParamSet1 = {text, "5"}; + req.setTemplateParamSet(templateParamSet1); + req.setTemplateID(conf.get("sms.tencent.tpl.reg_code")); + req.setSmsSdkAppid(conf.get("sms.tencent.appid")); + req.setSign(conf.get("sms.tencent.sign")); + SendSmsResponse resp = client.SendSms(req); + log.debug(SendSmsResponse.toJsonString(resp)); + return true; + } catch (TencentCloudSDKException tencentCloudSDKException) { + throw new BaseException(tencentCloudSDKException.getMessage()); + } + } /** * 发送短信通知 * * @param mobile 手机号码(最多200) - * @param text 模板参数值 + * @param param 模板参数值 * @return * @throws BaseException */ - public boolean sendMsg(String mobile, String text) throws BaseException { + public boolean sendMsg(String[] mobile, String[] param) throws BaseException { + try { + if (!conf.getBoolean("sms.enabled")) { + return true; + } + Credential cred = new Credential(conf.get("sms.tencent.secret-id"), conf.get("sms.tencent.secret-key")); - return true; + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint("sms.tencentcloudapi.com"); + + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + + SmsClient client = new SmsClient(cred, "", clientProfile); + + SendSmsRequest req = new SendSmsRequest(); + req.setPhoneNumberSet(mobile); + req.setTemplateParamSet(param); + req.setTemplateID(conf.get("sms.tencent.tpl.msg")); + req.setSmsSdkAppid(conf.get("sms.tencent.appid")); + req.setSign(conf.get("sms.tencent.sign")); + SendSmsResponse resp = client.SendSms(req); + log.debug(SendSmsResponse.toJsonString(resp)); + return true; + } catch (TencentCloudSDKException tencentCloudSDKException) { + throw new BaseException(tencentCloudSDKException.getMessage()); + } } - - } diff --git a/backend/src/main/java/com/budwk/app/web/controllers/open/OpenCommonController.java b/backend/src/main/java/com/budwk/app/web/controllers/open/OpenCommonController.java new file mode 100644 index 0000000..8a9e8f9 --- /dev/null +++ b/backend/src/main/java/com/budwk/app/web/controllers/open/OpenCommonController.java @@ -0,0 +1,28 @@ +package com.budwk.app.web.controllers.open; + +import com.budwk.app.base.result.Result; +import com.budwk.app.sys.models.Sys_unit; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; + +import java.util.List; + +@IocBean +@At("/open/common") +@Ok("json") +public class OpenCommonController { + + @Inject + private Dao dao; + + @At + public Result units() { + List units = dao.query(Sys_unit.class, Cnd.where(Sys_unit::getIsEnable, "=", 1).asc(Sys_unit::getId)); + return Result.success(units); + } + +} diff --git a/backend/src/main/resources/application.yaml b/backend/src/main/resources/application.yaml index 6a8d6bc..b3d8611 100644 --- a/backend/src/main/resources/application.yaml +++ b/backend/src/main/resources/application.yaml @@ -23,11 +23,11 @@ jetty: #结合ftp使用,或用nginx代理ftp路径 #staticPath: E:/project/NutzWk/upload #开发模式静态资源 - staticPathLocal: D:/project/hmc_gbhd/backend/src/main/resources/static + staticPathLocal: E:/projects/hmc_gbhd/src/main/resources/static security: tokenName: token - timeout: 3600 + timeout: 86400 # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) # 允许同一账号并发登录,则系统参数 SessionOnlyOne 有效,亦可踢人下线并多了弹框提示功能 isConcurrent: true @@ -69,7 +69,7 @@ xsssql: beetl: RESOURCE: #本地路径,开发时设置本地路径,便于调试 - rootLocal: D:/project/hmc_gbhd/backend/src/main/resources/views/ + rootLocal: E:/projects/hmc_gbhd/src/main/resources/views/ root: views/ DELIMITER_STATEMENT_START: '' @@ -141,18 +141,24 @@ quartz: connectionProvider: class: com.budwk.app.task.conn.NutConnectionProvider +swagger: + info: + title: 趣味运动会系统 + description: 趣味运动会系统 sms: enabled: false #腾讯云短信配置 tencent: - secret-id: 1 - secret-key: 2 - appid: 1 #应用ID - sign: '萌发开源' #短信签名 + secret-id: 1301383032 + secret-key: AKIDMZWDepjNnxqSotiHZeU6SYOyIMAj24rO + appid: 1400934413 #应用ID + sign: '武汉地大三思科技' #短信签名 tpl: - #验证码模板ID - code: 1 + #登录验证码模板ID + login_code: 2422443 + #注册验证码模板ID + reg_code: 2422440 #短信通知模板ID - msg: 2 + msg: '?' diff --git a/backend/src/main/resources/views/platform/activity/manage/itemForm.js b/backend/src/main/resources/views/platform/activity/manage/itemForm.js index a1d26a2..6ae184b 100644 --- a/backend/src/main/resources/views/platform/activity/manage/itemForm.js +++ b/backend/src/main/resources/views/platform/activity/manage/itemForm.js @@ -31,15 +31,15 @@ const itemForm = { + + + - + + + + 项目介绍 + + + + + {{ team.name }} + + + + + + + + + + + 活动形式 + + {{ team.form }} + + + + + + 评分规则 + + {{ team.rule }} + + + + + + + + @@ -60,7 +101,7 @@ 此项目是团队协作需要全体成员参与 - 此项目需【{{itemOptions.find(p => p.id === selectedItemId)?.num}}】名成员参与 + 此项目需【{{ itemOptions.find(p => p.id === selectedItemId)?.num }}】名成员参与 @@ -81,10 +122,22 @@ - - - 确认报名 ({{ selectedMemberIds.length }}人) - + + + + + 取消报名 + + + + + 确认报名 ({{ selectedMemberIds.length }}人) + + + + + @@ -97,6 +150,7 @@ import {useRequest} from '@/utils/request'; import {Dialog, Toast} from 'tdesign-mobile-vue'; import {onLoad} from '@dcloudio/uni-app'; import {useUserStore} from "@/store"; +import {config} from "@/utils/config"; const request = useRequest(); const userStore = useUserStore(); @@ -106,23 +160,7 @@ const actOptions = ref([]) // 选中的活动ID const selectActId = ref(null); // 项目列表数据 -const itemOptions = ref([ - { - id: 1, - name: '篮球比赛', - description: '3v3篮球友谊赛' - }, - { - id: 2, - name: '足球比赛', - description: '5人制足球赛' - }, - { - id: 3, - name: '羽毛球比赛', - description: '双打友谊赛' - } -]); +const itemOptions = ref([]); // 选中的项目ID const selectedItemId = ref(null); // 团队成员列表 @@ -147,6 +185,14 @@ const selectedMemberIds = ref([]); // 成员选择弹窗显示状态 const showMemberPicker = ref(false); +// 描述选择弹窗显示状态 +const showDescPicker = ref(false); + +const openDesc = (project) => { + team.value = project + showDescPicker.value = true +} + // 获取活动列表 async function listActs() { @@ -192,7 +238,7 @@ async function listTeamUser() { const {code, data, msg} = await request.get('/client/item/list-team-user/' + selectActId.value) if (code === 0) { teamMembers.value = data; - isSelfLeader.value = data.find(t => t.userId===userStore?.userInfo.id)?.isLeader + isSelfLeader.value = data.find(t => t.userId === userStore?.userInfo.id)?.isLeader } else { Toast.error(msg) } @@ -222,10 +268,10 @@ const team = ref({}) // 选择项目 const selectProject = (project) => { selectedItemId.value = project.id; - team.value=project - if (project.isTeamApply){ + team.value = project + if (project.isTeamApply) { selectedMemberIds.value = teamMembers.value.map(v => v.userId) - }else{ + } else { selectedMemberIds.value = selectedMemberList.value.filter(v => v.itemId === project.id).map(v => v.userId) } showMemberPicker.value = true; @@ -245,7 +291,23 @@ const getApplyUsers = async () => { Toast.error(e.message) } } - +// 取消报名 +const cancelRegistration = async () => { + try { + let data = {} + data.activityId = selectActId.value + data.itemId = selectedItemId.value + const {code, msg} = await useRequest().post('/client/item/cancel-team-sign-up/' ,{...data}) + if (code === 0) { + Toast.success('取消报名成功') + showMemberPicker.value = false; + await getApplyUsers(); + fetchRegistrationStatus(); + } + } catch (e) { + console.log(e) + } +}; // 提交报名 - 使用静态数据模拟 const submitRegistration = async () => { @@ -312,6 +374,71 @@ const submitRegistration = async () => { margin-bottom: 24px; } +.event-item-header { + display: flex; + align-items: center; + padding: 20rpx 24rpx; + background-color: #f9f9f9; + border-left: 8rpx solid var(--td-brand-color-5); + position: relative; +} + +.event-item-name { + color: #333333; + font-size: 30rpx; + font-weight: 500; + flex: 1; + margin-right: 8rpx; + position: relative; + z-index: 1; +} + +.event-item-content { + padding: 0; +} + +.event-item-image { + height: 300rpx; + display: block; +} + +.event-item-info { + padding: 24rpx; +} + +.event-item-section { + margin-bottom: 24rpx; + + &:last-child { + margin-bottom: 0; + } +} + +.event-item-section-title { + display: flex; + align-items: center; + margin-bottom: 12rpx; + + .t-icon { + margin-right: 8rpx; + } + + text { + font-size: 28rpx; + font-weight: 500; + color: #333333; + } +} + +.event-item-section-content { + font-size: 28rpx; + color: #666666; + line-height: 1.5; + word-break: break-all; + padding-left: 32rpx; +} + + .project-card { background-color: #fff; border-radius: 12px; @@ -323,6 +450,22 @@ const submitRegistration = async () => { position: relative; overflow: hidden; + .project-card__image { + height: 150px !important; + } + + .project-card__title { + font-size: 15px !important; + margin: 10px; + } + + .project-card__button { + margin-left: 10px; + background-color: #0052D9; + color: #ffffff; + } + + &:active { transform: scale(0.98); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1); diff --git a/frontend/src/pages/activity/team/index.vue b/frontend/src/pages/activity/team/index.vue index 745b0f7..b63f1b3 100644 --- a/frontend/src/pages/activity/team/index.vue +++ b/frontend/src/pages/activity/team/index.vue @@ -59,7 +59,7 @@
{{ team.groupUsers.length }}
-
+
{{ member.userName }} 队长 @@ -144,6 +144,15 @@
+ + + + + 成员信息 + + + + diff --git a/frontend/src/static/img/index.png b/frontend/src/static/img/index.png new file mode 100644 index 0000000..6cc8cf4 Binary files /dev/null and b/frontend/src/static/img/index.png differ diff --git a/frontend/src/utils/config.js b/frontend/src/utils/config.js new file mode 100644 index 0000000..3cb7cf4 --- /dev/null +++ b/frontend/src/utils/config.js @@ -0,0 +1,3 @@ +export const config = { + fileDomain: 'http://localhost', +} \ No newline at end of file diff --git a/frontend/src/utils/routerInterceptor.js b/frontend/src/utils/routerInterceptor.js index 3210941..a88672e 100644 --- a/frontend/src/utils/routerInterceptor.js +++ b/frontend/src/utils/routerInterceptor.js @@ -124,6 +124,7 @@ async function routeInterceptor(args, whiteList) { export const getDefaultWhiteList = () => { return [ '/pages/index/index', - '/pages/login/index' + '/pages/login/index', + '/pages/login/register' ] } diff --git a/frontend/vite.config.js b/frontend/vite.config.js index e57f9e6..845fe00 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -28,13 +28,13 @@ export default defineConfig({ } }, server: { - // https: { - // cert: fs.readFileSync(path.join(__dirname, 'src/ssl/localhost+2.pem')), - // key: fs.readFileSync(path.join(__dirname, 'src/ssl/localhost+2-key.pem')) - // }, + /* 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://192.168.41.118:9090', + target: 'http://localhost:9090', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') }