TRX 1 년 전
부모
커밋
61889a765c
14개의 변경된 파일440개의 추가작업 그리고 4개의 파일을 삭제
  1. 45 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/org/LoginParam.java
  2. 55 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/org/IndexController.java
  3. 4 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java
  4. 3 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/UserCountDao.java
  5. 19 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/UserLoginFailRecordDao.java
  6. 17 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/UserLoginRecordDao.java
  7. 31 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/org/UserLoginFailRecord.java
  8. 40 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/org/UserLoginRecord.java
  9. 1 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/base/CommonService.java
  10. 89 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/base/RedisService.java
  11. 1 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/base/SuperService.java
  12. 1 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/DepartmentServiceImpl.java
  13. 133 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/IndexService.java
  14. 1 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/UserAccountServiceImpl.java

+ 45 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/org/LoginParam.java

@@ -0,0 +1,45 @@
+package com.zhongshu.card.client.model.org;
+
+import com.github.microservice.auth.client.type.DeviceType;
+import com.github.microservice.auth.client.type.LoginType;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Schema(name = "LoginParam", description = "用户登陆参数")
+public class LoginParam {
+
+    //用户设备类型
+    @Schema(name = "deviceType", required = true, example = "Pc")
+    private DeviceType deviceType = DeviceType.Pc;
+
+    //用户设备编码
+    @Schema(name = "deviceUUid", required = false, example = "123456")
+    private String deviceUUid;
+
+    //登陆类型
+    @Schema(name = "loginType", required = true, example = "Phone")
+    private LoginType loginType = LoginType.Phone;
+
+    //登陆名
+    @Schema(name = "loginValue", required = true, example = "18723497166")
+    private String loginValue;
+
+    //密码
+    @Schema(name = "passWord", required = true, example = "123abc")
+    private String passWord;
+
+    //微信小程序openId
+    @Schema(name = "openId", required = false, example = "sss")
+    private String openId;
+
+    //访问令牌超时时间 (秒)
+    @Schema(name = "accessTokenTimeOut", required = false, example = "259200")
+    private Long accessTokenTimeOut = 10 * 60 * 60L;
+}

+ 55 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/org/IndexController.java

@@ -0,0 +1,55 @@
+package com.zhongshu.card.server.core.controller.org;
+
+import com.github.microservice.auth.client.model.LoginTokenModel;
+import com.zhongshu.card.client.model.org.LoginParam;
+import com.zhongshu.card.client.ret.ResultContent;
+import com.zhongshu.card.client.ret.ResultState;
+import com.zhongshu.card.server.core.service.org.IndexService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author TRX
+ * @date 2024/6/4
+ */
+@RestController
+@RequestMapping("index")
+@Tag(name = "登录注册")
+public class IndexController {
+
+    @Autowired
+    IndexService indexService;
+
+    /**
+     * 登录
+     *
+     * @param param
+     * @return
+     */
+    @Operation(summary = "登录--web端登录使用", description = "登录--web端登录使用")
+    @RequestMapping(value = "login", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
+    public ResultContent login(@RequestBody LoginParam param, HttpServletRequest request, HttpServletResponse response) {
+
+        ResultContent result = indexService.login(param);
+        if (result != null && result.getState() == ResultState.Success) {
+            LoginTokenModel tokenModel = (LoginTokenModel) result.getContent();
+            response.setHeader("accessToken", tokenModel.getAccess_token());
+
+            Cookie cookie = new Cookie("accessToken", tokenModel.getAccess_token());
+            cookie.setMaxAge(60 * 60 * 24 * 30);
+            cookie.setPath("/");
+            response.addCookie(cookie);
+        }
+        return result;
+    }
+
+}

+ 4 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java

@@ -1,6 +1,7 @@
 package com.zhongshu.card.server.core.dao.org;
 
 import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.card.client.type.OrganizationState;
 import com.zhongshu.card.server.core.dao.org.extend.OrganizationDaoExtend;
 import com.zhongshu.card.server.core.dao.org.extend.OrganizationUserDaoExtend;
 import com.zhongshu.card.server.core.dao.org.extend.UserCountDaoExtend;
@@ -21,4 +22,7 @@ public interface OrganizationUserDao extends MongoDao<OrganizationUser>, Organiz
 
     // 用户是否存在
     Boolean existsByOrganizationAndUser(Organization organization, UserAccount user);
+
+    // 统计用户所在的结构数量
+    long countByUserAndState(UserAccount user, OrganizationState state);
 }

+ 3 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/UserCountDao.java

@@ -14,4 +14,7 @@ public interface UserCountDao extends MongoDao<UserAccount>, UserCountDaoExtend
 
     UserAccount findTopByUserId(String userId);
 
+    UserAccount findTopByPhone(String phone);
+
+    UserAccount findTopByLoginName(String loginName);
 }

+ 19 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/UserLoginFailRecordDao.java

@@ -0,0 +1,19 @@
+package com.zhongshu.card.server.core.dao.org;
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.card.server.core.domain.org.Department;
+import com.zhongshu.card.server.core.domain.org.UserLoginFailRecord;
+import com.zhongshu.card.server.core.domain.org.UserLoginRecord;
+
+/**
+ * @author TRX
+ * @date 2024/3/21
+ */
+public interface UserLoginFailRecordDao extends MongoDao<UserLoginFailRecord> {
+
+    UserLoginFailRecord findTopById(String id);
+
+    long countByUserName(String userName);
+
+    long deleteByUserName(String userName);
+}

+ 17 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/UserLoginRecordDao.java

@@ -0,0 +1,17 @@
+package com.zhongshu.card.server.core.dao.org;
+
+import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
+import com.zhongshu.card.server.core.domain.org.Department;
+import com.zhongshu.card.server.core.domain.org.UserLoginRecord;
+
+import java.util.List;
+
+/**
+ * @author TRX
+ * @date 2024/3/21
+ */
+public interface UserLoginRecordDao extends MongoDao<UserLoginRecord> {
+
+    UserLoginRecord findTopById(String id);
+
+}

+ 31 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/org/UserLoginFailRecord.java

@@ -0,0 +1,31 @@
+package com.zhongshu.card.server.core.domain.org;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.card.server.core.domain.base.SuperMain;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.util.Date;
+
+@Data
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class UserLoginFailRecord extends SuperMain {
+
+    /**
+     * 账户名称
+     */
+    private String userName;
+
+    /**
+     * 过期时间
+     */
+    @Indexed(expireAfterSeconds = 0)
+    private Date ttl;
+}

+ 40 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/org/UserLoginRecord.java

@@ -0,0 +1,40 @@
+package com.zhongshu.card.server.core.domain.org;
+
+import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
+import com.zhongshu.card.server.core.domain.base.SuperMain;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.util.Date;
+
+/**
+ * 用户登录日志
+ */
+@Data
+@Document
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class UserLoginRecord extends SuperMain {
+
+    @Indexed
+    private String uid;
+
+    @Indexed
+    private String phone;
+
+    /**
+     * 账户名称
+     */
+    private String userName;
+
+    /**
+     * 过期时间
+     */
+    @Indexed(expireAfterSeconds = 0)
+    private Date TTL;
+}

+ 1 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/CommonService.java → FullCardServer/src/main/java/com/zhongshu/card/server/core/service/base/CommonService.java

@@ -1,4 +1,4 @@
-package com.zhongshu.card.server.core.service;
+package com.zhongshu.card.server.core.service.base;
 
 import com.mongodb.client.result.UpdateResult;
 import com.zhongshu.card.server.core.util.CommonUtil;

+ 89 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/base/RedisService.java

@@ -0,0 +1,89 @@
+package com.zhongshu.card.server.core.service.base;
+
+import com.zhongshu.card.server.core.util.exception.ServiceException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+
+@Service
+public class RedisService {
+
+    @Autowired
+    private StringRedisTemplate template;
+
+    public void addExpireToken(String loginName, String token, long tokenExpirePeriod) {
+        try {
+            String[] tokens = token.split("\\.");
+            //template.boundValueOps(tokenKey).set(loginName, 10000, TimeUnit.MILLISECONDS);
+            template.opsForValue().set(tokens[1], loginName, tokenExpirePeriod, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            throw new ServiceException("系统故障,请联系服务商");
+        }
+    }
+
+    public void removeExpireToken(String loginName, String token) {
+        try {
+            String[] tokens = token.split("\\.");
+            //template.boundValueOps(tokenKey).set(loginName, 10000, TimeUnit.MILLISECONDS);
+            template.delete(tokens[1]);
+        } catch (Exception e) {
+            throw new ServiceException("系统故障,请联系服务商");
+        }
+    }
+
+    public boolean verifyExpireJwtToken(String loginName, String jwtToken) {
+        try {
+            String[] tokens = jwtToken.split("\\.");
+            //template.boundValueOps(tokenKey).set(loginName, 10000, TimeUnit.MILLISECONDS);
+            return template.hasKey(tokens[1]);
+        } catch (Exception e) {
+            throw new ServiceException("系统故障,请联系服务商");
+        }
+    }
+
+    public boolean verifyExpireCode(String code) {
+        try {
+            //template.boundValueOps(tokenKey).set(loginName, 10000, TimeUnit.MILLISECONDS);
+            return template.hasKey(code);
+        } catch (Exception e) {
+            throw new ServiceException("系统故障,请联系服务商");
+        }
+    }
+
+
+    public void setValue(String key, String value, long expirePeriod) {
+        try {
+            template.opsForValue().set(key, value, expirePeriod, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            throw new ServiceException("系统故障,请联系服务商");
+        }
+    }
+
+    public void setValueSecond(String key, String value, long expirePeriod) {
+        try {
+            template.opsForValue().set(key, value, expirePeriod, TimeUnit.SECONDS);
+        } catch (Exception e) {
+            throw new ServiceException("系统故障,请联系服务商");
+        }
+    }
+
+    public String getValue(String key) {
+        try {
+            return template.opsForValue().get(key);
+        } catch (Exception e) {
+            throw new ServiceException("系统故障,请联系服务商");
+        }
+    }
+
+    public void removeValue(String key) {
+        try {
+            template.delete(key);
+        } catch (Exception e) {
+            throw new ServiceException("系统故障,请联系服务商");
+        }
+    }
+
+}

+ 1 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/SuperService.java → FullCardServer/src/main/java/com/zhongshu/card/server/core/service/base/SuperService.java

@@ -1,4 +1,4 @@
-package com.zhongshu.card.server.core.service;
+package com.zhongshu.card.server.core.service.base;
 
 /**
  * @author TRX

+ 1 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/DepartmentServiceImpl.java

@@ -12,7 +12,7 @@ import com.zhongshu.card.client.utils.TreeUtil;
 import com.zhongshu.card.server.core.dao.org.DepartmentDao;
 import com.zhongshu.card.server.core.domain.org.Department;
 import com.zhongshu.card.server.core.domain.org.Organization;
-import com.zhongshu.card.server.core.service.SuperService;
+import com.zhongshu.card.server.core.service.base.SuperService;
 import com.zhongshu.card.server.core.util.BeanUtils;
 import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.extern.slf4j.Slf4j;

+ 133 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/IndexService.java

@@ -0,0 +1,133 @@
+package com.zhongshu.card.server.core.service.org;
+
+import com.github.microservice.auth.client.model.LoginTokenModel;
+import com.github.microservice.auth.client.model.UserAuthLoginModel;
+import com.github.microservice.auth.client.service.UserService;
+import com.github.microservice.auth.security.helper.AuthHelper;
+import com.github.microservice.components.data.mongo.mongo.helper.DBHelper;
+import com.github.microservice.core.util.net.IPUtil;
+import com.zhongshu.card.client.model.org.LoginParam;
+import com.zhongshu.card.client.ret.ResultContent;
+import com.zhongshu.card.client.type.OrganizationState;
+import com.zhongshu.card.client.type.UserState;
+import com.zhongshu.card.server.core.dao.org.OrganizationUserDao;
+import com.zhongshu.card.server.core.dao.org.UserCountDao;
+import com.zhongshu.card.server.core.dao.org.UserLoginFailRecordDao;
+import com.zhongshu.card.server.core.dao.org.UserLoginRecordDao;
+import com.zhongshu.card.server.core.domain.org.UserAccount;
+import com.zhongshu.card.server.core.domain.org.UserLoginFailRecord;
+import com.zhongshu.card.server.core.domain.org.UserLoginRecord;
+import com.zhongshu.card.server.core.service.base.RedisService;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @author TRX
+ * @date 2024/6/4
+ */
+@Slf4j
+@Service
+public class IndexService {
+
+    @Autowired
+    private UserCountDao userCountDao;
+
+    @Autowired
+    UserService userService;
+
+    @Autowired
+    private AuthHelper authHelper;
+
+    @Autowired
+    private HttpServletRequest request;
+
+    @Autowired
+    RedisService redisService;
+
+    @Value("${oAuth.clientId}")
+    private String clientId;
+
+    @Value("${oAuth.clientSecret}")
+    private String clientSecret;
+
+    @Autowired
+    UserLoginRecordDao userLoginRecordDao;
+
+    @Autowired
+    UserLoginFailRecordDao userLoginFailRecordDao;
+
+    @Autowired
+    DBHelper dbHelper;
+
+    @Autowired
+    OrganizationUserDao organizationUserDao;
+
+    /**
+     * 登录--web
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent login(LoginParam param) {
+        String phone = param.getLoginValue();
+
+        UserAuthLoginModel userAuthLoginModel = new UserAuthLoginModel();
+        BeanUtils.copyProperties(param, userAuthLoginModel);
+        userAuthLoginModel.setDeviceIp(IPUtil.getRemoteIp(request));
+        userAuthLoginModel.setClientId(clientId);
+        userAuthLoginModel.setClientSecret(clientSecret);
+        userAuthLoginModel.setDeviceUserAgent(request.getHeader("user-agent"));
+        com.github.microservice.auth.client.content.ResultContent<LoginTokenModel> resultContent = userService.login(userAuthLoginModel);
+        if (resultContent.getState() == com.github.microservice.auth.client.content.ResultState.Success) {
+            UserAccount userAccount = userCountDao.findTopByLoginName(phone);
+            if (ObjectUtils.isEmpty(userAccount)) {
+                return ResultContent.buildFail("账号或密码不正确");
+            }
+            // 判断用户状态
+            if (userAccount.getState() == UserState.Frozen) {
+                return ResultContent.buildFail("该账号已被冻结,不能登录");
+            }
+
+            if (userAccount.getIsDelete() != null && userAccount.getIsDelete()) {
+                return ResultContent.buildFail("用户已被注销,登录失败");
+            }
+
+            long orgNumber = organizationUserDao.countByUserAndState(userAccount, OrganizationState.Normal);
+            if (orgNumber <= 0) {
+                return ResultContent.buildFail("用户未加入任何机构,不能登录");
+            }
+
+            // 记录已登录过
+            userAccount.setIsLogined(Boolean.TRUE);
+            userCountDao.save(userAccount);
+
+            UserLoginRecord record = new UserLoginRecord();
+            record.setPhone(userAccount.getPhone());
+            record.setUid(userAccount.getUserId());
+            record.setUserName(userAccount.getName());
+            record.setTTL(new Date(this.dbHelper.getTime() + 90 * 24L * 60 * 60 * 1000L));
+            userLoginRecordDao.save(record);
+
+            // 删除失败记录
+            userLoginFailRecordDao.deleteByUserName(param.getLoginValue());
+            return ResultContent.buildSuccess(resultContent.getContent());
+        }
+        // 记录登录失败信息
+        userLoginFailRecordDao.save(UserLoginFailRecord.builder().userName(param.getLoginValue())
+                .ttl(new Date(dbHelper.getTime() + 2 * 24L * 60 * 60 * 1000L)).build());
+        String msg = resultContent.getMsg();
+        if (StringUtils.isEmpty(msg)) {
+            msg = "账号或密码不正确.";
+        }
+        return ResultContent.buildFail(msg);
+    }
+}

+ 1 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/UserAccountServiceImpl.java

@@ -62,7 +62,7 @@ public class UserAccountServiceImpl implements UserAccountService, Serializable
             userAccount = new UserAccount();
             userAccount.setUserId(uid);
             userAccount.setPhone(entity.getContactPhone());
-            userAccount.setLoginName(entity.getContactName());
+            userAccount.setLoginName(entity.getContactPhone());
             if (!StringUtils.isEmpty(entity.getContactPhone())) {
                 userAccount.setName("用户" + entity.getContactPhone());
             } else {