新增以下内容1.客户端查看详情和断开连接,2.规则引擎的增删改查,3.资源的增删改查,

This commit is contained in:
sxh
2022-04-21 12:43:59 +08:00
44 changed files with 3588 additions and 589 deletions

View File

@@ -109,8 +109,8 @@ kerwincui/wumei-smart:1.1
* [演示地址>>](https://iot.wumei.live/)
##### 项目贡献者
|[小驿物联](https://gitee.com/iot-xiaoyi) |[guanshubiao](https://gitee.com/guanshubiao)|[crazyDull](https://gitee.com/crazyDull) |[kami0314](https://github.com/kami0314)| [sxh](https://gitee.com/sixiaohu) | [redamancy_zxp](https://gitee.com/redamancy-zxp)
|--|--|--|--|--|--|
|[小驿物联](https://gitee.com/iot-xiaoyi) |[guanshubiao](https://gitee.com/guanshubiao)|[crazyDull](https://gitee.com/crazyDull) |[kami0314](https://github.com/kami0314)| [sxh](https://gitee.com/sixiaohu) | [redamancy_zxp](https://gitee.com/redamancy-zxp) | [LEE](https://gitee.com/yueming188)
|--|--|--|--|--|--|--|
### 九、部分图片

View File

@@ -1,13 +1,13 @@
#### 一、物美智能项目是开源的可用于个人学习商业使用请赞助该项目获得授权同时还提供了小程序、APP和相关教程。
#### 二、获取移动端、教程和授权的方式
1. 赞助项目,赞助费暂定800元
2. 参与项目贡献代码减免300-800元
3. 推广项目减免10-800元
1. 赞助项目,赞助费暂定1500元
2. 参与项目贡献代码减免300-1500元
3. 推广项目减免10-1500元
#### 三、参与贡献代码
前端、后端、桌面端、移动端、嵌入式软件、嵌入式硬件、测试都可以。作者会发布一些任务到 [issues](https://gitee.com/kerwincui/wumei-smart/issues) 里面选择没有人参与并且自己可以完成的。Fork一份代码到自己仓库完成后提交合并请求。作者同意后减免300-800元。参与项目开发交流群946029159
前端、后端、桌面端、移动端、嵌入式软件、嵌入式硬件、测试都可以。作者会发布一些任务到 [issues](https://gitee.com/kerwincui/wumei-smart/issues) 里面选择没有人参与并且自己可以完成的。Fork一份代码到自己仓库完成后提交合并请求。作者同意后减免300-1500元。参与项目开发交流群946029159
#### 四、帮助推广项目
* 原创博客10-300元数量不限跟项目相关可以是介绍、教程、diy等
@@ -17,7 +17,7 @@
* 朋友圈分享10元/个限制1个
* 博客分享10元/平台限制3个
#### 五、通过赞助、贡献代码、推广可以加入项目内部,里面包含移动端源码和更多相关教程,并且获得一年的免费更新。目前项目还在完善,教程暂无,赞助费暂定800元。可以通过官网[http://wumei.live/](http://wumei.live/) 注册账号联系作者加入项目内部。QQ 164770707
#### 五、通过赞助、贡献代码、推广可以加入项目内部,里面包含移动端源码和更多相关教程,并且获得一年的免费更新。目前项目还在完善,教程暂无,赞助费暂定1500元。可以通过官网[http://wumei.live/](http://wumei.live/) 注册账号联系作者加入项目内部。QQ 164770707
<br /><br />

View File

@@ -24,6 +24,7 @@ target/
*.iws
*.iml
*.ipr
../.idea
### NetBeans ###
nbproject/private/

View File

@@ -33,6 +33,8 @@
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version>
<justAuth.version>1.16.5</justAuth.version>
<forest.version>1.5.19</forest.version>
</properties>
<!-- 依赖声明 -->
@@ -206,6 +208,20 @@
<version>${wumei.version}</version>
</dependency>
<!-- 第三方登录模块-->
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${justAuth.version}</version>
</dependency>
<!-- 通用http接口模块-->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>${forest.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@@ -8,8 +8,13 @@ spring:
master:
url: jdbc:mysql://localhost/wumei-smart?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
<<<<<<< HEAD
password: root
# password: 123456
=======
password: wumei-smart
# password: 123456
>>>>>>> 45a497af97959ef44d9172185e2ab1883a4fa25d
# 从库数据源
slave:
# 从数据源开关/默认关闭

View File

@@ -86,4 +86,9 @@ public class HttpStatus
* 接口未实现
*/
public static final int NOT_IMPLEMENTED = 501;
/**
* 不弹窗显示
*/
public static final int NO_MESSAGE_ALERT = 502;
}

View File

@@ -0,0 +1,22 @@
package com.ruoyi.common.core.domain.model;
/**
* 用户登录对象
*
* @author ruoyi
*/
public class BindLoginBody extends LoginBody
{
/**
* 绑定id
*/
private String bindId;
public String getBindId() {
return bindId;
}
public void setBindId(String bindId) {
this.bindId = bindId;
}
}

View File

@@ -0,0 +1,21 @@
package com.ruoyi.common.core.domain.model;
/**
* 用户注册对象
*
* @author ruoyi
*/
public class BindRegisterBody extends RegisterBody {
/**
* 绑定id
*/
private String bindId;
public String getBindId() {
return bindId;
}
public void setBindId(String bindId) {
this.bindId = bindId;
}
}

View File

@@ -213,7 +213,7 @@ public class RedisCache
* 删除Hash中的数据
*
* @param key
* @param mapkey
* @param hkey
*/
public void delCacheMapValue(final String key, final String hkey)
{
@@ -243,4 +243,15 @@ public class RedisCache
{
return redisTemplate.keys(pattern);
}
/**
* 是否存在key
*
* @param key 缓存key
* @return true存在key falsekey不存在或者已过期
*/
public boolean containsKey(String key) {
return redisTemplate.hasKey(key);
}
}

View File

@@ -0,0 +1,10 @@
package com.ruoyi.common.enums;
/**
* 第三方登录平台
*
* @author json
*/
public enum SocialPlatformType {
Wechat, QQ
}

View File

@@ -100,7 +100,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
.authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/register", "/captchaImage","/iot/tool/register","/iot/tool/ntp","/iot/tool/download",
"/iot/tool/mqtt/auth","/iot/tool/mqtt/webhook").anonymous()
"/iot/tool/mqtt/auth","/iot/tool/mqtt/webhook","/auth/**/**").anonymous()
.antMatchers(
HttpMethod.GET,
"/",

View File

@@ -6,6 +6,7 @@ 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.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
@@ -47,6 +48,9 @@ public class SysLoginService
@Autowired
private ISysConfigService configService;
@Autowired
private UserDetailsServiceImpl userDetailsServiceImpl;
/**
* 登录验证
*
@@ -64,6 +68,16 @@ public class SysLoginService
{
validateCaptcha(username, code, uuid);
}
return socialLogin(username,password);
}
/**
* 第三方验证后,调用登录方法
* @param username 用户名
* @param password 密码
* @return token
*/
public String socialLogin(String username, String password){
// 用户验证
Authentication authentication = null;
try
@@ -92,6 +106,25 @@ public class SysLoginService
return tokenService.createToken(loginUser);
}
/**
* 跳转登录认证接口
* @param username
* @param encodePwd
* @return
*/
public String redirectLogin(String username,String encodePwd){
UserDetails userDetails=userDetailsServiceImpl.loadUserByUsername(username);
if(!userDetails.getPassword().equals(encodePwd)){
throw new UserPasswordNotMatchException();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) userDetails;
recordLoginInfo(loginUser.getUserId());
// 生成token
return tokenService.createToken(loginUser);
}
/**
* 校验验证码
*

View File

@@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@@ -26,8 +27,7 @@ import io.jsonwebtoken.SignatureAlgorithm;
* @author ruoyi
*/
@Component
public class TokenService
{
public class TokenService {
// 令牌自定义标识
@Value("${token.header}")
private String header;
@@ -54,23 +54,27 @@ public class TokenService
*
* @return 用户信息
*/
public LoginUser getLoginUser(HttpServletRequest request)
{
public LoginUser getLoginUser(HttpServletRequest request) {
// 获取请求携带的令牌
String token = getToken(request);
if (StringUtils.isNotEmpty(token))
{
try
{
return getLoginUserByToken(token);
}
/**
* 获取用户身份信息
*
* @return 用户信息
*/
public LoginUser getLoginUserByToken(String token) {
if (StringUtils.isNotEmpty(token)) {
try {
Claims claims = parseToken(token);
// 解析对应的权限以及用户信息
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
String userKey = getTokenKey(uuid);
LoginUser user = redisCache.getCacheObject(userKey);
return user;
}
catch (Exception e)
{
} catch (Exception e) {
}
}
return null;
@@ -79,10 +83,8 @@ public class TokenService
/**
* 设置用户身份信息
*/
public void setLoginUser(LoginUser loginUser)
{
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
{
public void setLoginUser(LoginUser loginUser) {
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
refreshToken(loginUser);
}
}
@@ -90,10 +92,8 @@ public class TokenService
/**
* 删除用户身份信息
*/
public void delLoginUser(String token)
{
if (StringUtils.isNotEmpty(token))
{
public void delLoginUser(String token) {
if (StringUtils.isNotEmpty(token)) {
String userKey = getTokenKey(token);
redisCache.deleteObject(userKey);
}
@@ -105,8 +105,7 @@ public class TokenService
* @param loginUser 用户信息
* @return 令牌
*/
public String createToken(LoginUser loginUser)
{
public String createToken(LoginUser loginUser) {
String token = IdUtils.fastUUID();
loginUser.setToken(token);
setUserAgent(loginUser);
@@ -123,12 +122,10 @@ public class TokenService
* @param loginUser
* @return 令牌
*/
public void verifyToken(LoginUser loginUser)
{
public void verifyToken(LoginUser loginUser) {
long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
{
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
refreshToken(loginUser);
}
}
@@ -138,8 +135,7 @@ public class TokenService
*
* @param loginUser 登录信息
*/
public void refreshToken(LoginUser loginUser)
{
public void refreshToken(LoginUser loginUser) {
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存
@@ -152,8 +148,7 @@ public class TokenService
*
* @param loginUser 登录信息
*/
public void setUserAgent(LoginUser loginUser)
{
public void setUserAgent(LoginUser loginUser) {
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
loginUser.setIpaddr(ip);
@@ -168,8 +163,7 @@ public class TokenService
* @param claims 数据声明
* @return 令牌
*/
private String createToken(Map<String, Object> claims)
{
private String createToken(Map<String, Object> claims) {
String token = Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret).compact();
@@ -182,8 +176,7 @@ public class TokenService
* @param token 令牌
* @return 数据声明
*/
private Claims parseToken(String token)
{
private Claims parseToken(String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
@@ -196,8 +189,7 @@ public class TokenService
* @param token 令牌
* @return 用户名
*/
public String getUsernameFromToken(String token)
{
public String getUsernameFromToken(String token) {
Claims claims = parseToken(token);
return claims.getSubject();
}
@@ -208,18 +200,15 @@ public class TokenService
* @param request
* @return token
*/
private String getToken(HttpServletRequest request)
{
private String getToken(HttpServletRequest request) {
String token = request.getHeader(header);
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
{
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
token = token.replace(Constants.TOKEN_PREFIX, "");
}
return token;
}
private String getTokenKey(String uuid)
{
private String getTokenKey(String uuid) {
return Constants.LOGIN_TOKEN_KEY + uuid;
}
}

View File

@@ -74,6 +74,19 @@
<version>3.8.0</version>
</dependency>
<!--第三方登录通用接口-->
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<!-- <version>1.16.5</version>-->
</dependency>
<!--通用http接口-->
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
</dependency>
</dependencies>

View File

@@ -0,0 +1,103 @@
package com.ruoyi.iot.controller;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.BindLoginBody;
import com.ruoyi.common.core.domain.model.BindRegisterBody;
import com.ruoyi.iot.service.ISocialLoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import me.zhyd.oauth.model.AuthCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 第三方登录接口Controller
*
* @author json
* @date 2022-04-12
*/
@Api(tags = "第三方登录接口")
@RestController
@RequestMapping("/auth")
public class SocialLoginController {
@Autowired
private ISocialLoginService iSocialLoginService;
@GetMapping("/render/{source}")
@ApiOperation("跳转api")
@ApiImplicitParam(name = "source", value = "登录类型", required = true, dataType = "String", paramType = "path", dataTypeClass = String.class)
public void renderAuth(HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest, @PathVariable String source) throws IOException {
// 生成授权页面
httpServletResponse.sendRedirect(iSocialLoginService.renderAuth(source, httpServletRequest));
}
@GetMapping("/callback/{source}")
@ApiOperation("回调api")
@ApiImplicitParam(name = "source", value = "平台来源", required = true, dataType = "String", paramType = "path", dataTypeClass = String.class)
public void login(@PathVariable("source") String source, AuthCallback authCallback, HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest) throws IOException {
//回调接口
httpServletResponse.sendRedirect(iSocialLoginService.callback(source, authCallback, httpServletRequest));
}
@GetMapping("/checkBindId/{bindId}")
@ApiOperation("检查bindId")
@ApiImplicitParam(name = "bindId", value = "绑定ID", required = true, dataType = "String", paramType = "path", dataTypeClass = String.class)
public AjaxResult checkBindId(HttpServletResponse httpServletResponse, @PathVariable String bindId) {
return iSocialLoginService.checkBindId(bindId);
}
@GetMapping("/getErrorMsg/{errorId}")
@ApiOperation("获取errorMsg")
@ApiImplicitParam(name = "errorId", value = "错误提示ID", required = true, dataType = "String", paramType = "path", dataTypeClass = String.class)
public AjaxResult getErrorMsg(HttpServletResponse httpServletResponse, @PathVariable String errorId) {
return iSocialLoginService.getErrorMsg(errorId);
}
/**
* 已经绑定账户,跳转登录接口
*
* @param loginId
* @return
*/
@GetMapping("/login/{loginId}")
@ApiOperation("跳转登录api")
@ApiImplicitParam(name = "loginId", value = "登录Id", required = true, dataType = "String", paramType = "path", dataTypeClass = String.class)
public AjaxResult socialLogin(@PathVariable String loginId) {
// 生成授权页面
return iSocialLoginService.socialLogin(loginId);
}
/**
* 登录方法
*
* @param bindLoginBody 绑定登录信息
* @return 结果
*/
@PostMapping("/bind/login")
public AjaxResult bindLogin(@RequestBody BindLoginBody bindLoginBody) {
return iSocialLoginService.bindLogin(bindLoginBody);
}
/**
* 注册绑定接口
*
* @param bindRegisterBody 注册信息
* @return
*/
@PostMapping("/bind/register")
public AjaxResult bindRegister(@RequestBody BindRegisterBody bindRegisterBody) {
return iSocialLoginService.bindRegister(bindRegisterBody);
}
}

View File

@@ -0,0 +1,104 @@
package com.ruoyi.iot.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
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.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.iot.domain.SocialPlatform;
import com.ruoyi.iot.service.ISocialPlatformService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 第三方登录平台控制Controller
*
* @author kerwincui
* @date 2022-04-11
*/
@Api(tags = "第三方登录平台")
@RestController
@RequestMapping("/iot/platform")
public class SocialPlatformController extends BaseController {
@Autowired
private ISocialPlatformService socialPlatformService;
/**
* 查询第三方登录平台控制列表
*/
@PreAuthorize("@ss.hasPermi('iot:platform:list')")
@GetMapping("/list")
@ApiOperation("第三方登录平台分页列表")
public TableDataInfo list(SocialPlatform socialPlatform) {
startPage();
List<SocialPlatform> list = socialPlatformService.selectSocialPlatformList(socialPlatform);
return getDataTable(list);
}
/**
* 导出第三方登录平台控制列表
*/
@PreAuthorize("@ss.hasPermi('iot:platform:export')")
@Log(title = "第三方登录平台控制", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SocialPlatform socialPlatform) {
List<SocialPlatform> list = socialPlatformService.selectSocialPlatformList(socialPlatform);
ExcelUtil<SocialPlatform> util = new ExcelUtil<SocialPlatform>(SocialPlatform.class);
util.exportExcel(response, list, "第三方登录平台控制数据");
}
/**
* 获取第三方登录平台控制详细信息
*/
@PreAuthorize("@ss.hasPermi('iot:platform:query')")
@GetMapping(value = "/{socialPlatformId}")
public AjaxResult getInfo(@PathVariable("socialPlatformId") Long socialPlatformId) {
return AjaxResult.success(socialPlatformService.selectSocialPlatformBySocialPlatformId(socialPlatformId));
}
/**
* 新增第三方登录平台控制
*/
@PreAuthorize("@ss.hasPermi('iot:platform:add')")
@Log(title = "第三方登录平台控制", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SocialPlatform socialPlatform) {
socialPlatform.setCreateBy(getUsername());
return toAjax(socialPlatformService.insertSocialPlatform(socialPlatform));
}
/**
* 修改第三方登录平台控制
*/
@PreAuthorize("@ss.hasPermi('iot:platform:edit')")
@Log(title = "第三方登录平台控制", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SocialPlatform socialPlatform) {
socialPlatform.setUpdateBy(getUsername());
return toAjax(socialPlatformService.updateSocialPlatform(socialPlatform));
}
/**
* 删除第三方登录平台控制
*/
@PreAuthorize("@ss.hasPermi('iot:platform:remove')")
@Log(title = "第三方登录平台控制", businessType = BusinessType.DELETE)
@DeleteMapping("/{socialPlatformIds}")
public AjaxResult remove(@PathVariable Long[] socialPlatformIds) {
return toAjax(socialPlatformService.deleteSocialPlatformBySocialPlatformIds(socialPlatformIds));
}
}

View File

@@ -0,0 +1,176 @@
package com.ruoyi.iot.domain;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 第三方登录平台控制对象 iot_social_platform
*
* @author kerwincui
* @date 2022-04-11
*/
public class SocialPlatform extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 第三方登录平台主键
*/
private Long socialPlatformId;
/**
* 第三方登录平台
*/
@Excel(name = "第三方登录平台")
private String platform;
/**
* 0、内部上线 1、上线 2、下线
*/
@Excel(name = "0、内部上线 1、上线 2、下线")
private String status;
/**
* 第三方平台申请Id
*/
@Excel(name = "第三方平台申请Id")
private String clientId;
/**
* 第三方平台密钥
*/
@Excel(name = "第三方平台密钥")
private String secretKey;
/**
* 用户认证后跳转地址
*/
@Excel(name = "用户认证后跳转地址")
private String redirectUri;
/**
* 删除标记位(0代表存在2代表删除)
*/
private String delFlag;
/**
* 绑定注册登录uri
*/
@Excel(name = "绑定注册登录uri")
private String bindUri;
/**
* 跳转登录uri
*/
@Excel(name = "跳转登录uri")
private String redirectLoginUri;
/**
* 错误提示uri
*/
@Excel(name = "错误提示uri")
private String errorMsgUri;
public Long getSocialPlatformId() {
return socialPlatformId;
}
public void setSocialPlatformId(Long socialPlatformId) {
this.socialPlatformId = socialPlatformId;
}
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getBindUri() {
return bindUri;
}
public void setBindUri(String bindUri) {
this.bindUri = bindUri;
}
public String getRedirectLoginUri() {
return redirectLoginUri;
}
public void setRedirectLoginUri(String redirectLoginUri) {
this.redirectLoginUri = redirectLoginUri;
}
public String getErrorMsgUri() {
return errorMsgUri;
}
public void setErrorMsgUri(String errorMsgUri) {
this.errorMsgUri = errorMsgUri;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("socialPlatformId", getSocialPlatformId())
.append("platform", getPlatform())
.append("status", getStatus())
.append("clientId", getClientId())
.append("secretKey", getSecretKey())
.append("redirectUri", getRedirectUri())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateTime", getUpdateTime())
.append("updateBy", getUpdateBy())
.append("remark", getRemark())
.append("bindUri", getBindUri())
.append("redirectLoginUri", getRedirectLoginUri())
.append("errorMsgUri", getErrorMsgUri())
.toString();
}
}

View File

@@ -0,0 +1,376 @@
package com.ruoyi.iot.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 用户第三方用户信息对象 iot_social_user
*
* @author json
* @date 2022-04-18
*/
public class SocialUser extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 第三方系统用户表主键 */
private Long socialUserId;
/** 第三方系统的唯一ID */
@Excel(name = "第三方系统的唯一ID")
private String uuid;
/** 第三方用户来源 */
@Excel(name = "第三方用户来源")
private String source;
/** 用户的授权令牌 */
@Excel(name = "用户的授权令牌")
private String accessToken;
/** 第三方用户的授权令牌的有效期(部分平台可能没有) */
@Excel(name = "第三方用户的授权令牌的有效期", readConverterExp = "部=分平台可能没有")
private Long expireIn;
/** 刷新令牌(部分平台可能没有) */
@Excel(name = "刷新令牌(部分平台可能没有)")
private String refreshToken;
/** 第三方用户的 open id部分平台可能没有 */
@Excel(name = "第三方用户的 open id", readConverterExp = "部=分平台可能没有")
private String openId;
/** 第三方用户的 ID(部分平台可能没有) */
@Excel(name = "第三方用户的 ID(部分平台可能没有)")
private String uid;
/** 个别平台的授权信息(部分平台可能没有) */
@Excel(name = "个别平台的授权信息", readConverterExp = "部=分平台可能没有")
private String accessCode;
/** 第三方用户的 union id(部分平台可能没有) */
@Excel(name = "第三方用户的 union id(部分平台可能没有)")
private String unionId;
/** 第三方用户授予的权限(部分平台可能没有) */
@Excel(name = "第三方用户授予的权限(部分平台可能没有)")
private String scope;
/** 个别平台的授权信息(部分平台可能没有) */
@Excel(name = "个别平台的授权信息", readConverterExp = "部=分平台可能没有")
private String tokenType;
/** id token部分平台可能没有 */
@Excel(name = "id token", readConverterExp = "部=分平台可能没有")
private String idToken;
/** 小米平台用户的附带属性(部分平台可能没有) */
@Excel(name = "小米平台用户的附带属性", readConverterExp = "部=分平台可能没有")
private String macAlgorithm;
/** 小米平台用户的附带属性(部分平台可能没有) */
@Excel(name = "小米平台用户的附带属性(部分平台可能没有)")
private String macKey;
/** 用户的授权code部分平台可能没有 */
@Excel(name = "用户的授权code", readConverterExp = "部=分平台可能没有")
private String code;
/** Twitter平台用户的附带属性(部分平台可能没有) */
@Excel(name = "Twitter平台用户的附带属性(部分平台可能没有)")
private String oauthToken;
/** Twitter平台用户的附带属性(部分平台可能没有) */
@Excel(name = "Twitter平台用户的附带属性(部分平台可能没有)")
private String oauthTokenSecret;
/** 删除标记位(0代表存在,2代表删除) */
private String delFlag;
/** 绑定状态(0:未绑定,1:绑定) */
@Excel(name = "绑定状态(0:未绑定,1:绑定)")
private String status;
/** 用户ID */
@Excel(name = "用户ID")
private Long sysUserId;
/** 用户名 */
@Excel(name = "用户名")
private String username;
/** 用户昵称 */
@Excel(name = "用户昵称")
private String nickname;
/** 用户头像 */
@Excel(name = "用户头像")
private String avatar;
/** 用户性别 */
@Excel(name = "用户性别")
private Integer gender;
public void setSocialUserId(Long socialUserId)
{
this.socialUserId = socialUserId;
}
public Long getSocialUserId()
{
return socialUserId;
}
public void setUuid(String uuid)
{
this.uuid = uuid;
}
public String getUuid()
{
return uuid;
}
public void setSource(String source)
{
this.source = source;
}
public String getSource()
{
return source;
}
public void setAccessToken(String accessToken)
{
this.accessToken = accessToken;
}
public String getAccessToken()
{
return accessToken;
}
public void setExpireIn(Long expireIn)
{
this.expireIn = expireIn;
}
public Long getExpireIn()
{
return expireIn;
}
public void setRefreshToken(String refreshToken)
{
this.refreshToken = refreshToken;
}
public String getRefreshToken()
{
return refreshToken;
}
public void setOpenId(String openId)
{
this.openId = openId;
}
public String getOpenId()
{
return openId;
}
public void setUid(String uid)
{
this.uid = uid;
}
public String getUid()
{
return uid;
}
public void setAccessCode(String accessCode)
{
this.accessCode = accessCode;
}
public String getAccessCode()
{
return accessCode;
}
public void setUnionId(String unionId)
{
this.unionId = unionId;
}
public String getUnionId()
{
return unionId;
}
public void setScope(String scope)
{
this.scope = scope;
}
public String getScope()
{
return scope;
}
public void setTokenType(String tokenType)
{
this.tokenType = tokenType;
}
public String getTokenType()
{
return tokenType;
}
public void setIdToken(String idToken)
{
this.idToken = idToken;
}
public String getIdToken()
{
return idToken;
}
public void setMacAlgorithm(String macAlgorithm)
{
this.macAlgorithm = macAlgorithm;
}
public String getMacAlgorithm()
{
return macAlgorithm;
}
public void setMacKey(String macKey)
{
this.macKey = macKey;
}
public String getMacKey()
{
return macKey;
}
public void setCode(String code)
{
this.code = code;
}
public String getCode()
{
return code;
}
public void setOauthToken(String oauthToken)
{
this.oauthToken = oauthToken;
}
public String getOauthToken()
{
return oauthToken;
}
public void setOauthTokenSecret(String oauthTokenSecret)
{
this.oauthTokenSecret = oauthTokenSecret;
}
public String getOauthTokenSecret()
{
return oauthTokenSecret;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setSysUserId(Long sysUserId)
{
this.sysUserId = sysUserId;
}
public Long getSysUserId()
{
return sysUserId;
}
public void setUsername(String username)
{
this.username = username;
}
public String getUsername()
{
return username;
}
public void setNickname(String nickname)
{
this.nickname = nickname;
}
public String getNickname()
{
return nickname;
}
public void setAvatar(String avatar)
{
this.avatar = avatar;
}
public String getAvatar()
{
return avatar;
}
public void setGender(Integer gender)
{
this.gender = gender;
}
public Integer getGender()
{
return gender;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("socialUserId", getSocialUserId())
.append("uuid", getUuid())
.append("source", getSource())
.append("accessToken", getAccessToken())
.append("expireIn", getExpireIn())
.append("refreshToken", getRefreshToken())
.append("openId", getOpenId())
.append("uid", getUid())
.append("accessCode", getAccessCode())
.append("unionId", getUnionId())
.append("scope", getScope())
.append("tokenType", getTokenType())
.append("idToken", getIdToken())
.append("macAlgorithm", getMacAlgorithm())
.append("macKey", getMacKey())
.append("code", getCode())
.append("oauthToken", getOauthToken())
.append("oauthTokenSecret", getOauthTokenSecret())
.append("createTime", getCreateTime())
.append("createBy", getCreateBy())
.append("updateTime", getUpdateTime())
.append("updateBy", getUpdateBy())
.append("delFlag", getDelFlag())
.append("status", getStatus())
.append("sysUserId", getSysUserId())
.append("username", getUsername())
.append("nickname", getNickname())
.append("avatar", getAvatar())
.append("gender", getGender())
.toString();
}
}

View File

@@ -0,0 +1,69 @@
package com.ruoyi.iot.mapper;
import java.util.List;
import com.ruoyi.iot.domain.SocialPlatform;
/**
* 第三方登录平台控制Mapper接口
*
* @author kerwincui
* @date 2022-04-11
*/
public interface SocialPlatformMapper
{
/**
* 查询第三方登录平台控制
*
* @param socialPlatformId 第三方登录平台控制主键
* @return 第三方登录平台控制
*/
public SocialPlatform selectSocialPlatformBySocialPlatformId(Long socialPlatformId);
/**
* 查询第三方登录平台控制
*
* @param platform 第三方登录平台名称
* @return 第三方登录平台控制
*/
public SocialPlatform selectSocialPlatformByPlatform(String platform);
/**
* 查询第三方登录平台控制列表
*
* @param socialPlatform 第三方登录平台控制
* @return 第三方登录平台控制集合
*/
public List<SocialPlatform> selectSocialPlatformList(SocialPlatform socialPlatform);
/**
* 新增第三方登录平台控制
*
* @param socialPlatform 第三方登录平台控制
* @return 结果
*/
public int insertSocialPlatform(SocialPlatform socialPlatform);
/**
* 修改第三方登录平台控制
*
* @param socialPlatform 第三方登录平台控制
* @return 结果
*/
public int updateSocialPlatform(SocialPlatform socialPlatform);
/**
* 删除第三方登录平台控制
*
* @param socialPlatformId 第三方登录平台控制主键
* @return 结果
*/
public int deleteSocialPlatformBySocialPlatformId(Long socialPlatformId);
/**
* 批量删除第三方登录平台控制
*
* @param socialPlatformIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteSocialPlatformBySocialPlatformIds(Long[] socialPlatformIds);
}

View File

@@ -0,0 +1,61 @@
package com.ruoyi.iot.mapper;
import java.util.List;
import com.ruoyi.iot.domain.SocialUser;
/**
* 用户第三方用户信息Mapper接口
*
* @author json
* @date 2022-04-18
*/
public interface SocialUserMapper
{
/**
* 查询用户第三方用户信息
*
* @param socialUserId 用户第三方用户信息主键
* @return 用户第三方用户信息
*/
public SocialUser selectSocialUserBySocialUserId(Long socialUserId);
/**
* 查询用户第三方用户信息列表
*
* @param socialUser 用户第三方用户信息
* @return 用户第三方用户信息集合
*/
public List<SocialUser> selectSocialUserList(SocialUser socialUser);
/**
* 新增用户第三方用户信息
*
* @param socialUser 用户第三方用户信息
* @return 结果
*/
public int insertSocialUser(SocialUser socialUser);
/**
* 修改用户第三方用户信息
*
* @param socialUser 用户第三方用户信息
* @return 结果
*/
public int updateSocialUser(SocialUser socialUser);
/**
* 删除用户第三方用户信息
*
* @param socialUserId 用户第三方用户信息主键
* @return 结果
*/
public int deleteSocialUserBySocialUserId(Long socialUserId);
/**
* 批量删除用户第三方用户信息
*
* @param socialUserIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteSocialUserBySocialUserIds(Long[] socialUserIds);
}

View File

@@ -0,0 +1,26 @@
package com.ruoyi.iot.model.login;
import com.ruoyi.iot.domain.SocialPlatform;
import me.zhyd.oauth.request.AuthRequest;
public class AuthRequestWrap {
private AuthRequest authRequest;
private SocialPlatform socialPlatform;
public AuthRequest getAuthRequest() {
return authRequest;
}
public void setAuthRequest(AuthRequest authRequest) {
this.authRequest = authRequest;
}
public SocialPlatform getSocialPlatform() {
return socialPlatform;
}
public void setSocialPlatform(SocialPlatform socialPlatform) {
this.socialPlatform = socialPlatform;
}
}

View File

@@ -0,0 +1,23 @@
package com.ruoyi.iot.model.login;
public class BindIdValue {
private String uuid;
private String source;
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
}

View File

@@ -0,0 +1,22 @@
package com.ruoyi.iot.model.login;
public class LoginIdValue {
String username;
String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}

View File

@@ -0,0 +1,15 @@
package com.ruoyi.iot.service;
import com.ruoyi.iot.model.login.AuthRequestWrap;
/**
* AuthRequest简单工程类接口
*
* @author json
* @date 2022-04-12
*/
public interface IAuthRequestFactory {
AuthRequestWrap getAuthRequest(String source);
}

View File

@@ -0,0 +1,78 @@
package com.ruoyi.iot.service;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.BindLoginBody;
import com.ruoyi.common.core.domain.model.BindRegisterBody;
import me.zhyd.oauth.model.AuthCallback;
import javax.servlet.http.HttpServletRequest;
/**
* 第三方登录Service接口
* 处理登录跳转业务逻辑
*
* @author json
* @date 2022-04-12
*/
public interface ISocialLoginService {
/**
* 第三方登录跳转
*
* @param source 平台
* @param httpServletRequest 当前请求
* @return 跳转路径
*/
String renderAuth(String source, HttpServletRequest httpServletRequest);
/**
* 第三方登录callback
*
* @param source 平台
* @param authCallback 回调参数
* @param httpServletRequest 当前请求
* @return 跳转路径
*/
String callback(String source, AuthCallback authCallback, HttpServletRequest httpServletRequest);
/**
* 检查是否bindId
*
* @param bindId 绑定id
* @return
*/
AjaxResult checkBindId(String bindId);
/**
* 获得错误显示
*
* @param errorId errorId
* @return
*/
AjaxResult getErrorMsg(String errorId);
/**
* 跳转直接登录
*
* @param loginId 登录id
* @return
*/
AjaxResult socialLogin(String loginId);
/**
* 绑定登录api
*
* @param bindLoginBody 绑定账户参数
* @return
*/
AjaxResult bindLogin(BindLoginBody bindLoginBody);
/**
* 注册绑定api
*
* @param bindRegisterBody
* @return
*/
AjaxResult bindRegister(BindRegisterBody bindRegisterBody);
}

View File

@@ -0,0 +1,69 @@
package com.ruoyi.iot.service;
import java.util.List;
import com.ruoyi.iot.domain.SocialPlatform;
/**
* 第三方登录平台控制Service接口
*
* @author json
* @date 2022-04-12
*/
public interface ISocialPlatformService
{
/**
* 查询第三方登录平台控制
*
* @param socialPlatformId 第三方登录平台控制主键
* @return 第三方登录平台控制
*/
public SocialPlatform selectSocialPlatformBySocialPlatformId(Long socialPlatformId);
/**
* 查询第三方登录平台控制
*
* @param platform 第三方登录平台名称
* @return 第三方登录平台控制
*/
public SocialPlatform selectSocialPlatformByPlatform(String platform);
/**
* 查询第三方登录平台控制列表
*
* @param socialPlatform 第三方登录平台控制
* @return 第三方登录平台控制集合
*/
public List<SocialPlatform> selectSocialPlatformList(SocialPlatform socialPlatform);
/**
* 新增第三方登录平台控制
*
* @param socialPlatform 第三方登录平台控制
* @return 结果
*/
public int insertSocialPlatform(SocialPlatform socialPlatform);
/**
* 修改第三方登录平台控制
*
* @param socialPlatform 第三方登录平台控制
* @return 结果
*/
public int updateSocialPlatform(SocialPlatform socialPlatform);
/**
* 批量删除第三方登录平台控制
*
* @param socialPlatformIds 需要删除的第三方登录平台控制主键集合
* @return 结果
*/
public int deleteSocialPlatformBySocialPlatformIds(Long[] socialPlatformIds);
/**
* 删除第三方登录平台控制信息
*
* @param socialPlatformId 第三方登录平台控制主键
* @return 结果
*/
public int deleteSocialPlatformBySocialPlatformId(Long socialPlatformId);
}

View File

@@ -0,0 +1,61 @@
package com.ruoyi.iot.service;
import java.util.List;
import com.ruoyi.iot.domain.SocialUser;
/**
* 用户第三方用户信息Service接口
*
* @author json
* @date 2022-04-18
*/
public interface ISocialUserService
{
/**
* 查询用户第三方用户信息
*
* @param socialUserId 用户第三方用户信息主键
* @return 用户第三方用户信息
*/
public SocialUser selectSocialUserBySocialUserId(Long socialUserId);
/**
* 查询用户第三方用户信息列表
*
* @param socialUser 用户第三方用户信息
* @return 用户第三方用户信息集合
*/
public List<SocialUser> selectSocialUserList(SocialUser socialUser);
/**
* 新增用户第三方用户信息
*
* @param socialUser 用户第三方用户信息
* @return 结果
*/
public int insertSocialUser(SocialUser socialUser);
/**
* 修改用户第三方用户信息
*
* @param socialUser 用户第三方用户信息
* @return 结果
*/
public int updateSocialUser(SocialUser socialUser);
/**
* 批量删除用户第三方用户信息
*
* @param socialUserIds 需要删除的用户第三方用户信息主键集合
* @return 结果
*/
public int deleteSocialUserBySocialUserIds(Long[] socialUserIds);
/**
* 删除用户第三方用户信息信息
*
* @param socialUserId 用户第三方用户信息主键
* @return 结果
*/
public int deleteSocialUserBySocialUserId(Long socialUserId);
}

View File

@@ -0,0 +1,69 @@
package com.ruoyi.iot.service.impl;
import com.ruoyi.common.enums.SocialPlatformType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.iot.domain.SocialPlatform;
import com.ruoyi.iot.model.login.AuthRequestWrap;
import com.ruoyi.iot.service.IAuthRequestFactory;
import com.ruoyi.iot.service.ISocialPlatformService;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthQqRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.request.AuthWeChatMpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Locale;
@Service
public class AuthRequestFactoryImpl implements IAuthRequestFactory {
private static final Logger log = LoggerFactory.getLogger(AuthRequestFactoryImpl.class);
@Autowired
private ISocialPlatformService iSocialPlatformService;
@Autowired
private AuthStateRedisCache authStateRedisCache;
/**
* 获得对于AUthRequest
*
* @param source 登录方式
* @return 对应AuthRequest
*/
@Override
public AuthRequestWrap getAuthRequest(String source) {
AuthRequestWrap authRequestWrap = new AuthRequestWrap();
AuthRequest authRequest;
try {
SocialPlatformType socialPlatformType = SocialPlatformType.valueOf(source.toUpperCase(Locale.ROOT));
SocialPlatform socialPlatform = iSocialPlatformService.selectSocialPlatformByPlatform(source);
authRequestWrap.setSocialPlatform(socialPlatform);
AuthConfig authConfig = AuthConfig.builder()
.clientId(socialPlatform.getClientId())
.clientSecret(socialPlatform.getSecretKey())
.redirectUri(socialPlatform.getRedirectUri())
.build();
switch (socialPlatformType) {
case QQ: {
authRequest = new AuthQqRequest(authConfig, authStateRedisCache);
break;
}
case Wechat: {
authRequest = new AuthWeChatMpRequest(authConfig, authStateRedisCache);
break;
}
default: {
throw new ServiceException("source: " + source + ",暂不支持");
}
}
authRequestWrap.setAuthRequest(authRequest);
return authRequestWrap;
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
}

View File

@@ -0,0 +1,54 @@
package com.ruoyi.iot.service.impl;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.sign.Md5Utils;
import me.zhyd.oauth.cache.AuthCacheConfig;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* 扩展Redis版的state缓存
*
* @author json
* @date 2022/04/12
*/
@Component
public class AuthStateRedisCache implements AuthStateCache {
@Autowired
private RedisCache redisCache;
@Override
public void cache(String key, String value) {
redisCache.setCacheObject(key, getValue(value), (int) AuthCacheConfig.timeout, TimeUnit.MILLISECONDS);
}
@Override
public void cache(String key, String value, long timeout) {
redisCache.setCacheObject(key, getValue(value), (int) timeout, TimeUnit.MILLISECONDS);
}
@Override
public String get(String key) {
return redisCache.getCacheObject(key);
}
@Override
public boolean containsKey(String key) {
return redisCache.containsKey(key);
}
/**
* 自定义state
* @param oldState
* @return state
*/
private String getValue(String oldState) {
return Md5Utils.hash(oldState + System.currentTimeMillis());
}
}

View File

@@ -0,0 +1,353 @@
package com.ruoyi.iot.service.impl;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.BindLoginBody;
import com.ruoyi.common.core.domain.model.BindRegisterBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysRegisterService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.iot.domain.SocialPlatform;
import com.ruoyi.iot.domain.SocialUser;
import com.ruoyi.iot.model.login.AuthRequestWrap;
import com.ruoyi.iot.model.login.BindIdValue;
import com.ruoyi.iot.model.login.LoginIdValue;
import com.ruoyi.iot.service.IAuthRequestFactory;
import com.ruoyi.iot.service.ISocialLoginService;
import com.ruoyi.iot.service.ISocialUserService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.AuthStateUtils;
import me.zhyd.oauth.utils.RandomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.ruoyi.common.constant.HttpStatus.NO_MESSAGE_ALERT;
import static com.ruoyi.common.core.domain.AjaxResult.error;
/**
* 第三方登录Service业务层处理
*
* @author json
* @date 2022-04-12
*/
@Service
public class SocialLoginServiceImpl implements ISocialLoginService {
public static final Integer BIND_EXPIRE_TIME = 60 * 60;
public static final Integer LOGIN_SOCIAL_EXPIRE_TIME = 60;
public static final String ONLINE_STATUS = "0"; //1 offline
public static final String DEL_FLAG = "0"; //1 offline
//redis key: uuid+source
public static final String BIND_REDIS_KEY = "login:bind:user:";
//redis key : userId+random 32
public static final String LOGIN_SOCIAL_REDIS_KEY = "login:social:user:";
//redis key : msg+ code+currentTime
public static final String LOGIN_ERROR_MSG_REDIS_KEY = "login:error:msg:";
public static final String HTTPS = "https://";
private static final Logger log = LoggerFactory.getLogger(SocialLoginServiceImpl.class);
@Autowired
private RedisCache redisCache;
@Autowired
private ISysConfigService iSysConfigService;
@Autowired
private TokenService tokenService;
@Autowired
private SysRegisterService sysRegisterService;
@Autowired
private SysLoginService sysLoginService;
@Autowired
private ISysUserService iSysUserService;
@Autowired
private IAuthRequestFactory iAuthRequestFactory;
@Autowired
private ISocialUserService iSocialUserService;
@Override
public String renderAuth(String source, HttpServletRequest httpServletRequest) {
AuthRequestWrap authRequestWrap = null;
try {
authRequestWrap = iAuthRequestFactory.getAuthRequest(source);
checkSocialPlatform(authRequestWrap.getSocialPlatform());
return authRequestWrap.getAuthRequest().authorize(AuthStateUtils.createState());
} catch (AuthException authException) {
//返回错误信息
log.error("", authException);
if (authRequestWrap != null) {
String errorId = genErrorId(authException.getMessage());
return authRequestWrap.getSocialPlatform().getErrorMsgUri() + errorId;
} else {
return httpServletRequest.getProtocol() + httpServletRequest.getServerName() + httpServletRequest.getServerPort();
}
} catch (Exception exception) {
//这类错误 直接不返回,重定向到主页
log.error("", exception);
return HTTPS + httpServletRequest.getServerName();
}
}
@Override
public String callback(String source, AuthCallback authCallback, HttpServletRequest httpServletRequest) {
AuthRequestWrap authRequestWrap = null;
try {
authRequestWrap = iAuthRequestFactory.getAuthRequest(source);
checkSocialPlatform(authRequestWrap.getSocialPlatform());
AuthResponse<AuthUser> authResponse = authRequestWrap.getAuthRequest().login(authCallback);
String bindId = null;
String loginId = null;
if (authResponse.ok()) {
SocialUser socialUser = findSocialUser(authResponse.getData().getUuid(), authResponse.getData().getSource());
createOrUpdateSocialUser(socialUser, authResponse.getData());
if (socialUser == null) {
//第一次登录
bindId = genBindId(authResponse.getData());
} else if (socialUser.getSysUserId() == null || socialUser.getSysUserId() <= 0) {
//初次绑定
bindId = genBindId(authResponse.getData());
} else {
//查看是否已经绑定
SysUser sysUser = iSysUserService.selectUserById(socialUser.getSysUserId());
if (sysUser == null) {
bindId = genBindId(authResponse.getData());
} else {
//直接登录跳转
loginId = genLoginId(sysUser);
}
}
if (StringUtils.isNotEmpty(bindId)) {
return authRequestWrap.getSocialPlatform().getBindUri() + bindId;
} else {
return authRequestWrap.getSocialPlatform().getRedirectLoginUri() + loginId;
}
} else {
log.error("登录授权异常,code:{}, msg:{}", authResponse.getCode(), authResponse.getMsg());
String errorId = genErrorId(authResponse.getMsg());
return authRequestWrap.getSocialPlatform().getErrorMsgUri() + errorId;
}
} catch (AuthException authException) {
//返回错误信息
log.error("", authException);
if (authRequestWrap != null) {
String errorId = genErrorId(authException.getMessage());
return authRequestWrap.getSocialPlatform().getErrorMsgUri() + errorId;
} else {
return httpServletRequest.getServerName() + httpServletRequest.getServerPort();
}
} catch (Exception exception) {
log.error("", exception);
return HTTPS + httpServletRequest.getServerName();
}
}
@Override
public AjaxResult checkBindId(String bindId) {
AjaxResult ajax = AjaxResult.success();
ajax.put("bindAccount", false);
if (StringUtils.isEmpty(bindId)) {
return ajax;
}
BindIdValue bindValue = redisCache.getCacheObject(BIND_REDIS_KEY + bindId);
if (bindValue == null) {
return ajax;
}
ajax.put("bindAccount", true);
return AjaxResult.success(bindId);
}
@Override
public AjaxResult getErrorMsg(String errorId) {
String errorMsg = redisCache.getCacheObject(LOGIN_ERROR_MSG_REDIS_KEY + errorId);
if (StringUtils.isEmpty(errorMsg)) {
return error(NO_MESSAGE_ALERT, "");
} else {
return error(errorMsg);
}
}
@Override
public AjaxResult socialLogin(String loginId) {
AjaxResult ajax = AjaxResult.success();
String loginKey = LOGIN_SOCIAL_REDIS_KEY + loginId;
LoginIdValue loginIdValue = redisCache.getCacheObject(loginKey);
if (loginIdValue != null) {
//login
String token = sysLoginService.redirectLogin(loginIdValue.getUsername(), loginIdValue.getPassword());
ajax.put(Constants.TOKEN, token);
} else {
log.info("loginId:{} ", loginId);
return error(NO_MESSAGE_ALERT, "数据错误");
}
return ajax;
}
@Override
public AjaxResult bindLogin(BindLoginBody bindLoginBody) {
BindIdValue bindValue = redisCache.getCacheObject(BIND_REDIS_KEY + bindLoginBody.getBindId());
SocialUser socialUser = findSocialUser(bindValue.getUuid(), bindValue.getSource());
AjaxResult checkAjax = checkSocialUser(socialUser, bindLoginBody.getBindId());
if (checkAjax != null) {
return checkAjax;
}
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = sysLoginService.login(bindLoginBody.getUsername(), bindLoginBody.getPassword(), bindLoginBody.getCode(),
bindLoginBody.getUuid());
LoginUser loginUser = tokenService.getLoginUserByToken(token);
//绑定和更新
SocialUser updateSocialUser = new SocialUser();
updateSocialUser.setSysUserId(loginUser.getUserId());
updateSocialUser.setSocialUserId(socialUser.getSocialUserId());
iSocialUserService.updateSocialUser(updateSocialUser);
ajax.put(Constants.TOKEN, token);
redisCache.deleteObject(BIND_REDIS_KEY + bindLoginBody.getBindId());
return ajax;
}
@Override
public AjaxResult bindRegister(BindRegisterBody bindRegisterBody) {
if (!("true".equals(iSysConfigService.selectConfigByKey("sys.account.registerUser")))) {
return error("当前系统没有开启注册功能!");
}
BindIdValue bindValue = redisCache.getCacheObject(BIND_REDIS_KEY + bindRegisterBody.getBindId());
SocialUser socialUser = findSocialUser(bindValue.getUuid(), bindValue.getSource());
AjaxResult checkAjax = checkSocialUser(socialUser, bindRegisterBody.getBindId());
if (checkAjax != null) {
return checkAjax;
}
AjaxResult ajax = AjaxResult.success();
String msg = sysRegisterService.register(bindRegisterBody);
if (StringUtils.isEmpty(msg)) {
SysUser sysUser = iSysUserService.selectUserByUserName(bindRegisterBody.getUsername());
//绑定和更新
SocialUser updateSocialUser = new SocialUser();
updateSocialUser.setSysUserId(sysUser.getUserId());
updateSocialUser.setSocialUserId(socialUser.getSocialUserId());
iSocialUserService.updateSocialUser(updateSocialUser);
redisCache.deleteObject(BIND_REDIS_KEY + bindRegisterBody.getBindId());
}
return StringUtils.isEmpty(msg) ? ajax : error(msg);
}
private void checkSocialPlatform(SocialPlatform socialPlatform) {
if (socialPlatform != null && (!socialPlatform.getStatus().equals(ONLINE_STATUS) || !socialPlatform.getDelFlag().equals(DEL_FLAG))) {
throw new AuthException("当前第三方登录平台被禁用");
}
}
public SocialUser findSocialUser(String uuid, String source) {
SocialUser socialUser = new SocialUser();
socialUser.setSource(source);
socialUser.setUuid(uuid);
List<SocialUser> socialUserList = iSocialUserService.selectSocialUserList(socialUser);
return socialUserList == null || socialUserList.isEmpty() ? null : socialUserList.get(0);
}
public void createOrUpdateSocialUser(SocialUser socialUser, AuthUser authUser) {
if (socialUser != null) {
//更新数据
SocialUser updateSocialUser = new SocialUser();
updateSocialUser.setSocialUserId(socialUser.getSocialUserId());
replaceSocialUser(updateSocialUser, authUser);
updateSocialUser.setUpdateBy("System");
updateSocialUser.setUpdateTime(DateUtils.getNowDate());
iSocialUserService.updateSocialUser(updateSocialUser);
} else {
//创建
SocialUser saveSocialUser = new SocialUser();
replaceSocialUser(saveSocialUser, authUser);
saveSocialUser.setDelFlag("0");
saveSocialUser.setStatus("0");
saveSocialUser.setCreateBy("System");
saveSocialUser.setCreateTime(DateUtils.getNowDate());
iSocialUserService.insertSocialUser(saveSocialUser);
}
}
private void replaceSocialUser(SocialUser socialUser, AuthUser authUser) {
socialUser.setUuid(authUser.getUuid());
socialUser.setSource(authUser.getSource());
socialUser.setAccessToken(authUser.getToken().getAccessToken());
//nullable
socialUser.setExpireIn((long) authUser.getToken().getExpireIn());
socialUser.setRefreshToken(authUser.getToken().getRefreshToken());
socialUser.setOpenId(authUser.getToken().getOpenId());
socialUser.setUid(authUser.getToken().getUid());
socialUser.setAccessCode(authUser.getToken().getAccessCode());
socialUser.setUnionId(authUser.getToken().getUnionId());
socialUser.setCode(authUser.getToken().getCode());
socialUser.setAvatar(authUser.getAvatar());
socialUser.setUsername(authUser.getUsername());
socialUser.setNickname(authUser.getNickname());
}
private String genBindId(AuthUser authUser) {
String bindId = Md5Utils.hash(authUser.getUuid() + authUser.getSource());
String key = BIND_REDIS_KEY + bindId;
BindIdValue bindIdValue = new BindIdValue();
bindIdValue.setSource(authUser.getSource());
bindIdValue.setUuid(authUser.getUuid());
redisCache.setCacheObject(key, bindIdValue, BIND_EXPIRE_TIME, TimeUnit.SECONDS);
return bindId;
}
private String genLoginId(SysUser sysUser) {
String loginId = Md5Utils.hash(sysUser.getUserId() + RandomUtil.randomString(32));
String key = LOGIN_SOCIAL_REDIS_KEY + loginId;
LoginIdValue loginIdValue = new LoginIdValue();
loginIdValue.setPassword(sysUser.getPassword());
loginIdValue.setUsername(sysUser.getUserName());
redisCache.setCacheObject(key, loginIdValue, LOGIN_SOCIAL_EXPIRE_TIME, TimeUnit.SECONDS);
return loginId;
}
private String genErrorId(String msg) {
String errorId = Md5Utils.hash(msg + RandomUtil.randomString(32));
String key = LOGIN_ERROR_MSG_REDIS_KEY + errorId;
redisCache.setCacheObject(key, msg, LOGIN_SOCIAL_EXPIRE_TIME, TimeUnit.SECONDS);
return errorId;
}
private AjaxResult checkSocialUser(SocialUser socialUser, String bindId) {
if (socialUser == null) {
log.info("bindId不存在, bindId: {}", bindId);
return error("绑定账户不存在");
} else {
return null;
}
}
}

View File

@@ -0,0 +1,103 @@
package com.ruoyi.iot.service.impl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.iot.domain.SocialPlatform;
import com.ruoyi.iot.mapper.SocialPlatformMapper;
import com.ruoyi.iot.service.ISocialPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 第三方登录平台控制Service业务层处理
*
* @author kerwincui
* @date 2022-04-11
*/
@Service
public class SocialPlatformServiceImpl implements ISocialPlatformService
{
@Autowired
private SocialPlatformMapper socialPlatformMapper;
/**
* 查询第三方登录平台控制
*
* @param socialPlatformId 第三方登录平台控制主键
* @return 第三方登录平台控制
*/
@Override
public SocialPlatform selectSocialPlatformBySocialPlatformId(Long socialPlatformId)
{
return socialPlatformMapper.selectSocialPlatformBySocialPlatformId(socialPlatformId);
}
@Override
public SocialPlatform selectSocialPlatformByPlatform(String platform) {
return socialPlatformMapper.selectSocialPlatformByPlatform(platform);
}
/**
* 查询第三方登录平台控制列表
*
* @param socialPlatform 第三方登录平台控制
* @return 第三方登录平台控制
*/
@Override
public List<SocialPlatform> selectSocialPlatformList(SocialPlatform socialPlatform)
{
return socialPlatformMapper.selectSocialPlatformList(socialPlatform);
}
/**
* 新增第三方登录平台控制
*
* @param socialPlatform 第三方登录平台控制
* @return 结果
*/
@Override
public int insertSocialPlatform(SocialPlatform socialPlatform)
{
socialPlatform.setCreateTime(DateUtils.getNowDate());
socialPlatform.setDelFlag("0");
return socialPlatformMapper.insertSocialPlatform(socialPlatform);
}
/**
* 修改第三方登录平台控制
*
* @param socialPlatform 第三方登录平台控制
* @return 结果
*/
@Override
public int updateSocialPlatform(SocialPlatform socialPlatform)
{
socialPlatform.setUpdateTime(DateUtils.getNowDate());
return socialPlatformMapper.updateSocialPlatform(socialPlatform);
}
/**
* 批量删除第三方登录平台控制
*
* @param socialPlatformIds 需要删除的第三方登录平台控制主键
* @return 结果
*/
@Override
public int deleteSocialPlatformBySocialPlatformIds(Long[] socialPlatformIds)
{
return socialPlatformMapper.deleteSocialPlatformBySocialPlatformIds(socialPlatformIds);
}
/**
* 删除第三方登录平台控制信息
*
* @param socialPlatformId 第三方登录平台控制主键
* @return 结果
*/
@Override
public int deleteSocialPlatformBySocialPlatformId(Long socialPlatformId)
{
return socialPlatformMapper.deleteSocialPlatformBySocialPlatformId(socialPlatformId);
}
}

View File

@@ -0,0 +1,96 @@
package com.ruoyi.iot.service.impl;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.iot.mapper.SocialUserMapper;
import com.ruoyi.iot.domain.SocialUser;
import com.ruoyi.iot.service.ISocialUserService;
/**
* 用户第三方用户信息Service业务层处理
*
* @author json
* @date 2022-04-18
*/
@Service
public class SocialUserServiceImpl implements ISocialUserService
{
@Autowired
private SocialUserMapper socialUserMapper;
/**
* 查询用户第三方用户信息
*
* @param socialUserId 用户第三方用户信息主键
* @return 用户第三方用户信息
*/
@Override
public SocialUser selectSocialUserBySocialUserId(Long socialUserId)
{
return socialUserMapper.selectSocialUserBySocialUserId(socialUserId);
}
/**
* 查询用户第三方用户信息列表
*
* @param socialUser 用户第三方用户信息
* @return 用户第三方用户信息
*/
@Override
public List<SocialUser> selectSocialUserList(SocialUser socialUser)
{
return socialUserMapper.selectSocialUserList(socialUser);
}
/**
* 新增用户第三方用户信息
*
* @param socialUser 用户第三方用户信息
* @return 结果
*/
@Override
public int insertSocialUser(SocialUser socialUser)
{
socialUser.setCreateTime(DateUtils.getNowDate());
return socialUserMapper.insertSocialUser(socialUser);
}
/**
* 修改用户第三方用户信息
*
* @param socialUser 用户第三方用户信息
* @return 结果
*/
@Override
public int updateSocialUser(SocialUser socialUser)
{
socialUser.setUpdateTime(DateUtils.getNowDate());
return socialUserMapper.updateSocialUser(socialUser);
}
/**
* 批量删除用户第三方用户信息
*
* @param socialUserIds 需要删除的用户第三方用户信息主键
* @return 结果
*/
@Override
public int deleteSocialUserBySocialUserIds(Long[] socialUserIds)
{
return socialUserMapper.deleteSocialUserBySocialUserIds(socialUserIds);
}
/**
* 删除用户第三方用户信息信息
*
* @param socialUserId 用户第三方用户信息主键
* @return 结果
*/
@Override
public int deleteSocialUserBySocialUserId(Long socialUserId)
{
return socialUserMapper.deleteSocialUserBySocialUserId(socialUserId);
}
}

View File

@@ -0,0 +1,141 @@
<?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.ruoyi.iot.mapper.SocialPlatformMapper">
<resultMap type="SocialPlatform" id="SocialPlatformResult">
<result property="socialPlatformId" column="social_platform_id"/>
<result property="platform" column="platform"/>
<result property="status" column="status"/>
<result property="clientId" column="client_id"/>
<result property="secretKey" column="secret_key"/>
<result property="redirectUri" column="redirect_uri"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="updateBy" column="update_by"/>
<result property="remark" column="remark"/>
<result property="bindUri" column="bind_uri"/>
<result property="redirectLoginUri" column="redirect_login_uri"/>
<result property="errorMsgUri" column="error_msg_uri"/>
</resultMap>
<sql id="selectSocialPlatformVo">
select social_platform_id,
platform,
status,
client_id,
secret_key,
redirect_uri,
del_flag,
create_by,
create_time,
update_time,
update_by,
remark,
bind_uri,
redirect_login_uri,
error_msg_uri
from iot_social_platform
</sql>
<select id="selectSocialPlatformList" parameterType="SocialPlatform" resultMap="SocialPlatformResult">
<include refid="selectSocialPlatformVo"/>
<where>
<if test="platform != null and platform != ''">and platform = #{platform}</if>
<if test="status != null and status != ''">and status = #{status}</if>
<if test="clientId != null and clientId != ''">and client_id = #{clientId}</if>
<if test="secretKey != null and secretKey != ''">and secret_key = #{secretKey}</if>
<if test="redirectUri != null and redirectUri != ''">and redirect_uri = #{redirectUri}</if>
<if test="bindUri != null and bindUri != ''">and bind_uri = #{bindUri}</if>
<if test="redirectLoginUri != null and redirectLoginUri != ''">and redirect_login_uri =
#{redirectLoginUri}
</if>
<if test="errorMsgUri != null ">and error_msg_uri = #{errorMsgUri}</if>
</where>
</select>
<select id="selectSocialPlatformBySocialPlatformId" parameterType="Long" resultMap="SocialPlatformResult">
<include refid="selectSocialPlatformVo"/>
where social_platform_id = #{socialPlatformId}
</select>
<select id="selectSocialPlatformByPlatform" parameterType="String" resultMap="SocialPlatformResult">
<include refid="selectSocialPlatformVo"/>
where platform = #{platform}
</select>
<insert id="insertSocialPlatform" parameterType="SocialPlatform" useGeneratedKeys="true"
keyProperty="socialPlatformId">
insert into iot_social_platform
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="platform != null and platform != ''">platform,</if>
<if test="status != null and status != ''">status,</if>
<if test="clientId != null and clientId != ''">client_id,</if>
<if test="secretKey != null and secretKey != ''">secret_key,</if>
<if test="redirectUri != null and redirectUri != ''">redirect_uri,</if>
<if test="delFlag != null and delFlag != ''">del_flag,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateTime != null">update_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="remark != null">remark,</if>
<if test="bindUri != null and bindUri != ''">bind_uri,</if>
<if test="redirectLoginUri != null and redirectLoginUri != ''">redirect_login_uri,</if>
<if test="errorMsgUri != null and errorMsgUri != ''">error_msg_uri,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="platform != null and platform != ''">#{platform},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="clientId != null and clientId != ''">#{clientId},</if>
<if test="secretKey != null and secretKey != ''">#{secretKey},</if>
<if test="redirectUri != null and redirectUri != ''">#{redirectUri},</if>
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="remark != null">#{remark},</if>
<if test="bindUri != null and bindUri != ''">#{bindUri},</if>
<if test="redirectLoginUri != null and redirectLoginUri != ''">#{redirectLoginUri},</if>
<if test="errorMsgUri != null and errorMsgUri != ''">#{errorMsgUri},</if>
</trim>
</insert>
<update id="updateSocialPlatform" parameterType="SocialPlatform">
update iot_social_platform
<trim prefix="SET" suffixOverrides=",">
<if test="platform != null and platform != ''">platform = #{platform},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="clientId != null and clientId != ''">client_id = #{clientId},</if>
<if test="secretKey != null and secretKey != ''">secret_key = #{secretKey},</if>
<if test="redirectUri != null and redirectUri != ''">redirect_uri = #{redirectUri},</if>
<if test="delFlag != null and delFlag != ''">del_flag = #{delFlag},</if>
<if test="createBy != null and createBy != ''">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="bindUri != null and bindUri != ''">bind_uri = #{bindUri},</if>
<if test="redirectLoginUri != null and redirectLoginUri != ''">redirect_login_uri = #{redirectLoginUri},
</if>
<if test="errorMsgUri != null and errorMsgUri != ''">error_msg_uri = #{errorMsgUri},</if>
</trim>
where social_platform_id = #{socialPlatformId}
</update>
<delete id="deleteSocialPlatformBySocialPlatformId" parameterType="Long">
delete
from iot_social_platform
where social_platform_id = #{socialPlatformId}
</delete>
<delete id="deleteSocialPlatformBySocialPlatformIds" parameterType="String">
delete from iot_social_platform where social_platform_id in
<foreach item="socialPlatformId" collection="array" open="(" separator="," close=")">
#{socialPlatformId}
</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,219 @@
<?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.ruoyi.iot.mapper.SocialUserMapper">
<resultMap type="SocialUser" id="SocialUserResult">
<result property="socialUserId" column="social_user_id"/>
<result property="uuid" column="uuid"/>
<result property="source" column="source"/>
<result property="accessToken" column="access_token"/>
<result property="expireIn" column="expire_in"/>
<result property="refreshToken" column="refresh_token"/>
<result property="openId" column="open_id"/>
<result property="uid" column="uid"/>
<result property="accessCode" column="access_code"/>
<result property="unionId" column="union_id"/>
<result property="scope" column="scope"/>
<result property="tokenType" column="token_type"/>
<result property="idToken" column="id_token"/>
<result property="macAlgorithm" column="mac_algorithm"/>
<result property="macKey" column="mac_key"/>
<result property="code" column="code"/>
<result property="oauthToken" column="oauth_token"/>
<result property="oauthTokenSecret" column="oauth_token_secret"/>
<result property="createTime" column="create_time"/>
<result property="createBy" column="create_by"/>
<result property="updateTime" column="update_time"/>
<result property="updateBy" column="update_by"/>
<result property="delFlag" column="del_flag"/>
<result property="status" column="status"/>
<result property="sysUserId" column="sys_user_id"/>
<result property="username" column="username"/>
<result property="nickname" column="nickname"/>
<result property="avatar" column="avatar"/>
<result property="gender" column="gender"/>
</resultMap>
<sql id="selectSocialUserVo">
select social_user_id,
uuid,
source,
access_token,
expire_in,
refresh_token,
open_id,
uid,
access_code,
union_id,
scope,
token_type,
id_token,
mac_algorithm,
mac_key,
code,
oauth_token,
oauth_token_secret,
create_time,
create_by,
update_time,
update_by,
del_flag,
status,
sys_user_id,
username,
nickname,
avatar,
gender
from iot_social_user
</sql>
<select id="selectSocialUserList" parameterType="SocialUser" resultMap="SocialUserResult">
<include refid="selectSocialUserVo"/>
<where>
<if test="uuid != null and uuid != ''">and uuid = #{uuid}</if>
<if test="source != null and source != ''">and source = #{source}</if>
<if test="accessToken != null and accessToken != ''">and access_token = #{accessToken}</if>
<if test="expireIn != null ">and expire_in = #{expireIn}</if>
<if test="refreshToken != null and refreshToken != ''">and refresh_token = #{refreshToken}</if>
<if test="openId != null and openId != ''">and open_id = #{openId}</if>
<if test="uid != null and uid != ''">and uid = #{uid}</if>
<if test="accessCode != null and accessCode != ''">and access_code = #{accessCode}</if>
<if test="unionId != null and unionId != ''">and union_id = #{unionId}</if>
<if test="scope != null and scope != ''">and scope = #{scope}</if>
<if test="tokenType != null and tokenType != ''">and token_type = #{tokenType}</if>
<if test="idToken != null and idToken != ''">and id_token = #{idToken}</if>
<if test="macAlgorithm != null and macAlgorithm != ''">and mac_algorithm = #{macAlgorithm}</if>
<if test="macKey != null and macKey != ''">and mac_key = #{macKey}</if>
<if test="code != null and code != ''">and code = #{code}</if>
<if test="oauthToken != null and oauthToken != ''">and oauth_token = #{oauthToken}</if>
<if test="oauthTokenSecret != null and oauthTokenSecret != ''">and oauth_token_secret =
#{oauthTokenSecret}
</if>
<if test="status != null and status != ''">and status = #{status}</if>
<if test="sysUserId != null ">and sys_user_id = #{sysUserId}</if>
<if test="username != null and username != ''">and username like concat('%', #{username}, '%')</if>
<if test="nickname != null and nickname != ''">and nickname like concat('%', #{nickname}, '%')</if>
<if test="avatar != null and avatar != ''">and avatar = #{avatar}</if>
<if test="gender != null ">and gender = #{gender}</if>
</where>
</select>
<select id="selectSocialUserBySocialUserId" parameterType="Long" resultMap="SocialUserResult">
<include refid="selectSocialUserVo"/>
where social_user_id = #{socialUserId}
</select>
<insert id="insertSocialUser" parameterType="SocialUser" useGeneratedKeys="true" keyProperty="socialUserId">
insert into iot_social_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="uuid != null and uuid != ''">uuid,</if>
<if test="source != null and source != ''">source,</if>
<if test="accessToken != null and accessToken != ''">access_token,</if>
<if test="expireIn != null">expire_in,</if>
<if test="refreshToken != null">refresh_token,</if>
<if test="openId != null">open_id,</if>
<if test="uid != null">uid,</if>
<if test="accessCode != null">access_code,</if>
<if test="unionId != null">union_id,</if>
<if test="scope != null">scope,</if>
<if test="tokenType != null">token_type,</if>
<if test="idToken != null">id_token,</if>
<if test="macAlgorithm != null">mac_algorithm,</if>
<if test="macKey != null">mac_key,</if>
<if test="code != null">code,</if>
<if test="oauthToken != null">oauth_token,</if>
<if test="oauthTokenSecret != null">oauth_token_secret,</if>
<if test="createTime != null">create_time,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="delFlag != null and delFlag != ''">del_flag,</if>
<if test="status != null and status != ''">status,</if>
<if test="sysUserId != null">sys_user_id,</if>
<if test="username != null">username,</if>
<if test="nickname != null">nickname,</if>
<if test="avatar != null">avatar,</if>
<if test="gender != null">gender,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="uuid != null and uuid != ''">#{uuid},</if>
<if test="source != null and source != ''">#{source},</if>
<if test="accessToken != null and accessToken != ''">#{accessToken},</if>
<if test="expireIn != null">#{expireIn},</if>
<if test="refreshToken != null">#{refreshToken},</if>
<if test="openId != null">#{openId},</if>
<if test="uid != null">#{uid},</if>
<if test="accessCode != null">#{accessCode},</if>
<if test="unionId != null">#{unionId},</if>
<if test="scope != null">#{scope},</if>
<if test="tokenType != null">#{tokenType},</if>
<if test="idToken != null">#{idToken},</if>
<if test="macAlgorithm != null">#{macAlgorithm},</if>
<if test="macKey != null">#{macKey},</if>
<if test="code != null">#{code},</if>
<if test="oauthToken != null">#{oauthToken},</if>
<if test="oauthTokenSecret != null">#{oauthTokenSecret},</if>
<if test="createTime != null">#{createTime},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="sysUserId != null">#{sysUserId},</if>
<if test="username != null">#{username},</if>
<if test="nickname != null">#{nickname},</if>
<if test="avatar != null">#{avatar},</if>
<if test="gender != null">#{gender},</if>
</trim>
</insert>
<update id="updateSocialUser" parameterType="SocialUser">
update iot_social_user
<trim prefix="SET" suffixOverrides=",">
<if test="uuid != null and uuid != ''">uuid = #{uuid},</if>
<if test="source != null and source != ''">source = #{source},</if>
<if test="accessToken != null and accessToken != ''">access_token = #{accessToken},</if>
<if test="expireIn != null">expire_in = #{expireIn},</if>
<if test="refreshToken != null">refresh_token = #{refreshToken},</if>
<if test="openId != null">open_id = #{openId},</if>
<if test="uid != null">uid = #{uid},</if>
<if test="accessCode != null">access_code = #{accessCode},</if>
<if test="unionId != null">union_id = #{unionId},</if>
<if test="scope != null">scope = #{scope},</if>
<if test="tokenType != null">token_type = #{tokenType},</if>
<if test="idToken != null">id_token = #{idToken},</if>
<if test="macAlgorithm != null">mac_algorithm = #{macAlgorithm},</if>
<if test="macKey != null">mac_key = #{macKey},</if>
<if test="code != null">code = #{code},</if>
<if test="oauthToken != null">oauth_token = #{oauthToken},</if>
<if test="oauthTokenSecret != null">oauth_token_secret = #{oauthTokenSecret},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="createBy != null and createBy != ''">create_by = #{createBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="delFlag != null and delFlag != ''">del_flag = #{delFlag},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="sysUserId != null">sys_user_id = #{sysUserId},</if>
<if test="username != null">username = #{username},</if>
<if test="nickname != null">nickname = #{nickname},</if>
<if test="avatar != null">avatar = #{avatar},</if>
<if test="gender != null">gender = #{gender},</if>
</trim>
where social_user_id = #{socialUserId}
</update>
<delete id="deleteSocialUserBySocialUserId" parameterType="Long">
delete
from iot_social_user
where social_user_id = #{socialUserId}
</delete>
<delete id="deleteSocialUserBySocialUserIds" parameterType="String">
delete from iot_social_user where social_user_id in
<foreach item="socialUserId" collection="array" open="(" separator="," close=")">
#{socialUserId}
</foreach>
</delete>
</mapper>

View File

@@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询第三方登录平台控制列表
export function listPlatform(query) {
return request({
url: '/iot/platform/list',
method: 'get',
params: query
})
}
// 查询第三方登录平台控制详细
export function getPlatform(socialPlatformId) {
return request({
url: '/iot/platform/' + socialPlatformId,
method: 'get'
})
}
// 新增第三方登录平台控制
export function addPlatform(data) {
return request({
url: '/iot/platform',
method: 'post',
data: data
})
}
// 修改第三方登录平台控制
export function updatePlatform(data) {
return request({
url: '/iot/platform',
method: 'put',
data: data
})
}
// 删除第三方登录平台控制
export function delPlatform(socialPlatformId) {
return request({
url: '/iot/platform/' + socialPlatformId,
method: 'delete'
})
}

View File

@@ -57,3 +57,58 @@ export function getCodeImg() {
timeout: 20000
})
}
//查看是否存在bindId
export function checkBindId(bindId) {
return request({
url: '/auth/checkBindId/' + bindId,
method: 'get',
})
}
//查看是否存在errorId
export function getErrorMsg(errorId) {
return request({
url: '/auth/getErrorMsg/' + errorId,
method: 'get',
})
}
// 登录方法
export function bindLogin(username, password, code, uuid, bindId) {
const data = {
username,
password,
code,
uuid,
bindId
}
return request({
url: '/auth/bind/login',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
// 注册方法
export function bindRegister(data) {
return request({
url: '/auth/bind/register',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
//跳转登录
export function redirectLogin(loginId) {
return request({
url: '/auth/login/' + loginId,
method: 'get',
})
}

View File

@@ -1,5 +1,5 @@
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import {bindLogin, getInfo, login, logout, redirectLogin} from '@/api/login'
import {getToken, removeToken, setToken} from '@/utils/auth'
const user = {
state: {
@@ -35,7 +35,9 @@ const user = {
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
const bindId = userInfo.bindId;
return new Promise((resolve, reject) => {
if (bindId === undefined || bindId === "") {
login(username, password, code, uuid).then(res => {
setToken(res.token)
commit('SET_TOKEN', res.token)
@@ -43,6 +45,27 @@ const user = {
}).catch(error => {
reject(error)
})
} else {
bindLogin(username, password, code, uuid, bindId).then(res => {
setToken(res.token)
commit('SET_TOKEN', res.token)
resolve()
}).catch(error => {
reject(error)
})
}
})
},
RedirectLogin({commit}, loginId) {
return new Promise((resolve, reject) => {
redirectLogin(loginId).then(res => {
setToken(res.token)
commit('SET_TOKEN', res.token)
resolve()
}).catch(error => {
reject(error)
})
})
},

View File

@@ -1,9 +1,9 @@
import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import {Loading, Message, MessageBox, Notification} from 'element-ui'
import store from '@/store'
import {getToken} from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import {blobValidate, tansParams} from "@/utils/ruoyi";
import {saveAs} from 'file-saver'
let downloadLoadingInstance;
@@ -65,6 +65,8 @@ service.interceptors.response.use(res => {
type: 'error'
})
return Promise.reject(new Error(msg))
} else if (code === 502) {
return Promise.reject('error')
} else if (code !== 200) {
Notification.error({
title: msg

View File

@@ -0,0 +1,366 @@
<template>
<div class="app-container">
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="85px">
<el-form-item label="第三方平台" prop="platform">
<el-select v-model="queryParams.platform" clearable placeholder="请选择第三方平台" size="small">
<el-option
v-for="dict in dict.type.iot_social_platform"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" clearable placeholder="请选择 0:启用 ,1:禁用" size="small">
<el-option
v-for="dict in dict.type.iot_social_platform_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['iot:platform:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['iot:platform:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['iot:platform:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['iot:platform:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="platformList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column align="center" label="登录平台主键" prop="socialPlatformId"/>
<el-table-column align="center" label="第三方平台" prop="platform">
<template slot-scope="scope">
<dict-tag :options="dict.type.iot_social_platform" :value="scope.row.platform"/>
</template>
</el-table-column>
<el-table-column align="center" label="状态" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.iot_social_platform_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="第三方平台申请Id" align="center" prop="clientId"/>
<el-table-column label="第三方平台密钥" align="center" prop="secretKey"/>
<el-table-column label="用户认证后跳转地址" align="center" prop="redirectUri"/>
<el-table-column align="center" label="创建者" prop="createBy"/>
<el-table-column align="center" label="创建时间" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="更新时间" prop="updateTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="更新者" prop="updateBy"/>
<el-table-column align="center" label="备注" prop="remark"/>
<el-table-column align="center" label="绑定注册登录uri,http://localhost/login?bindId=" prop="bindUri"/>
<el-table-column align="center" label="跳转登录uri,http://localhost/login?loginId=" prop="redirectLoginUri"/>
<el-table-column align="center" label="错误提示uri,http://localhost/login?errorId=" prop="errorMsgUri"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['iot:platform:edit']"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['iot:platform:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改第三方登录平台控制对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="第三方平台" prop="platform">
<el-select v-model="form.platform" placeholder="请选择第三方平台">
<el-option
v-for="dict in dict.type.iot_social_platform"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label=" 0:启用 ,1:禁用" prop="status">
<el-select v-model="form.status" placeholder="请选择 0:启用 ,1:禁用">
<el-option
v-for="dict in dict.type.iot_social_platform_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="第三方平台申请Id" prop="clientId">
<el-input v-model="form.clientId" placeholder="请输入第三方平台申请Id"/>
</el-form-item>
<el-form-item label="第三方平台密钥" prop="secretKey">
<el-input v-model="form.secretKey" placeholder="请输入第三方平台密钥"/>
</el-form-item>
<el-form-item label="用户认证后跳转地址" prop="redirectUri">
<el-input v-model="form.redirectUri" placeholder="请输入用户认证后跳转地址"/>
</el-form-item>
<el-form-item label="删除标记位(0代表存在2代表删除)" prop="delFlag">
<el-input v-model="form.delFlag" placeholder="请输入删除标记位(0代表存在2代表删除)"/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入内容" type="textarea"/>
</el-form-item>
<el-form-item label="绑定注册登录uri,http://localhost/login?bindId=" prop="bindUri">
<el-input v-model="form.bindUri" placeholder="请输入绑定注册登录uri,http://localhost/login?bindId="/>
</el-form-item>
<el-form-item label="跳转登录uri,http://localhost/login?loginId=" prop="redirectLoginUri">
<el-input v-model="form.redirectLoginUri" placeholder="请输入跳转登录uri,http://localhost/login?loginId="/>
</el-form-item>
<el-form-item label="错误提示uri,http://localhost/login?errorId=" prop="errorMsgUri">
<el-input v-model="form.errorMsgUri" placeholder="请输入错误提示uri,http://localhost/login?errorId="/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {addPlatform, delPlatform, getPlatform, listPlatform, updatePlatform} from "@/api/iot/platform";
export default {
name: "Platform",
dicts: ['iot_social_platform', 'iot_social_platform_status'],
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 第三方登录平台控制表格数据
platformList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
platform: null,
status: null,
},
// 表单参数
form: {},
// 表单校验
rules: {
platform: [
{required: true, message: "第三方平台不能为空", trigger: "change"}
],
status: [
{required: true, message: " 0:启用 ,1:禁用不能为空", trigger: "change"}
],
clientId: [
{required: true, message: "第三方平台申请Id不能为空", trigger: "blur"}
],
secretKey: [
{required: true, message: "第三方平台密钥不能为空", trigger: "blur"}
],
redirectUri: [
{required: true, message: "用户认证后跳转地址不能为空", trigger: "blur"}
],
bindUri: [
{required: true, message: "绑定注册登录uri,http://localhost/login?bindId=不能为空", trigger: "blur"}
],
redirectLoginUri: [
{required: true, message: "跳转登录uri,http://localhost/login?loginId=不能为空", trigger: "blur"}
],
errorMsgUri: [
{required: true, message: "错误提示uri,http://localhost/login?errorId=不能为空", trigger: "blur"}
]
}
};
},
created() {
this.getList();
},
methods: {
/** 查询第三方登录平台控制列表 */
getList() {
this.loading = true;
listPlatform(this.queryParams).then(response => {
this.platformList = response.rows;
this.total = response.total;
this.loading = false;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
socialPlatformId: null,
platform: null,
status: null,
clientId: null,
secretKey: null,
redirectUri: null,
delFlag: null,
createBy: null,
createTime: null,
updateTime: null,
updateBy: null,
remark: null,
bindUri: null,
redirectLoginUri: null,
errorMsgUri: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.socialPlatformId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加第三方登录平台控制";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const socialPlatformId = row.socialPlatformId || this.ids
getPlatform(socialPlatformId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改第三方登录平台控制";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.socialPlatformId != null) {
updatePlatform(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addPlatform(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const socialPlatformIds = row.socialPlatformId || this.ids;
this.$modal.confirm('是否确认删除第三方登录平台控制编号为"' + socialPlatformIds + '"的数据项?').then(function() {
return delPlatform(socialPlatformIds);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('iot/platform/export', {
...this.queryParams
}, `platform_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@@ -39,7 +39,7 @@
<dict-tag :options="dict.type.iot_data_type" :value="scope.row.datatype" />
</template>
</el-table-column>
<el-table-column label="数据定义" align="left" prop="specs" min-width="150" class-name="specsColor">
<el-table-column label="数据定义" align="left" header-align="center" prop="specs" min-width="150" class-name="specsColor">
<template slot-scope="scope">
<div v-html="formatSpecsDisplay(scope.row.specs)"></div>
</template>
@@ -355,6 +355,7 @@ export default {
this.form.datatype = "integer"
this.form.specs = {
enumList: [],
arrayType: "int"
};
},
/** 修改按钮操作 */
@@ -543,8 +544,6 @@ export default {
value: "",
text: ""
}];
} else if (val == "array") {
this.form.specs.arrayType = "int";
}
},
/** 添加枚举项 */

View File

@@ -63,7 +63,7 @@
<dict-tag :options="dict.type.iot_data_type" :value="scope.row.datatype" />
</template>
</el-table-column>
<el-table-column label="数据定义" align="left" prop="specs" min-width="150" class-name="specsColor">
<el-table-column label="数据定义" align="left" header-align="center" prop="specs" min-width="150" class-name="specsColor">
<template slot-scope="scope">
<div v-html="formatSpecsDisplay(scope.row.specs)"></div>
</template>
@@ -350,6 +350,7 @@ export default {
this.form.datatype = "integer"
this.form.specs = {
enumList: [],
arrayType: "int"
};
},
/** 修改按钮操作 */
@@ -467,8 +468,6 @@ export default {
value: "",
text: ""
}];
} else if (val == "array") {
this.form.specs.arrayType = "int";
}
},
/** 添加枚举项 */

View File

@@ -11,21 +11,25 @@
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" style="z-index:1000">
<h3 class="title">账号登录
<h3 class="title" v-if="!bindAccount">账号登录
<span style="font-size:16px;color:#eee"> 演示账号wumei<span style="margin:0 10px;">123456 </span></span>
</h3>
<h3 class="bindAccountTitle" v-else>绑定物美智能账户
</h3>
<el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin">
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码"
@keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaOnOff">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%"
@keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
</el-input>
<div class="login-code">
@@ -34,28 +38,39 @@
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;color:#000;">记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin">
<el-button v-if="!bindAccount" :loading="loading" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleLogin">
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
<div style="margin-top:10px;">
<span style="color:#fff;margin-right:10px;">第三方登录</span>
<el-button v-else :loading="loading" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleLogin">
<span v-if="!loading">绑定</span>
<span v-else> 中...</span>
</el-button>
<div style="margin-top:20px;" v-if="!bindAccount">
<div v-if="!bindAccount" style=";text-align: center ">
<el-button type="success" circle title="微信登录" size="small" @click="authLogin">
<svg-icon icon-class="wechat"/>
</el-button>
<el-button type="danger" circle title="QQ登录" size="small" @click="authLogin">
<el-button type="danger" circle title="QQ登录" size="small" @click="qqLogin">
<svg-icon icon-class="qq"/>
</el-button>
<el-button type="primary" circle title="支付宝登录" size="small" @click="authLogin">
<svg-icon icon-class="zhifubao"/>
</el-button>
</div>
</div>
<a style="margin-right:20px;color:#222" target="_blank" href="http://wumei.live">返回官网</a>
<div style="float: right;margin-top:10px;" v-if="register">
<a style="margin-right:20px;color:#222" target="_blank" href="http://wumei.live">返回官网</a>
<router-link style="color:#fff;font-size:16px;" :to="'/register'">立即注册 >></router-link>
<router-link style="color:#fff;font-size:16px;" :to='{path:"/register",query: this.$route.query }'>立即注册
>>
</router-link>
</div>
</el-form-item>
</el-form>
@@ -64,14 +79,17 @@
</div>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2021 <a target="_blank" href="http://wumei.live">wumei smart</a> All Rights Reserved.</span>
<span>Copyright © 2018-2021 <a target="_blank"
href="http://wumei.live">wumei smart</a> All Rights Reserved.</span>
</div>
</div>
</template>
<script>
import {
getCodeImg
getCodeImg,
checkBindId,
getErrorMsg
} from "@/api/login";
import Cookies from "js-cookie";
import {
@@ -89,7 +107,8 @@ export default {
password: "",
rememberMe: false,
code: "",
uuid: ""
uuid: "",
bindId: ""
},
loginRules: {
username: [{
@@ -111,6 +130,7 @@ export default {
loading: false,
// 验证码开关
captchaOnOff: true,
bindAccount: false,
// 注册开关
register: true,
redirect: undefined
@@ -125,10 +145,67 @@ export default {
}
},
created() {
let loginId = this.$route.query.loginId;
if (loginId === undefined || loginId === null) {
this.checkBind();
this.checkErrorMsg();
this.getCode();
this.getCookie();
} else {
this.redirectLogin(loginId);
}
},
methods: {
redirectLogin(loginId) {
this.loading = true;
this.$store.dispatch("RedirectLogin", loginId).then(() => {
this.$router.push({
path: this.redirect || "/"
}).catch(() => {
});
}).catch(() => {
this.loading = false;
if (this.captchaOnOff) {
this.getCode();
}
this.$router.push({
query: {}
})
});
},
checkBind() {
let query = this.$route.query;
let bindId = query.bindId;
if (bindId === undefined || bindId === null) {
this.bindAccount = false;
} else {
this.bindAccount = true;
checkBindId(bindId).then(res => {
this.bindAccount = res.bindAccount === undefined ? true : res.bindAccount
if (this.bindAccount) {
this.loginForm.bindId = bindId;
} else {
this.loginForm.bindId = "";
this.$router.push({
query: {}
})
}
})
}
},
checkErrorMsg() {
let errorId = this.$route.query.errorId;
if (errorId !== undefined && errorId !== null) {
getErrorMsg(errorId).then(res => {
}).catch(err => {
this.$router.push({
query: {}
})
})
}
},
getCode() {
getCodeImg().then(res => {
this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff;
@@ -148,8 +225,11 @@ export default {
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
},
weixinLogin() {
this.$alert('微信登录正在集成中...', '提示消息', {
qqLogin() {
window.location.href = "http://localhost:8080/auth/render/qq";
},
authLogin() {
this.$alert('第三方登录正在集成中...', '提示消息', {
confirmButtonText: '确定',
callback: action => {
this.$message({
@@ -159,18 +239,6 @@ export default {
}
});
},
authLogin() {
this.$alert('第三方登录正在集成中...', '提示消息', {
confirmButtonText: '确定',
callback: action => {
// this.$message({
// type: 'info',
// message: `action: ${ action }`
// });
}
});
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
@@ -190,10 +258,12 @@ export default {
Cookies.remove("password");
Cookies.remove('rememberMe');
}
console.log(this.loginForm)
this.$store.dispatch("Login", this.loginForm).then(() => {
this.$router.push({
path: this.redirect || "/"
}).catch(() => {});
}).catch(() => {
});
}).catch(() => {
this.loading = false;
if (this.captchaOnOff) {
@@ -202,7 +272,7 @@ export default {
});
}
});
}
},
}
};
</script>
@@ -223,6 +293,13 @@ export default {
font-size: 24px;
}
.bindAccountTitle {
margin: 0px auto 30px auto;
text-align: center;
color: #333;
font-size: 24px;
}
.login-top {
color: #fff;
text-align: center;

View File

@@ -10,8 +10,10 @@
</div>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form" style="z-index:1000">
<h3 class="title">注册账号</h3>
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form"
style="z-index:1000">
<h3 class="title" v-if="!bindAccount">注册账号</h3>
<h3 class="title" v-else>注册绑定物美智能账户</h3>
<el-form-item prop="username">
<el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon"/>
@@ -23,17 +25,20 @@
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="registerForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleRegister">
<el-input v-model="registerForm.password" type="password" auto-complete="off" placeholder="密码"
@keyup.enter.native="handleRegister">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input v-model="registerForm.confirmPassword" type="password" auto-complete="off" placeholder="确认密码" @keyup.enter.native="handleRegister">
<el-input v-model="registerForm.confirmPassword" type="password" auto-complete="off" placeholder="确认密码"
@keyup.enter.native="handleRegister">
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon"/>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaOnOff">
<el-input v-model="registerForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleRegister">
<el-input v-model="registerForm.code" auto-complete="off" placeholder="验证码" style="width: 63%"
@keyup.enter.native="handleRegister">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
</el-input>
<div class="register-code">
@@ -41,13 +46,42 @@
</div>
</el-form-item>
<el-form-item style="width:100%;">
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleRegister">
<el-button v-if="!bindAccount" :loading="loading" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleRegister">
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
<div style="float: right;margin-top:10px;">
<el-button v-else :loading="loading" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleRegister">
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
<div style="margin-top:20px;">
<div v-if="!bindAccount" style=" margin-bottom: 10px;text-align: center ">
<!-- <span style="color:#fff;margin-right:10px; float: left">快速登录</span>-->
<el-button type="success" circle title="微信登录" size="small" @click="authLogin">
<svg-icon icon-class="wechat"/>
</el-button>
<el-button type="danger" circle title="QQ登录" size="small" @click="qqLogin">
<svg-icon icon-class="qq"/>
</el-button>
<el-button type="primary" circle title="支付宝登录" size="small" @click="authLogin">
<svg-icon icon-class="zhifubao"/>
</el-button>
</div>
<router-link style="float:left;color:#fff;font-size:16px;"
:to='{path:"/login",query: this.$route.query }'>使用已有账户登录 >>
</router-link>
<div style="float: right">
<a style="margin-right:20px;" target="_blank" href="http://wumei.live">返回官网</a>
<router-link style="color:#fff;font-size:16px;" :to="'/login'">使用已有账户登录 >> </router-link>
</div>
</div>
</el-form-item>
</el-form>
@@ -57,14 +91,15 @@
</div>
<!-- 底部 -->
<div class="el-register-footer">
<span>Copyright © 2018-2021 <a target="_blank" href="http://wumei.live">wumei smart</a> All Rights Reserved.</span>
<span>Copyright © 2018-2021 <a target="_blank"
href="http://wumei.live">wumei smart</a> All Rights Reserved.</span>
</div>
</div>
</template>
<script>
import {
getCodeImg
getCodeImg, checkBindId, bindRegister
} from "@/api/login";
import {
register
@@ -88,7 +123,8 @@ export default {
password: "",
confirmPassword: "",
code: "",
uuid: ""
uuid: "",
bindId: ""
},
registerRules: {
username: [{
@@ -145,13 +181,36 @@ export default {
}]
},
loading: false,
captchaOnOff: true
captchaOnOff: true,
bindAccount: false
};
},
created() {
this.checkBind();
this.getCode();
},
methods: {
checkBind() {
let query = this.$route.query;
let bindId = query.bindId;
if (bindId === undefined || bindId === null) {
this.bindAccount = false;
} else {
this.bindAccount = true;
checkBindId(bindId).then(res => {
this.bindAccount = res.bindAccount === undefined ? true : res.bindAccount
if (this.bindAccount) {
this.registerForm.bindId = bindId;
} else {
this.registerForm.bindId = "";
this.$router.push({
query: {}
})
}
})
}
},
getCode() {
getCodeImg().then(res => {
this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff;
@@ -161,18 +220,36 @@ export default {
}
});
},
qqLogin() {
window.location.href = "http://localhost:8080/auth/render/qq";
},
authLogin() {
this.$alert('第三方登录正在集成中...', '提示消息', {
confirmButtonText: '确定',
callback: action => {
this.$message({
type: 'info',
message: `action: ${action}`
});
}
});
},
handleRegister() {
this.$refs.registerForm.validate(valid => {
if (valid) {
this.loading = true;
if (this.bindAccount) {
bindRegister(this.registerForm).then(res => {
this.innerRegister(res)
}).catch(() => {
this.loading = false;
if (this.captchaOnOff) {
this.getCode();
}
});
} else {
register(this.registerForm).then(res => {
const username = this.registerForm.username;
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
dangerouslyUseHTMLString: true,
type: 'success'
}).then(() => {
this.$router.push("/login");
}).catch(() => {});
this.innerRegister(res)
}).catch(() => {
this.loading = false;
if (this.captchaOnOff) {
@@ -180,6 +257,19 @@ export default {
}
})
}
}
});
},
innerRegister(res) {
const username = this.registerForm.username;
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
dangerouslyUseHTMLString: true,
type: 'success'
}).then(() => {
this.$router.push("/login");
}).catch(() => {
});
}
}