疯狂的狮子Li
2023-06-28 b0909dbe3ddd7fb06180704c241b4cebabff6665
!379 合并 客户端授权功能
已添加17个文件
已修改19个文件
2317 ■■■■ 文件已修改
ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginVo.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/IAuthStrategy.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/i18n/messages.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/i18n/messages_en_US.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/auth/EmailGroup.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/auth/PasswordGroup.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/auth/SmsGroup.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/auth/WechatGroup.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelEnumConvert.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysClient.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysClientBo.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysClientVo.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysClientMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysClientMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/oracle/oracle_ry_vue_5.X.sql 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/postgres/postgres_ry_vue_5.X.sql 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/ry_vue_5.X.sql 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/sqlserver/sqlserver_ry_vue_5.X.sql 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/update/oracle/update_5.0-5.1.sql 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/update/postgres/update_5.0-5.1.sql 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/update/sqlserver/update_5.0-5.1.sql 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/update/update_5.0-5.1.sql 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
@@ -4,33 +4,35 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.EmailLoginBody;
import org.dromara.common.core.domain.model.LoginBody;
import org.dromara.common.core.domain.model.RegisterBody;
import org.dromara.common.core.domain.model.SmsLoginBody;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.utils.SocialUtils;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.bo.SysTenantBo;
import org.dromara.system.domain.vo.SysTenantVo;
import org.dromara.system.service.ISysSocialService;
import org.dromara.system.service.ISysClientService;
import org.dromara.system.service.ISysConfigService;
import org.dromara.system.service.ISysSocialService;
import org.dromara.system.service.ISysTenantService;
import org.dromara.web.domain.vo.LoginTenantVo;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.domain.vo.TenantListVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.dromara.web.service.SysRegisterService;
import org.springframework.validation.annotation.Validated;
@@ -44,6 +46,7 @@
 *
 * @author Lion Li
 */
@Slf4j
@SaIgnore
@Validated
@RequiredArgsConstructor
@@ -57,77 +60,31 @@
    private final ISysConfigService configService;
    private final ISysTenantService tenantService;
    private final ISysSocialService socialUserService;
    private final ISysClientService clientService;
    /**
     * ç™»å½•方法
     *
     * @param body ç™»å½•信息
     * @param loginBody ç™»å½•信息
     * @return ç»“æžœ
     */
    @PostMapping("/login")
    public R<LoginVo> login(@Validated @RequestBody LoginBody body) {
        LoginVo loginVo = new LoginVo();
        // ç”Ÿæˆä»¤ç‰Œ
        String token = loginService.login(
            body.getTenantId(),
            body.getUsername(), body.getPassword(),
            body.getCode(), body.getUuid());
        loginVo.setToken(token);
        return R.ok(loginVo);
    public R<LoginVo> login(@Validated @RequestBody LoginBody loginBody) {
        // æŽˆæƒç±»åž‹å’Œå®¢æˆ·ç«¯id
        String clientId = loginBody.getClientId();
        String grantType = loginBody.getGrantType();
        SysClient client = clientService.queryByClientId(clientId);
        // æŸ¥è¯¢ä¸åˆ° client æˆ– client å†…不包含 grantType
        if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
            log.info("客户端id: {} è®¤è¯ç±»åž‹ï¼š{} å¼‚常!.", clientId, grantType);
            return R.fail(MessageUtils.message("auth.grant.type.error"));
        }
        // æ ¡éªŒç§Ÿæˆ·
        loginService.checkTenant(loginBody.getTenantId());
        // ç™»å½•
        return R.ok(IAuthStrategy.login(loginBody, client));
    }
    /**
     * çŸ­ä¿¡ç™»å½•
     *
     * @param body ç™»å½•信息
     * @return ç»“æžœ
     */
    @PostMapping("/smsLogin")
    public R<LoginVo> smsLogin(@Validated @RequestBody SmsLoginBody body) {
        LoginVo loginVo = new LoginVo();
        // ç”Ÿæˆä»¤ç‰Œ
        String token = loginService.smsLogin(
            body.getTenantId(),
            body.getPhonenumber(),
            body.getSmsCode());
        loginVo.setToken(token);
        return R.ok(loginVo);
    }
    /**
     * é‚®ä»¶ç™»å½•
     *
     * @param body ç™»å½•信息
     * @return ç»“æžœ
     */
    @PostMapping("/emailLogin")
    public R<LoginVo> emailLogin(@Validated @RequestBody EmailLoginBody body) {
        LoginVo loginVo = new LoginVo();
        // ç”Ÿæˆä»¤ç‰Œ
        String token = loginService.emailLogin(
            body.getTenantId(),
            body.getEmail(),
            body.getEmailCode());
        loginVo.setToken(token);
        return R.ok(loginVo);
    }
    /**
     * å°ç¨‹åºç™»å½•(示例)
     *
     * @param xcxCode å°ç¨‹åºcode
     * @return ç»“æžœ
     */
    @PostMapping("/xcxLogin")
    public R<LoginVo> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) {
        LoginVo loginVo = new LoginVo();
        // ç”Ÿæˆä»¤ç‰Œ
        String token = loginService.xcxLogin(xcxCode);
        loginVo.setToken(token);
        return R.ok(loginVo);
    }
    /**
     * è®¤è¯æŽˆæƒ
ruoyi-admin/src/main/java/org/dromara/web/domain/vo/LoginVo.java
@@ -1,5 +1,6 @@
package org.dromara.web.domain.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
@@ -10,6 +11,44 @@
@Data
public class LoginVo {
    private String token;
    /**
     * æŽˆæƒä»¤ç‰Œ
     */
    @JsonProperty("access_token")
    private String accessToken;
    /**
     * åˆ·æ–°ä»¤ç‰Œ
     */
    @JsonProperty("refresh_token")
    private String refreshToken;
    /**
     * æŽˆæƒä»¤ç‰Œ access_token çš„æœ‰æ•ˆæœŸ
     */
    @JsonProperty("expire_in")
    private Long expireIn;
    /**
     * åˆ·æ–°ä»¤ç‰Œ refresh_token çš„æœ‰æ•ˆæœŸ
     */
    @JsonProperty("refresh_expire_in")
    private Long refreshExpireIn;
    /**
     * åº”用id
     */
    @JsonProperty("client_id")
    private String clientId;
    /**
     * ä»¤ç‰Œæƒé™
     */
    private String scope;
    /**
     * ç”¨æˆ· openid
     */
    private String openid;
}
ruoyi-admin/src/main/java/org/dromara/web/service/IAuthStrategy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
package org.dromara.web.service;
import org.dromara.common.core.domain.model.LoginBody;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.system.domain.SysClient;
import org.dromara.web.domain.vo.LoginVo;
/**
 * æŽˆæƒç­–ç•¥
 *
 * @author Michelle.Chung
 */
public interface IAuthStrategy {
    String BASE_NAME = "AuthStrategy";
    /**
     * ç™»å½•
     */
    static LoginVo login(LoginBody loginBody, SysClient client) {
        // æŽˆæƒç±»åž‹å’Œå®¢æˆ·ç«¯id
        String clientId = loginBody.getClientId();
        String grantType = loginBody.getGrantType();
        String beanName = grantType + BASE_NAME;
        if (!SpringUtils.containsBean(beanName)) {
            throw new ServiceException("授权类型不正确!");
        }
        IAuthStrategy instance = SpringUtils.getBean(beanName);
        instance.validate(loginBody);
        return instance.login(clientId, loginBody, client);
    }
    /**
     * å‚数校验
     */
    void validate(LoginBody loginBody);
    /**
     * ç™»å½•
     */
    LoginVo login(String clientId, LoginBody loginBody, SysClient client);
}
ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
@@ -1,7 +1,7 @@
package org.dromara.web.service;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -16,13 +16,10 @@
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.dto.RoleDTO;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.domain.model.XcxLoginUser;
import org.dromara.common.core.enums.DeviceType;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.enums.TenantStatus;
import org.dromara.common.core.enums.UserStatus;
import org.dromara.common.core.exception.user.CaptchaException;
import org.dromara.common.core.exception.user.CaptchaExpireException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.*;
import org.dromara.common.log.event.LogininforEvent;
@@ -30,15 +27,14 @@
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.exception.TenantException;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.config.properties.CaptchaProperties;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysSocialBo;
import org.dromara.system.domain.vo.SysSocialVo;
import org.dromara.system.domain.vo.SysTenantVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysSocialService;
import org.dromara.system.service.ISysPermissionService;
import org.dromara.system.service.ISysSocialService;
import org.dromara.system.service.ISysTenantService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
@@ -59,108 +55,16 @@
@Service
public class SysLoginService {
    private final SysUserMapper userMapper;
    private final ISysSocialService sysSocialService;
    private final CaptchaProperties captchaProperties;
    private final ISysPermissionService permissionService;
    private final ISysTenantService tenantService;
    @Value("${user.password.maxRetryCount}")
    private Integer maxRetryCount;
    @Value("${user.password.lockTime}")
    private Integer lockTime;
    /**
     * ç™»å½•验证
     *
     * @param username ç”¨æˆ·å
     * @param password å¯†ç 
     * @param code     éªŒè¯ç 
     * @param uuid     å”¯ä¸€æ ‡è¯†
     * @return ç»“æžœ
     */
    public String login(String tenantId, String username, String password, String code, String uuid) {
        boolean captchaEnabled = captchaProperties.getEnable();
        // éªŒè¯ç å¼€å…³
        if (captchaEnabled) {
            validateCaptcha(tenantId, username, code, uuid);
        }
        // æ ¡éªŒç§Ÿæˆ·
        checkTenant(tenantId);
        // æ¡†æž¶ç™»å½•不限制从什么表查询 åªè¦æœ€ç»ˆæž„建出 LoginUser å³å¯
        SysUserVo user = loadUserByUsername(tenantId, username);
        checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
        // æ­¤å¤„可根据登录用户的数据不同 è‡ªè¡Œåˆ›å»º loginUser å±žæ€§ä¸å¤Ÿç”¨ç»§æ‰¿æ‰©å±•就行了
        LoginUser loginUser = buildLoginUser(user);
        // ç”Ÿæˆtoken
        LoginHelper.loginByDevice(loginUser, DeviceType.PC);
        recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        recordLoginInfo(user.getUserId());
        return StpUtil.getTokenValue();
    }
    public String smsLogin(String tenantId, String phonenumber, String smsCode) {
        // æ ¡éªŒç§Ÿæˆ·
        checkTenant(tenantId);
        // é€šè¿‡æ‰‹æœºå·æŸ¥æ‰¾ç”¨æˆ·
        SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber);
        checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode));
        // æ­¤å¤„可根据登录用户的数据不同 è‡ªè¡Œåˆ›å»º loginUser å±žæ€§ä¸å¤Ÿç”¨ç»§æ‰¿æ‰©å±•就行了
        LoginUser loginUser = buildLoginUser(user);
        // ç”Ÿæˆtoken
        LoginHelper.loginByDevice(loginUser, DeviceType.APP);
        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        recordLoginInfo(user.getUserId());
        return StpUtil.getTokenValue();
    }
    public String emailLogin(String tenantId, String email, String emailCode) {
        // æ ¡éªŒç§Ÿæˆ·
        checkTenant(tenantId);
        // é€šè¿‡é‚®ç®±æŸ¥æ‰¾ç”¨æˆ·
        SysUserVo user = loadUserByEmail(tenantId, email);
        checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
        // æ­¤å¤„可根据登录用户的数据不同 è‡ªè¡Œåˆ›å»º loginUser å±žæ€§ä¸å¤Ÿç”¨ç»§æ‰¿æ‰©å±•就行了
        LoginUser loginUser = buildLoginUser(user);
        // ç”Ÿæˆtoken
        LoginHelper.loginByDevice(loginUser, DeviceType.APP);
        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        recordLoginInfo(user.getUserId());
        return StpUtil.getTokenValue();
    }
    public String xcxLogin(String xcxCode) {
        // xcxCode ä¸º å°ç¨‹åºè°ƒç”¨ wx.login æŽˆæƒåŽèŽ·å–
        // todo ä»¥ä¸‹è‡ªè¡Œå®žçް
        // æ ¡éªŒ appid + appsrcret + xcxCode è°ƒç”¨ç™»å½•凭证校验接口 èŽ·å– session_key ä¸Ž openid
        String openid = "";
        // æ¡†æž¶ç™»å½•不限制从什么表查询 åªè¦æœ€ç»ˆæž„建出 LoginUser å³å¯
        SysUserVo user = loadUserByOpenid(openid);
        // æ ¡éªŒç§Ÿæˆ·
        checkTenant(user.getTenantId());
        // æ­¤å¤„可根据登录用户的数据不同 è‡ªè¡Œåˆ›å»º loginUser å±žæ€§ä¸å¤Ÿç”¨ç»§æ‰¿æ‰©å±•就行了
        XcxLoginUser loginUser = new XcxLoginUser();
        loginUser.setTenantId(user.getTenantId());
        loginUser.setUserId(user.getUserId());
        loginUser.setUsername(user.getUserName());
        loginUser.setUserType(user.getUserType());
        loginUser.setOpenid(openid);
        // ç”Ÿæˆtoken
        LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
        recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        recordLoginInfo(user.getUserId());
        return StpUtil.getTokenValue();
    }
    private final ISysTenantService tenantService;
    private final ISysPermissionService permissionService;
    private final ISysSocialService sysSocialService;
    private final SysUserMapper userMapper;
    /**
     * ç¤¾äº¤ç™»å½•
@@ -214,7 +118,10 @@
    private R<String> loginAndRecord(String tenantId, String userName, AuthUser authUser) {
        checkTenant(tenantId);
        SysUserVo user = loadUserByUsername(tenantId, userName);
        LoginHelper.loginByDevice(buildLoginUser(user), DeviceType.SOCIAL);
        SaLoginModel model = new SaLoginModel();
        model.setDevice(DeviceType.PC.getDevice());
        // ç”Ÿæˆtoken
        LoginHelper.login(buildLoginUser(user), model);
        recordLogininfor(user.getTenantId(), userName, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        recordLoginInfo(user.getUserId());
        return R.ok(StpUtil.getTokenValue());
@@ -244,7 +151,7 @@
     * @param status   çŠ¶æ€
     * @param message  æ¶ˆæ¯å†…容
     */
    private void recordLogininfor(String tenantId, String username, String status, String message) {
    public void recordLogininfor(String tenantId, String username, String status, String message) {
        LogininforEvent logininforEvent = new LogininforEvent();
        logininforEvent.setTenantId(tenantId);
        logininforEvent.setUsername(username);
@@ -254,56 +161,12 @@
        SpringUtils.context().publishEvent(logininforEvent);
    }
    /**
     * æ ¡éªŒçŸ­ä¿¡éªŒè¯ç 
     */
    private boolean validateSmsCode(String tenantId, String phonenumber, String smsCode) {
        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
        if (StringUtils.isBlank(code)) {
            recordLogininfor(tenantId, phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        return code.equals(smsCode);
    }
    /**
     * æ ¡éªŒé‚®ç®±éªŒè¯ç 
     */
    private boolean validateEmailCode(String tenantId, String email, String emailCode) {
        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
        if (StringUtils.isBlank(code)) {
            recordLogininfor(tenantId, email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        return code.equals(emailCode);
    }
    /**
     * æ ¡éªŒéªŒè¯ç 
     *
     * @param username ç”¨æˆ·å
     * @param code     éªŒè¯ç 
     * @param uuid     å”¯ä¸€æ ‡è¯†
     */
    public void validateCaptcha(String tenantId, String username, String code, String uuid) {
        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
        String captcha = RedisUtils.getCacheObject(verifyKey);
        RedisUtils.deleteObject(verifyKey);
        if (captcha == null) {
            recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
            throw new CaptchaException();
        }
    }
    private SysUserVo loadUserByUsername(String tenantId, String username) {
        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getUserName, SysUser::getStatus)
            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
            .eq(SysUser::getUserName, username));
                .select(SysUser::getUserName, SysUser::getStatus)
                .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
                .eq(SysUser::getUserName, username));
        if (ObjectUtil.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", username);
            throw new UserException("user.not.exists", username);
@@ -317,60 +180,10 @@
        return userMapper.selectUserByUserName(username);
    }
    private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) {
        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getPhonenumber, SysUser::getStatus)
            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
            .eq(SysUser::getPhonenumber, phonenumber));
        if (ObjectUtil.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", phonenumber);
            throw new UserException("user.not.exists", phonenumber);
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户:{} å·²è¢«åœç”¨.", phonenumber);
            throw new UserException("user.blocked", phonenumber);
        }
        if (TenantHelper.isEnable()) {
            return userMapper.selectTenantUserByPhonenumber(phonenumber, tenantId);
        }
        return userMapper.selectUserByPhonenumber(phonenumber);
    }
    private SysUserVo loadUserByEmail(String tenantId, String email) {
        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getEmail, SysUser::getStatus)
            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
            .eq(SysUser::getEmail, email));
        if (ObjectUtil.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", email);
            throw new UserException("user.not.exists", email);
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户:{} å·²è¢«åœç”¨.", email);
            throw new UserException("user.blocked", email);
        }
        if (TenantHelper.isEnable()) {
            return userMapper.selectTenantUserByEmail(email, tenantId);
        }
        return userMapper.selectUserByEmail(email);
    }
    private SysUserVo loadUserByOpenid(String openid) {
        // ä½¿ç”¨ openid æŸ¥è¯¢ç»‘定用户 å¦‚未绑定用户 åˆ™æ ¹æ®ä¸šåŠ¡è‡ªè¡Œå¤„ç† ä¾‹å¦‚ åˆ›å»ºé»˜è®¤ç”¨æˆ·
        // todo è‡ªè¡Œå®žçް userService.selectUserByOpenid(openid);
        SysUserVo user = new SysUserVo();
        if (ObjectUtil.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", openid);
            // todo ç”¨æˆ·ä¸å­˜åœ¨ ä¸šåŠ¡é€»è¾‘è‡ªè¡Œå®žçŽ°
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户:{} å·²è¢«åœç”¨.", openid);
            // todo ç”¨æˆ·å·²è¢«åœç”¨ ä¸šåŠ¡é€»è¾‘è‡ªè¡Œå®žçŽ°
        }
        return user;
    }
    /**
     * æž„建登录用户
     */
    private LoginUser buildLoginUser(SysUserVo user) {
    public LoginUser buildLoginUser(SysUserVo user) {
        LoginUser loginUser = new LoginUser();
        loginUser.setTenantId(user.getTenantId());
        loginUser.setUserId(user.getUserId());
@@ -402,7 +215,7 @@
    /**
     * ç™»å½•校验
     */
    private void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) {
    public void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) {
        String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username;
        String loginFail = Constants.LOGIN_FAIL;
@@ -433,7 +246,12 @@
        RedisUtils.deleteObject(errorKey);
    }
    private void checkTenant(String tenantId) {
    /**
     * æ ¡éªŒç§Ÿæˆ·
     *
     * @param tenantId ç§Ÿæˆ·ID
     */
    public void checkTenant(String tenantId) {
        if (!TenantHelper.isEnable()) {
            return;
        }
ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
package org.dromara.web.service.impl;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.model.LoginBody;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.enums.UserStatus;
import org.dromara.common.core.exception.user.CaptchaExpireException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.core.validate.auth.EmailGroup;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
/**
 * é‚®ä»¶è®¤è¯ç­–ç•¥
 *
 * @author Michelle.Chung
 */
@Slf4j
@Service("email" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class EmailAuthStrategy implements IAuthStrategy {
    private final SysLoginService loginService;
    private final SysUserMapper userMapper;
    @Override
    public void validate(LoginBody loginBody) {
        ValidatorUtils.validate(loginBody, EmailGroup.class);
    }
    @Override
    public LoginVo login(String clientId, LoginBody loginBody, SysClient client) {
        String tenantId = loginBody.getTenantId();
        String email = loginBody.getEmail();
        String emailCode = loginBody.getEmailCode();
        // é€šè¿‡é‚®ç®±æŸ¥æ‰¾ç”¨æˆ·
        SysUserVo user = loadUserByEmail(tenantId, email);
        loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
        // æ­¤å¤„可根据登录用户的数据不同 è‡ªè¡Œåˆ›å»º loginUser å±žæ€§ä¸å¤Ÿç”¨ç»§æ‰¿æ‰©å±•就行了
        LoginUser loginUser = loginService.buildLoginUser(user);
        SaLoginModel model = new SaLoginModel();
        model.setDevice(client.getDeviceType());
        // è‡ªå®šä¹‰åˆ†é… ä¸åŒç”¨æˆ·ä½“ç³» ä¸åŒ token æŽˆæƒæ—¶é—´ ä¸è®¾ç½®é»˜è®¤èµ°å…¨å±€ yml é…ç½®
        // ä¾‹å¦‚: åŽå°ç”¨æˆ·30分钟过期 app用户1天过期
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        // ç”Ÿæˆtoken
        LoginHelper.login(loginUser, model);
        loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        loginService.recordLoginInfo(user.getUserId());
        LoginVo loginVo = new LoginVo();
        loginVo.setAccessToken(StpUtil.getTokenValue());
        return loginVo;
    }
    /**
     * æ ¡éªŒé‚®ç®±éªŒè¯ç 
     */
    private boolean validateEmailCode(String tenantId, String email, String emailCode) {
        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
        if (StringUtils.isBlank(code)) {
            loginService.recordLogininfor(tenantId, email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        return code.equals(emailCode);
    }
    private SysUserVo loadUserByEmail(String tenantId, String email) {
        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getEmail, SysUser::getStatus)
            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
            .eq(SysUser::getEmail, email));
        if (ObjectUtil.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", email);
            throw new UserException("user.not.exists", email);
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户:{} å·²è¢«åœç”¨.", email);
            throw new UserException("user.blocked", email);
        }
        if (TenantHelper.isEnable()) {
            return userMapper.selectTenantUserByEmail(email, tenantId);
        }
        return userMapper.selectUserByEmail(email);
    }
}
ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,130 @@
package org.dromara.web.service.impl;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.model.LoginBody;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.enums.UserStatus;
import org.dromara.common.core.exception.user.CaptchaException;
import org.dromara.common.core.exception.user.CaptchaExpireException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.core.validate.auth.PasswordGroup;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.config.properties.CaptchaProperties;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
/**
 * å¯†ç è®¤è¯ç­–ç•¥
 *
 * @author Michelle.Chung
 */
@Slf4j
@Service("password" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class PasswordAuthStrategy implements IAuthStrategy {
    private final CaptchaProperties captchaProperties;
    private final SysLoginService loginService;
    private final SysUserMapper userMapper;
    @Override
    public void validate(LoginBody loginBody) {
        ValidatorUtils.validate(loginBody, PasswordGroup.class);
    }
    @Override
    public LoginVo login(String clientId, LoginBody loginBody, SysClient client) {
        String tenantId = loginBody.getTenantId();
        String username = loginBody.getUsername();
        String password = loginBody.getPassword();
        String code = loginBody.getCode();
        String uuid = loginBody.getUuid();
        boolean captchaEnabled = captchaProperties.getEnable();
        // éªŒè¯ç å¼€å…³
        if (captchaEnabled) {
            validateCaptcha(tenantId, username, code, uuid);
        }
        SysUserVo user = loadUserByUsername(tenantId, username);
        loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
        // æ­¤å¤„可根据登录用户的数据不同 è‡ªè¡Œåˆ›å»º loginUser
        LoginUser loginUser = loginService.buildLoginUser(user);
        SaLoginModel model = new SaLoginModel();
        model.setDevice(client.getDeviceType());
        // è‡ªå®šä¹‰åˆ†é… ä¸åŒç”¨æˆ·ä½“ç³» ä¸åŒ token æŽˆæƒæ—¶é—´ ä¸è®¾ç½®é»˜è®¤èµ°å…¨å±€ yml é…ç½®
        // ä¾‹å¦‚: åŽå°ç”¨æˆ·30分钟过期 app用户1天过期
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        // ç”Ÿæˆtoken
        LoginHelper.login(loginUser, model);
        loginService.recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        loginService.recordLoginInfo(user.getUserId());
        LoginVo loginVo = new LoginVo();
        loginVo.setAccessToken(StpUtil.getTokenValue());
        loginVo.setExpireIn(StpUtil.getTokenTimeout());
        return loginVo;
    }
    /**
     * æ ¡éªŒéªŒè¯ç 
     *
     * @param username ç”¨æˆ·å
     * @param code     éªŒè¯ç 
     * @param uuid     å”¯ä¸€æ ‡è¯†
     */
    private void validateCaptcha(String tenantId, String username, String code, String uuid) {
        String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
        String captcha = RedisUtils.getCacheObject(verifyKey);
        RedisUtils.deleteObject(verifyKey);
        if (captcha == null) {
            loginService.recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            loginService.recordLogininfor(tenantId, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"));
            throw new CaptchaException();
        }
    }
    private SysUserVo loadUserByUsername(String tenantId, String username) {
        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getUserName, SysUser::getStatus)
            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
            .eq(SysUser::getUserName, username));
        if (ObjectUtil.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", username);
            throw new UserException("user.not.exists", username);
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户:{} å·²è¢«åœç”¨.", username);
            throw new UserException("user.blocked", username);
        }
        if (TenantHelper.isEnable()) {
            return userMapper.selectTenantUserByUserName(username, tenantId);
        }
        return userMapper.selectUserByUserName(username);
    }
}
ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
package org.dromara.web.service.impl;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.model.LoginBody;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.enums.UserStatus;
import org.dromara.common.core.exception.user.CaptchaExpireException;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.core.validate.auth.SmsGroup;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
/**
 * çŸ­ä¿¡è®¤è¯ç­–ç•¥
 *
 * @author Michelle.Chung
 */
@Slf4j
@Service("sms" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class SmsAuthStrategy implements IAuthStrategy {
    private final SysLoginService loginService;
    private final SysUserMapper userMapper;
    @Override
    public void validate(LoginBody loginBody) {
        ValidatorUtils.validate(loginBody, SmsGroup.class);
    }
    @Override
    public LoginVo login(String clientId, LoginBody loginBody, SysClient client) {
        String tenantId = loginBody.getTenantId();
        String phonenumber = loginBody.getPhonenumber();
        String smsCode = loginBody.getSmsCode();
        // é€šè¿‡æ‰‹æœºå·æŸ¥æ‰¾ç”¨æˆ·
        SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber);
        loginService.checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode));
        // æ­¤å¤„可根据登录用户的数据不同 è‡ªè¡Œåˆ›å»º loginUser å±žæ€§ä¸å¤Ÿç”¨ç»§æ‰¿æ‰©å±•就行了
        LoginUser loginUser = loginService.buildLoginUser(user);
        SaLoginModel model = new SaLoginModel();
        model.setDevice(client.getDeviceType());
        // è‡ªå®šä¹‰åˆ†é… ä¸åŒç”¨æˆ·ä½“ç³» ä¸åŒ token æŽˆæƒæ—¶é—´ ä¸è®¾ç½®é»˜è®¤èµ°å…¨å±€ yml é…ç½®
        // ä¾‹å¦‚: åŽå°ç”¨æˆ·30分钟过期 app用户1天过期
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        // ç”Ÿæˆtoken
        LoginHelper.login(loginUser, model);
        loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        loginService.recordLoginInfo(user.getUserId());
        LoginVo loginVo = new LoginVo();
        loginVo.setAccessToken(StpUtil.getTokenValue());
        return loginVo;
    }
    /**
     * æ ¡éªŒçŸ­ä¿¡éªŒè¯ç 
     */
    private boolean validateSmsCode(String tenantId, String phonenumber, String smsCode) {
        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
        if (StringUtils.isBlank(code)) {
            loginService.recordLogininfor(tenantId, phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
            throw new CaptchaExpireException();
        }
        return code.equals(smsCode);
    }
    private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) {
        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getPhonenumber, SysUser::getStatus)
            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
            .eq(SysUser::getPhonenumber, phonenumber));
        if (ObjectUtil.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", phonenumber);
            throw new UserException("user.not.exists", phonenumber);
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户:{} å·²è¢«åœç”¨.", phonenumber);
            throw new UserException("user.blocked", phonenumber);
        }
        if (TenantHelper.isEnable()) {
            return userMapper.selectTenantUserByPhonenumber(phonenumber, tenantId);
        }
        return userMapper.selectUserByPhonenumber(phonenumber);
    }
}
ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,88 @@
package org.dromara.web.service.impl;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.domain.model.LoginBody;
import org.dromara.common.core.domain.model.XcxLoginUser;
import org.dromara.common.core.enums.UserStatus;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.core.validate.auth.WechatGroup;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.web.domain.vo.LoginVo;
import org.dromara.web.service.IAuthStrategy;
import org.dromara.web.service.SysLoginService;
import org.springframework.stereotype.Service;
/**
 * é‚®ä»¶è®¤è¯ç­–ç•¥
 *
 * @author Michelle.Chung
 */
@Slf4j
@Service("xcx" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class XcxAuthStrategy implements IAuthStrategy {
    private final SysLoginService loginService;
    @Override
    public void validate(LoginBody loginBody) {
        ValidatorUtils.validate(loginBody, WechatGroup.class);
    }
    @Override
    public LoginVo login(String clientId, LoginBody loginBody, SysClient client) {
        // xcxCode ä¸º å°ç¨‹åºè°ƒç”¨ wx.login æŽˆæƒåŽèŽ·å–
        String xcxCode = loginBody.getXcxCode();
        // todo ä»¥ä¸‹è‡ªè¡Œå®žçް
        // æ ¡éªŒ appid + appsrcret + xcxCode è°ƒç”¨ç™»å½•凭证校验接口 èŽ·å– session_key ä¸Ž openid
        String openid = "";
        // æ¡†æž¶ç™»å½•不限制从什么表查询 åªè¦æœ€ç»ˆæž„建出 LoginUser å³å¯
        SysUserVo user = loadUserByOpenid(openid);
        // æ­¤å¤„可根据登录用户的数据不同 è‡ªè¡Œåˆ›å»º loginUser å±žæ€§ä¸å¤Ÿç”¨ç»§æ‰¿æ‰©å±•就行了
        XcxLoginUser loginUser = new XcxLoginUser();
        loginUser.setTenantId(user.getTenantId());
        loginUser.setUserId(user.getUserId());
        loginUser.setUsername(user.getUserName());
        loginUser.setUserType(user.getUserType());
        loginUser.setOpenid(openid);
        SaLoginModel model = new SaLoginModel();
        model.setDevice(client.getDeviceType());
        // è‡ªå®šä¹‰åˆ†é… ä¸åŒç”¨æˆ·ä½“ç³» ä¸åŒ token æŽˆæƒæ—¶é—´ ä¸è®¾ç½®é»˜è®¤èµ°å…¨å±€ yml é…ç½®
        // ä¾‹å¦‚: åŽå°ç”¨æˆ·30分钟过期 app用户1天过期
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        // ç”Ÿæˆtoken
        LoginHelper.login(loginUser, model);
        loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
        loginService.recordLoginInfo(user.getUserId());
        LoginVo loginVo = new LoginVo();
        loginVo.setAccessToken(StpUtil.getTokenValue());
        return loginVo;
    }
    private SysUserVo loadUserByOpenid(String openid) {
        // ä½¿ç”¨ openid æŸ¥è¯¢ç»‘定用户 å¦‚未绑定用户 åˆ™æ ¹æ®ä¸šåŠ¡è‡ªè¡Œå¤„ç† ä¾‹å¦‚ åˆ›å»ºé»˜è®¤ç”¨æˆ·
        // todo è‡ªè¡Œå®žçް userService.selectUserByOpenid(openid);
        SysUserVo user = new SysUserVo();
        if (ObjectUtil.isNull(user)) {
            log.info("登录用户:{} ä¸å­˜åœ¨.", openid);
            // todo ç”¨æˆ·ä¸å­˜åœ¨ ä¸šåŠ¡é€»è¾‘è‡ªè¡Œå®žçŽ°
        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            log.info("登录用户:{} å·²è¢«åœç”¨.", openid);
            // todo ç”¨æˆ·å·²è¢«åœç”¨ ä¸šåŠ¡é€»è¾‘è‡ªè¡Œå®žçŽ°
        }
        return user;
    }
}
ruoyi-admin/src/main/resources/application.yml
@@ -140,6 +140,7 @@
    - sys_role_menu
    - sys_user_post
    - sys_user_role
    - sys_client
# MyBatisPlus配置
# https://baomidou.com/config/
ruoyi-admin/src/main/resources/i18n/messages.properties
@@ -28,6 +28,9 @@
user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=未知错误,请重新登录
auth.grant.type.error=认证权限类型错误
auth.grant.type.not.blank=认证权限类型不能为空
auth.clientid.not.blank=认证客户端id不能为空
##文件上传消息
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
upload.filename.exceed.length=上传的文件名最长{0}个字符
ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
@@ -28,6 +28,9 @@
user.notfound=Please login again
user.forcelogout=The administrator is forced to exit,please login again
user.unknown.error=Unknown error, please login again
auth.grant.type.error=Auth grant type error
auth.grant.type.not.blank=Auth grant type cannot be blank
auth.clientid.not.blank=Auth clientid cannot be blank
##文件上传消息
upload.exceed.maxSize=The uploaded file size exceeds the limit file size!<br/>the maximum allowed file size is:{0}MB!
upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters
ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
@@ -28,6 +28,9 @@
user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=未知错误,请重新登录
auth.grant.type.error=认证权限类型错误
auth.grant.type.not.blank=认证权限类型不能为空
auth.clientid.not.blank=认证客户端id不能为空
##文件上传消息
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
upload.filename.exceed.length=上传的文件名最长{0}个字符
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
@@ -1,7 +1,12 @@
package org.dromara.common.core.domain.model;
import jakarta.validation.constraints.Email;
import org.dromara.common.core.constant.UserConstants;
import lombok.Data;
import org.dromara.common.core.validate.auth.EmailGroup;
import org.dromara.common.core.validate.auth.PasswordGroup;
import org.dromara.common.core.validate.auth.SmsGroup;
import org.dromara.common.core.validate.auth.WechatGroup;
import org.hibernate.validator.constraints.Length;
import jakarta.validation.constraints.NotBlank;
@@ -16,6 +21,28 @@
public class LoginBody {
    /**
     * å®¢æˆ·ç«¯id
     */
    @NotBlank(message = "{auth.clientid.not.blank}")
    private String clientId;
    /**
     * å®¢æˆ·ç«¯key
     */
    private String clientKey;
    /**
     * å®¢æˆ·ç«¯ç§˜é’¥
     */
    private String clientSecret;
    /**
     * æŽˆæƒç±»åž‹
     */
    @NotBlank(message = "{auth.grant.type.not.blank}")
    private String grantType;
    /**
     * ç§Ÿæˆ·ID
     */
    @NotBlank(message = "{tenant.number.not.blank}")
@@ -24,15 +51,15 @@
    /**
     * ç”¨æˆ·å
     */
    @NotBlank(message = "{user.username.not.blank}")
    @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
    @NotBlank(message = "{user.username.not.blank}", groups = {PasswordGroup.class})
    @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}", groups = {PasswordGroup.class})
    private String username;
    /**
     * ç”¨æˆ·å¯†ç 
     */
    @NotBlank(message = "{user.password.not.blank}")
    @Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
    @NotBlank(message = "{user.password.not.blank}", groups = {PasswordGroup.class})
    @Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}", groups = {PasswordGroup.class})
    private String password;
    /**
@@ -45,4 +72,35 @@
     */
    private String uuid;
    /**
     * æ‰‹æœºå·
     */
    @NotBlank(message = "{user.phonenumber.not.blank}", groups = {SmsGroup.class})
    private String phonenumber;
    /**
     * çŸ­ä¿¡code
     */
    @NotBlank(message = "{sms.code.not.blank}", groups = {SmsGroup.class})
    private String smsCode;
    /**
     * é‚®ç®±
     */
    @NotBlank(message = "{user.email.not.blank}", groups = {EmailGroup.class})
    @Email(message = "{user.email.not.valid}")
    private String email;
    /**
     * é‚®ç®±code
     */
    @NotBlank(message = "{email.code.not.blank}", groups = {EmailGroup.class})
    private String emailCode;
    /**
     * å°ç¨‹åºcode
     */
    @NotBlank(message = "{xcx.code.not.blank}", groups = {WechatGroup.class})
    private String xcxCode;
}
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/auth/EmailGroup.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
package org.dromara.common.core.validate.auth;
/**
 * @Author Michelle.Chung
 */
public interface EmailGroup {
}
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/auth/PasswordGroup.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
package org.dromara.common.core.validate.auth;
/**
 * @Author Michelle.Chung
 */
public interface PasswordGroup {
}
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/auth/SmsGroup.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
package org.dromara.common.core.validate.auth;
/**
 * @Author Michelle.Chung
 */
public interface SmsGroup {
}
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/validate/auth/WechatGroup.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
package org.dromara.common.core.validate.auth;
/**
 * @Author Michelle.Chung
 */
public interface WechatGroup {
}
ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/convert/ExcelEnumConvert.java
@@ -37,14 +37,26 @@
    @Override
    public Object convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
        Object codeValue = cellData.getData();
        cellData.checkEmpty();
        // Excel中填入的是枚举中指定的描述
        Object textValue = switch (cellData.getType()) {
            case STRING, DIRECT_STRING, RICH_TEXT_STRING -> cellData.getStringValue();
            case NUMBER -> cellData.getNumberValue();
            case BOOLEAN -> cellData.getBooleanValue();
            default -> throw new IllegalArgumentException("单元格类型异常!");
        };
        // å¦‚果是空值
        if (ObjectUtil.isNull(codeValue)) {
        if (ObjectUtil.isNull(textValue)) {
            return null;
        }
        Map<Object, String> enumValueMap = beforeConvert(contentProperty);
        String textValue = enumValueMap.get(codeValue);
        return Convert.convert(contentProperty.getField().getType(), textValue);
        Map<Object, String> enumCodeToTextMap = beforeConvert(contentProperty);
        // ä»ŽJava输出至Excel是code转text
        // å› æ­¤ä»ŽExcel转Java应该将text与code对调
        Map<Object, Object> enumTextToCodeMap = new HashMap<>();
        enumCodeToTextMap.forEach((key, value) -> enumTextToCodeMap.put(value, key));
        // åº”该从text -> code中查找
        Object codeValue = enumTextToCodeMap.get(textValue);
        return Convert.convert(contentProperty.getField().getType(), codeValue);
    }
    @Override
ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
@@ -7,13 +7,12 @@
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.DeviceType;
import org.dromara.common.core.enums.UserType;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.Set;
@@ -37,40 +36,21 @@
    public static final String USER_KEY = "userId";
    /**
     * ç™»å½•系统
     *
     * @param loginUser ç™»å½•用户信息
     */
    public static void login(LoginUser loginUser) {
        loginByDevice(loginUser, null);
    }
    /**
     * ç™»å½•系统 åŸºäºŽ è®¾å¤‡ç±»åž‹
     * é’ˆå¯¹ç›¸åŒç”¨æˆ·ä½“系不同设备
     *
     * @param loginUser ç™»å½•用户信息
     * @param model     é…ç½®å‚æ•°
     */
    public static void loginByDevice(LoginUser loginUser, DeviceType deviceType) {
    public static void login(LoginUser loginUser, SaLoginModel model) {
        SaStorage storage = SaHolder.getStorage();
        storage.set(LOGIN_USER_KEY, loginUser);
        storage.set(TENANT_KEY, loginUser.getTenantId());
        storage.set(USER_KEY, loginUser.getUserId());
        SaLoginModel model = new SaLoginModel();
        if (ObjectUtil.isNotNull(deviceType)) {
            model.setDevice(deviceType.getDevice());
        }
        // è‡ªå®šä¹‰åˆ†é… ä¸åŒç”¨æˆ·ä½“ç³» ä¸åŒ token æŽˆæƒæ—¶é—´ ä¸è®¾ç½®é»˜è®¤èµ°å…¨å±€ yml é…ç½®
        // ä¾‹å¦‚: åŽå°ç”¨æˆ·30分钟过期 app用户1天过期
//        UserType userType = UserType.getUserType(loginUser.getUserType());
//        if (userType == UserType.SYS_USER) {
//            model.setTimeout(86400).setActiveTimeout(1800);
//        } else if (userType == UserType.APP_USER) {
//            model.setTimeout(86400).setActiveTimeout(1800);
//        }
        model = ObjectUtil.defaultIfNull(model, new SaLoginModel());
        StpUtil.login(loginUser.getLoginId(),
                model.setExtra(TENANT_KEY, loginUser.getTenantId())
                    .setExtra(USER_KEY, loginUser.getUserId()));
            model.setExtra(TENANT_KEY, loginUser.getTenantId())
                .setExtra(USER_KEY, loginUser.getUserId()));
        StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
    }
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysClientController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,115 @@
package org.dromara.system.controller.system;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.bo.SysClientBo;
import org.dromara.system.service.ISysClientService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
 * å®¢æˆ·ç«¯ç®¡ç†
 *
 * @author Michelle.Chung
 * @date 2023-06-18
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/client")
public class SysClientController extends BaseController {
    private final ISysClientService sysClientService;
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ç®¡ç†åˆ—表
     */
    @SaCheckPermission("system:client:list")
    @GetMapping("/list")
    public TableDataInfo<SysClientVo> list(SysClientBo bo, PageQuery pageQuery) {
        return sysClientService.queryPageList(bo, pageQuery);
    }
    /**
     * å¯¼å‡ºå®¢æˆ·ç«¯ç®¡ç†åˆ—表
     */
    @SaCheckPermission("system:client:export")
    @Log(title = "客户端管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(SysClientBo bo, HttpServletResponse response) {
        List<SysClientVo> list = sysClientService.queryList(bo);
        ExcelUtil.exportExcel(list, "客户端管理", SysClientVo.class, response);
    }
    /**
     * èŽ·å–å®¢æˆ·ç«¯ç®¡ç†è¯¦ç»†ä¿¡æ¯
     *
     * @param id ä¸»é”®
     */
    @SaCheckPermission("system:client:query")
    @GetMapping("/{id}")
    public R<SysClientVo> getInfo(@NotNull(message = "主键不能为空")
                                  @PathVariable Long id) {
        return R.ok(sysClientService.queryById(id));
    }
    /**
     * æ–°å¢žå®¢æˆ·ç«¯ç®¡ç†
     */
    @SaCheckPermission("system:client:add")
    @Log(title = "客户端管理", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysClientBo bo) {
        return toAjax(sysClientService.insertByBo(bo));
    }
    /**
     * ä¿®æ”¹å®¢æˆ·ç«¯ç®¡ç†
     */
    @SaCheckPermission("system:client:edit")
    @Log(title = "客户端管理", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysClientBo bo) {
        return toAjax(sysClientService.updateByBo(bo));
    }
    /**
     * çŠ¶æ€ä¿®æ”¹
     */
    @SaCheckPermission("system:client:edit")
    @Log(title = "客户端管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public R<Void> changeStatus(@RequestBody SysClientBo bo) {
        return toAjax(sysClientService.updateUserStatus(bo.getId(), bo.getStatus()));
    }
    /**
     * åˆ é™¤å®¢æˆ·ç«¯ç®¡ç†
     *
     * @param ids ä¸»é”®ä¸²
     */
    @SaCheckPermission("system:client:remove")
    @Log(title = "客户端管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(sysClientService.deleteWithValidByIds(List.of(ids), true));
    }
}
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysClient.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package org.dromara.system.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
 * æŽˆæƒç®¡ç†å¯¹è±¡ sys_client
 *
 * @author Michelle.Chung
 * @date 2023-05-15
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_client")
public class SysClient extends BaseEntity {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     * id
     */
    @TableId(value = "id")
    private Long id;
    /**
     * å®¢æˆ·ç«¯id
     */
    private String clientId;
    /**
     * å®¢æˆ·ç«¯key
     */
    private String clientKey;
    /**
     * å®¢æˆ·ç«¯ç§˜é’¥
     */
    private String clientSecret;
    /**
     * æŽˆæƒç±»åž‹
     */
    private String grantType;
    /**
     * è®¾å¤‡ç±»åž‹
     */
    private String deviceType;
    /**
     * token活跃超时时间
     */
    private Long activeTimeout;
    /**
     * token固定超时时间
     */
    private Long timeout;
    /**
     * çŠ¶æ€ï¼ˆ0正常 1停用)
     */
    private String status;
    /**
     * åˆ é™¤æ ‡å¿—(0代表存在 2代表删除)
     */
    @TableLogic
    private String delFlag;
}
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysClientBo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
package org.dromara.system.domain.bo;
import org.dromara.system.domain.SysClient;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.List;
/**
 * æŽˆæƒç®¡ç†ä¸šåŠ¡å¯¹è±¡ sys_client
 *
 * @author Michelle.Chung
 * @date 2023-05-15
 */
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SysClient.class, reverseConvertGenerate = false)
public class SysClientBo extends BaseEntity {
    /**
     * id
     */
    @NotNull(message = "id不能为空", groups = { EditGroup.class })
    private Long id;
    /**
     * å®¢æˆ·ç«¯id
     */
    private String clientId;
    /**
     * å®¢æˆ·ç«¯key
     */
    @NotBlank(message = "客户端key不能为空", groups = { AddGroup.class, EditGroup.class })
    private String clientKey;
    /**
     * å®¢æˆ·ç«¯ç§˜é’¥
     */
    @NotBlank(message = "客户端秘钥不能为空", groups = { AddGroup.class, EditGroup.class })
    private String clientSecret;
    /**
     * æŽˆæƒç±»åž‹
     */
    @NotNull(message = "授权类型不能为空", groups = { AddGroup.class, EditGroup.class })
    private List<String> grantTypeList;
    /**
     * æŽˆæƒç±»åž‹
     */
    private String grantType;
    /**
     * è®¾å¤‡ç±»åž‹
     */
    private String deviceType;
    /**
     * token活跃超时时间
     */
    private Long activeTimeout;
    /**
     * token固定超时时间
     */
    private Long timeout;
    /**
     * çŠ¶æ€ï¼ˆ0正常 1停用)
     */
    private String status;
}
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysClientVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
package org.dromara.system.domain.vo;
import org.dromara.system.domain.SysClient;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
 * æŽˆæƒç®¡ç†è§†å›¾å¯¹è±¡ sys_client
 *
 * @author Michelle.Chung
 * @date 2023-05-15
 */
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = SysClient.class)
public class SysClientVo implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     * id
     */
    @ExcelProperty(value = "id")
    private Long id;
    /**
     * å®¢æˆ·ç«¯id
     */
    @ExcelProperty(value = "客户端id")
    private String clientId;
    /**
     * å®¢æˆ·ç«¯key
     */
    @ExcelProperty(value = "客户端key")
    private String clientKey;
    /**
     * å®¢æˆ·ç«¯ç§˜é’¥
     */
    @ExcelProperty(value = "客户端秘钥")
    private String clientSecret;
    /**
     * æŽˆæƒç±»åž‹
     */
    @ExcelProperty(value = "授权类型")
    private List<String> grantTypeList;
    /**
     * æŽˆæƒç±»åž‹
     */
    private String grantType;
    /**
     * è®¾å¤‡ç±»åž‹
     */
    private String deviceType;
    /**
     * token活跃超时时间
     */
    @ExcelProperty(value = "token活跃超时时间")
    private Long activeTimeout;
    /**
     * token固定超时时间
     */
    @ExcelProperty(value = "token固定超时时间")
    private Long timeout;
    /**
     * çŠ¶æ€ï¼ˆ0正常 1停用)
     */
    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
    private String status;
}
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysClientMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package org.dromara.system.mapper;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
 * æŽˆæƒç®¡ç†Mapper接口
 *
 * @author Michelle.Chung
 * @date 2023-05-15
 */
public interface SysClientMapper extends BaseMapperPlus<SysClient, SysClientVo> {
}
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysClientService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package org.dromara.system.service;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.bo.SysClientBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
 * å®¢æˆ·ç«¯ç®¡ç†Service接口
 *
 * @author Michelle.Chung
 * @date 2023-06-18
 */
public interface ISysClientService {
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ç®¡ç†
     */
    SysClientVo queryById(Long id);
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ä¿¡æ¯åŸºäºŽå®¢æˆ·ç«¯id
     */
    SysClient queryByClientId(String clientId);
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ç®¡ç†åˆ—表
     */
    TableDataInfo<SysClientVo> queryPageList(SysClientBo bo, PageQuery pageQuery);
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ç®¡ç†åˆ—表
     */
    List<SysClientVo> queryList(SysClientBo bo);
    /**
     * æ–°å¢žå®¢æˆ·ç«¯ç®¡ç†
     */
    Boolean insertByBo(SysClientBo bo);
    /**
     * ä¿®æ”¹å®¢æˆ·ç«¯ç®¡ç†
     */
    Boolean updateByBo(SysClientBo bo);
    /**
     * ä¿®æ”¹çŠ¶æ€
     */
    int updateUserStatus(Long id, String status);
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤å®¢æˆ·ç«¯ç®¡ç†ä¿¡æ¯
     */
    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysClientServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
package org.dromara.system.service.impl;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.SysClient;
import org.dromara.system.domain.bo.SysClientBo;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.mapper.SysClientMapper;
import org.dromara.system.service.ISysClientService;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
 * å®¢æˆ·ç«¯ç®¡ç†Service业务层处理
 *
 * @author Michelle.Chung
 * @date 2023-06-18
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysClientServiceImpl implements ISysClientService {
    private final SysClientMapper baseMapper;
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ç®¡ç†
     */
    @Override
    public SysClientVo queryById(Long id) {
        SysClientVo vo = baseMapper.selectVoById(id);
        vo.setGrantTypeList(List.of(vo.getGrantType().split(",")));
        return vo;
    }
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ç®¡ç†
     */
    @Override
    public SysClient queryByClientId(String clientId) {
        return baseMapper.selectOne(new LambdaQueryWrapper<SysClient>().eq(SysClient::getClientId, clientId));
    }
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ç®¡ç†åˆ—表
     */
    @Override
    public TableDataInfo<SysClientVo> queryPageList(SysClientBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SysClient> lqw = buildQueryWrapper(bo);
        Page<SysClientVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        result.getRecords().forEach(r -> r.setGrantTypeList(List.of(r.getGrantType().split(","))));
        return TableDataInfo.build(result);
    }
    /**
     * æŸ¥è¯¢å®¢æˆ·ç«¯ç®¡ç†åˆ—表
     */
    @Override
    public List<SysClientVo> queryList(SysClientBo bo) {
        LambdaQueryWrapper<SysClient> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }
    private LambdaQueryWrapper<SysClient> buildQueryWrapper(SysClientBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SysClient> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getClientId()), SysClient::getClientId, bo.getClientId());
        lqw.eq(StringUtils.isNotBlank(bo.getClientKey()), SysClient::getClientKey, bo.getClientKey());
        lqw.eq(StringUtils.isNotBlank(bo.getClientSecret()), SysClient::getClientSecret, bo.getClientSecret());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysClient::getStatus, bo.getStatus());
        return lqw;
    }
    /**
     * æ–°å¢žå®¢æˆ·ç«¯ç®¡ç†
     */
    @Override
    public Boolean insertByBo(SysClientBo bo) {
        SysClient add = MapstructUtils.convert(bo, SysClient.class);
        validEntityBeforeSave(add);
        add.setGrantType(String.join(",", bo.getGrantTypeList()));
        // ç”Ÿæˆclientid
        String clientKey = bo.getClientKey();
        String clientSecret = bo.getClientSecret();
        add.setClientId(SecureUtil.md5(clientKey + clientSecret));
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }
    /**
     * ä¿®æ”¹å®¢æˆ·ç«¯ç®¡ç†
     */
    @Override
    public Boolean updateByBo(SysClientBo bo) {
        SysClient update = MapstructUtils.convert(bo, SysClient.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }
    /**
     * ä¿®æ”¹çŠ¶æ€
     */
    @Override
    public int updateUserStatus(Long id, String status) {
        return baseMapper.update(null,
            new LambdaUpdateWrapper<SysClient>()
                .set(SysClient::getStatus, status)
                .eq(SysClient::getId, id));
    }
    /**
     * ä¿å­˜å‰çš„æ•°æ®æ ¡éªŒ
     */
    private void validEntityBeforeSave(SysClient entity) {
        //TODO åšä¸€äº›æ•°æ®æ ¡éªŒ,如唯一约束
    }
    /**
     * æ‰¹é‡åˆ é™¤å®¢æˆ·ç«¯ç®¡ç†
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO åšä¸€äº›ä¸šåŠ¡ä¸Šçš„æ ¡éªŒ,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
@@ -453,6 +453,11 @@
    @Override
    public void cleanOnlineUserByRole(Long roleId) {
        // å¦‚果角色未绑定用户 ç›´æŽ¥è¿”回
        Long num = userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
        if (num == 0) {
            return;
        }
        List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
        if (CollUtil.isEmpty(keys)) {
            return;
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysClientMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?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="org.dromara.system.mapper.SysClientMapper">
</mapper>
script/sql/oracle/oracle_ry_vue_5.X.sql
@@ -439,7 +439,8 @@
insert into sys_menu values('114',  '表单构建',     '3',   '1', 'build',            'tool/build/index',             '', 1, 0, 'C', '0', '0', 'tool:build:list',             'build',         103, 1, sysdate, null, null, '表单构建菜单');
insert into sys_menu values('115',  '代码生成',     '3',   '2', 'gen',              'tool/gen/index',               '', 1, 0, 'C', '0', '0', 'tool:gen:list',               'code',          103, 1, sysdate, null, null, '代码生成菜单');
insert into sys_menu values('121',  '租户管理',     '6',   '1', 'tenant',           'system/tenant/index',          '', 1, 0, 'C', '0', '0', 'system:tenant:list',          'list',          103, 1, sysdate, null, null, '租户管理菜单');
insert into sys_menu values('122',  '租户套餐管理',  '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, sysdate, null, null, '租户套餐管理菜单');
insert into sys_menu values('122',  '租户套餐管理', '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, sysdate, null, null, '租户套餐管理菜单');
insert into sys_menu values('123',  '客户端管理',   '1',   '1', 'client',           'system/client/index',          '', 1, 0, 'C', '0', '0', 'system:client:list',          'international', 103, 1, sysdate, null, null, '客户端管理菜单');
-- springboot-admin监控
insert into sys_menu values('117',  'Admin监控',   '2',    '5', 'Admin',            'monitor/admin/index',         '', 1, 0, 'C', '0', '0', 'monitor:admin:list',          'dashboard',     103, 1, sysdate, null, null, 'Admin监控菜单');
-- oss菜单
@@ -536,7 +537,12 @@
insert into sys_menu values('1613', '租户套餐修改', '122', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenantPackage:edit',    '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1614', '租户套餐删除', '122', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenantPackage:remove',  '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1615', '租户套餐导出', '122', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenantPackage:export',  '#', 103, 1, sysdate, null, null, '');
-- å®¢æˆ·ç«¯ç®¡ç†æŒ‰é’®
insert into sys_menu values('1061', '客户端管理查询', '123', '1',  '#', '', 1, 0, 'F', '0', '0', 'system:client:query',        '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1062', '客户端管理新增', '123', '2',  '#', '', 1, 0, 'F', '0', '0', 'system:client:add',          '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1063', '客户端管理修改', '123', '3',  '#', '', 1, 0, 'F', '0', '0', 'system:client:edit',         '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1064', '客户端管理删除', '123', '4',  '#', '', 1, 0, 'F', '0', '0', 'system:client:remove',       '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1065', '客户端管理导出', '123', '5',  '#', '', 1, 0, 'F', '0', '0', 'system:client:export',       '#', 103, 1, sysdate, null, null, '');
-- ----------------------------
-- 6、用户和角色关联表  ç”¨æˆ·N-1角色
@@ -655,6 +661,11 @@
insert into sys_role_menu values ('2', '1058');
insert into sys_role_menu values ('2', '1059');
insert into sys_role_menu values ('2', '1060');
insert into sys_role_menu values ('2', '1061');
insert into sys_role_menu values ('2', '1062');
insert into sys_role_menu values ('2', '1063');
insert into sys_role_menu values ('2', '1064');
insert into sys_role_menu values ('2', '1065');
-- ----------------------------
-- 8、角色和部门关联表  è§’色1-N部门
@@ -789,7 +800,9 @@
insert into sys_dict_type values(7, '000000', '通知类型', 'sys_notice_type',     '0', 103, 1, sysdate, null, null, '通知类型列表');
insert into sys_dict_type values(8, '000000', '通知状态', 'sys_notice_status',   '0', 103, 1, sysdate, null, null, '通知状态列表');
insert into sys_dict_type values(9, '000000', '操作类型', 'sys_oper_type',       '0', 103, 1, sysdate, null, null, '操作类型列表');
insert into sys_dict_type values(10, '000000', '系统状态', 'sys_common_status',   '0', 103, 1, sysdate, null, null, '登录状态列表');
insert into sys_dict_type values(10, '000000', '系统状态', 'sys_common_status',  '0', 103, 1, sysdate, null, null, '登录状态列表');
insert into sys_dict_type values(11, '000000', '授权类型', 'sys_grant_type',     '0', 103, 1, sysdate, null, null, '认证授权类型');
insert into sys_dict_type values(12, '000000', '设备类型', 'sys_device_type',    '0', 103, 1, sysdate, null, null, '客户端设备类型');
-- ----------------------------
@@ -859,6 +872,13 @@
insert into sys_dict_data values(26, '000000', 9,  '清空数据', '9',       'sys_oper_type',       '',   'danger',  'N', '0', 103, 1, sysdate, null, null, '清空操作');
insert into sys_dict_data values(27, '000000', 1,  '成功',     '0',       'sys_common_status',   '',   'primary', 'N', '0', 103, 1, sysdate, null, null, '正常状态');
insert into sys_dict_data values(28, '000000', 2,  '失败',     '1',       'sys_common_status',   '',   'danger',  'N', '0', 103, 1, sysdate, null, null, '停用状态');
insert into sys_dict_data values(30, '000000', 0,  '密码认证', 'password',   'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '密码认证');
insert into sys_dict_data values(31, '000000', 0,  '短信认证', 'sms',        'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '短信认证');
insert into sys_dict_data values(32, '000000', 0,  '邮件认证', 'email',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '邮件认证');
insert into sys_dict_data values(33, '000000', 0,  '小程序认证', 'xcx',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '小程序认证');
insert into sys_dict_data values(34, '000000', 0,  '三方登录认证', 'social', 'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '三方登录认证');
insert into sys_dict_data values(35, '000000', 0,  'PC端',      'pc',        'sys_device_type',  '',   'default', 'N', '0', 103, 1, sysdate, null, null, 'PC端');
insert into sys_dict_data values(36, '000000', 0,  'APP端',     'app',       'sys_device_type',  '',   'default', 'N', '0', 103, 1, sysdate, null, null, 'APP端');
-- ----------------------------
@@ -1178,6 +1198,49 @@
insert into sys_oss_config values (4, '000000', 'qcloud', 'XXXXXXXXXXXXXXX',  'XXXXXXXXXXXXXXX', 'ruoyi-1250000000',  '', 'cos.ap-beijing.myqcloud.com',   '','N', 'ap-beijing',  '1', '1', '', NULL, 103, 1, sysdate, 1, sysdate);
insert into sys_oss_config values (5, '000000', 'image',  'ruoyi',            'ruoyi123',        'ruoyi',             'image', '127.0.0.1:9000',           '','N', '',            '1', '1', '', NULL, 103, 1, sysdate, 1, sysdate);
-- ----------------------------
-- ç³»ç»ŸæŽˆæƒè¡¨
-- ----------------------------
create table sys_client (
    id                  number(20)    not null,
    client_id           varchar(64)   default null,
    client_key          varchar(32)   default null,
    client_secret       varchar(255)  default null,
    grant_type          varchar(255)  default null,
    device_type         varchar(32)   default null,
    active_timeout      number(11)    default 1800,
    timeout             number(11)    default 604800,
    status              char(1)       default '0',
    del_flag            char(1)       default '0',
    create_dept         number(20)    default null,
    create_by           number(20)    default null,
    create_time         date,
    update_by           number(20)    default null,
    update_time         date
)
alter table sys_client add constraint pk_sys_client primary key (id);
comment on table sys_client                         is '系统授权表';
comment on column sys_client.id                     is '主建';
comment on column sys_client.client_id              is '客户端id';
comment on column sys_client.client_key             is '客户端key';
comment on column sys_client.client_secret          is '客户端秘钥';
comment on column sys_client.grant_type             is '授权类型';
comment on column sys_client.device_type            is '设备类型';
comment on column sys_client.active_timeout         is 'token活跃超时时间';
comment on column sys_client.timeout                is 'token固定超时';
comment on column sys_client.status                 is '状态(0正常 1停用)';
comment on column sys_client.del_flag               is '删除标志(0代表存在 2代表删除)';
comment on column sys_client.create_dept            is '创建部门';
comment on column sys_client.create_by              is '创建者';
comment on column sys_client.create_time            is '创建时间';
comment on column sys_client.update_by              is '更新者';
comment on column sys_client.update_time            is '更新时间';
insert into sys_client values (1, 'e5cd7e4891bf95d1d19206ce24a7b32e', 'pc', 'pc123', 'password,social', 'pc', 1800, 604800, 0, 0, 103, 1, sysdate, 1, sysdate);
insert into sys_client values (2, '428a8310cd442757ae699df5d894f051', 'app', 'app123', 'password,sms,social', 'app', 1800, 604800, 0, 0, 103, 1, sysdate, 1, sysdate);
-- ----------------------------
-- é’©å­ ï¼Œç”¨äºŽsession连接之后 è‡ªåŠ¨è®¾ç½®é»˜è®¤çš„date类型格式化 ç®€åŒ–时间查询
script/sql/postgres/postgres_ry_vue_5.X.sql
@@ -447,7 +447,8 @@
insert into sys_menu values('114',  '表单构建',     '3',   '1', 'build',            'tool/build/index',             '', '1', '0', 'C', '0', '0', 'tool:build:list',             'build',         103, 1, now(), null, null, '表单构建菜单');
insert into sys_menu values('115',  '代码生成',     '3',   '2', 'gen',              'tool/gen/index',               '', '1', '0', 'C', '0', '0', 'tool:gen:list',               'code',          103, 1, now(), null, null, '代码生成菜单');
insert into sys_menu values('121',  '租户管理',     '6',   '1', 'tenant',           'system/tenant/index',          '', '1', '0', 'C', '0', '0', 'system:tenant:list',          'list',          103, 1, now(), null, null, '租户管理菜单');
insert into sys_menu values('122',  '租户套餐管理',  '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', '1', '0', 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, now(), null, null, '租户套餐管理菜单');
insert into sys_menu values('122',  '租户套餐管理', '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', '1', '0', 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, now(), null, null, '租户套餐管理菜单');
insert into sys_menu values('123',  '客户端管理',   '1',   '1', 'client',           'system/client/index',          '', '1', '0', 'C', '0', '0', 'system:client:list',          'international', 103, 1, now(), null, null, '客户端管理菜单');
-- springboot-admin监控
insert into sys_menu values('117',  'Admin监控',   '2',   '5',  'Admin',            'monitor/admin/index',         '', '1', '0', 'C', '0', '0', 'monitor:admin:list',          'dashboard',     103, 1, now(), null, null, 'Admin监控菜单');
@@ -545,7 +546,12 @@
insert into sys_menu values('1613', '租户套餐修改', '122', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:tenantPackage:edit',    '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1614', '租户套餐删除', '122', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:tenantPackage:remove',  '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1615', '租户套餐导出', '122', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:tenantPackage:export',  '#', 103, 1, now(), null, null, '');
-- å®¢æˆ·ç«¯ç®¡ç†æŒ‰é’®
insert into sys_menu values('1061', '客户端管理查询', '123', '1',  '#', '', '1', '0', 'F', '0', '0', 'system:client:query',        '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1062', '客户端管理新增', '123', '2',  '#', '', '1', '0', 'F', '0', '0', 'system:client:add',          '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1063', '客户端管理修改', '123', '3',  '#', '', '1', '0', 'F', '0', '0', 'system:client:edit',         '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1064', '客户端管理删除', '123', '4',  '#', '', '1', '0', 'F', '0', '0', 'system:client:remove',       '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1065', '客户端管理导出', '123', '5',  '#', '', '1', '0', 'F', '0', '0', 'system:client:export',       '#', 103, 1, now(), null, null, '');
-- ----------------------------
-- 6、用户和角色关联表  ç”¨æˆ·N-1角色
@@ -666,6 +672,11 @@
insert into sys_role_menu values ('2', '1058');
insert into sys_role_menu values ('2', '1059');
insert into sys_role_menu values ('2', '1060');
insert into sys_role_menu values ('2', '1061');
insert into sys_role_menu values ('2', '1062');
insert into sys_role_menu values ('2', '1063');
insert into sys_role_menu values ('2', '1064');
insert into sys_role_menu values ('2', '1065');
-- ----------------------------
-- 8、角色和部门关联表  è§’色1-N部门
@@ -805,8 +816,9 @@
insert into sys_dict_type values(7, '000000', '通知类型', 'sys_notice_type',     '0', 103, 1, now(), null, null, '通知类型列表');
insert into sys_dict_type values(8, '000000', '通知状态', 'sys_notice_status',   '0', 103, 1, now(), null, null, '通知状态列表');
insert into sys_dict_type values(9, '000000', '操作类型', 'sys_oper_type',       '0', 103, 1, now(), null, null, '操作类型列表');
insert into sys_dict_type values(10, '000000', '系统状态', 'sys_common_status',   '0', 103, 1, now(), null, null, '登录状态列表');
insert into sys_dict_type values(10, '000000', '系统状态', 'sys_common_status',  '0', 103, 1, now(), null, null, '登录状态列表');
insert into sys_dict_type values(11, '000000', '授权类型', 'sys_grant_type',     '0', 103, 1, now(), null, null, '认证授权类型');
insert into sys_dict_type values(12, '000000', '设备类型', 'sys_device_type',    '0', 103, 1, now(), null, null, '客户端设备类型');
-- ----------------------------
-- 12、字典数据表
@@ -876,6 +888,13 @@
insert into sys_dict_data values(26, '000000', 9,  '清空数据', '9',       'sys_oper_type',       '',   'danger',  'N', '0', 103, 1, now(), null, null, '清空操作');
insert into sys_dict_data values(27, '000000', 1,  '成功',     '0',       'sys_common_status',   '',   'primary', 'N', '0', 103, 1, now(), null, null, '正常状态');
insert into sys_dict_data values(28, '000000', 2,  '失败',     '1',       'sys_common_status',   '',   'danger',  'N', '0', 103, 1, now(), null, null, '停用状态');
insert into sys_dict_data values(30, '000000', 0,  '密码认证', 'password',   'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '密码认证');
insert into sys_dict_data values(31, '000000', 0,  '短信认证', 'sms',        'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '短信认证');
insert into sys_dict_data values(32, '000000', 0,  '邮件认证', 'email',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '邮件认证');
insert into sys_dict_data values(33, '000000', 0,  '小程序认证', 'xcx',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '小程序认证');
insert into sys_dict_data values(34, '000000', 0,  '三方登录认证', 'social', 'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '三方登录认证');
insert into sys_dict_data values(35, '000000', 0,  'PC端', 'pc',            'sys_device_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, 'PC端');
insert into sys_dict_data values(36, '000000', 0,  'APP端', 'app',          'sys_device_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, 'APP端');
-- ----------------------------
@@ -1200,6 +1219,49 @@
insert into sys_oss_config values (4, '000000', 'qcloud', 'XXXXXXXXXXXXXXX',  'XXXXXXXXXXXXXXX', 'ruoyi-1250000000',  '', 'cos.ap-beijing.myqcloud.com',         '','N', 'ap-beijing',  '1', '1', '', 103, 1, now(), 1, now(), null);
insert into sys_oss_config values (5, '000000', 'image',  'ruoyi',            'ruoyi123',        'ruoyi',             'image', '127.0.0.1:9000',                 '','N', '',            '1', '1', '', 103, 1, now(), 1, now(), NULL);
-- ----------------------------
-- ç³»ç»ŸæŽˆæƒè¡¨
-- ----------------------------
drop table if exists sys_client;
create table sys_client (
    id                  int8,
    client_id           varchar(64)   ''::varchar,
    client_key          varchar(32)   ''::varchar,
    client_secret       varchar(255)  ''::varchar,
    grant_type          varchar(255)  ''::varchar,
    device_type         varchar(32)   ''::varchar,
    active_timeout      int4          default 1800,
    timeout             int4          default 604800,
    status              char(1)       default '0'::bpchar,
    del_flag            char(1)       default '0'::bpchar,
    create_dept         int8,
    create_by           int8,
    create_time         timestamp,
    update_by           int8,
    update_time         timestamp,
    constraint sys_client_pk primary key (id)
)
comment on table sys_client                         is '系统授权表';
comment on column sys_client.id                     is '主建';
comment on column sys_client.client_id              is '客户端id';
comment on column sys_client.client_key             is '客户端key';
comment on column sys_client.client_secret          is '客户端秘钥';
comment on column sys_client.grant_type             is '授权类型';
comment on column sys_client.device_type            is '设备类型';
comment on column sys_client.active_timeout         is 'token活跃超时时间';
comment on column sys_client.timeout                is 'token固定超时';
comment on column sys_client.status                 is '状态(0正常 1停用)';
comment on column sys_client.del_flag               is '删除标志(0代表存在 2代表删除)';
comment on column sys_client.create_dept            is '创建部门';
comment on column sys_client.create_by              is '创建者';
comment on column sys_client.create_time            is '创建时间';
comment on column sys_client.update_by              is '更新者';
comment on column sys_client.update_time            is '更新时间';
insert into sys_client values (1, 'e5cd7e4891bf95d1d19206ce24a7b32e', 'pc', 'pc123', 'password,social', 'pc', 1800, 604800, 0, 0, 103, 1, now(), 1, now());
insert into sys_client values (2, '428a8310cd442757ae699df5d894f051', 'app', 'app123', 'password,sms,social', 'app', 1800, 604800, 0, 0, 103, 1, now(), 1, now());
-- å­—符串自动转时间 é¿å…æ¡†æž¶æ—¶é—´æŸ¥è¯¢æŠ¥é”™é—®é¢˜
create or replace function cast_varchar_to_timestamp(varchar) returns timestamptz as $$
select to_timestamp($1, 'yyyy-mm-dd hh24:mi:ss');
script/sql/ry_vue_5.X.sql
@@ -283,8 +283,9 @@
insert into sys_menu values('113',  '缓存监控',     '2',   '5', 'cache',            'monitor/cache/index',          '', 1, 0, 'C', '0', '0', 'monitor:cache:list',          'redis',         103, 1, sysdate(), null, null, '缓存监控菜单');
insert into sys_menu values('114',  '表单构建',     '3',   '1', 'build',            'tool/build/index',             '', 1, 0, 'C', '0', '0', 'tool:build:list',             'build',         103, 1, sysdate(), null, null, '表单构建菜单');
insert into sys_menu values('115',  '代码生成',     '3',   '2', 'gen',              'tool/gen/index',               '', 1, 0, 'C', '0', '0', 'tool:gen:list',               'code',          103, 1, sysdate(), null, null, '代码生成菜单');
insert into sys_menu values ('121', '租户管理',     '6',   '1', 'tenant',           'system/tenant/index',          '', 1, 0, 'C', '0', '0', 'system:tenant:list',          'list',          103, 1, sysdate(), null, null, '租户管理菜单');
insert into sys_menu values ('122', '租户套餐管理',  '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, sysdate(), null, null, '租户套餐管理菜单');
insert into sys_menu values('121',  '租户管理',     '6',   '1', 'tenant',           'system/tenant/index',          '', 1, 0, 'C', '0', '0', 'system:tenant:list',          'list',          103, 1, sysdate(), null, null, '租户管理菜单');
insert into sys_menu values('122',  '租户套餐管理', '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, sysdate(), null, null, '租户套餐管理菜单');
insert into sys_menu values('123',  '客户端管理',   '1',   '1', 'client',           'system/client/index',          '', 1, 0, 'C', '0', '0', 'system:client:list',          'international', 103, 1, sysdate(), null, null, '客户端管理菜单');
-- springboot-admin监控
insert into sys_menu values('117',  'Admin监控',   '2',   '5',  'Admin',            'monitor/admin/index',         '', 1, 0, 'C', '0', '0', 'monitor:admin:list',           'dashboard',     103, 1, sysdate(), null, null, 'Admin监控菜单');
@@ -382,7 +383,12 @@
insert into sys_menu values ('1613', '租户套餐修改', '122', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenantPackage:edit',    '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values ('1614', '租户套餐删除', '122', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenantPackage:remove',  '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values ('1615', '租户套餐导出', '122', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenantPackage:export',  '#', 103, 1, sysdate(), null, null, '');
-- å®¢æˆ·ç«¯ç®¡ç†æŒ‰é’®
insert into sys_menu values('1061', '客户端管理查询', '123', '1',  '#', '', 1, 0, 'F', '0', '0', 'system:client:query',        '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1062', '客户端管理新增', '123', '2',  '#', '', 1, 0, 'F', '0', '0', 'system:client:add',          '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1063', '客户端管理修改', '123', '3',  '#', '', 1, 0, 'F', '0', '0', 'system:client:edit',         '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1064', '客户端管理删除', '123', '4',  '#', '', 1, 0, 'F', '0', '0', 'system:client:remove',       '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1065', '客户端管理导出', '123', '5',  '#', '', 1, 0, 'F', '0', '0', 'system:client:export',       '#', 103, 1, sysdate(), null, null, '');
-- ----------------------------
-- 6、用户和角色关联表  ç”¨æˆ·N-1角色
@@ -493,6 +499,11 @@
insert into sys_role_menu values ('2', '1058');
insert into sys_role_menu values ('2', '1059');
insert into sys_role_menu values ('2', '1060');
insert into sys_role_menu values ('2', '1061');
insert into sys_role_menu values ('2', '1062');
insert into sys_role_menu values ('2', '1063');
insert into sys_role_menu values ('2', '1064');
insert into sys_role_menu values ('2', '1065');
-- ----------------------------
-- 8、角色和部门关联表  è§’色1-N部门
@@ -588,7 +599,9 @@
insert into sys_dict_type values(7, '000000', '通知类型', 'sys_notice_type',     '0', 103, 1, sysdate(), null, null, '通知类型列表');
insert into sys_dict_type values(8, '000000', '通知状态', 'sys_notice_status',   '0', 103, 1, sysdate(), null, null, '通知状态列表');
insert into sys_dict_type values(9, '000000', '操作类型', 'sys_oper_type',       '0', 103, 1, sysdate(), null, null, '操作类型列表');
insert into sys_dict_type values(10, '000000', '系统状态', 'sys_common_status',   '0', 103, 1, sysdate(), null, null, '登录状态列表');
insert into sys_dict_type values(10, '000000', '系统状态', 'sys_common_status',  '0', 103, 1, sysdate(), null, null, '登录状态列表');
insert into sys_dict_type values(11, '000000', '授权类型', 'sys_grant_type',     '0', 103, 1, sysdate(), null, null, '认证授权类型');
insert into sys_dict_type values(12, '000000', '设备类型', 'sys_device_type',    '0', 103, 1, sysdate(), null, null, '客户端设备类型');
-- ----------------------------
@@ -641,6 +654,13 @@
insert into sys_dict_data values(26, '000000', 9,  '清空数据', '9',       'sys_oper_type',       '',   'danger',  'N', '0', 103, 1, sysdate(), null, null, '清空操作');
insert into sys_dict_data values(27, '000000', 1,  '成功',     '0',       'sys_common_status',   '',   'primary', 'N', '0', 103, 1, sysdate(), null, null, '正常状态');
insert into sys_dict_data values(28, '000000', 2,  '失败',     '1',       'sys_common_status',   '',   'danger',  'N', '0', 103, 1, sysdate(), null, null, '停用状态');
insert into sys_dict_data values(30, '000000', 0,  '密码认证', 'password',   'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '密码认证');
insert into sys_dict_data values(31, '000000', 0,  '短信认证', 'sms',        'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '短信认证');
insert into sys_dict_data values(32, '000000', 0,  '邮件认证', 'email',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '邮件认证');
insert into sys_dict_data values(33, '000000', 0,  '小程序认证', 'xcx',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '小程序认证');
insert into sys_dict_data values(34, '000000', 0,  '三方登录认证', 'social', 'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '三方登录认证');
insert into sys_dict_data values(35, '000000', 0,  'PC端', 'pc',          'sys_device_type',     '',   'default', 'N', '0', 103, 1, sysdate(), null, null, 'PC端');
insert into sys_dict_data values(36, '000000', 0,  'APP端', 'app',        'sys_device_type',     '',   'default', 'N', '0', 103, 1, sysdate(), null, null, 'APP端');
-- ----------------------------
@@ -833,3 +853,29 @@
insert into sys_oss_config values (3, '000000', 'aliyun', 'XXXXXXXXXXXXXXX',  'XXXXXXXXXXXXXXX', 'ruoyi',             '', 'oss-cn-beijing.aliyuncs.com',   '','N', '',             '1' ,'1', '', 103, 1, sysdate(), 1, sysdate(), null);
insert into sys_oss_config values (4, '000000', 'qcloud', 'XXXXXXXXXXXXXXX',  'XXXXXXXXXXXXXXX', 'ruoyi-1250000000',  '', 'cos.ap-beijing.myqcloud.com',   '','N', 'ap-beijing',   '1' ,'1', '', 103, 1, sysdate(), 1, sysdate(), null);
insert into sys_oss_config values (5, '000000', 'image',  'ruoyi',            'ruoyi123',        'ruoyi',             'image', '127.0.0.1:9000',           '','N', '',             '1' ,'1', '', 103, 1, sysdate(), 1, sysdate(), null);
-- ----------------------------
-- ç³»ç»ŸæŽˆæƒè¡¨
-- ----------------------------
drop table if exists sys_client;
create table sys_client (
    id                  bigint(20)    not null            comment 'id',
    client_id           varchar(64)   default null        comment '客户端id',
    client_key          varchar(32)   default null        comment '客户端key',
    client_secret       varchar(255)  default null        comment '客户端秘钥',
    grant_type          varchar(255)  default null        comment '授权类型',
    device_type         varchar(32)   default null        comment '设备类型',
    active_timeout      int(11)       default 1800        comment 'token活跃超时时间',
    timeout             int(11)       default 604800      comment 'token固定超时',
    status              char(1)       default '0'         comment '状态(0正常 1停用)',
    del_flag            char(1)       default '0'         comment '删除标志(0代表存在 2代表删除)',
    create_dept         bigint(20)    default null        comment '创建部门',
    create_by           bigint(20)    default null        comment '创建者',
    create_time         datetime      default null        comment '创建时间',
    update_by           bigint(20)    default null        comment '更新者',
    update_time         datetime      default null        comment '更新时间',
    primary key (id)
) engine=innodb comment='系统授权表';
insert into sys_client values (1, 'e5cd7e4891bf95d1d19206ce24a7b32e', 'pc', 'pc123', 'password,social', 'pc', 1800, 604800, 0, 0, 103, 1, sysdate(), 1, sysdate());
insert into sys_client values (2, '428a8310cd442757ae699df5d894f051', 'app', 'app123', 'password,sms,social', 'app', 1800, 604800, 0, 0, 103, 1, sysdate(), 1, sysdate());
script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
@@ -1259,6 +1259,20 @@
GO
INSERT sys_dict_data VALUES (28, N'000000', 2, N'失败', N'1', N'sys_common_status', N'', N'danger', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'停用状态')
GO
INSERT sys_dict_data VALUES (30, N'000000', 0, N'密码认证', N'password', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'密码认证')
GO
INSERT sys_dict_data VALUES (31, N'000000', 0, N'短信认证', N'sms', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'短信认证')
GO
INSERT sys_dict_data VALUES (32, N'000000', 0, N'邮件认证', N'email', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'邮件认证')
GO
INSERT sys_dict_data VALUES (33, N'000000', 0, N'小程序认证', N'xcx', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'小程序认证')
GO
INSERT sys_dict_data VALUES (34, N'000000', 0, N'三方登录认证', N'`social`', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'三方登录认证')
GO
INSERT sys_dict_data VALUES (35, N'000000', 0, N'PC端', N'`pc`', N'sys_device_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'PC端')
GO
INSERT sys_dict_data VALUES (36, N'000000', 0, N'APP端', N'`app`', N'sys_device_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'APP端')
GO
CREATE TABLE sys_dict_type
(
@@ -1374,6 +1388,10 @@
INSERT sys_dict_type VALUES (9, N'000000', N'操作类型', N'sys_oper_type', N'0', 103, 1, getdate(), NULL, NULL, N'操作类型列表')
GO
INSERT sys_dict_type VALUES (10, N'000000', N'系统状态', N'sys_common_status', N'0', 103, 1, getdate(), NULL, NULL, N'登录状态列表')
GO
INSERT sys_dict_type VALUES (11, N'000000', N'授权类型', N'sys_grant_type', N'0', 103, 1, getdate(), NULL, NULL, N'认证授权类型')
GO
INSERT sys_dict_type VALUES (12, N'000000', N'设备类型', N'sys_device_type', N'0', 103, 1, getdate(), NULL, NULL, N'客户端设备类型')
GO
CREATE TABLE sys_logininfor
@@ -1661,6 +1679,8 @@
GO
INSERT sys_menu VALUES (122, N'租户套餐管理', 6, 2, N'tenantPackage', N'system/tenantPackage/index', N'', 1, 0, N'C', N'0', N'0', N'system:tenantPackage:list', N'code', 103, 1, getdate(), NULL, NULL, N'租户套餐管理菜单')
GO
INSERT sys_menu VALUES (123, N'客户端管理', 1, 1, N'client', N'system/client/index', N'', 1, 0, N'C', N'0', N'0', N'system:client:list', N'international', 103, 1, getdate(), NULL, NULL, N'客户端管理菜单')
GO
INSERT sys_menu VALUES (117, N'Admin监控', 2, 5, N'Admin', N'monitor/admin/index', N'', 1, 0, N'C', N'0', N'0', N'monitor:admin:list', N'dashboard', 103, 1, getdate(), NULL, NULL, N'Admin监控菜单');
GO
INSERT sys_menu VALUES (118, N'文件管理', 1, 10, N'oss', N'system/oss/index', N'', 1, 0, N'C', '0', N'0', N'system:oss:list', N'upload', 103, 1, getdate(), NULL, NULL, N'文件管理菜单');
@@ -1815,6 +1835,17 @@
INSERT sys_menu VALUES (1614, N'租户套餐删除', 122, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:tenantPackage:remove', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1615, N'租户套餐导出', 122, 5, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:tenantPackage:export', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
-- å®¢æˆ·ç«¯ç®¡ç†æŒ‰é’®
INSERT sys_menu VALUES (1061, N'客户端管理查询', 123, 1, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:query', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1062, N'客户端管理新增', 123, 2, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:add', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1063, N'客户端管理修改', 123, 3, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:edit', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1064, N'客户端管理删除', 123, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:remove', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1065, N'客户端管理导出', 123, 5, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:export', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
CREATE TABLE sys_notice
@@ -2539,6 +2570,16 @@
GO
INSERT sys_role_menu VALUES (2, 1060)
GO
INSERT sys_role_menu VALUES (2, 1061)
GO
INSERT sys_role_menu VALUES (2, 1062)
GO
INSERT sys_role_menu VALUES (2, 1063)
GO
INSERT sys_role_menu VALUES (2, 1064)
GO
INSERT sys_role_menu VALUES (2, 1065)
GO
CREATE TABLE sys_user
(
@@ -3039,3 +3080,129 @@
GO
INSERT INTO sys_oss_config VALUES (N'5', N'000000', N'image',  N'ruoyi',           N'ruoyi123',        N'ruoyi',            N'image', N'127.0.0.1:9000',               N'',N'N', N'',           N'1', N'1', N'', 103, 1, getdate(), 1, getdate(), NULL)
GO
CREATE TABLE sys_client
(
    id                  bigint                              NOT NULL,
    client_id           nvarchar(20)  DEFAULT ''            NULL,
    client_key          nvarchar(255) DEFAULT ''            NULL,
    client_secret       nvarchar(255) DEFAULT ''            NULL,
    grant_type          nvarchar(255) DEFAULT ''            NULL,
    device_type         nvarchar(32) DEFAULT ''            NULL,
    active_timeout      int           DEFAULT ((1800))      NULL,
    timeout             int           DEFAULT ((604800))    NULL,
    status              nchar(1)      DEFAULT ('0')         NULL,
    del_flag            nchar(1)      DEFAULT ('0')         NULL,
    create_dept         bigint                              NULL,
    create_by           bigint                              NULL,
    create_time         datetime2(7)                        NULL,
    update_by           bigint                              NULL,
    update_time         datetime2(7)                        NULL
    CONSTRAINT PK__sys_client___BFBDE87009ED2882 PRIMARY KEY CLUSTERED (id)
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
        ON [PRIMARY]
)
ON [PRIMARY]
GO
EXEC sp_addextendedproperty
'MS_Description', N'主建',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'id'
GO
EXEC sys.sp_addextendedproperty
'MS_Description', N'客户端id' ,
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'tenant_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'客户端key',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'client_key'
GO
EXEC sp_addextendedproperty
'MS_Description', N'客户端秘钥',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'client_secret'
GO
EXEC sp_addextendedproperty
'MS_Description', N'授权类型',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'grant_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'设备类型',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'device_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'token活跃超时时间',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'active_timeout'
GO
EXEC sp_addextendedproperty
'MS_Description', N'token固定超时',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'timeout'
GO
EXEC sp_addextendedproperty
'MS_Description', N'状态(0正常 1停用)',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'删除标志(0代表存在 2代表删除)',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'del_flag'
GO
EXEC sys.sp_addextendedproperty
'MS_Description', N'创建部门' ,
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'create_dept'
GO
EXEC sp_addextendedproperty
'MS_Description', N'创建者',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'create_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'创建时间',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'create_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'更新者',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'update_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'更新时间',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'update_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'系统授权表',
'SCHEMA', N'dbo',
'TABLE', N'sys_client'
GO
INSERT INTO sys_client VALUES (N'1', N'e5cd7e4891bf95d1d19206ce24a7b32e', N'pc', N'pc123', N'password,social', N'pc', 1800, 604800, N'0', N'0', 103, 1, getdate(), 1, getdate())
GO
INSERT INTO sys_client VALUES (N'2', N'428a8310cd442757ae699df5d894f051', N'app', N'app123', N'password,sms,social', N'app', 1800, 604800, N'0', N'0', 103, 1, getdate(), 1, getdate())
GO
script/sql/update/oracle/update_5.0-5.1.sql
@@ -72,3 +72,73 @@
comment on column  sys_social.update_by         is '更新者';
comment on column  sys_social.update_time       is '更新时间';
comment on column  sys_social.del_flag          is '删除标志(0代表存在 2代表删除)';
-- ----------------------------
-- ç³»ç»ŸæŽˆæƒè¡¨
-- ----------------------------
create table sys_client (
    id                  number(20)    not null,
    client_id           varchar(64)   default null,
    client_key          varchar(32)   default null,
    client_secret       varchar(255)  default null,
    grant_type          varchar(255)  default null,
    device_type         varchar(32)   default null,
    active_timeout      number(11)    default 1800,
    timeout             number(11)    default 604800,
    status              char(1)       default '0',
    del_flag            char(1)       default '0',
    create_dept         number(20)    default null,
    create_by           number(20)    default null,
    create_time         date,
    update_by           number(20)    default null,
    update_time         date
)
alter table sys_client add constraint pk_sys_client primary key (id);
comment on table sys_client                         is '系统授权表';
comment on column sys_client.id                     is '主建';
comment on column sys_client.client_id              is '客户端id';
comment on column sys_client.client_key             is '客户端key';
comment on column sys_client.client_secret          is '客户端秘钥';
comment on column sys_client.grant_type             is '授权类型';
comment on column sys_client.device_type            is '设备类型';
comment on column sys_client.active_timeout         is 'token活跃超时时间';
comment on column sys_client.timeout                is 'token固定超时';
comment on column sys_client.status                 is '状态(0正常 1停用)';
comment on column sys_client.del_flag               is '删除标志(0代表存在 2代表删除)';
comment on column sys_client.create_dept            is '创建部门';
comment on column sys_client.create_by              is '创建者';
comment on column sys_client.create_time            is '创建时间';
comment on column sys_client.update_by              is '更新者';
comment on column sys_client.update_time            is '更新时间';
insert into sys_client values (1, 'e5cd7e4891bf95d1d19206ce24a7b32e', 'pc', 'pc123', 'password,social', 'pc', 1800, 604800, 0, 0, 103, 1, sysdate, 1, sysdate);
insert into sys_client values (2, '428a8310cd442757ae699df5d894f051', 'app', 'app123', 'password,sms,social', 'app', 1800, 604800, 0, 0, 103, 1, sysdate, 1, sysdate);
insert into sys_dict_type values(11, '000000', '授权类型', 'sys_grant_type',     '0', 103, 1, sysdate, null, null, '认证授权类型');
insert into sys_dict_type values(12, '000000', '设备类型', 'sys_device_type',    '0', 103, 1, sysdate, null, null, '客户端设备类型');
insert into sys_dict_data values(30, '000000', 0,  '密码认证', 'password',   'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '密码认证');
insert into sys_dict_data values(31, '000000', 0,  '短信认证', 'sms',        'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '短信认证');
insert into sys_dict_data values(32, '000000', 0,  '邮件认证', 'email',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '邮件认证');
insert into sys_dict_data values(33, '000000', 0,  '小程序认证', 'xcx',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '小程序认证');
insert into sys_dict_data values(34, '000000', 0,  '三方登录认证', 'social', 'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate, null, null, '三方登录认证');
insert into sys_dict_data values(35, '000000', 0,  'PC端',      'pc',        'sys_device_type',  '',   'default', 'N', '0', 103, 1, sysdate, null, null, 'PC端');
insert into sys_dict_data values(36, '000000', 0,  'APP端',     'app',       'sys_device_type',  '',   'default', 'N', '0', 103, 1, sysdate, null, null, 'APP端');
-- äºŒçº§èœå•
insert into sys_menu values('123',  '客户端管理',   '1',   '1', 'client',           'system/client/index',          '', 1, 0, 'C', '0', '0', 'system:client:list',          'international', 103, 1, sysdate, null, null, '客户端管理菜单');
-- å®¢æˆ·ç«¯ç®¡ç†æŒ‰é’®
insert into sys_menu values('1061', '客户端管理查询', '123', '1',  '#', '', 1, 0, 'F', '0', '0', 'system:client:query',        '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1062', '客户端管理新增', '123', '2',  '#', '', 1, 0, 'F', '0', '0', 'system:client:add',          '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1063', '客户端管理修改', '123', '3',  '#', '', 1, 0, 'F', '0', '0', 'system:client:edit',         '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1064', '客户端管理删除', '123', '4',  '#', '', 1, 0, 'F', '0', '0', 'system:client:remove',       '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1065', '客户端管理导出', '123', '5',  '#', '', 1, 0, 'F', '0', '0', 'system:client:export',       '#', 103, 1, sysdate, null, null, '');
-- è§’色菜单权限
insert into sys_role_menu values ('2', '1061');
insert into sys_role_menu values ('2', '1062');
insert into sys_role_menu values ('2', '1063');
insert into sys_role_menu values ('2', '1064');
insert into sys_role_menu values ('2', '1065');
script/sql/update/postgres/update_5.0-5.1.sql
@@ -71,3 +71,73 @@
comment on column  sys_social.update_by         is '更新者';
comment on column  sys_social.update_time       is '更新时间';
comment on column  sys_social.del_flag          is '删除标志(0代表存在 2代表删除)';
-- ----------------------------
-- ç³»ç»ŸæŽˆæƒè¡¨
-- ----------------------------
drop table if exists sys_client;
create table sys_client (
    id                  int8,
    client_id           varchar(64)   ''::varchar,
    client_key          varchar(32)   ''::varchar,
    client_secret       varchar(255)  ''::varchar,
    grant_type          varchar(255)  ''::varchar,
    device_type         varchar(32)   ''::varchar,
    active_timeout      int4          default 1800,
    timeout             int4          default 604800,
    status              char(1)       default '0'::bpchar,
    del_flag            char(1)       default '0'::bpchar,
    create_dept         int8,
    create_by           int8,
    create_time         timestamp,
    update_by           int8,
    update_time         timestamp,
    constraint sys_client_pk primary key (id)
)
comment on table sys_client                         is '系统授权表';
comment on column sys_client.id                     is '主建';
comment on column sys_client.client_id              is '客户端id';
comment on column sys_client.client_key             is '客户端key';
comment on column sys_client.client_secret          is '客户端秘钥';
comment on column sys_client.grant_type             is '授权类型';
comment on column sys_client.device_type            is '设备类型';
comment on column sys_client.active_timeout         is 'token活跃超时时间';
comment on column sys_client.timeout                is 'token固定超时';
comment on column sys_client.status                 is '状态(0正常 1停用)';
comment on column sys_client.del_flag               is '删除标志(0代表存在 2代表删除)';
comment on column sys_client.create_dept            is '创建部门';
comment on column sys_client.create_by              is '创建者';
comment on column sys_client.create_time            is '创建时间';
comment on column sys_client.update_by              is '更新者';
comment on column sys_client.update_time            is '更新时间';
insert into sys_client values (1, 'e5cd7e4891bf95d1d19206ce24a7b32e', 'pc', 'pc123', 'password,social', 'pc', 1800, 604800, 0, 0, 103, 1, now(), 1, now());
insert into sys_client values (2, '428a8310cd442757ae699df5d894f051', 'app', 'app123', 'password,sms,social', 'app', 1800, 604800, 0, 0, 103, 1, now(), 1, now());
insert into sys_dict_type values(11, '000000', '授权类型', 'sys_grant_type',     '0', 103, 1, now(), null, null, '认证授权类型');
insert into sys_dict_type values(12, '000000', '设备类型', 'sys_device_type',    '0', 103, 1, now(), null, null, '客户端设备类型');
insert into sys_dict_data values(30, '000000', 0,  '密码认证', 'password',   'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '密码认证');
insert into sys_dict_data values(31, '000000', 0,  '短信认证', 'sms',        'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '短信认证');
insert into sys_dict_data values(32, '000000', 0,  '邮件认证', 'email',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '邮件认证');
insert into sys_dict_data values(33, '000000', 0,  '小程序认证', 'xcx',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '小程序认证');
insert into sys_dict_data values(34, '000000', 0,  '三方登录认证', 'social', 'sys_grant_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, '三方登录认证');
insert into sys_dict_data values(35, '000000', 0,  'PC端', 'pc',            'sys_device_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, 'PC端');
insert into sys_dict_data values(36, '000000', 0,  'APP端', 'app',          'sys_device_type',   '',   'default', 'N', '0', 103, 1, now(), null, null, 'APP端');
-- äºŒçº§èœå•
insert into sys_menu values('123',  '客户端管理',   '1',   '1', 'client',           'system/client/index',          '', '1', '0', 'C', '0', '0', 'system:client:list',          'international', 103, 1, now(), null, null, '客户端管理菜单');
-- å®¢æˆ·ç«¯ç®¡ç†æŒ‰é’®
insert into sys_menu values('1061', '客户端管理查询', '123', '1',  '#', '', '1', '0', 'F', '0', '0', 'system:client:query',        '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1062', '客户端管理新增', '123', '2',  '#', '', '1', '0', 'F', '0', '0', 'system:client:add',          '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1063', '客户端管理修改', '123', '3',  '#', '', '1', '0', 'F', '0', '0', 'system:client:edit',         '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1064', '客户端管理删除', '123', '4',  '#', '', '1', '0', 'F', '0', '0', 'system:client:remove',       '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1065', '客户端管理导出', '123', '5',  '#', '', '1', '0', 'F', '0', '0', 'system:client:export',       '#', 103, 1, now(), null, null, '');
-- è§’色菜单权限
insert into sys_role_menu values ('2', '1061');
insert into sys_role_menu values ('2', '1062');
insert into sys_role_menu values ('2', '1063');
insert into sys_role_menu values ('2', '1064');
insert into sys_role_menu values ('2', '1065');
script/sql/update/sqlserver/update_5.0-5.1.sql
@@ -229,3 +229,177 @@
    'TABLE', N'sys_social',
    'COLUMN', N'update_time'
GO
CREATE TABLE sys_client
(
    id                  bigint                              NOT NULL,
    client_id           nvarchar(20)  DEFAULT ''            NULL,
    client_key          nvarchar(255) DEFAULT ''            NULL,
    client_secret       nvarchar(255) DEFAULT ''            NULL,
    grant_type          nvarchar(255) DEFAULT ''            NULL,
    device_type         nvarchar(32) DEFAULT ''            NULL,
    active_timeout      int           DEFAULT ((1800))      NULL,
    timeout             int           DEFAULT ((604800))    NULL,
    status              nchar(1)      DEFAULT ('0')         NULL,
    del_flag            nchar(1)      DEFAULT ('0')         NULL,
    create_dept         bigint                              NULL,
    create_by           bigint                              NULL,
    create_time         datetime2(7)                        NULL,
    update_by           bigint                              NULL,
    update_time         datetime2(7)                        NULL
    CONSTRAINT PK__sys_client___BFBDE87009ED2882 PRIMARY KEY CLUSTERED (id)
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
        ON [PRIMARY]
)
ON [PRIMARY]
GO
EXEC sp_addextendedproperty
'MS_Description', N'主建',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'id'
GO
EXEC sys.sp_addextendedproperty
'MS_Description', N'客户端id' ,
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'tenant_id'
GO
EXEC sp_addextendedproperty
'MS_Description', N'客户端key',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'client_key'
GO
EXEC sp_addextendedproperty
'MS_Description', N'客户端秘钥',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'client_secret'
GO
EXEC sp_addextendedproperty
'MS_Description', N'授权类型',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'grant_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'设备类型',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'device_type'
GO
EXEC sp_addextendedproperty
'MS_Description', N'token活跃超时时间',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'active_timeout'
GO
EXEC sp_addextendedproperty
'MS_Description', N'token固定超时',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'timeout'
GO
EXEC sp_addextendedproperty
'MS_Description', N'状态(0正常 1停用)',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'status'
GO
EXEC sp_addextendedproperty
'MS_Description', N'删除标志(0代表存在 2代表删除)',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'del_flag'
GO
EXEC sys.sp_addextendedproperty
'MS_Description', N'创建部门' ,
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'create_dept'
GO
EXEC sp_addextendedproperty
'MS_Description', N'创建者',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'create_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'创建时间',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'create_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'更新者',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'update_by'
GO
EXEC sp_addextendedproperty
'MS_Description', N'更新时间',
'SCHEMA', N'dbo',
'TABLE', N'sys_client',
'COLUMN', N'update_time'
GO
EXEC sp_addextendedproperty
'MS_Description', N'系统授权表',
'SCHEMA', N'dbo',
'TABLE', N'sys_client'
GO
INSERT INTO sys_client VALUES (N'1', N'e5cd7e4891bf95d1d19206ce24a7b32e', N'pc', N'pc123', N'password,social', N'pc', 1800, 604800, N'0', N'0', 103, 1, getdate(), 1, getdate())
GO
INSERT INTO sys_client VALUES (N'2', N'428a8310cd442757ae699df5d894f051', N'app', N'app123', N'password,sms,social', N'app', 1800, 604800, N'0', N'0', 103, 1, getdate(), 1, getdate())
GO
INSERT sys_dict_type VALUES (11, N'000000', N'授权类型', N'sys_grant_type', N'0', 103, 1, getdate(), NULL, NULL, N'认证授权类型')
GO
INSERT sys_dict_type VALUES (12, N'000000', N'设备类型', N'sys_device_type', N'0', 103, 1, getdate(), NULL, NULL, N'客户端设备类型')
GO
INSERT sys_dict_data VALUES (30, N'000000', 0, N'密码认证', N'password', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'密码认证');
GO
INSERT sys_dict_data VALUES (31, N'000000', 0, N'短信认证', N'sms', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'短信认证')
GO
INSERT sys_dict_data VALUES (32, N'000000', 0, N'邮件认证', N'email', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'邮件认证')
GO
INSERT sys_dict_data VALUES (33, N'000000', 0, N'小程序认证', N'xcx', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'小程序认证')
GO
INSERT sys_dict_data VALUES (34, N'000000', 0, N'三方登录认证', N'`social`', N'sys_grant_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'三方登录认证')
GO
INSERT sys_dict_data VALUES (35, N'000000', 0, N'PC端', N'`pc`', N'sys_device_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'PC端')
GO
INSERT sys_dict_data VALUES (36, N'000000', 0, N'APP端', N'`app`', N'sys_device_type', N'', N'default', N'N', N'0', 103, 1, getdate(), NULL, NULL, N'APP端')
GO
-- äºŒçº§èœå•
INSERT sys_menu VALUES (123, N'客户端管理', 1, 1, N'client', N'system/client/index', N'', 1, 0, N'C', N'0', N'0', N'system:client:list', N'international', 103, 1, getdate(), NULL, NULL, N'客户端管理菜单')
GO
-- å®¢æˆ·ç«¯ç®¡ç†æŒ‰é’®
INSERT sys_menu VALUES (1061, N'客户端管理查询', 123, 1, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:query', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1062, N'客户端管理新增', 123, 2, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:add', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1063, N'客户端管理修改', 123, 3, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:edit', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1064, N'客户端管理删除', 123, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:remove', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
INSERT sys_menu VALUES (1065, N'客户端管理导出', 123, 5, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:client:export', N'#', 103, 1, getdate(), NULL, NULL, N'');
GO
-- è§’色菜单权限
INSERT sys_role_menu VALUES (2, 1061)
GO
INSERT sys_role_menu VALUES (2, 1062)
GO
INSERT sys_role_menu VALUES (2, 1063)
GO
INSERT sys_role_menu VALUES (2, 1064)
GO
INSERT sys_role_menu VALUES (2, 1065)
GO
script/sql/update/update_5.0-5.1.sql
@@ -39,3 +39,56 @@
    del_flag           char(1)          default '0'     comment '删除标志(0代表存在 2代表删除)',
    PRIMARY KEY (id)
) engine=innodb comment = '社会化关系表';
-- ----------------------------
-- ç³»ç»ŸæŽˆæƒè¡¨
-- ----------------------------
drop table if exists sys_client;
create table sys_client (
    id                  bigint(20)    not null            comment 'id',
    client_id           varchar(64)   default null        comment '客户端id',
    client_key          varchar(32)   default null        comment '客户端key',
    client_secret       varchar(255)  default null        comment '客户端秘钥',
    grant_type          varchar(255)  default null        comment '授权类型',
    device_type         varchar(32)   default null        comment '设备类型',
    active_timeout      int(11)       default 1800        comment 'token活跃超时时间',
    timeout             int(11)       default 604800      comment 'token固定超时',
    status              char(1)       default '0'         comment '状态(0正常 1停用)',
    del_flag            char(1)       default '0'         comment '删除标志(0代表存在 2代表删除)',
    create_dept         bigint(20)    default null        comment '创建部门',
    create_by           bigint(20)    default null        comment '创建者',
    create_time         datetime      default null        comment '创建时间',
    update_by           bigint(20)    default null        comment '更新者',
    update_time         datetime      default null        comment '更新时间',
    primary key (id)
) engine=innodb comment='系统授权表';
insert into sys_client values (1, 'e5cd7e4891bf95d1d19206ce24a7b32e', 'pc', 'pc123', 'password,social', 'pc', 1800, 604800, 0, 0, 103, 1, sysdate(), 1, sysdate());
insert into sys_client values (2, '428a8310cd442757ae699df5d894f051', 'app', 'app123', 'password,sms,social', 'app', 1800, 604800, 0, 0, 103, 1, sysdate(), 1, sysdate());
insert into sys_dict_type values(11, '000000', '授权类型', 'sys_grant_type',     '0', 103, 1, sysdate(), null, null, '认证授权类型');
insert into sys_dict_type values(12, '000000', '设备类型', 'sys_device_type',    '0', 103, 1, sysdate(), null, null, '客户端设备类型');
insert into sys_dict_data values(30, '000000', 0,  '密码认证', 'password',   'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '密码认证');
insert into sys_dict_data values(31, '000000', 0,  '短信认证', 'sms',        'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '短信认证');
insert into sys_dict_data values(32, '000000', 0,  '邮件认证', 'email',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '邮件认证');
insert into sys_dict_data values(33, '000000', 0,  '小程序认证', 'xcx',      'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '小程序认证');
insert into sys_dict_data values(34, '000000', 0,  '三方登录认证', 'social', 'sys_grant_type',   '',   'default', 'N', '0', 103, 1, sysdate(), null, null, '三方登录认证');
insert into sys_dict_data values(35, '000000', 0,  'PC端', 'pc',          'sys_device_type',     '',   'default', 'N', '0', 103, 1, sysdate(), null, null, 'PC端');
insert into sys_dict_data values(36, '000000', 0,  'APP端', 'app',        'sys_device_type',     '',   'default', 'N', '0', 103, 1, sysdate(), null, null, 'APP端');
-- äºŒçº§èœå•
insert into sys_menu values('123',  '客户端管理',   '1',   '1', 'client',           'system/client/index',          '', 1, 0, 'C', '0', '0', 'system:client:list',          'international', 103, 1, sysdate(), null, null, '客户端管理菜单');
-- å®¢æˆ·ç«¯ç®¡ç†æŒ‰é’®
insert into sys_menu values('1061', '客户端管理查询', '123', '1',  '#', '', 1, 0, 'F', '0', '0', 'system:client:query',        '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1062', '客户端管理新增', '123', '2',  '#', '', 1, 0, 'F', '0', '0', 'system:client:add',          '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1063', '客户端管理修改', '123', '3',  '#', '', 1, 0, 'F', '0', '0', 'system:client:edit',         '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1064', '客户端管理删除', '123', '4',  '#', '', 1, 0, 'F', '0', '0', 'system:client:remove',       '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1065', '客户端管理导出', '123', '5',  '#', '', 1, 0, 'F', '0', '0', 'system:client:export',       '#', 103, 1, sysdate(), null, null, '');
-- è§’色菜单权限
insert into sys_role_menu values ('2', '1061');
insert into sys_role_menu values ('2', '1062');
insert into sys_role_menu values ('2', '1063');
insert into sys_role_menu values ('2', '1064');
insert into sys_role_menu values ('2', '1065');