Merge branch 'preview' of https://gitea.qinmian.online/CY/mcwl-ai into feature/resource

feature/comment
ChenYan 2024-12-30 17:17:51 +08:00
commit 1f84a178b0
46 changed files with 1269 additions and 156 deletions

View File

@ -55,6 +55,13 @@
<artifactId>mcwl-quartz</artifactId>
</dependency>
<!-- 我的邀请模块-->
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-myInvitation</artifactId>
<version>3.8.8</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.mcwl</groupId>

View File

@ -0,0 +1,12 @@
package com.mcwl.web.controller.myInvitation;
import org.springframework.web.bind.annotation.RestController;
@RestController("/consume")
public class ConsumeController {
}

View File

@ -0,0 +1,49 @@
package com.mcwl.web.controller.myInvitation;
import com.mcwl.common.annotation.Anonymous;
import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.myInvitation.domain.Invitation;
import com.mcwl.myInvitation.service.InvitationService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static com.mcwl.common.core.domain.AjaxResult.success;
@RestController("/invitation")
@RequiredArgsConstructor
public class InvitationController {
private final InvitationService invitationService;
@GetMapping("/getInvitationCode")
@Anonymous
public AjaxResult getInvitationCode() {
// 获取当前用户
Long userId = SecurityUtils.getUserId();
String invitationCode = invitationService.getInvitationCode(userId);
return success("操作成功", invitationCode);
}
@GetMapping("/list")
public AjaxResult list() {
List<Invitation> list = invitationService.list();
return success(list);
}
@GetMapping("/getById")
public AjaxResult getById(Long id) {
Invitation invitation = invitationService.getById(id);
return success(invitation);
}
}

View File

@ -1,18 +1,5 @@
package com.mcwl.web.controller.system;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.mcwl.common.annotation.Log;
import com.mcwl.common.constant.UserConstants;
import com.mcwl.common.core.controller.BaseController;
@ -21,6 +8,13 @@ import com.mcwl.common.core.domain.entity.SysDept;
import com.mcwl.common.enums.BusinessType;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.system.service.ISysDeptService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
*

View File

@ -1,29 +1,38 @@
package com.mcwl.web.controller.system;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.mcwl.common.annotation.Anonymous;
import com.mcwl.common.constant.Constants;
import com.mcwl.common.constant.RedisConstants;
import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.core.domain.entity.SysMenu;
import com.mcwl.common.core.domain.entity.SysUser;
import com.mcwl.common.core.domain.model.LoginBody;
import com.mcwl.common.core.domain.model.LoginUser;
import com.mcwl.common.core.domain.model.PhoneLoginBody;
import com.mcwl.common.core.redis.RedisCache;
import com.mcwl.common.utils.CodeUtils;
import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.common.utils.uuid.TelSmsUtils;
import com.mcwl.framework.web.service.SysLoginService;
import com.mcwl.framework.web.service.SysPermissionService;
import com.mcwl.framework.web.service.TokenService;
import com.mcwl.system.service.ISysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
*
*
* @author mcwl
*/
@Slf4j
@RestController
public class SysLoginController
{
@ -39,6 +48,31 @@ public class SysLoginController
@Autowired
private TokenService tokenService;
@Autowired
private RedisCache redisCache;
@Anonymous
@GetMapping("/getCode")
public AjaxResult code(@RequestParam String phone){
//生成验证码
String s = CodeUtils.generateCaptcha();
log.info("获取到的验证码:{}",s);
//存储redis
redisCache.setCacheObject(RedisConstants.CODE_PHONE+phone,s,1, TimeUnit.MINUTES);
//发送短信服务
// 构建 sendDataMap
Map<String, String> sendDataMap = new HashMap<>();
sendDataMap.put("code", s);
TelSmsUtils.sendSms(phone,"SMS_460535072",sendDataMap);
return AjaxResult.success();
}
/**
*
*
@ -56,6 +90,20 @@ public class SysLoginController
return ajax;
}
@PostMapping("/phoneLogin")
@Anonymous
public AjaxResult phoneLogin(@RequestBody PhoneLoginBody phoneLoginBody){
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.phoneLogin(phoneLoginBody.getPhone(),phoneLoginBody.getCode());
ajax.put(Constants.TOKEN, token);
return ajax;
}
/**
*
*

View File

@ -1,21 +1,5 @@
package com.mcwl.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.mcwl.common.annotation.Log;
import com.mcwl.common.core.controller.BaseController;
import com.mcwl.common.core.domain.AjaxResult;
@ -31,6 +15,16 @@ import com.mcwl.system.service.ISysDeptService;
import com.mcwl.system.service.ISysPostService;
import com.mcwl.system.service.ISysRoleService;
import com.mcwl.system.service.ISysUserService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;
/**
*

View File

@ -286,6 +286,13 @@
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- 阿里大鱼 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,39 @@
package com.mcwl.common.constant;
public class JwtConstants {
/**
* ID
*/
public static final String DETAILS_USER_ID = "user_id";
/**
*
*/
public static final String DETAILS_USERNAME = "user_name";
/**
*
*/
public static final String USER_KEY = "user_key";
/**
*
*/
public final static String SECRET = "abcdefghijklmnopqrstuvwxyz";
/**
*
*/
public static final String USER_PHONE = "user_phone";
/**
* token
*/
public static final String LOGIN_TOKEN = "login_token:";
/**
* token 1h = 60 * 60 * 1000L
*/
public static final Long EXPIRATION = 60 * 60 * 1000L;
}

View File

@ -0,0 +1,14 @@
package com.mcwl.common.constant;
/**
* redis
*
* @author DaiZibo
* @date 2024/12/28
* @apiNote
*/
public class RedisConstants {
public static final String CODE_PHONE = "code_phone:";
}

View File

@ -0,0 +1,25 @@
package com.mcwl.common.core.domain.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*
* @author DaiZibo
* @date 2024/12/28
* @apiNote
*/
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class PhoneLoginBody {
private String phone;
private String code;
}

View File

@ -0,0 +1,39 @@
package com.mcwl.common.enums;
/**
*
*
* @author DaiZibo
* @date 2024/12/30
* @apiNote
*/
public enum ResultCode {
SUCCESS(200),//成功
FAIL(400),//失败
FAIL_SIGN_IN(401),//登录失败
TOKEN_OVERDUE(402),//token过期
NOT_FOUND(404),//接口不存在
INTERNAL_SERVICE_ERROR(500);//服务器内部错误
private final Integer code;
ResultCode(Integer code) {
this.code = code;
}
private Integer code() {
return code;
}
public Integer getCode() {
return code;
}
}

View File

@ -0,0 +1,40 @@
package com.mcwl.common.exception;
import com.mcwl.common.enums.ResultCode;
/**
*
* @author DaiZibo
* @date 2024/12/30
* @apiNote
*/
public class ErrorCodeException extends RuntimeException {
private Integer code;
private String message;
public ErrorCodeException(ResultCode resultCode, String msg) {
this.code = resultCode.getCode();
this.message = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,29 @@
package com.mcwl.common.utils;
import java.util.Random;
/**
*
*
* @author DaiZibo
* @date 2024/12/28
* @apiNote
*/
public class CodeUtils {
/**
* 4
*
* @return
*/
public static String generateCaptcha() {
// 创建Random对象用于生成随机数
Random random = new Random();
// 生成1000到9999之间的随机整数包括1000和9999
int captcha = 1000 + random.nextInt(9000);
// 将整数转换为字符串并返回
return String.valueOf(captcha);
}
}

View File

@ -0,0 +1,114 @@
package com.mcwl.common.utils;
import com.mcwl.common.constant.JwtConstants;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;
/**
* @description: Jwt
* @author DongZl
*/
public class JwtUtils {
/**
*
*/
public static String secret = JwtConstants.SECRET;
/**
*
*
* @param claims
* @return
*/
public static String createToken(Map<String, Object> claims){
String token = Jwts.builder()
.addClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret)
.setExpiration(new Date(System.currentTimeMillis() + JwtConstants.EXPIRATION))
.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, JwtConstants.USER_KEY);
}
/**
*
*
* @param claims
* @return ID
*/
public static String getUserKey(Claims claims){
return getValue(claims, JwtConstants.USER_KEY);
}
/**
* ID
*
* @param token
* @return ID
*/
public static String getUserId(String token){
Claims claims = parseToken(token);
return getValue(claims, JwtConstants.DETAILS_USER_ID);
}
/**
* ID
*
* @param claims
* @return ID
*/
public static String getUserId(Claims claims){
return getValue(claims, JwtConstants.DETAILS_USER_ID);
}
/**
*
*
* @param token
* @return
*/
public static String getUserName(String token){
Claims claims = parseToken(token);
return getValue(claims, JwtConstants.DETAILS_USERNAME);
}
/**
*
*
* @param claims
* @return
*/
public static String getUserName(Claims claims){
return getValue(claims, JwtConstants.DETAILS_USERNAME);
}
/**
*
*
* @param claims
* @param key
* @return
*/
public static String getValue(Claims claims, String key){
Object obj = claims.get(key);
return obj == null ? "" : obj.toString();
}
}

View File

@ -0,0 +1,87 @@
package com.mcwl.common.utils.uuid;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import lombok.extern.log4j.Log4j2;
import java.util.Map;
/**
*
*/
@Log4j2
public class TelSmsUtils {
/**
* AccessKeyaccessKeySecretAPI访
*/
private static String accessKeyId = "LTAIEVXszCmcd1T5";
private static String accessKeySecret = "2zHwciQXln8wExSEnkIYtRTSwLeRNd";
/**
* 访
*/
private static String endpoint = "dysmsapi.aliyuncs.com";
/**
*
*/
private static String signName = "帝宇";
/**
*
*/
private static Client client;
static {
log.info("初始化短信服务开始");
long startTime = System.currentTimeMillis();
try {
client = initClient();
log.info("初始化短信成功:{}",signName);
} catch (Exception e) {
e.printStackTrace();
}
log.info("初始化短信服务结束:耗时:{}MS",(System.currentTimeMillis()-startTime));
}
/**
*
* @return
* @throws Exception
*/
private static Client initClient() throws Exception{
Config config = new Config()
// 您的AccessKey ID
.setAccessKeyId(accessKeyId)
// 您的AccessKey Secret
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = endpoint;
return new Client(config);
}
/**
*
* @param tel
* @param templateCode SMS_153991546
* @param sendDataMap
*/
public static String sendSms(String tel , String templateCode , Map<String,String> sendDataMap){
SendSmsRequest sendSmsRequest = new SendSmsRequest()
.setPhoneNumbers(tel)
.setSignName(signName)
.setTemplateCode(templateCode)
.setTemplateParam(JSONObject.toJSONString(sendDataMap));
SendSmsResponse sendSmsResponse = null;
try {
log.info("发送短信验证码:消息内容是:【{}】", JSONObject.toJSONString(sendDataMap));
sendSmsResponse = client.sendSms(sendSmsRequest);
} catch (Exception e) {
log.error("短信发送异常,手机号:【{}】,短信内容:【{}】,异常信息:【{}】", tel, sendDataMap, e);
}
return JSONObject.toJSONString(sendSmsResponse.getBody());
}
}

View File

@ -1,5 +1,11 @@
package com.mcwl.framework.config;
import com.mcwl.framework.config.properties.PermitAllUrlProperties;
import com.mcwl.framework.security.core.OtherUserDetailsService;
import com.mcwl.framework.security.filter.JwtAuthenticationTokenFilter;
import com.mcwl.framework.security.handle.AuthenticationEntryPointImpl;
import com.mcwl.framework.security.handle.LogoutSuccessHandlerImpl;
import com.mcwl.framework.security.sms.SmsCodeByEmailAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -16,10 +22,6 @@ import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.filter.CorsFilter;
import com.mcwl.framework.config.properties.PermitAllUrlProperties;
import com.mcwl.framework.security.filter.JwtAuthenticationTokenFilter;
import com.mcwl.framework.security.handle.AuthenticationEntryPointImpl;
import com.mcwl.framework.security.handle.LogoutSuccessHandlerImpl;
/**
* spring security
@ -36,6 +38,13 @@ public class SecurityConfig
@Autowired
private UserDetailsService userDetailsService;
/**
* ()
*/
@Autowired
private OtherUserDetailsService userDetailsServiceByPhone;
/**
*
*/
@ -78,6 +87,15 @@ public class SecurityConfig
return new ProviderManager(daoAuthenticationProvider);
}
@Bean
public AuthenticationManager authenticationManagerPhone() {
SmsCodeByEmailAuthenticationProvider daoAuthenticationProvider = new SmsCodeByEmailAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsServiceByPhone);
return new ProviderManager(daoAuthenticationProvider);
}
/**
* anyRequest |
* access | SpringEltrue访

View File

@ -0,0 +1,16 @@
package com.mcwl.framework.security.core;
import com.mcwl.framework.security.core.otherUserdetails.OtherLoginNotFoundException;
import org.springframework.security.core.userdetails.UserDetails;
/**
* @author DaiZibo
* @date 2024/12/30
* @apiNote
*/
public interface OtherUserDetailsService {
UserDetails otherLoadUser(String o, int num) throws OtherLoginNotFoundException;
}

View File

@ -0,0 +1,20 @@
package com.mcwl.framework.security.core.otherUserdetails;
import org.springframework.security.core.AuthenticationException;
/**
* @author DaiZibo
* @date 2024/12/30
* @apiNote
*/
public class OtherLoginNotFoundException extends AuthenticationException {
public OtherLoginNotFoundException(String msg) {
super(msg);
}
public OtherLoginNotFoundException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -0,0 +1,74 @@
package com.mcwl.framework.security.sms;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import javax.security.auth.Subject;
import java.util.Collection;
/**
* AuthenticationToken仿 UsernamePasswordAuthenticationToken
*
* @author DaiZibo
* @date 2024/12/30
* @apiNote
*/
public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = 550L;
/**
* UsernamePasswordAuthenticationToken
*
*/
private final Object principal;
/**
* SmsCodeAuthenticationToken
*/
public SmsCodeAuthenticationToken(Object principal) {
super(null);
this.principal = principal;
setAuthenticated(false);
}
/**
* SmsCodeAuthenticationToken
*/
public SmsCodeAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
super.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) {
throw new IllegalArgumentException(
"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
}
super.setAuthenticated(false);
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
}
@Override
public boolean implies(Subject subject) {
return super.implies(subject);
}
}

View File

@ -0,0 +1,47 @@
package com.mcwl.framework.security.sms;
import com.mcwl.framework.security.core.OtherUserDetailsService;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.AuthenticationException;
/**
* @author DaiZibo
* @date 2024/12/30
* @apiNote
*/
public class SmsCodeByEmailAuthenticationProvider implements AuthenticationProvider {
private OtherUserDetailsService userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
String email = (String) authenticationToken.getPrincipal();
UserDetails userDetails = userDetailsService.otherLoadUser(email, 1);
// 此时鉴权成功后,应当重新 new 一个拥有鉴权的 authenticationResult 返回
SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(userDetails, userDetails.getAuthorities());
authenticationResult.setDetails(authenticationToken.getDetails());
return authenticationResult;
}
@Override
public boolean supports(Class<?> authentication) {
// 判断 authentication 是不是 SmsCodeAuthenticationToken 的子类或子接口
return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
}
public OtherUserDetailsService getUserDetailsService() {
return userDetailsService;
}
public void setUserDetailsService(OtherUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
}

View File

@ -1,6 +1,13 @@
package com.mcwl.framework.web.exception;
import javax.servlet.http.HttpServletRequest;
import com.mcwl.common.constant.HttpStatus;
import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.core.text.Convert;
import com.mcwl.common.exception.DemoModeException;
import com.mcwl.common.exception.ErrorCodeException;
import com.mcwl.common.exception.ServiceException;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.common.utils.html.EscapeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
@ -11,13 +18,8 @@ import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import com.mcwl.common.constant.HttpStatus;
import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.core.text.Convert;
import com.mcwl.common.exception.DemoModeException;
import com.mcwl.common.exception.ServiceException;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.common.utils.html.EscapeUtil;
import javax.servlet.http.HttpServletRequest;
/**
*
@ -29,6 +31,21 @@ public class GlobalExceptionHandler
{
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 仿
*/
@ExceptionHandler(ErrorCodeException.class)
public AjaxResult UserDefinedException(ErrorCodeException e){
System.out.println("StringUtils.isNull(e.getCode()):"+StringUtils.isNull(e.getCode()));
if (StringUtils.isNull(e.getCode()))
{
return AjaxResult.error(e.getMessage());
}
return AjaxResult.error(e.getCode(), e.getMessage());
}
/**
*
*/

View File

@ -1,24 +1,16 @@
package com.mcwl.framework.web.service;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.mcwl.common.constant.CacheConstants;
import com.mcwl.common.constant.Constants;
import com.mcwl.common.constant.RedisConstants;
import com.mcwl.common.constant.UserConstants;
import com.mcwl.common.core.domain.entity.SysUser;
import com.mcwl.common.core.domain.model.LoginUser;
import com.mcwl.common.core.redis.RedisCache;
import com.mcwl.common.enums.ResultCode;
import com.mcwl.common.exception.ErrorCodeException;
import com.mcwl.common.exception.ServiceException;
import com.mcwl.common.exception.user.BlackListException;
import com.mcwl.common.exception.user.CaptchaException;
import com.mcwl.common.exception.user.CaptchaExpireException;
import com.mcwl.common.exception.user.UserNotExistsException;
import com.mcwl.common.exception.user.UserPasswordNotMatchException;
import com.mcwl.common.exception.user.*;
import com.mcwl.common.utils.DateUtils;
import com.mcwl.common.utils.MessageUtils;
import com.mcwl.common.utils.StringUtils;
@ -26,8 +18,17 @@ import com.mcwl.common.utils.ip.IpUtils;
import com.mcwl.framework.manager.AsyncManager;
import com.mcwl.framework.manager.factory.AsyncFactory;
import com.mcwl.framework.security.context.AuthenticationContextHolder;
import com.mcwl.framework.security.sms.SmsCodeAuthenticationToken;
import com.mcwl.system.service.ISysConfigService;
import com.mcwl.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
*
@ -37,12 +38,19 @@ import com.mcwl.system.service.ISysUserService;
@Component
public class SysLoginService
{
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private TokenService tokenService;
@Resource
private AuthenticationManager authenticationManager;
@Resource
private AuthenticationManager authenticationManagerPhone;
@Autowired
private RedisCache redisCache;
@ -178,4 +186,81 @@ public class SysLoginService
sysUser.setLoginDate(DateUtils.getNowDate());
userService.updateUserProfile(sysUser);
}
public String phoneLogin(String phone, String code) {
//校验验证码
validateCaptcha(phone, code);
//根据手机号查询数据
SysUser sysUser = userService.selectUserByPhone(phone);
if (sysUser == null){
throw new UserNotExistsException();
}
// 登录前置校验
otherLoginPreCheck(sysUser.getUserName());
// 用户验证
Authentication authentication;
try {
SmsCodeAuthenticationToken smsCodeAuthenticationToken = new SmsCodeAuthenticationToken(sysUser.getPhonenumber());
System.out.println(smsCodeAuthenticationToken);
AuthenticationContextHolder.setContext(smsCodeAuthenticationToken);
authentication = authenticationManagerPhone.authenticate(smsCodeAuthenticationToken);
}
// SmsCodeAuthenticationToken [Principal=admin, Credentials=[PROTECTED], Authenticated=false, Details=null, Granted Authorities=[]]
catch (Exception e) {
if (e instanceof BadCredentialsException) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
} else {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_FAIL, e.getMessage()));
throw new ServiceException(e.getMessage());
}
}
finally {
AuthenticationContextHolder.clearContext();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
return tokenService.createToken(loginUser);
}
private void validateCaptcha(String phone, String code) {
//校验验证码
Object cacheObject = redisCache.getCacheObject(RedisConstants.CODE_PHONE + phone);
System.out.println("验证码:"+cacheObject);
if (cacheObject == null) {
// 处理未找到验证码的情况
throw new ErrorCodeException(ResultCode.FAIL,"验证码已过期或未发送");
}
String c = (String) cacheObject;
if (!c.equals(code)){
//验证码错误
throw new ErrorCodeException(ResultCode.FAIL,"验证码错误");
}
}
public void otherLoginPreCheck(String username) {
// 用户名为空 错误
if (StringUtils.isEmpty(username)) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
throw new UserNotExistsException();
}
// 用户名不在指定范围内 错误
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
}
// IP黑名单校验
String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
throw new BlackListException();
}
}
}

View File

@ -1,5 +1,13 @@
package com.mcwl.framework.web.service;
import com.mcwl.common.core.domain.entity.SysUser;
import com.mcwl.common.core.domain.model.LoginUser;
import com.mcwl.common.enums.UserStatus;
import com.mcwl.common.exception.ServiceException;
import com.mcwl.common.utils.MessageUtils;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.framework.security.core.OtherUserDetailsService;
import com.mcwl.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -7,13 +15,6 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.mcwl.common.core.domain.entity.SysUser;
import com.mcwl.common.core.domain.model.LoginUser;
import com.mcwl.common.enums.UserStatus;
import com.mcwl.common.exception.ServiceException;
import com.mcwl.common.utils.MessageUtils;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.system.service.ISysUserService;
/**
*
@ -21,10 +22,12 @@ import com.mcwl.system.service.ISysUserService;
* @author mcwl
*/
@Service
public class UserDetailsServiceImpl implements UserDetailsService
{
public class UserDetailsServiceImpl implements UserDetailsService, OtherUserDetailsService {
private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
private int num = 0;
@Autowired
private ISysUserService userService;
@ -35,32 +38,41 @@ public class UserDetailsServiceImpl implements UserDetailsService
private SysPermissionService permissionService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
SysUser user = userService.selectUserByUserName(username);
if (StringUtils.isNull(user))
{
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser user = null;
if (num == 0 ){
user = userService.selectUserByUserName(username);
}else {
user = userService.selectUserByPhone(username);
}
if (StringUtils.isNull(user)) {
log.info("登录用户:{} 不存在.", username);
throw new ServiceException(MessageUtils.message("user.not.exists"));
}
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
} else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
log.info("登录用户:{} 已被删除.", username);
throw new ServiceException(MessageUtils.message("user.password.delete"));
}
else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
log.info("登录用户:{} 已被停用.", username);
throw new ServiceException(MessageUtils.message("user.blocked"));
}
// passwordService.validate(user);
if (num == 0) {
passwordService.validate(user);
}
num = 0;
return createLoginUser(user);
}
public UserDetails createLoginUser(SysUser user)
{
public UserDetails createLoginUser(SysUser user) {
return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
}
@Override
public UserDetails otherLoadUser(String username, int num) throws UsernameNotFoundException {
this.num = num;
return loadUserByUsername(username);
}
}

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mcwl</groupId>
<artifactId>mcwl</artifactId>
<version>3.8.8</version>
</parent>
<artifactId>mcwl-myInvitation</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
</properties>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.mcwl</groupId>
<artifactId>mcwl-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,41 @@
package com.mcwl.myInvitation.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mcwl.common.core.domain.BaseEntity;
import lombok.Data;
import java.util.Objects;
// 提成表
@Data
@TableName("commissions")
public class Commission extends BaseEntity {
@TableId
private Long id;
// 用户id
private Long userId;
// 消费id
private Long consumeId;
// 提成金额
private Double amount;
// 支付状态
private Integer payStatus;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Commission that = (Commission) o;
return Objects.equals(id, that.id) && Objects.equals(userId, that.userId) && Objects.equals(consumeId, that.consumeId) && Objects.equals(amount, that.amount) && Objects.equals(payStatus, that.payStatus);
}
@Override
public int hashCode() {
return Objects.hash(id, userId, consumeId, amount, payStatus);
}
}

View File

@ -0,0 +1,39 @@
package com.mcwl.myInvitation.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mcwl.common.core.domain.BaseEntity;
import lombok.Data;
import java.util.Date;
import java.util.Objects;
// 消费表
@Data
@TableName("consumes")
public class Consume extends BaseEntity {
@TableId
private Long id;
// 用户id
private Long userId;
// 消费金额
private Double amount;
// 消费时间
private Date consumeDate;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Consume consume = (Consume) o;
return Objects.equals(id, consume.id) && Objects.equals(userId, consume.userId) && Objects.equals(amount, consume.amount) && Objects.equals(consumeDate, consume.consumeDate);
}
@Override
public int hashCode() {
return Objects.hash(id, userId, amount, consumeDate);
}
}

View File

@ -0,0 +1,39 @@
package com.mcwl.myInvitation.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mcwl.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Objects;
// 邀请表
@Data
@TableName("invitations")
public class Invitation extends BaseEntity {
@TableId
private Long id;
// 邀请者
private Long userId;
// 被邀请者
private Long userInviteId ;
// 邀请码
private String invitationCode;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Invitation that = (Invitation) o;
return Objects.equals(id, that.id) && Objects.equals(userId, that.userId) && Objects.equals(userInviteId, that.userInviteId) && Objects.equals(invitationCode, that.invitationCode);
}
@Override
public int hashCode() {
return Objects.hash(id, userId, userInviteId, invitationCode);
}
}

View File

@ -0,0 +1,13 @@
package com.mcwl.myInvitation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mcwl.myInvitation.domain.Commission;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface CommissionMapper extends BaseMapper<Commission> {
}

View File

@ -0,0 +1,11 @@
package com.mcwl.myInvitation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mcwl.myInvitation.domain.Commission;
import com.mcwl.myInvitation.domain.Consume;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ConsumeMapper extends BaseMapper<Consume> {
}

View File

@ -0,0 +1,11 @@
package com.mcwl.myInvitation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mcwl.myInvitation.domain.Commission;
import com.mcwl.myInvitation.domain.Invitation;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface InvitationMapper extends BaseMapper<Invitation> {
}

View File

@ -0,0 +1,8 @@
package com.mcwl.myInvitation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mcwl.myInvitation.domain.Commission;
public interface CommissionService extends IService<Commission> {
}

View File

@ -0,0 +1,8 @@
package com.mcwl.myInvitation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mcwl.myInvitation.domain.Consume;
public interface ConsumeService extends IService<Consume> {
}

View File

@ -0,0 +1,14 @@
package com.mcwl.myInvitation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mcwl.myInvitation.domain.Invitation;
public interface InvitationService extends IService<Invitation> {
/**
*
* @param userId id
* @return
*/
String getInvitationCode(Long userId);
}

View File

@ -0,0 +1,16 @@
package com.mcwl.myInvitation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.myInvitation.domain.Commission;
import com.mcwl.myInvitation.mapper.CommissionMapper;
import com.mcwl.myInvitation.service.CommissionService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commission> implements CommissionService {
}

View File

@ -0,0 +1,15 @@
package com.mcwl.myInvitation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.myInvitation.domain.Consume;
import com.mcwl.myInvitation.mapper.ConsumeMapper;
import com.mcwl.myInvitation.service.ConsumeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ConsumeServiceImpl extends ServiceImpl<ConsumeMapper, Consume> implements ConsumeService {
}

View File

@ -0,0 +1,28 @@
package com.mcwl.myInvitation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mcwl.common.constant.JwtConstants;
import com.mcwl.common.utils.JwtUtils;
import com.mcwl.myInvitation.domain.Invitation;
import com.mcwl.myInvitation.mapper.InvitationMapper;
import com.mcwl.myInvitation.service.InvitationService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class InvitationServiceImpl extends ServiceImpl<InvitationMapper, Invitation> implements InvitationService {
@Override
public String getInvitationCode(Long userId) {
// 生成邀请码
Map<String, Object> claims = new HashMap<>() ;
claims.put(JwtConstants.DETAILS_USER_ID, userId);
String invitationCode = JwtUtils.createToken(claims);
return invitationCode;
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mcwl.myInvitation.mapper.CommissionMapper">
</mapper>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mcwl.myInvitation.mapper.ConsumeMapper">
</mapper>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mcwl.myInvitation.mapper.InvitationMapper">
</mapper>

View File

@ -8,9 +8,7 @@
<artifactId>mcwl</artifactId>
<version>3.8.8</version>
</parent>
<artifactId>mcwl-resource</artifactId>
<description>
resource资源中心模块
</description>

View File

@ -1,8 +1,9 @@
package com.mcwl.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.mcwl.common.core.domain.entity.SysUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
*
@ -124,4 +125,7 @@ public interface SysUserMapper
* @return
*/
public SysUser checkEmailUnique(String email);
SysUser selectUserByPhone(@Param("phone") String phone);
}

View File

@ -1,8 +1,9 @@
package com.mcwl.system.service;
import java.util.List;
import com.mcwl.common.core.domain.entity.SysUser;
import java.util.List;
/**
*
*
@ -203,4 +204,7 @@ public interface ISysUserService
* @return
*/
public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
SysUser selectUserByPhone(String phone);
}

View File

@ -1,15 +1,5 @@
package com.mcwl.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Validator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import com.mcwl.common.annotation.DataScope;
import com.mcwl.common.constant.UserConstants;
import com.mcwl.common.core.domain.entity.SysRole;
@ -22,14 +12,21 @@ import com.mcwl.common.utils.spring.SpringUtils;
import com.mcwl.system.domain.SysPost;
import com.mcwl.system.domain.SysUserPost;
import com.mcwl.system.domain.SysUserRole;
import com.mcwl.system.mapper.SysPostMapper;
import com.mcwl.system.mapper.SysRoleMapper;
import com.mcwl.system.mapper.SysUserMapper;
import com.mcwl.system.mapper.SysUserPostMapper;
import com.mcwl.system.mapper.SysUserRoleMapper;
import com.mcwl.system.mapper.*;
import com.mcwl.system.service.ISysConfigService;
import com.mcwl.system.service.ISysDeptService;
import com.mcwl.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
*
@ -547,4 +544,10 @@ public class SysUserServiceImpl implements ISysUserService
}
return successMsg.toString();
}
@Override
public SysUser selectUserByPhone(String phone) {
return userMapper.selectUserByPhone(phone);
}
}

View File

@ -142,6 +142,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select user_id, email from sys_user where email = #{email} and del_flag = '0' limit 1
</select>
<select id="selectUserByPhone" resultMap="SysUserResult">
<include refid="selectUserVo"/>
where u.phonenumber = #{phone} and u.del_flag = '0'
</select>
<insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
insert into sys_user(
<if test="userId != null and userId != 0">user_id,</if>

View File

@ -228,6 +228,7 @@
<module>mcwl-quartz</module>
<module>mcwl-generator</module>
<module>mcwl-common</module>
<module>mcwl-myInvitation</module>
<module>mcwl-resource</module>
</modules>
<packaging>pom</packaging>

View File

@ -1,7 +1,6 @@
-- ----------------------------
-- 0、 xxx
-- ----------------------------
-- create table xxx
-- (
-- post_id bigint(20) not null auto_increment comment '岗位ID',