From 709681d7e52674907353c9c07be25e01e3298558 Mon Sep 17 00:00:00 2001 From: yyb <1416014977@qq.com> Date: Thu, 25 Dec 2025 10:03:41 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E7=A7=9F=E8=B5=81=E7=B3=BB=E7=BB=9F1.?= =?UTF-8?q?1.0=20=E6=96=B0=E5=A2=9E=E7=99=BB=E5=BD=95=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=EF=BC=8C=E5=87=86=E5=A4=87=E8=BF=81=E7=A7=BB=E8=AF=A5=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E4=B8=BA=E7=8B=AC=E7=AB=8B=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- m2pool-modules/m2pool-lease/pom.xml | 9 + .../lease/annotation/LoginRequired.java | 10 + .../m2pool/lease/aspect/DecryptAspect.java | 2 +- .../m2pool/lease/config/LoginInterceptor.java | 90 ++++ .../com/m2pool/lease/config/WebMvcConfig.java | 21 + .../com/m2pool/lease/constant/Algorithm.java | 7 +- .../com/m2pool/lease/constant/GpuBrand.java | 47 ++ .../lease/controller/LeaseAuthController.java | 84 +++ .../LeaseMachineAvgPowerController.java | 20 - .../LeaseMachinePowerController.java | 20 - .../controller/LeaseOrderInfoController.java | 2 + .../LeaseOrderInfoV2Controller.java | 2 + .../LeaseProductMachineController.java | 2 + .../LeaseProductMachineV2Controller.java | 4 + .../lease/controller/LeaseShopController.java | 2 + .../controller/LeaseShopV2Controller.java | 2 + .../LeaseShoppingCartController.java | 2 + .../LeaseShoppingCartV2Controller.java | 2 + .../lease/controller/LeaseUserController.java | 16 +- .../com/m2pool/lease/entity/LeaseUser.java | 11 +- .../m2pool/lease/exception/AuthException.java | 10 + .../exception/GlobalExceptionHandler.java | 5 + .../netty/handler/ServerChannelHandler.java | 5 +- .../m2pool/lease/redis/EmailCodeValue.java | 24 + .../com/m2pool/lease/redis/RedisAuthKey.java | 76 +++ .../RedisCoinInfoKey.java} | 4 +- .../config/FastJson2JsonRedisSerializer.java | 73 +++ .../lease/redis/config/RedisConfig.java | 139 +++++ .../lease/redis/service/RedisService.java | 313 ++++++++++++ .../lease/service/LeaseUserService.java | 54 +- .../impl/LeaseOrderInfoServiceImpl.java | 9 +- .../impl/LeaseProductMachineServiceImpl.java | 13 +- .../service/impl/LeaseProductServiceImpl.java | 12 +- .../impl/LeaseShoppingCartServiceImpl.java | 14 +- .../LeaseUserOwnedProductServiceImpl.java | 9 +- .../service/impl/LeaseUserServiceImpl.java | 483 +++++++++++++++++- .../com/m2pool/lease/task/OwnProductTask.java | 17 +- .../com/m2pool/lease/utils/CodeUtils.java | 43 ++ .../com/m2pool/lease/utils/CryptoUtils.java | 30 ++ .../java/com/m2pool/lease/utils/JwtUtils.java | 148 ++++++ .../m2pool/lease/utils/TokenConstants.java | 30 ++ .../m2pool/lease/utils/UserThreadLocal.java | 20 + .../java/com/m2pool/lease/vo/EmailCodeVo.java | 23 + .../vo/{UserURDVo.java => UserLoginVo.java} | 20 +- .../com/m2pool/lease/vo/UserRegisterVo.java | 35 ++ .../src/main/resources/bootstrap-dev.yml | 17 + .../src/main/resources/bootstrap-test.yml | 39 ++ .../mapper/lease/LeaseShopConfigMapper.xml | 2 +- .../resources/templates/emailCode-en.html | 50 ++ .../resources/templates/emailoffline-en.html | 37 ++ 50 files changed, 1967 insertions(+), 142 deletions(-) create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/annotation/LoginRequired.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/config/LoginInterceptor.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/config/WebMvcConfig.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/GpuBrand.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseAuthController.java delete mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseMachineAvgPowerController.java delete mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseMachinePowerController.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/AuthException.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/EmailCodeValue.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/RedisAuthKey.java rename m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/{constant/RedisKey.java => redis/RedisCoinInfoKey.java} (97%) create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/config/FastJson2JsonRedisSerializer.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/config/RedisConfig.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/service/RedisService.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/CodeUtils.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/CryptoUtils.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/JwtUtils.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/TokenConstants.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/UserThreadLocal.java create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/EmailCodeVo.java rename m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/{UserURDVo.java => UserLoginVo.java} (55%) create mode 100644 m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserRegisterVo.java create mode 100644 m2pool-modules/m2pool-lease/src/main/resources/templates/emailCode-en.html create mode 100644 m2pool-modules/m2pool-lease/src/main/resources/templates/emailoffline-en.html diff --git a/m2pool-modules/m2pool-lease/pom.xml b/m2pool-modules/m2pool-lease/pom.xml index e40b527..9ee3437 100644 --- a/m2pool-modules/m2pool-lease/pom.xml +++ b/m2pool-modules/m2pool-lease/pom.xml @@ -164,6 +164,15 @@ 3.1.2 + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-mail + diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/annotation/LoginRequired.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/annotation/LoginRequired.java new file mode 100644 index 0000000..e3e75e2 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/annotation/LoginRequired.java @@ -0,0 +1,10 @@ +package com.m2pool.lease.annotation; + +import java.lang.annotation.*; + +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface LoginRequired { + boolean value() default true; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/aspect/DecryptAspect.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/aspect/DecryptAspect.java index 9755c2a..811b408 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/aspect/DecryptAspect.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/aspect/DecryptAspect.java @@ -90,7 +90,7 @@ public class DecryptAspect { field.set(obj, decryptedValue); } } catch (Exception e) { - throw new RSAException("解密失败: " + e.getMessage()); + throw new RSAException("校验失败: " + e.getMessage()); } finally { field.setAccessible(false); } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/config/LoginInterceptor.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/config/LoginInterceptor.java new file mode 100644 index 0000000..f025bae --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/config/LoginInterceptor.java @@ -0,0 +1,90 @@ +package com.m2pool.lease.config; + +import com.m2pool.common.redis.service.RedisService; +import com.m2pool.lease.annotation.LoginRequired; +import com.m2pool.lease.entity.LeaseUser; +import com.m2pool.lease.exception.AuthException; +import com.m2pool.lease.redis.RedisAuthKey; +import com.m2pool.lease.utils.JwtUtils; +import com.m2pool.lease.utils.UserThreadLocal; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +import static com.m2pool.lease.utils.JwtUtils.AUTHENTICATION; +import static com.m2pool.lease.utils.JwtUtils.EXPIRETIME; + +@Component +public class LoginInterceptor implements HandlerInterceptor { + + @Resource + private RedisService redisService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 如果不是映射到方法直接通过 + if (!(handler instanceof HandlerMethod)) { + return true; + } + + String uri = request.getRequestURI(); + if (uri.contains("/doc.html") || uri.contains("/webjars/") + || uri.contains("/swagger-resources") || uri.contains("/v2/api-docs")) { + return true; + } + + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + + // 获取方法上的注解 + LoginRequired loginRequired = method.getAnnotation(LoginRequired.class); + // 如果方法上没有注解,获取类上的注解 + if (loginRequired == null) { + loginRequired = handlerMethod.getBeanType().getAnnotation(LoginRequired.class); + } + + // 如果没有注解或者注解值为true,则校验token + if (loginRequired == null || loginRequired.value()) { + String token = request.getHeader(AUTHENTICATION); + System.out.println("用户token:"+token); + if (token == null || !isValidToken(token)) { + throw new AuthException("用户未登录"); + } + } + + return true; + } + + + + /** + * 验证token 并刷新token + */ + private boolean isValidToken(String token) { + String userEmail = JwtUtils.getUserName(token); + //1.把userEmail存入ThreadLocal 本地线程变量中 + UserThreadLocal.setUserEmail(userEmail); + //2.校验token是否过期 + String userKey = RedisAuthKey.getUserLoginKey(userEmail); + LeaseUser loginUser = redisService.getCacheObject(userKey); + if (loginUser == null){ + return false; + } + //3.刷新token 过期时间 + redisService.setCacheObject(userKey, loginUser, EXPIRETIME, TimeUnit.MINUTES); + + return true; + } + + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + UserThreadLocal.remove(); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/config/WebMvcConfig.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/config/WebMvcConfig.java new file mode 100644 index 0000000..e220596 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/config/WebMvcConfig.java @@ -0,0 +1,21 @@ +package com.m2pool.lease.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.annotation.Resource; + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + @Resource + private LoginInterceptor loginInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(loginInterceptor) + .addPathPatterns("/**"); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/Algorithm.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/Algorithm.java index d7afab5..c3b5eda 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/Algorithm.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/Algorithm.java @@ -13,13 +13,12 @@ import java.util.Map; * @Author yyb */ public class Algorithm { - // GRS 出块间隔时间单位s public static final String GRS_ALGORITHM= "groestl"; - // Mona 出块间隔时间单位s + public static final String MONA_ALGORITHM= "Lyra2REv2"; - // NEXA 出块间隔时间单位s + public static final String NEXA_ALGORITHM= "NexaPow"; - // RXD 出块间隔时间单位s + public static final String RXD_ALGORITHM= "Sha512256D"; public static final String DGBQ_ALGORITHM= "DigiByte(Qubit)"; diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/GpuBrand.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/GpuBrand.java new file mode 100644 index 0000000..7f2f25d --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/GpuBrand.java @@ -0,0 +1,47 @@ +package com.m2pool.lease.constant; + +import com.m2pool.lease.netty.message.GpuMessage; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Description 币种算法 + * @Date 2025/8/18 16:19 + * @Author yyb + */ +public class GpuBrand { + + private static final String NVIDIA= "NVIDIA"; + + private static final String AMD= "ADM"; + + private static final String APPLE= "APPLE"; + + private static final String INTEL= "INTEL"; + + private static final List BRAND_LIST; + + + static { + BRAND_LIST = new ArrayList<>(); + BRAND_LIST.add(NVIDIA); + BRAND_LIST.add(AMD); + BRAND_LIST.add(APPLE); + BRAND_LIST.add(INTEL); + } + + public static List trimBrand(List targetList) { + return targetList.stream() + .map(model -> { + for (String brand : BRAND_LIST) { + if (model.contains(brand)) { + return model.replace(brand, "").trim(); + } + } + return model.trim(); + }) + .collect(Collectors.toList()); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseAuthController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseAuthController.java new file mode 100644 index 0000000..6d59fa8 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseAuthController.java @@ -0,0 +1,84 @@ +package com.m2pool.lease.controller; + + +import com.m2pool.lease.annotation.Decrypt; +import com.m2pool.lease.annotation.LoginRequired; +import com.m2pool.lease.dto.*; +import com.m2pool.lease.service.LeaseUserService; +import com.m2pool.lease.vo.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.Map; +import java.util.Objects; + +/** + *

+ * 用户表 前端控制器 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Api(tags = "用户授权控制器") +@LoginRequired(value = false) +@RestController +@RequestMapping("/auth") +public class LeaseAuthController { + + @Resource + private LeaseUserService leaseUserService; + + @Decrypt + @PostMapping("/login") + @ApiOperation(value = "用户登录") + public Result> login(@RequestBody UserLoginVo userLoginVo){ + return leaseUserService.login(userLoginVo); + } + + + @Decrypt + @PostMapping("/register") + @ApiOperation(value = "用户注册") + public Result register(@RequestBody UserRegisterVo userRegisterVo){ + return leaseUserService.register(userRegisterVo); + } + + @Decrypt + @LoginRequired + @PostMapping("/updatePassword") + @ApiOperation(value = "修改密码") + public Result updatePassword(@RequestBody UserLoginVo userLoginVo){ + return leaseUserService.updatePassword(userLoginVo); + } + + + @PostMapping("/logout") + @ApiOperation(value = "登出") + public Result logout(){ + return leaseUserService.logout(); + } + + @PostMapping("/sendLoginCode") + @ApiOperation(value = "发送用户登录邮箱验证码") + public Result sendLoginCode(@RequestBody @Valid EmailCodeVo emailCodeVo){ + return leaseUserService.sendLoginCode(emailCodeVo); + } + + @PostMapping("/sendRegisterCode") + @ApiOperation(value = "发送用户注册邮箱验证码") + public Result sendRegisterCode(@RequestBody @Valid EmailCodeVo emailCodeVo){ + return leaseUserService.sendRegisterCode(emailCodeVo); + } + + @PostMapping("/sendUpdatePwdCode") + @ApiOperation(value = "发送修改密码验证码") + public Result sendUpdatePwdCode(@RequestBody @Valid EmailCodeVo emailCodeVo){ + return leaseUserService.sendUpdatePwdCode(emailCodeVo); + } +} + diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseMachineAvgPowerController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseMachineAvgPowerController.java deleted file mode 100644 index 15740b2..0000000 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseMachineAvgPowerController.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.m2pool.lease.controller; - - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - *

- * 矿池nexa机器实时平均算力 前端控制器 - *

- * - * @author yyb - * @since 2025-07-29 - */ -@RestController -@RequestMapping("/machine/avg/power") -public class LeaseMachineAvgPowerController { - -} - diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseMachinePowerController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseMachinePowerController.java deleted file mode 100644 index 5fb106d..0000000 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseMachinePowerController.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.m2pool.lease.controller; - - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - *

- * 已售商品矿工实时算力表 前端控制器 - *

- * - * @author yyb - * @since 2025-07-25 - */ -@RestController -@RequestMapping("/machine/power") -public class LeaseMachinePowerController { - -} - diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoController.java index 3cf2e79..3d81a18 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoController.java @@ -3,6 +3,7 @@ package com.m2pool.lease.controller; import com.m2pool.common.security.annotation.RequiresLogin; import com.m2pool.lease.annotation.Decrypt; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.OrderInfoDto; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.PaymentRecordDto; @@ -29,6 +30,7 @@ import java.util.List; * @since 2025-07-23 */ @Api(tags = "订单控制器") +@LoginRequired @RestController @RequestMapping("/order/info") public class LeaseOrderInfoController { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoV2Controller.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoV2Controller.java index 6872ae9..190928f 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoV2Controller.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseOrderInfoV2Controller.java @@ -2,6 +2,7 @@ package com.m2pool.lease.controller; import com.m2pool.lease.annotation.Decrypt; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.Result; import com.m2pool.lease.dto.v2.*; @@ -29,6 +30,7 @@ import java.util.List; * @since 2025-07-23 */ @Api(tags = "v2版本--订单控制器") +@LoginRequired @RestController @RequestMapping("/v2/order/info") public class LeaseOrderInfoV2Controller { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineController.java index 09ac4e6..8f126e8 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineController.java @@ -1,6 +1,7 @@ package com.m2pool.lease.controller; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.ProductUpdateMachineDto; import com.m2pool.lease.dto.Result; @@ -27,6 +28,7 @@ import java.util.Map; * @since 2025-07-23 */ @Api(tags = "商品矿机控制器(库存控制器)") +@LoginRequired @RestController @RequestMapping("/product/machine") public class LeaseProductMachineController { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineV2Controller.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineV2Controller.java index 17e6de8..83408cd 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineV2Controller.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseProductMachineV2Controller.java @@ -1,6 +1,7 @@ package com.m2pool.lease.controller; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.*; import com.m2pool.lease.dto.v2.MachineInfoDto; import com.m2pool.lease.dto.v2.SellerMachineInfoDto; @@ -24,6 +25,7 @@ import java.util.List; * @since 2025-07-23 */ @Api(tags = "v2版本--矿机控制器类") +@LoginRequired @RestController @RequestMapping("/v2/product/machine") public class LeaseProductMachineV2Controller { @@ -33,6 +35,7 @@ public class LeaseProductMachineV2Controller { private LeaseMachineService leaseMachineService; @ApiOperation("商城首页---店铺列表") + @LoginRequired(value = false) @PostMapping("/getShopList") public PageResult getShopList(@RequestBody(required = false) ProductPageVo productPageVo) { if(productPageVo == null){ @@ -43,6 +46,7 @@ public class LeaseProductMachineV2Controller { @ApiOperation("商城首页---店铺对应矿机详情列表") + @LoginRequired(value = false) @PostMapping("/getShopMachineList") public PageResult getShopMachineList(@RequestBody ShopMachineVo shopMachineVo) { return leaseMachineService.getShopMachineList(shopMachineVo); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopController.java index 1a29d4d..38408e7 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopController.java @@ -1,6 +1,7 @@ package com.m2pool.lease.controller; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.*; import com.m2pool.lease.service.LeaseShopService; import com.m2pool.lease.vo.BaseVo; @@ -22,6 +23,7 @@ import java.util.List; * @since 2025-08-05 */ @Api(tags = "店铺控制器") +@LoginRequired @RestController @RequestMapping("/shop") public class LeaseShopController { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopV2Controller.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopV2Controller.java index 3613a7f..00470a3 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopV2Controller.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShopV2Controller.java @@ -3,6 +3,7 @@ package com.m2pool.lease.controller; import com.m2pool.lease.annotation.Decrypt; import com.m2pool.lease.annotation.LedgerLog; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.Result; import com.m2pool.lease.dto.v2.PayWithdrawSellerRecordDto; @@ -31,6 +32,7 @@ import java.util.List; * @since 2025-08-05 */ @Api(tags = "v2版本--店铺控制器") +@LoginRequired @RestController @RequestMapping("/v2/shop") public class LeaseShopV2Controller { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartController.java index c8e8488..2517bfe 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartController.java @@ -1,6 +1,7 @@ package com.m2pool.lease.controller; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.Result; import com.m2pool.lease.dto.ShopCartDto; @@ -28,6 +29,7 @@ import java.util.List; * @since 2025-07-23 */ @Api(tags = "购物车表控制器") +@LoginRequired @RestController @RequestMapping("/shopping/cart") public class LeaseShoppingCartController { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartV2Controller.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartV2Controller.java index 21c1bf9..c9ce578 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartV2Controller.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseShoppingCartV2Controller.java @@ -1,6 +1,7 @@ package com.m2pool.lease.controller; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.PageResult; import com.m2pool.lease.dto.Result; import com.m2pool.lease.dto.ShopCartDto; @@ -31,6 +32,7 @@ import java.util.List; * @since 2025-07-23 */ @Api(tags = "v2版本---购物车表控制器") +@LoginRequired @RestController @RequestMapping("/v2/shopping/cart") public class LeaseShoppingCartV2Controller { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseUserController.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseUserController.java index f8820a3..e0da72a 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseUserController.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/controller/LeaseUserController.java @@ -1,12 +1,15 @@ package com.m2pool.lease.controller; -import com.m2pool.common.security.annotation.RequiresLogin; import com.m2pool.lease.annotation.Decrypt; import com.m2pool.lease.annotation.LedgerLog; +import com.m2pool.lease.annotation.LoginRequired; import com.m2pool.lease.dto.*; import com.m2pool.lease.service.LeaseUserService; -import com.m2pool.lease.vo.*; +import com.m2pool.lease.vo.BalancePageVo; +import com.m2pool.lease.vo.BalanceVo; +import com.m2pool.lease.vo.ChainAndCoinVo; +import com.m2pool.lease.vo.RecordTypePageVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; @@ -24,19 +27,14 @@ import java.util.List; * @author yyb * @since 2025-07-23 */ -@Api(tags = "用户控制器") +@Api(tags = "用户信息控制器") +@LoginRequired @RestController @RequestMapping("/user") public class LeaseUserController { @Resource private LeaseUserService leaseUserService; - @PostMapping("/login") - @ApiOperation(value = "用户登录/注册") - @Deprecated - public Result login(@RequestBody UserURDVo userURDVo){ - return leaseUserService.login(userURDVo); - } @PostMapping("/bindWallet") diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseUser.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseUser.java index 6955012..8e785d8 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseUser.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/entity/LeaseUser.java @@ -39,8 +39,15 @@ public class LeaseUser implements Serializable { * 密码 */ private String password; + /** + * 登录token + */ + private String token; - + /** + * 最后登录时间 + */ + private LocalDateTime lastLoginTime; /** * 创建时间 */ @@ -51,5 +58,7 @@ public class LeaseUser implements Serializable { */ private LocalDateTime updateTime; + private Boolean del; + } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/AuthException.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/AuthException.java new file mode 100644 index 0000000..dd0dfc2 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/AuthException.java @@ -0,0 +1,10 @@ +package com.m2pool.lease.exception; + +/** + * 权限校验异常 + */ +public class AuthException extends RuntimeException { + public AuthException(String message) { + super(message); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/GlobalExceptionHandler.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/GlobalExceptionHandler.java index 6e5b562..24bbcac 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/GlobalExceptionHandler.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/exception/GlobalExceptionHandler.java @@ -46,6 +46,11 @@ public class GlobalExceptionHandler { return Result.fail(e.getMessage()); } + @ExceptionHandler(AuthException.class) + public Result handleAuthException(AuthException e) { + return Result.fail(e.getMessage()); + } + /** * 处理其他未明确捕获的异常,返回统一的错误结果。 * diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ServerChannelHandler.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ServerChannelHandler.java index b2c6c47..1ed325b 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ServerChannelHandler.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/netty/handler/ServerChannelHandler.java @@ -3,6 +3,7 @@ package com.m2pool.lease.netty.handler; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.m2pool.lease.constant.GpuBrand; import com.m2pool.lease.dto.v2.CoinAndAlgorithmDto; import com.m2pool.lease.dto.v2.MachineConfigDto; import com.m2pool.lease.entity.*; @@ -93,8 +94,7 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler gpus = gpuAndSoftMessage.getGpus(); List miningsofts = gpuAndSoftMessage.getMiningsofts(); - List modelList = gpus.values().stream().map(GpuMessage::getModel).collect(Collectors.toList()); - + List modelList = GpuBrand.trimBrand(gpus.values().stream().map(GpuMessage::getModel).collect(Collectors.toList())); //挖矿软件公共配置 List supportAlgorithmAndCoin = leaseMiningSoftwareConfigMapper.selectSupportAlgorithm(miningsofts,modelList); // 新增主机相关信息 @@ -162,7 +162,6 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler packageInsert(Long machineId,Map gpus,List supportAlgorithmAndCoin){ List list = new ArrayList<>(); - System.out.println("gpu信息"+ JSONUtil.toJsonStr(gpus.values())); for (GpuMessage value : gpus.values()) { for (CoinAndAlgorithmDto coinAndAlgorithmDto : supportAlgorithmAndCoin) { if (coinAndAlgorithmDto.getModel() != null && value.getModel().contains(coinAndAlgorithmDto.getModel())){ diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/EmailCodeValue.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/EmailCodeValue.java new file mode 100644 index 0000000..0d50c79 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/EmailCodeValue.java @@ -0,0 +1,24 @@ +package com.m2pool.lease.redis; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @Description 用户登录对象 + * @Date 2024/6/11 14:13 + * @Author dy + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class EmailCodeValue implements Serializable { + + private String email; + + private String emailCode; + + private int times; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/RedisAuthKey.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/RedisAuthKey.java new file mode 100644 index 0000000..8ef7985 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/RedisAuthKey.java @@ -0,0 +1,76 @@ +package com.m2pool.lease.redis; + +/** + * @Description 用户权限redis + * @Date 2025/12/23 16:19 + * @Author yyb + */ +public class RedisAuthKey { + + private static final String LOGIN_CODE_KEY= "login:code"; + + private static final String REGISTER_CODE_KEY= "register:code"; + + private static final String UPDATE_PASSWORD_CODE_KEY= "update:password:code"; + + private static final String USER_LOCK_KEY= "user:lock"; + + private static final String PASSWORD_ERROR_COUNT_KEY= "password:error:count"; + + private static final String USER_LOGIN_KEY= "user:login"; + + /** + * 获取登录验证码key + * @param email + * @return + */ + public static String getLoginCodeKey(String email) { + return LOGIN_CODE_KEY + ":" + email; + } + + /** + * 获取注册验证码key + * @param email + * @return + */ + public static String getRegisterCodeKey(String email) { + return REGISTER_CODE_KEY + ":" + email; + } + + /** + * 获取修改密码验证码key + * @param email + * @return + */ + public static String getUpdatePasswordCodeKey(String email) { + return UPDATE_PASSWORD_CODE_KEY + ":" + email; + } + + /** + * 获取用户密码输入次数过多 禁止登录 key + * @param email + * @return + */ + public static String getUserLockKey(String email) { + return USER_LOCK_KEY + ":" + email; + } + + /** + * 获取用户密码输入次数 key + * @param email + * @return + */ + public static String getPasswordErrorCountKey(String email) { + return PASSWORD_ERROR_COUNT_KEY + ":" + email; + } + + /** + * 获取用户登录信息 key + * @param email + * @return + */ + public static String getUserLoginKey(String email) { + return USER_LOGIN_KEY + ":" + email; + } + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/RedisKey.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/RedisCoinInfoKey.java similarity index 97% rename from m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/RedisKey.java rename to m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/RedisCoinInfoKey.java index c64cdec..44800e5 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/constant/RedisKey.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/RedisCoinInfoKey.java @@ -1,4 +1,4 @@ -package com.m2pool.lease.constant; +package com.m2pool.lease.redis; import java.util.Collections; import java.util.HashMap; @@ -9,7 +9,7 @@ import java.util.Map; * @Date 2025/8/18 09:49 * @Author yyb */ -public class RedisKey { +public class RedisCoinInfoKey { // 静态不可变的 Map,存储币种名和对应价格标识 private static final Map COIN_PRICE_MAP; diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/config/FastJson2JsonRedisSerializer.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/config/FastJson2JsonRedisSerializer.java new file mode 100644 index 0000000..1047ccb --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/config/FastJson2JsonRedisSerializer.java @@ -0,0 +1,73 @@ +package com.m2pool.lease.redis.config; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; +import org.springframework.util.Assert; + +import java.nio.charset.Charset; + +/** + * @Description redis使用FastJson序列化 + * @Date 2024/6/13 10:01 + * @Author dy + */ +public class FastJson2JsonRedisSerializer implements RedisSerializer { + + @SuppressWarnings("unused") + private ObjectMapper objectMapper = new ObjectMapper(); + + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + private Class clazz; + + static + { + ParserConfig.getGlobalInstance().setAutoTypeSupport(true); + } + + public FastJson2JsonRedisSerializer(Class clazz) + { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException + { + if (t == null) + { + return new byte[0]; + } + return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException + { + if (bytes == null || bytes.length <= 0) + { + return null; + } + String str = new String(bytes, DEFAULT_CHARSET); + + return JSON.parseObject(str, clazz); + } + + public void setObjectMapper(ObjectMapper objectMapper) + { + Assert.notNull(objectMapper, "'objectMapper' must not be null"); + this.objectMapper = objectMapper; + } + + protected JavaType getJavaType(Class clazz) + { + return TypeFactory.defaultInstance().constructType(clazz); + } + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/config/RedisConfig.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/config/RedisConfig.java new file mode 100644 index 0000000..e421534 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/config/RedisConfig.java @@ -0,0 +1,139 @@ +//package com.m2pool.lease.redis.config; +// +//import com.fasterxml.jackson.annotation.JsonAutoDetect; +//import com.fasterxml.jackson.annotation.JsonTypeInfo; +//import com.fasterxml.jackson.annotation.PropertyAccessor; +//import com.fasterxml.jackson.databind.ObjectMapper; +//import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +//import org.springframework.beans.factory.annotation.Qualifier; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.cache.annotation.CachingConfigurerSupport; +//import org.springframework.cache.annotation.EnableCaching; +//import org.springframework.cloud.context.config.annotation.RefreshScope; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.context.annotation.Primary; +//import org.springframework.data.redis.connection.RedisConnectionFactory; +//import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.data.redis.core.script.DefaultRedisScript; +//import org.springframework.data.redis.serializer.StringRedisSerializer; +// +///** +// * @Description redis配置 +// * @Date 2024/6/13 09:58 +// * @Author dy +// */ +//@RefreshScope +//@Configuration +//@EnableCaching +//public class RedisConfig extends CachingConfigurerSupport { +// +// @Value("${spring.redis.host}") +// private String host; +// @Value("${spring.redis.port}") +// private int port; +// @Value("${spring.redis.database:0}") +// private int database = 0; +// +// @Bean +// @SuppressWarnings(value = { "unchecked", "rawtypes" }) +// public RedisTemplate redisTemplate(@Qualifier("redisConnectionFactory0") RedisConnectionFactory connectionFactory) +// { +// RedisTemplate template = new RedisTemplate<>(); +// template.setConnectionFactory(connectionFactory); +// +// FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); +// +// +// ObjectMapper mapper = new ObjectMapper(); +// mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); +// mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); +// serializer.setObjectMapper(mapper); +// +// // 使用StringRedisSerializer来序列化和反序列化redis的key值 +// template.setKeySerializer(new StringRedisSerializer()); +// template.setValueSerializer(serializer); +// +// // Hash的key也采用StringRedisSerializer的序列化方式 +// template.setHashKeySerializer(new StringRedisSerializer()); +// template.setHashValueSerializer(serializer); +// +// template.afterPropertiesSet(); +// return template; +// } +// +// @Bean(name = "redisTemplate7") +// public RedisTemplate redisTemplate7(@Qualifier("redisConnectionFactory7") RedisConnectionFactory redisConnectionFactory0) { +// RedisTemplate template = new RedisTemplate<>(); +// template.setConnectionFactory(redisConnectionFactory0); +// template.setKeySerializer(new StringRedisSerializer()); +// template.setValueSerializer(new StringRedisSerializer()); +// return template; +// } +// +// +// /** +// * 7号 数据库 - > +// * @return +// */ +// @Bean +// public RedisConnectionFactory redisConnectionFactory7() { +// LettuceConnectionFactory factory = new LettuceConnectionFactory(); +// factory.setHostName(host); +// factory.setPort(port); +// factory.setDatabase(7); +// return factory; +// } +// +// /** +// * 默认 数据库 +// * @return +// */ +// @Bean +// @Primary //添加@Primary默认使用的库 +// public RedisConnectionFactory redisConnectionFactory0() { +// LettuceConnectionFactory factory = new LettuceConnectionFactory(); +// factory.setHostName(host); +// factory.setPort(port); +// factory.setDatabase(database); +// return factory; +// } +// +// +// +// @Bean +// public DefaultRedisScript limitScript() +// { +// // 泛型是返回值的类型 +// DefaultRedisScript redisScript = new DefaultRedisScript<>(); +// // 设置脚本 +// redisScript.setScriptText(limitScriptText()); +// // 设置返回值类型 +// redisScript.setResultType(Long.class); +// return redisScript; +// } +// +// +// +// /** +// * 限流脚本 +// */ +// private String limitScriptText() +// { +// return "local key = KEYS[1]\n" + +// "local count = tonumber(ARGV[1])\n" + +// "local time = tonumber(ARGV[2])\n" + +// "local current = redis.call('get', key);\n" + +// "if current and tonumber(current) > count then\n" + +// " return tonumber(current);\n" + +// "end\n" + +// "current = redis.call('incr', key)\n" + +// "if tonumber(current) == 1 then\n" + +// " redis.call('expire', key, time)\n" + +// "end\n" + +// "return tonumber(current);"; +// } +// +// +//} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/service/RedisService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/service/RedisService.java new file mode 100644 index 0000000..05e89d0 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/redis/service/RedisService.java @@ -0,0 +1,313 @@ +//package com.m2pool.lease.redis.service; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.beans.factory.annotation.Qualifier; +//import org.springframework.data.redis.core.BoundSetOperations; +//import org.springframework.data.redis.core.HashOperations; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.data.redis.core.ValueOperations; +//import org.springframework.stereotype.Component; +// +//import java.math.BigDecimal; +//import java.util.*; +//import java.util.concurrent.TimeUnit; +// +///** +// * @Description redis 相关 +// * @Date 2024/6/13 9:22 +// * @Author dy +// */ +//@SuppressWarnings(value = { "unchecked", "rawtypes" }) +//@Component +//public class RedisService { +// +// @Autowired +// @Qualifier("redisTemplate") +// private RedisTemplate redisTemplate; +// +// @Autowired +// @Qualifier("redisTemplate7") +// private RedisTemplate redisTemplate7; +// +// +// /** +// * 缓存基本的对象,Integer、String、实体类等 +// * +// * @param key 缓存的键值 +// * @param value 缓存的值 +// */ +// public void setCacheObject(final String key, final T value) +// { +// redisTemplate.opsForValue().set(key, value); +// } +// +// +// /** +// * 缓存基本的对象,Integer、String、实体类等 +// * +// * @param key 缓存的键值 +// * @param value 缓存的值 +// * @param timeout 时间 +// * @param timeUnit 时间颗粒度 +// */ +// public void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) +// { +// redisTemplate.opsForValue().set(key, value, timeout, timeUnit); +// } +// +// +// public void setCacheObject7(final String key, final T value, final Long timeout, final TimeUnit timeUnit) +// { +// redisTemplate7.opsForValue().set(key, value, timeout, timeUnit); +// } +// +// /** +// * 设置有效时间 +// * +// * @param key Redis键 +// * @param timeout 超时时间 +// * @return true=设置成功;false=设置失败 +// */ +// public boolean expire(final String key, final long timeout) +// { +// return expire(key, timeout, TimeUnit.SECONDS); +// } +// +// /** +// * 设置有效时间 +// * +// * @param key Redis键 +// * @param timeout 超时时间 +// * @param unit 时间单位 +// * @return true=设置成功;false=设置失败 +// */ +// public boolean expire(final String key, final long timeout, final TimeUnit unit) +// { +// return redisTemplate.expire(key, timeout, unit); +// } +// +// /** +// * 获取有效时间 +// * +// * @param key Redis键 +// * @return 有效时间 +// */ +// public long getExpire(final String key) +// { +// return redisTemplate.getExpire(key); +// } +// +// /** +// * 获取有效时间 +// * +// * @param key Redis键 +// * @return 有效时间 +// */ +// public long getExpire(final String key,TimeUnit timetype) +// { +// return redisTemplate.getExpire(key,timetype); +// } +// +// +// /** +// * 判断 key是否存在 +// * +// * @param key 键 +// * @return true 存在 false不存在 +// */ +// public Boolean hasKey(String key) +// { +// return redisTemplate.hasKey(key); +// } +// +// /** +// * 获得缓存的基本对象。 +// * +// * @param key 缓存键值 +// * @return 缓存键值对应的数据 +// */ +// public T getCacheObject(final String key) +// { +// ValueOperations operation = redisTemplate.opsForValue(); +// return operation.get(key); +// } +// +// public T getCacheObject7(final String key) +// { +// ValueOperations operation = redisTemplate7.opsForValue(); +// return operation.get(key); +// } +// +// /** +// * 所有数字类型转换为BigDecimal +// * @param key 缓存键值 +// * @return 缓存键值对应数据 +// */ +// public BigDecimal getCacheBigDecimal(final String key) { +// ValueOperations operation = redisTemplate.opsForValue(); +// Object value = operation.get(key); +// if (value != null) { +// if (value instanceof BigDecimal) { +// return (BigDecimal) value; +// } else if (value instanceof String) { +// try { +// return new BigDecimal((String) value); +// } catch (NumberFormatException e) { +// // 处理字符串无法转换为 BigDecimal 的情况 +// return null; +// } +// } else if (value instanceof Number) { +// return new BigDecimal(value.toString()); +// } +// } +// return null; +// } +// +// /** +// * 删除单个对象 +// * +// * @param key +// */ +// public boolean deleteObject(final String key) +// { +// return redisTemplate.delete(key); +// } +// +// +// /** +// * 删除集合对象 +// * +// * @param collection 多个对象 +// * @return +// */ +// public long deleteObject(final Collection collection) +// { +// return redisTemplate.delete(collection); +// } +// +// /** +// * 缓存List数据 +// * +// * @param key 缓存的键值 +// * @param dataList 待缓存的List数据 +// * @return 缓存的对象 +// */ +// public long setCacheList(final String key, final List dataList) +// { +// Long count = redisTemplate.opsForList().rightPushAll(key, dataList); +// return count == null ? 0 : count; +// } +// /** +// * 获得缓存的list对象 +// * +// * @param key 缓存的键值 +// * @return 缓存键值对应的数据 +// */ +// public List getCacheList(final String key) +// { +// return redisTemplate.opsForList().range(key, 0, -1); +// } +// +// /** +// * 缓存Set +// * +// * @param key 缓存键值 +// * @param dataSet 缓存的数据 +// * @return 缓存数据的对象 +// */ +// public BoundSetOperations setCacheSet(final String key, final Set dataSet) +// { +// BoundSetOperations setOperation = redisTemplate.boundSetOps(key); +// Iterator it = dataSet.iterator(); +// while (it.hasNext()) +// { +// setOperation.add(it.next()); +// } +// return setOperation; +// } +// +// /** +// * 获得缓存的set +// * +// * @param key +// * @return +// */ +// public Set getCacheSet(final String key) +// { +// return redisTemplate.opsForSet().members(key); +// } +// +// /** +// * 缓存Map +// * +// * @param key +// * @param dataMap +// */ +// public void setCacheMap(final String key, final Map dataMap) +// { +// if (dataMap != null) { +// redisTemplate.opsForHash().putAll(key, dataMap); +// } +// } +// +// /** +// * 获得缓存的Map +// * +// * @param key +// * @return +// */ +// public Map getCacheMap(final String key) +// { +// return redisTemplate.opsForHash().entries(key); +// +// } +// +// /** +// * 往Hash中存入数据 +// * +// * @param key Redis键 +// * @param hKey Hash键 +// * @param value 值 +// */ +// public void setCacheMapValue(final String key, final String hKey, final T value) +// { +// redisTemplate.opsForHash().put(key, hKey, value); +// } +// +// /** +// * 获取Hash中的数据 +// * +// * @param key Redis键 +// * @param hKey Hash键 +// * @return Hash中的对象 +// */ +// public T getCacheMapValue(final String key, final String hKey) +// { +// HashOperations opsForHash = redisTemplate.opsForHash(); +// return opsForHash.get(key, hKey); +// } +// +// /** +// * 获取多个Hash中的数据 +// * +// * @param key Redis键 +// * @param hKeys Hash键集合 +// * @return Hash对象集合 +// */ +// public List getMultiCacheMapValue(final String key, final Collection hKeys) +// { +// return redisTemplate.opsForHash().multiGet(key, hKeys); +// } +// +// /** +// * 获得缓存的基本对象列表 +// * +// * @param pattern 字符串前缀 +// * @return 对象列表 +// */ +// public Collection keys(final String pattern) +// { +// return redisTemplate.keys(pattern); +// } +// +//} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseUserService.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseUserService.java index 499206c..392642c 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseUserService.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/LeaseUserService.java @@ -5,11 +5,11 @@ import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.LeaseUser; import com.m2pool.lease.vo.*; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; +import java.util.Map; /** *

@@ -23,10 +23,58 @@ public interface LeaseUserService extends IService { /** * 用户登录/注册 - * @param userURDVo + * @param userLoginVo * @return */ - Result login(UserURDVo userURDVo); + Result> login(UserLoginVo userLoginVo); + + + /** + * 用户注册 + * @param userRegisterVo + * @return + */ + Result register( UserRegisterVo userRegisterVo); + + + /** + * 修改密码 + * @param userLoginVo + * @return + */ + Result updatePassword(UserLoginVo userLoginVo); + + /** + * 发送用户登录邮箱验证码 + * @param emailCodeVo + * @return + */ + Result sendLoginCode( EmailCodeVo emailCodeVo); + + + /** + * 获取用户注册邮箱验证码 + * @param emailCodeVo + * @return + */ + Result sendRegisterCode(EmailCodeVo emailCodeVo); + + + /** + * 获取用户修改密码邮箱验证码 + * @param emailCodeVo + * @return + */ + Result sendUpdatePwdCode(EmailCodeVo emailCodeVo); + + + /** + * 登出 + * @return + */ + Result logout(); + + //---------------用户权限----------------------- /** diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseOrderInfoServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseOrderInfoServiceImpl.java index e21e29c..9afbba8 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseOrderInfoServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseOrderInfoServiceImpl.java @@ -1,6 +1,5 @@ package com.m2pool.lease.service.impl; -import cn.hutool.json.JSONUtil; import com.baomidou.dynamic.datasource.annotation.DSTransactional; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -13,7 +12,7 @@ import com.m2pool.common.core.utils.StringUtils; import com.m2pool.common.redis.service.RedisService; import com.m2pool.common.security.utils.SecurityUtils; import com.m2pool.lease.constant.CoinCharge; -import com.m2pool.lease.constant.RedisKey; +import com.m2pool.lease.redis.RedisCoinInfoKey; import com.m2pool.lease.dto.*; import com.m2pool.lease.dto.v2.*; import com.m2pool.lease.entity.*; @@ -467,7 +466,9 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl getOrdersByStatusForSeller(OrderInfoStateVo orderInfoStateVo) { LeaseShop leaseShop = leaseShopMapper.selectOne(new LambdaQueryWrapper() .eq(LeaseShop::getUserEmail, SecurityUtils.getUsername())); - + if (leaseShop == null){ + return PageResult.fail(new ArrayList<>(),"不存在商铺"); + } //查询到商铺的所有订单 List orderItemList = leaseOrderItemMapper.selectList(new LambdaQueryWrapper() .eq(LeaseOrderItem::getShopId, leaseShop.getId())); @@ -590,7 +591,7 @@ public class LeaseOrderInfoServiceImpl extends ServiceImpl dto.getUser() + "-" + dto.getMiner(), dto -> dto )); - String priceKey = RedisKey.getPiceKey(product.getCoin()); - String rewardKey = RedisKey.getRewardKey(product.getCoin()); - String mhsKey = RedisKey.getMhsKey(product.getCoin()); + String priceKey = RedisCoinInfoKey.getPiceKey(product.getCoin()); + String rewardKey = RedisCoinInfoKey.getRewardKey(product.getCoin()); + String mhsKey = RedisCoinInfoKey.getMhsKey(product.getCoin()); if (priceKey == null || rewardKey == null || mhsKey == null){ return Result.fail("添加商品失败,该币种挖矿机器暂时不支持"); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductServiceImpl.java index f205ccd..c9afdee 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseProductServiceImpl.java @@ -1,7 +1,6 @@ package com.m2pool.lease.service.impl; import cn.hutool.json.JSONUtil; -import com.alibaba.druid.support.json.JSONUtils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -13,7 +12,7 @@ import com.m2pool.common.security.utils.SecurityUtils; import com.m2pool.lease.constant.Algorithm; import com.m2pool.lease.constant.BlockInterval; import com.m2pool.lease.constant.PowerUnit; -import com.m2pool.lease.constant.RedisKey; +import com.m2pool.lease.redis.RedisCoinInfoKey; import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.*; import com.m2pool.lease.exception.ProductSoldOutException; @@ -35,7 +34,6 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; /** @@ -148,11 +146,11 @@ public class LeaseProductServiceImpl extends ServiceImpl(),"不存在矿机"); } //币价 单位usdt - BigDecimal price = redisService.getCacheBigDecimal(RedisKey.getPiceKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisKey.getPiceKey(product.getCoin())); + BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(product.getCoin())); //报块奖励 - BigDecimal reward =redisService.getCacheBigDecimal(RedisKey.getRewardKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisKey.getRewardKey(product.getCoin())) ; + BigDecimal reward =redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(product.getCoin())) ; //全网算力单位是MH/s - BigDecimal mhs = redisService.getCacheBigDecimal(RedisKey.getMhsKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisKey.getMhsKey(product.getCoin())); + BigDecimal mhs = redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(product.getCoin())) == null ? BigDecimal.ZERO : redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(product.getCoin())); List productMachines = productMachineDtoList.stream() .peek(productMachineDto -> { @@ -432,7 +430,7 @@ public class LeaseProductServiceImpl extends ServiceImpl productMachineForWalletConfigDtoList = leaseProductMachineMapper.getProductListForShopWalletConfig(shopId); - BigDecimal usdtPrice = redisService.getCacheBigDecimal(RedisKey.getPiceKey(productForShopWalletConfigDtoList.get(0).getCoin())); + BigDecimal usdtPrice = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(productForShopWalletConfigDtoList.get(0).getCoin())); Map> collect = productMachineForWalletConfigDtoList.stream() .peek(productMachineForWalletConfigDto -> { productMachineForWalletConfigDto.setTheoryUsdtIncome(productMachineForWalletConfigDto.getTheoryIncome() diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java index 720657a..5e07483 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseShoppingCartServiceImpl.java @@ -10,7 +10,7 @@ import com.m2pool.common.redis.service.RedisService; import com.m2pool.common.security.utils.SecurityUtils; import com.m2pool.lease.constant.BlockInterval; import com.m2pool.lease.constant.CoinCharge; -import com.m2pool.lease.constant.RedisKey; +import com.m2pool.lease.redis.RedisCoinInfoKey; import com.m2pool.lease.dto.*; import com.m2pool.lease.dto.v2.CartMachineInfoDto; import com.m2pool.lease.dto.v2.ShopCartV2Dto; @@ -168,9 +168,9 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl coinRewardMap = new HashMap<>(); Map coinMhsMap = new HashMap<>(); for (String coin : coins) { - BigDecimal price = redisService.getCacheBigDecimal(RedisKey.getPiceKey(coin)); - BigDecimal reward =redisService.getCacheBigDecimal(RedisKey.getRewardKey(coin)); - BigDecimal mhs = redisService.getCacheBigDecimal(RedisKey.getMhsKey(coin)); + BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(coin)); + BigDecimal reward =redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(coin)); + BigDecimal mhs = redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(coin)); coinMhsMap.put(coin, mhs); coinRewardMap.put(coin, reward); coinPriceMap.put(coin, price); @@ -455,9 +455,9 @@ public class LeaseShoppingCartServiceImpl extends ServiceImpl coinRewardMap = new HashMap<>(); //Map coinMhsMap = new HashMap<>(); //for (String coin : coins) { - // BigDecimal price = redisService.getCacheBigDecimal(RedisKey.getPiceKey(coin)); - // BigDecimal reward =redisService.getCacheBigDecimal(RedisKey.getRewardKey(coin)); - // BigDecimal mhs = redisService.getCacheBigDecimal(RedisKey.getMhsKey(coin)); + // BigDecimal price = redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(coin)); + // BigDecimal reward =redisService.getCacheBigDecimal(RedisCoinInfoKey.getRewardKey(coin)); + // BigDecimal mhs = redisService.getCacheBigDecimal(RedisCoinInfoKey.getMhsKey(coin)); // coinMhsMap.put(coin, mhs); // coinRewardMap.put(coin, reward); // coinPriceMap.put(coin, price); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserOwnedProductServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserOwnedProductServiceImpl.java index b8fe29a..1b39806 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserOwnedProductServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserOwnedProductServiceImpl.java @@ -7,7 +7,7 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.m2pool.common.redis.service.RedisService; import com.m2pool.common.security.utils.SecurityUtils; -import com.m2pool.lease.constant.RedisKey; +import com.m2pool.lease.redis.RedisCoinInfoKey; import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.*; import com.m2pool.lease.mapper.*; @@ -21,7 +21,6 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; -import java.time.LocalTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -88,7 +87,7 @@ public class LeaseUserOwnedProductServiceImpl extends ServiceImpl userOwnedProducts = leaseUserOwnedProducts.stream().map(leaseUserOwnedProduct ->{ String coin = leaseUserOwnedProduct.getCoin(); - BigDecimal bigDecimal = coinPrice.putIfAbsent(coin, redisService.getCacheBigDecimal(RedisKey.getPiceKey(coin))); + BigDecimal bigDecimal = coinPrice.putIfAbsent(coin, redisService.getCacheBigDecimal(RedisCoinInfoKey.getPiceKey(coin))); UserOwnedProductDto build = UserOwnedProductDto.builder() .id(leaseUserOwnedProduct.getId()) @@ -130,7 +129,7 @@ public class LeaseUserOwnedProductServiceImpl extends ServiceImpl recentlyFiveMinutesData = leaseProductMachineMapper.getRecentlyFiveMinutesData(leaseProductMachines, leaseUserOwnedProduct.getCoin()); Integer status = leaseUserOwnedProduct.getStatus(); @@ -177,7 +176,7 @@ public class LeaseUserOwnedProductServiceImpl extends ServiceImpl collect = leaseOrderItems.stream() .map(item -> { // 获取当前的 LocalDateTime diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserServiceImpl.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserServiceImpl.java index 239172b..be253a7 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserServiceImpl.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/service/impl/LeaseUserServiceImpl.java @@ -1,52 +1,72 @@ package com.m2pool.lease.service.impl; + +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; import com.baomidou.dynamic.datasource.annotation.DSTransactional; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; -import com.m2pool.common.core.utils.DateUtils; +import com.m2pool.common.core.Result.R; +import com.m2pool.common.core.exception.ServiceException; +import com.m2pool.common.core.text.Convert; +import com.m2pool.common.core.utils.CodeUtils; import com.m2pool.common.core.utils.StringUtils; +import com.m2pool.common.core.utils.uuid.IdUtils; +import com.m2pool.common.redis.service.RedisService; import com.m2pool.common.security.utils.SecurityUtils; import com.m2pool.lease.dto.*; import com.m2pool.lease.entity.*; +import com.m2pool.lease.exception.AuthException; import com.m2pool.lease.exception.PaymentException; import com.m2pool.lease.mapper.*; import com.m2pool.lease.mq.message.RabbitmqPayRechargeMessage; import com.m2pool.lease.mq.message.RabbitmqPayWithdrawMessage; +import com.m2pool.lease.redis.EmailCodeValue; +import com.m2pool.lease.redis.RedisAuthKey; import com.m2pool.lease.service.LeaseUserService; import com.m2pool.lease.utils.*; import com.m2pool.lease.vo.*; -import org.apache.commons.io.FileUtils; +import com.m2pool.system.api.entity.EmailTemplateEntity; +import com.m2pool.system.api.entity.SysUser; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.context.Context; import javax.annotation.Resource; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; import java.math.BigDecimal; import java.net.URLEncoder; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; +import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import static com.m2pool.lease.constant.CoinCharge.getAllChargesAsDtoList; import static com.m2pool.lease.constant.CoinCharge.getChargeByChainAndCoin; import static com.m2pool.lease.constant.RabbitmqConstant.PAY_RECHARGE_QUEUE; import static com.m2pool.lease.constant.RabbitmqConstant.PAY_WITHDRAW_QUEUE; +import static com.m2pool.lease.utils.JwtUtils.EXPIRETIME; /** *

@@ -87,7 +107,14 @@ public class LeaseUserServiceImpl extends ServiceImpl PASSWORD_MAX_LENGTH) { + throw new AuthException("用户密码长度应该为:"+PASSWORD_MIN_LENGTH+"~"+PASSWORD_MAX_LENGTH); + } + } + + /** + * 验证码校验 + * @param key + * @param code + */ + public void verifyCode(String key, String code){ + if(redisService.hasKey(key)){ + Object o = redisService.getCacheObject(key);//user:emailCode:email + EmailCodeValue emailCodeValue = JSON.parseObject(JSON.toJSONString(o), EmailCodeValue.class); + //验证验证码 + if(!code.equals(emailCodeValue.getEmailCode())){ + throw new AuthException("验证码错误"); + } + }else{ + throw new AuthException("验证码未获取或已过期,请重新获取验证码"); + } + } + + /** + * jwt 令牌创建 + * @param loginUser + * @return + */ + public Map createToken(LeaseUser loginUser) + { + String token = IdUtils.fastUUID(); + loginUser.setToken(token); + //刷新token + String userKey = RedisAuthKey.getUserLoginKey(loginUser.getUserId()); + redisService.setCacheObject(userKey, loginUser, EXPIRETIME, TimeUnit.MINUTES); + + // Jwt存储信息 + Map claimsMap = new HashMap(); + claimsMap.put(JwtUtils.USER_KEY, token); + claimsMap.put(JwtUtils.DETAILS_USER_ID, loginUser.getId()); + claimsMap.put(JwtUtils.DETAILS_USERNAME, loginUser.getUserId()); + + // 接口返回信息 + Map rspMap = new HashMap(); + rspMap.put("access_token", JwtUtils.createToken(claimsMap)); + rspMap.put("expires_in", EXPIRETIME); + rspMap.put("userName", loginUser.getUserId()); + return rspMap; + } + + + @Override + @Transactional + public Result> login(UserLoginVo userLoginVo) { + String email = userLoginVo.getEmail(); + String password = userLoginVo.getPassword(); + String code = userLoginVo.getCode(); + //1.校验密码,邮箱等参数格式 + verifyParams(email,password); + //2.验证码校验 + verifyCode(RedisAuthKey.getLoginCodeKey(email),code); + //3.校验用户信息 + LeaseUser user = getUser(email); + if (user == null){ + throw new AuthException("用户不存在或已注销"); + } + //4.密码输入错误次数过多,禁止登录 + String userLockKey = RedisAuthKey.getUserLockKey(email); + if(redisService.hasKey(userLockKey)){ + throw new AuthException("该账户因密码错误多次被暂时限制登陆24h!"); + } + //校验登录密码是否是注册密码 + String passwordErrorCountKey = RedisAuthKey.getPasswordErrorCountKey( email); + if (!CryptoUtils.matchesPassword(password, user.getPassword())){ + int count = 0; + if(redisService.hasKey(passwordErrorCountKey)){ + //判断key是否过期 + long expire = redisService.getExpire(passwordErrorCountKey, TimeUnit.SECONDS); + if(expire > 0){ + count = Convert.toInt(redisService.getCacheObject(passwordErrorCountKey)); + } + } + count++; + if(count == 1){ + redisService.setCacheObject(passwordErrorCountKey,count,1L,TimeUnit.HOURS); + }else if(count < 6){ + long expire = redisService.getExpire(passwordErrorCountKey, TimeUnit.SECONDS); + System.out.println(expire); + redisService.setCacheObject(passwordErrorCountKey,count,redisService.getExpire(passwordErrorCountKey,TimeUnit.SECONDS),TimeUnit.SECONDS); + } + if(count >= 5){ + //锁定用户账号 并清除输入错误次数的记录 + redisService.setCacheObject(userLockKey, email, 24L, TimeUnit.HOURS); + //清除输入错误次数的记录 + redisService.deleteObject(passwordErrorCountKey); + } + throw new AuthException("密码错误,一小时内错误五次之后锁定账户24h,当前已失败"+count+"次"); + } + user.setLastLoginTime(LocalDateTime.now()); + leaseUserMapper.updateById(user); + return Result.success(createToken(user)); + } + + + @Override + @Transactional + public Result register(UserRegisterVo userRegisterVo) { + String email = userRegisterVo.getUserEmail(); + String password = userRegisterVo.getPassword(); + //1.校验密码,邮箱等参数格式 + verifyParams(email,password); + //2.验证码校验 + verifyCode(RedisAuthKey.getRegisterCodeKey(email),userRegisterVo.getCode()); + //3.注册用户信息 + int insert = leaseUserMapper.insert(LeaseUser.builder() + .userId(email) + .password(CryptoUtils.encryptPassword(password)) + .del(false) + .build()); + if (insert > 0){ + return Result.success("注册成功"); + } + return Result.fail("注册失败"); + } + + @Override + @Transactional + public Result updatePassword(UserLoginVo userLoginVo) { + String email = userLoginVo.getEmail(); + String password = userLoginVo.getPassword(); + String updatePwdCode = userLoginVo.getCode(); + //1.校验密码,邮箱等参数格式 + verifyParams(email,password); + //2.验证码校验 + verifyCode(RedisAuthKey.getRegisterCodeKey(email),userLoginVo.getCode()); + //3.修改密码 + LeaseUser user = getUser(email); + if (CryptoUtils.matchesPassword(password, user.getPassword())){ + throw new AuthException("新密码不能与原密码一致"); + } + String updatePasswordCodeKey = RedisAuthKey.getUpdatePasswordCodeKey(email); + if ( redisService.hasKey(updatePasswordCodeKey)){ + Object o = redisService.getCacheObject(updatePasswordCodeKey);//user:emailCode:username + EmailCodeValue emailCodeValue = JSON.parseObject(JSON.toJSONString(o), EmailCodeValue.class); + if(updatePwdCode.equals(emailCodeValue.getEmailCode())){ + user.setPassword(CryptoUtils.encryptPassword(password)); + leaseUserMapper.updateById(user); + }else { + return Result.fail("邮箱验证码错误"); + } + } + + return Result.success("修改密码成功"); + } + + @Override + public Result logout() { + String userEmail = UserThreadLocal.getUserEmail(); + boolean b = redisService.deleteObject(RedisAuthKey.getUserLoginKey(userEmail)); + if (b){ + return Result.success("登出成功"); + } + return Result.fail("登出失败"); + } + + + @Override + @Transactional + public Result sendLoginCode(EmailCodeVo emailCodeVo) { + //1.邮箱格式校验(注解校验) + //String email = emailCodeVo.getEmail(); + //if(!StringUtils.isBlank(email)){ + // if(!email.matches(EMAIL_REGEX)){ + // return Result.fail("邮箱格式错误"); + // } + //}else { + // return Result.fail("601,\"邮箱不能为空\""); + //} + String email = emailCodeVo.getEmail(); + //2.请求次数限制 + String loginCodeKey = RedisAuthKey.getLoginCodeKey(email); + if (redisService.hasKey(loginCodeKey)){ + if (checkSendTimes(email, loginCodeKey,0)){ + return Result.fail("请求次数过多,请10分钟后再试,(同一用户10分钟内只能请求5次)"); + } + }else{ + LeaseUser user = getUser(email); + if (user == null){ + return Result.fail(606,"邮箱"+email+"未注册"); + }else{ + String emailCode = CodeUtils.creatCode(5); + // 最多允许用户在10分钟内发送2次的邮箱验证 + // 0s倒计时后用户可以再发送验证码,但是间隔在10分钟内只能再发送1次 + EmailCodeValue emailCodeValue = new EmailCodeValue( + email, emailCode,1 + ); + + sendLoginCodeMailMessage(email, emailCodeValue.getEmailCode()); + //设置失效时间10分钟 + redisService.setCacheObject(loginCodeKey, emailCodeValue, + 10L, TimeUnit.MINUTES + ); + } + } + return Result.success("发送验证码成功,验证码已经发送至用户邮箱"); + } + + @Override + @Transactional + public Result sendRegisterCode(EmailCodeVo emailCodeVo) { + String email = emailCodeVo.getEmail(); + //2.请求次数限制 + String loginCodeKey = RedisAuthKey.getRegisterCodeKey(email); + if (redisService.hasKey(loginCodeKey)){ + if (checkSendTimes(email, loginCodeKey,1)){ + return Result.fail("请求次数过多,请10分钟后再试,(同一用户10分钟内只能请求5次)"); + } + }else{ + LeaseUser user = getUser(email); + if (user != null){ + return Result.fail(606,"邮箱"+email+"已被注册"); + }else{ + String emailCode = CodeUtils.creatCode(5); + // 最多允许用户在10分钟内发送2次的邮箱验证 + // 0s倒计时后用户可以再发送验证码,但是间隔在10分钟内只能再发送1次 + EmailCodeValue emailCodeValue = new EmailCodeValue( + email, emailCode,1 + ); + + sendRegisterMessage(email, emailCodeValue.getEmailCode()); + //设置失效时间10分钟 + redisService.setCacheObject(loginCodeKey, emailCodeValue, + 10L, TimeUnit.MINUTES + ); + } + } + return Result.success("发送验证码成功,验证码已经发送至用户邮箱"); + } + @Override - public Result login(UserURDVo userURDVo) { - LeaseUser leaseUser = leaseUserMapper.selectOne(new LambdaQueryWrapper() - .eq(LeaseUser::getUserId, userURDVo.getUserId())); - if (leaseUser != null){ - return Result.success(UserDto.builder() - .id(leaseUser.getId()) - .userId(leaseUser.getUserId()) - .password(leaseUser.getPassword()) - .build()); - } - LeaseUser build = LeaseUser.builder().password(userURDVo.getPassword()).userId(userURDVo.getUserId()).build(); - int insert = leaseUserMapper.insert(build); + @Transactional + public Result sendUpdatePwdCode(EmailCodeVo emailCodeVo) { + String email = emailCodeVo.getEmail(); + //2.请求次数限制 + String loginCodeKey = RedisAuthKey.getUpdatePasswordCodeKey(email); + if (redisService.hasKey(loginCodeKey)){ + if (checkSendTimes(email, loginCodeKey,2)){ + return Result.fail("请求次数过多,请10分钟后再试,(同一用户10分钟内只能请求5次)"); + } + }else{ + String emailCode = CodeUtils.creatCode(5); + // 最多允许用户在10分钟内发送2次的邮箱验证 + // 0s倒计时后用户可以再发送验证码,但是间隔在10分钟内只能再发送1次 + EmailCodeValue emailCodeValue = new EmailCodeValue( + email, emailCode,1 + ); - if (insert > 0){ - return Result.success(UserDto.builder() - .id(build.getId()) - .userId(build.getUserId()) - .password(build.getPassword()) - .build()); - }else { - return Result.fail("登录失败"); + sendLoginCodeMailMessage(email, emailCodeValue.getEmailCode()); + //设置失效时间10分钟 + redisService.setCacheObject(loginCodeKey, emailCodeValue, + 10L, TimeUnit.MINUTES + ); + } + return Result.success("发送验证码成功,验证码已经发送至用户邮箱"); + } + + + + + + /** + * 检查发送次数是否大于5次 + * @param email + * @param key + * @param type 0 登录验证码 1 注册验证码 2 修改密码验证码 + * @return + */ + private boolean checkSendTimes(String email, String key,Integer type) { + Object o = redisService.getCacheObject(key); + EmailCodeValue emailCodeValue = JSON.parseObject(JSON.toJSONString(o), EmailCodeValue.class); + if (emailCodeValue.getTimes() >= 5){ + return true; + }else{ + String emailCode = CodeUtils.creatCode(6); + emailCodeValue.setEmailCode(emailCode); + emailCodeValue.setTimes(emailCodeValue.getTimes() + 1); + long overTime = redisService.getExpire(key); + redisService.setCacheObject(key, emailCodeValue, overTime, TimeUnit.SECONDS); + if (type == 0){ + sendLoginCodeMailMessage(email, emailCodeValue.getEmailCode()); + }else if (type == 1){ + sendRegisterMessage(email, emailCodeValue.getEmailCode()); + }else if (type == 2){ + sendUpdatePwdMailMessage(email, emailCodeValue.getEmailCode()); + } + + } + return false; + } + + /** + * 根据邮箱获取用户 + * @param userEmail + * @return + */ + public LeaseUser getUser(String userEmail){ + return leaseUserMapper.selectOne(new LambdaQueryWrapper() + .eq(LeaseUser::getUserId,userEmail ).eq(LeaseUser::getDel,false)); + } + + /** + * 发送登录验证码 + * @param to + * @param code + */ + public void sendLoginCodeMailMessage(String to, String code) { + //String subject = "用户登录,邮箱验证码"; + //String text = "登录验证码10分钟内有效:\n\t"+code; + Map content = new HashMap<>(); + content.put("code",code); + content.put("text","Login verification code is valid within 10 minutes"); + EmailTemplateEntity entity = new EmailTemplateEntity(to,"User login, email verification code","emailCode-en",content); + sendHtmlEmail(entity.getEmail(),entity.getSubject(),entity.getTemplateName(),entity.getData()); + } + + /** + * 发送注册验证码 + * @param to + * @param code + */ + public void sendRegisterMessage(String to, String code) { + //String subject = "账号注册,邮箱验证码"; + //String text = "注册验证码10分钟内有效:\n\t"+code; + Map content = new HashMap<>(); + content.put("code",code); + content.put("text","The verification code for registration is valid for 10 minutes"); + EmailTemplateEntity message = new EmailTemplateEntity(to,"Account registration, email verification code","emailCode-en",content); + sendHtmlEmail(message.getEmail(),message.getSubject(),message.getTemplateName(),message.getData()); + } + + public void sendUpdatePwdMailMessage(String to, String code) { + //String subject = "修改密码,邮箱验证码"; + //String text = "您正在修改密码,如果不是您本人操作,请忽略。验证码10分钟内有效:\n\t"+code; + + Map content = new HashMap<>(); + content.put("code",code); + content.put("text","You are currently modifying your password. If this is not done by you, please ignore it. The verification code is valid for 10 minutes."); + EmailTemplateEntity entity = new EmailTemplateEntity(to,"Change password, email verification code","emailCode-en",content); + sendHtmlEmail(entity.getEmail(),entity.getSubject(),entity.getTemplateName(),entity.getData()); + } + + /** + * 通过thymeleaf发送html邮件 + * @param to + * @param subject + * @param templateName + * @param variables + * @throws MessagingException + */ + public void sendHtmlEmail(String to, String subject, String templateName, Map variables) { + + // 创建 MimeMessage 对象 + MimeMessage message = javaMailSender.createMimeMessage(); + MimeMessageHelper helper = null; + try { + helper = new MimeMessageHelper(message, true); + //邮件发信人 + helper.setFrom(sendMailer); + + // 收件人一个活多个 + helper.setTo(to.split(",")); + helper.setSubject(subject); + + // 创建 Thymeleaf 上下文并添加变量 + Context context = new Context(); + //设置图片访问前缀 + variables.put("imagePrefix", imagePrefix); + context.setVariables(variables); + + // 处理 HTML 模板 + String htmlContent = templateEngine.process(templateName, context); + + // 设置邮件内容为 HTML + helper.setText(htmlContent, true); + + //邮件发送时间 + helper.setSentDate(new Date()); + + // 发送邮件 + javaMailSender.send(message); + System.out.println("发送邮件成功:"+sendMailer+"->"+to); + } catch (Exception e) { + System.out.println("发送失败原因"+e.getMessage()); + throw new AuthException("发送邮箱验证码失败,请稍后重试"); } } + @Override @Transactional public Result bindWallet(ChainAndCoinVo chainAndCoinVo) { diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OwnProductTask.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OwnProductTask.java index c89f0cd..b8b6ceb 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OwnProductTask.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/task/OwnProductTask.java @@ -138,9 +138,8 @@ public class OwnProductTask { } - //开发 - //@Scheduled(cron = "0 35 0/1 * * ? ") - @Scheduled(cron = "30 0/2 * * * ? ") + @Scheduled(cron = "0 35 0/1 * * ? ") + //@Scheduled(cron = "30 0/2 * * * ? ") @DSTransactional public void updateNexaIncomeTask(){ List updateList = computeIncome("nexa"); @@ -149,8 +148,8 @@ public class OwnProductTask { } - //@Scheduled(cron = "10 35 0/1 * * ? ") - @Scheduled(cron = "30 0/2 * * * ? ") + @Scheduled(cron = "10 35 0/1 * * ? ") + //@Scheduled(cron = "30 0/2 * * * ? ") @DSTransactional public void updateGrsIncomeTask(){ List updateList = computeIncome("grs"); @@ -158,8 +157,8 @@ public class OwnProductTask { batchUpdateLeaseUserOwnedProducts(updateList); } - //@Scheduled(cron = "20 35 0/1 * * ? ") - @Scheduled(cron = "30 0/2 * * * ? ") + @Scheduled(cron = "20 35 0/1 * * ? ") + //@Scheduled(cron = "30 0/2 * * * ? ") @DSTransactional public void updateRxdIncomeTask(){ List updateList = computeIncome("rxd"); @@ -167,8 +166,8 @@ public class OwnProductTask { batchUpdateLeaseUserOwnedProducts(updateList); } - //@Scheduled(cron = "30 35 0/1 * * ? ") - @Scheduled(cron = "30 0/2 * * * ? ") + @Scheduled(cron = "30 35 0/1 * * ? ") + //@Scheduled(cron = "30 0/2 * * * ? ") @DSTransactional public void updateMonaIncomeTask(){ List updateList = computeIncome("mona"); diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/CodeUtils.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/CodeUtils.java new file mode 100644 index 0000000..9387c3d --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/CodeUtils.java @@ -0,0 +1,43 @@ +package com.m2pool.lease.utils; + +import java.util.Random; + +/** + * @Description TODO + * @Date 2024/6/13 14:26 + * @Author dy + */ +public class CodeUtils { + //public static void main(String[] args) { + // String s = creatCode(4); + // //System.out.println("随机验证码为:" + s); + //} + + //定义一个方法返回一个随机验证码 + public static String creatCode(int n) { + + String code = ""; + Random r = new Random(); + //2.在方法内部使用for循环生成指定位数的随机字符,并连接起来 + for (int i = 0; i <= n; i++) { + //生成一个随机字符:大写 ,小写 ,数字(0 1 2) + int type = r.nextInt(3); + switch (type) { + case 0: + char ch = (char) (r.nextInt(26) + 65); + code += ch; + break; + case 1: + char ch1 = (char) (r.nextInt(26) + 97); + code += ch1; + break; + case 2: + code += r.nextInt(10); + break; + } + + } + return code; + } + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/CryptoUtils.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/CryptoUtils.java new file mode 100644 index 0000000..94f3453 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/CryptoUtils.java @@ -0,0 +1,30 @@ +package com.m2pool.lease.utils; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +public class CryptoUtils { + /** + * 生成BCryptPasswordEncoder密码 + * + * @param password 密码 + * @return 加密字符串 + */ + public static String encryptPassword(String password) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.encode(password); + } + + /** + * 判断密码是否相同 + * + * @param rawPassword 真实密码 + * @param encodedPassword 加密后字符 + * @return 结果 + */ + public static boolean matchesPassword(String rawPassword, String encodedPassword) + { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + return passwordEncoder.matches(rawPassword, encodedPassword); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/JwtUtils.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/JwtUtils.java new file mode 100644 index 0000000..a39a177 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/JwtUtils.java @@ -0,0 +1,148 @@ +package com.m2pool.lease.utils; + + +import com.m2pool.common.core.constant.SecurityConstants; +import com.m2pool.common.core.text.Convert; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +import java.util.Map; + +/** + * @Description Jwt工具类 + * @Date 2024/6/12 16:38 + * @Author dy + */ +public class JwtUtils +{ + public static String secret = TokenConstants.SECRET; + + /** + * 用户标识 + */ + public static final String USER_KEY = "user_key"; + + /** + * 用户ID字段 + */ + public static final String DETAILS_USER_ID = "user_id"; + + /** + * 用户名字段 + */ + public static final String DETAILS_USERNAME = "username"; + + /** + * 令牌自定义标识 + */ + public static final String AUTHENTICATION = "Authorization"; + + /** + * 缓存有效期,默认6个月 60*24*30*3=129600(分钟) + */ + public final static long EXPIRETIME = 129600; + /** + * 从数据声明生成令牌 + * + * @param claims 数据声明 + * @return 令牌 + */ + public static String createToken(Map claims) + { + String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact(); + return token; + } + + /** + * 从令牌中获取数据声明 + * + * @param token 令牌 + * @return 数据声明 + */ + public static Claims parseToken(String token) + { + return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); + } + + /** + * 根据令牌获取用户标识 + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserKey(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.USER_KEY); + } + + /** + * 根据令牌获取用户标识 + * + * @param claims 身份信息 + * @return 用户ID + */ + public static String getUserKey(Claims claims) + { + return getValue(claims, SecurityConstants.USER_KEY); + } + + /** + * 根据令牌获取用户ID + * + * @param token 令牌 + * @return 用户ID + */ + public static String getUserId(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.DETAILS_USER_ID); + } + + /** + * 根据身份信息获取用户ID + * + * @param claims 身份信息 + * @return 用户ID + */ + public static String getUserId(Claims claims) + { + return getValue(claims, SecurityConstants.DETAILS_USER_ID); + } + + /** + * 根据令牌获取用户名 + * + * @param token 令牌 + * @return 用户名 + */ + public static String getUserName(String token) + { + Claims claims = parseToken(token); + return getValue(claims, SecurityConstants.DETAILS_USERNAME); + } + + /** + * 根据身份信息获取用户名 + * + * @param claims 身份信息 + * @return 用户名 + */ + public static String getUserName(Claims claims) + { + return getValue(claims, SecurityConstants.DETAILS_USERNAME); + } + + /** + * 根据身份信息获取键值 + * + * @param claims 身份信息 + * @param key 键 + * @return 值 + */ + public static String getValue(Claims claims, String key) + { + return Convert.toStr(claims.get(key), ""); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/TokenConstants.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/TokenConstants.java new file mode 100644 index 0000000..582443b --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/TokenConstants.java @@ -0,0 +1,30 @@ +package com.m2pool.lease.utils; + +/** + * @Description Token的Key常量 + * @Date 2024/6/11 16:12 + * @Author dy + */ +public class TokenConstants { + + /** + * 令牌自定义标识 + */ + public static final String AUTHENTICATION = "Authorization"; + + public static final String API_KEY = "API-KEY"; + + /** + * 令牌前缀 + */ + public static final String PREFIX = "Bearer "; + + /** + * 令牌秘钥 + */ + //TODO 根据情况更改密钥 + public final static String SECRET = "mabsadba2basdsanwepsdaowwwxxsodddl"; + + public final static String API_SECRET = "mabsadba2bttxdnwcabpiowwwxxsodddl"; + +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/UserThreadLocal.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/UserThreadLocal.java new file mode 100644 index 0000000..a7bbff8 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/utils/UserThreadLocal.java @@ -0,0 +1,20 @@ +package com.m2pool.lease.utils; + +/** + * 线程变量 + */ +public class UserThreadLocal { + private static final ThreadLocal USER_EMAIL = new ThreadLocal<>(); + + public static void setUserEmail(String email) { + USER_EMAIL.set(email); + } + + public static String getUserEmail() { + return USER_EMAIL.get(); + } + + public static void remove() { + USER_EMAIL.remove(); + } +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/EmailCodeVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/EmailCodeVo.java new file mode 100644 index 0000000..021c25a --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/EmailCodeVo.java @@ -0,0 +1,23 @@ +package com.m2pool.lease.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; + +/** + * @Description 用户登录对象 + * @Date 2024/6/12 16:13 + * @Author dy + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class EmailCodeVo { + /** 邮箱 */ + @NotNull(message = "用户邮箱不能为空") + @Email(message = "邮箱格式错误") + private String email; +} diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserURDVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserLoginVo.java similarity index 55% rename from m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserURDVo.java rename to m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserLoginVo.java index 7bb95cb..f0ebdf3 100644 --- a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserURDVo.java +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserLoginVo.java @@ -1,5 +1,6 @@ package com.m2pool.lease.vo; +import com.m2pool.lease.annotation.EncryptedField; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -19,17 +20,16 @@ import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor -@ApiModel(description = "用户请求对象",value = "UserDto") -public class UserURDVo { - /** - * 用户名 - */ - @ApiModelProperty(value = "用户id(邮箱)",example = "Eudora.law@outlook.com") - private String userId; +@ApiModel(description = "用户登录请求对象",value = "UserLoginVo") +public class UserLoginVo { + + @ApiModelProperty(value = "用户eamil",example = "Eudora.law@outlook.com") + private String email; - /** - * 密码 - */ @ApiModelProperty(value = "密码",example = "123456") + @EncryptedField private String password; + + @ApiModelProperty(value = "验证码",example = "123456") + private String code; } diff --git a/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserRegisterVo.java b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserRegisterVo.java new file mode 100644 index 0000000..c8e190c --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/java/com/m2pool/lease/vo/UserRegisterVo.java @@ -0,0 +1,35 @@ +package com.m2pool.lease.vo; + +import com.m2pool.lease.annotation.EncryptedField; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *

+ * 用户请求对象 + *

+ * + * @author yyb + * @since 2025-07-23 + */ +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "用户注册请求对象",value = "UserRegisterVo") +public class UserRegisterVo { + + @ApiModelProperty(value = "用户eamil",example = "Eudora.law@outlook.com") + private String userEmail; + + @ApiModelProperty(value = "密码",example = "123456") + @EncryptedField + private String password; + + @ApiModelProperty(value = "验证码",example = "123456") + private String code; +} diff --git a/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-dev.yml b/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-dev.yml index 6ee627f..9e2fa2b 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-dev.yml +++ b/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-dev.yml @@ -5,6 +5,23 @@ server: enabled: true mime-types: application/json spring: + #邮箱基本配置 + mail: + # 配置在limit_time内,用户可以发送limit次验证码 + limit: 2 这个是我额外的配置,结合邮箱服务用的 + limitTime: 10 这个是我额外的配置 + #配置smtp服务主机地址 + # sina smtp.sina.cn + # aliyun smtp.aliyun.com + # 163 smtp.163.com 端口号465或994 + host: mail.privateemail.com + #发送者邮箱 + username: do.not.reply@m2pool.com + #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 + # password: + # password: M2202401! + # password: axvm-zfgx-cgcg-qhhu + password: M2202401! mvc: pathmatch: matching-strategy: ant_path_matcher diff --git a/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-test.yml b/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-test.yml index 149111b..7b91062 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-test.yml +++ b/m2pool-modules/m2pool-lease/src/main/resources/bootstrap-test.yml @@ -5,6 +5,43 @@ server: enabled: true mime-types: application/json spring: + #邮箱基本配置 + mail: + # 配置在limit_time内,用户可以发送limit次验证码 + limit: 2 这个是我额外的配置,结合邮箱服务用的 + limitTime: 10 这个是我额外的配置 + #配置smtp服务主机地址 + # sina smtp.sina.cn + # aliyun smtp.aliyun.com + # 163 smtp.163.com 端口号465或994 + host: mail.privateemail.com + #发送者邮箱 + username: do.not.reply@m2pool.com + #配置密码,注意不是真正的密码,而是刚刚申请到的授权码 + # password: + # password: M2202401! + # password: axvm-zfgx-cgcg-qhhu + password: M2202401! + + #端口号 + port: 587 + # port: 465 + #默认的邮件编码为UTF-8 + default-encoding: UTF-8 + #其他参数 + properties: + mail: + #配置SSL 加密工厂 + smtp: + ssl: + #本地测试,先放开ssl + enable: false + required: false + #开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误 + debug: false + socketFactory: + class: javax.net.ssl.SSLSocketFactory + mvc: pathmatch: matching-strategy: ant_path_matcher @@ -57,3 +94,5 @@ netty: tcp: client: port: 2345 +image: + prefix: https://test.m2pool.com diff --git a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopConfigMapper.xml b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopConfigMapper.xml index 9022921..3df827c 100644 --- a/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopConfigMapper.xml +++ b/m2pool-modules/m2pool-lease/src/main/resources/mapper/lease/LeaseShopConfigMapper.xml @@ -93,7 +93,7 @@ UPDATE lease_shop_config SET balance = balance + #{item.realAmount} - WHERE pay_address = #{item.payAddress} AND pay_coin = #{item.payCoin} AND chain = #{item.chain} AND del = false + WHERE pay_address = #{item.fromAddress} AND pay_coin = #{item.fromSymbol} AND chain = #{item.fromChain} AND del = false diff --git a/m2pool-modules/m2pool-lease/src/main/resources/templates/emailCode-en.html b/m2pool-modules/m2pool-lease/src/main/resources/templates/emailCode-en.html new file mode 100644 index 0000000..144b875 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/templates/emailCode-en.html @@ -0,0 +1,50 @@ + + + + + + + Email code + + + + +
+ +
+ logo +
+ + + +
+ +

+ +
+ + +
+
+ + + +
+ + + diff --git a/m2pool-modules/m2pool-lease/src/main/resources/templates/emailoffline-en.html b/m2pool-modules/m2pool-lease/src/main/resources/templates/emailoffline-en.html new file mode 100644 index 0000000..b99f740 --- /dev/null +++ b/m2pool-modules/m2pool-lease/src/main/resources/templates/emailoffline-en.html @@ -0,0 +1,37 @@ + + + + + + offline notification + + +
+ +
+ logo +
+ + +
+

Your mining account:  

+

mining machines are offline!

+

If your mining rig has been abnormally disconnected, please address it promptly!

+
+ + + +
+ + + +