Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/mail-1.6.1

# Conflicts:
#	yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
#	yudao-module-system/yudao-module-system-biz/pom.xml
This commit is contained in:
YunaiV
2022-12-23 19:38:00 +08:00
3082 changed files with 174737 additions and 58537 deletions

View File

@ -29,13 +29,6 @@
<optional>true</optional>
</dependency>
<!-- 用户信息 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-security</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -1,56 +0,0 @@
package cn.iocoder.yudao.module.system.api.auth;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 在线用户 Session API 接口
*
* @author 芋道源码
*/
public interface UserSessionApi {
/**
* 创建在线用户 Session
*
* @param loginUser 登录用户
* @param userIp 用户 IP
* @param userAgent 用户 UA
* @return Token 令牌
*/
String createUserSession(@NotNull(message = "登录用户不能为空") LoginUser loginUser, String userIp, String userAgent);
/**
* 刷新在线用户 Session 的更新时间
*
* @param token Token 令牌
* @param loginUser 登录用户
*/
void refreshUserSession(@NotEmpty(message = "Token 令牌不能为空") String token,
@NotNull(message = "登录用户不能为空") LoginUser loginUser);
/**
* 删除在线用户 Session
*
* @param token Token 令牌
*/
void deleteUserSession(String token);
/**
* 获得 Token 令牌对应的在线用户
*
* @param token Token 令牌
* @return 在线用户
*/
LoginUser getLoginUser(String token);
/**
* 获得 Session 超时时间,单位:毫秒
*
* @return 超时时间
*/
Long getSessionTimeoutMillis();
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.api.dept;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import java.util.Collection;
@ -45,6 +46,9 @@ public interface DeptApi {
* @param ids 部门编号数组
* @return 部门 Map
*/
Map<Long, DeptRespDTO> getDeptMap(Set<Long> ids);
default Map<Long, DeptRespDTO> getDeptMap(Set<Long> ids) {
List<DeptRespDTO> list = getDepts(ids);
return CollectionUtils.convertMap(list, DeptRespDTO::getId);
}
}

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.system.api.dict;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import java.util.Collection;
/**
@ -19,4 +21,22 @@ public interface DictDataApi {
*/
void validDictDatas(String dictType, Collection<String> values);
/**
* 获得指定的字典数据,从缓存中
*
* @param type 字典类型
* @param value 字典数据值
* @return 字典数据
*/
DictDataRespDTO getDictData(String type, String value);
/**
* 解析获得指定的字典数据,从缓存中
*
* @param type 字典类型
* @param label 字典数据标签
* @return 字典数据
*/
DictDataRespDTO parseDictData(String type, String label);
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.system.api.dict.dto;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import lombok.Data;
/**
* 字典数据 Response DTO
*
* @author 芋道源码
*/
@Data
public class DictDataRespDTO {
/**
* 字典标签
*/
private String label;
/**
* 字典值
*/
private String value;
/**
* 字典类型
*/
private String dictType;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
}

View File

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.system.api.errorcode;
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeAutoGenerateReqDTO;
import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeRespDTO;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
/**
* 错误码 Api 接口
*
* @author 芋道源码
*/
public interface ErrorCodeApi {
/**
* 自动创建错误码
*
* @param autoGenerateDTOs 错误码信息
*/
void autoGenerateErrorCodes(@Valid List<ErrorCodeAutoGenerateReqDTO> autoGenerateDTOs);
/**
* 增量获得错误码数组
*
* 如果 minUpdateTime 为空时,则获取所有错误码
*
* @param applicationName 应用名
* @param minUpdateTime 最小更新时间
* @return 错误码数组
*/
List<ErrorCodeRespDTO> getErrorCodeList(String applicationName, LocalDateTime minUpdateTime);
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.system.api.errorcode.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 错误码自动生成 DTO
*
* @author dylan
*/
@Data
@Accessors(chain = true)
public class ErrorCodeAutoGenerateReqDTO {
/**
* 应用名
*/
@NotNull(message = "应用名不能为空")
private String applicationName;
/**
* 错误码编码
*/
@NotNull(message = "错误码编码不能为空")
private Integer code;
/**
* 错误码错误提示
*/
@NotEmpty(message = "错误码错误提示不能为空")
private String message;
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.system.api.errorcode.dto;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 错误码的 Response DTO
*
* @author 芋道源码
*/
@Data
public class ErrorCodeRespDTO {
/**
* 错误码编码
*/
private Integer code;
/**
* 错误码错误提示
*/
private String message;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.system.api.logger;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
import javax.validation.Valid;
/**
* 操作日志 API 接口
*
* @author 芋道源码
*/
public interface OperateLogApi {
/**
* 创建操作日志
*
* @param createReqDTO 请求
*/
void createOperateLog(@Valid OperateLogCreateReqDTO createReqDTO);
}

View File

@ -0,0 +1,123 @@
package cn.iocoder.yudao.module.system.api.logger.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.Map;
/**
* 操作日志创建 Request DTO
*/
@Data
public class OperateLogCreateReqDTO {
/**
* 链路追踪编号
*/
private String traceId;
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Long userId;
/**
* 用户类型
*/
@NotNull(message = "用户类型不能为空")
private Integer userType;
/**
* 操作模块
*/
@NotEmpty(message = "操作模块不能为空")
private String module;
/**
* 操作名
*/
@NotEmpty(message = "操作名")
private String name;
/**
* 操作分类
*/
@NotNull(message = "操作分类不能为空")
private Integer type;
/**
* 操作明细
*/
private String content;
/**
* 拓展字段
*/
private Map<String, Object> exts;
/**
* 请求方法名
*/
@NotEmpty(message = "请求方法名不能为空")
private String requestMethod;
/**
* 请求地址
*/
@NotEmpty(message = "请求地址不能为空")
private String requestUrl;
/**
* 用户 IP
*/
@NotEmpty(message = "用户 IP 不能为空")
private String userIp;
/**
* 浏览器 UserAgent
*/
@NotEmpty(message = "浏览器 UserAgent 不能为空")
private String userAgent;
/**
* Java 方法名
*/
@NotEmpty(message = "Java 方法名不能为空")
private String javaMethod;
/**
* Java 方法的参数
*/
private String javaMethodArgs;
/**
* 开始时间
*/
@NotNull(message = "开始时间不能为空")
private LocalDateTime startTime;
/**
* 执行时长,单位:毫秒
*/
@NotNull(message = "执行时长不能为空")
private Integer duration;
/**
* 结果码
*/
@NotNull(message = "结果码不能为空")
private Integer resultCode;
/**
* 结果提示
*/
private String resultMsg;
/**
* 结果数据
*/
private String resultData;
}

View File

@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.system.api.oauth2;
import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCreateReqDTO;
import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO;
import javax.validation.Valid;
/**
* OAuth2.0 Token API 接口
*
* @author 芋道源码
*/
public interface OAuth2TokenApi {
/**
* 创建访问令牌
*
* @param reqDTO 访问令牌的创建信息
* @return 访问令牌的信息
*/
OAuth2AccessTokenRespDTO createAccessToken(@Valid OAuth2AccessTokenCreateReqDTO reqDTO);
/**
* 校验访问令牌
*
* @param accessToken 访问令牌
* @return 访问令牌的信息
*/
OAuth2AccessTokenCheckRespDTO checkAccessToken(String accessToken);
/**
* 移除访问令牌
*
* @param accessToken 访问令牌
* @return 访问令牌的信息
*/
OAuth2AccessTokenRespDTO removeAccessToken(String accessToken);
/**
* 刷新访问令牌
*
* @param refreshToken 刷新令牌
* @param clientId 客户端编号
* @return 访问令牌的信息
*/
OAuth2AccessTokenRespDTO refreshAccessToken(String refreshToken, String clientId);
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.system.api.oauth2.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* OAuth2.0 访问令牌的校验 Response DTO
*
* @author 芋道源码
*/
@Data
public class OAuth2AccessTokenCheckRespDTO implements Serializable {
/**
* 用户编号
*/
private Long userId;
/**
* 用户类型
*/
private Integer userType;
/**
* 租户编号
*/
private Long tenantId;
/**
* 授权范围的数组
*/
private List<String> scopes;
}

View File

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.system.api.oauth2.dto;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* OAuth2.0 访问令牌创建 Request DTO
*
* @author 芋道源码
*/
@Data
public class OAuth2AccessTokenCreateReqDTO implements Serializable {
/**
* 用户编号
*/
@NotNull(message = "用户编号不能为空")
private Long userId;
/**
* 用户类型
*/
@NotNull(message = "用户类型不能为空")
@InEnum(value = UserTypeEnum.class, message = "用户类型必须是 {value}")
private Integer userType;
/**
* 客户端编号
*/
@NotNull(message = "客户端编号不能为空")
private String clientId;
/**
* 授权范围
*/
private List<String> scopes;
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.system.api.oauth2.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* OAuth2.0 访问令牌的信息 Response DTO
*
* @author 芋道源码
*/
@Data
@Accessors(chain = true)
public class OAuth2AccessTokenRespDTO implements Serializable {
/**
* 访问令牌
*/
private String accessToken;
/**
* 刷新令牌
*/
private String refreshToken;
/**
* 用户编号
*/
private Long userId;
/**
* 用户类型
*/
private Integer userType;
/**
* 过期时间
*/
private LocalDateTime expiresTime;
}

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.system.api.permission;
import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO;
import java.util.Collection;
import java.util.Set;
@ -18,4 +20,30 @@ public interface PermissionApi {
*/
Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds);
/**
* 判断是否有权限,任一一个即可
*
* @param userId 用户编号
* @param permissions 权限
* @return 是否
*/
boolean hasAnyPermissions(Long userId, String... permissions);
/**
* 判断是否有角色,任一一个即可
*
* @param userId 用户编号
* @param roles 角色数组
* @return 是否
*/
boolean hasAnyRoles(Long userId, String... roles);
/**
* 获得登陆用户的部门数据权限
*
* @param userId 用户编号
* @return 部门数据权限
*/
DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
}

View File

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.system.api.permission.dto;
import lombok.Data;
import java.util.HashSet;
import java.util.Set;
/**
* 部门的数据权限 Response DTO
*
* @author 芋道源码
*/
@Data
public class DeptDataPermissionRespDTO {
/**
* 是否可查看全部数据
*/
private Boolean all;
/**
* 是否可查看自己的数据
*/
private Boolean self;
/**
* 可查看的部门编号数组
*/
private Set<Long> deptIds;
public DeptDataPermissionRespDTO() {
this.all = false;
this.self = false;
this.deptIds = new HashSet<>();
}
}

View File

@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.validation.Mobile;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Map;
/**

View File

@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.system.api.social.dto;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ -14,6 +16,8 @@ import javax.validation.constraints.NotNull;
* @author 芋道源码
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SocialUserBindReqDTO {
/**
@ -42,7 +46,7 @@ public class SocialUserBindReqDTO {
/**
* state
*/
@NotEmpty(message = "state 不能为空")
@NotNull(message = "state 不能为空")
private String state;
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.system.api.tenant;
import java.util.List;
/**
* 多租户的 API 接口
*
* @author 芋道源码
*/
public interface TenantApi {
/**
* 获得所有租户
*
* @return 租户编号数组
*/
List<Long> getTenantIds();
/**
* 校验租户是否合法
*
* @param id 租户编号
*/
void validTenant(Long id);
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.api.user;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import java.util.Collection;
@ -22,6 +23,14 @@ public interface AdminUserApi {
*/
AdminUserRespDTO getUser(Long id);
/**
* 通过用户 ID 查询用户们
*
* @param ids 用户 ID 们
* @return 用户对象信息
*/
List<AdminUserRespDTO> getUsers(Collection<Long> ids);
/**
* 获得指定部门的用户数组
*
@ -44,7 +53,10 @@ public interface AdminUserApi {
* @param ids 用户编号数组
* @return 用户 Map
*/
Map<Long, AdminUserRespDTO> getUserMap(Collection<Long> ids);
default Map<Long, AdminUserRespDTO> getUserMap(Collection<Long> ids) {
List<AdminUserRespDTO> users = getUsers(ids);
return CollectionUtils.convertMap(users, AdminUserRespDTO::getId);
}
/**
* 校验用户们是否有效。如下情况,视为无效:

View File

@ -12,11 +12,10 @@ public interface ErrorCodeConstants {
// ========== AUTH 模块 1002000000 ==========
ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1002000000, "登录失败,账号密码不正确");
ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1002000001, "登录失败,账号被禁用");
ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1002000002, "登录失败"); // 登录失败的兜底,未知原因
ErrorCode AUTH_LOGIN_CAPTCHA_NOT_FOUND = new ErrorCode(1002000003, "验证码不存在");
ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确");
ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确,原因:{}");
ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1002000005, "未绑定账号,需要进行绑定");
ErrorCode AUTH_TOKEN_EXPIRED = new ErrorCode(1002000006, "Token 已经过期");
ErrorCode AUTH_MOBILE_NOT_EXISTS = new ErrorCode(1002000007, "手机号不存在");
// ========== 菜单模块 1002001000 ==========
ErrorCode MENU_NAME_DUPLICATE = new ErrorCode(1002001000, "已经存在该名字的菜单");
@ -119,10 +118,31 @@ public interface ErrorCodeConstants {
ErrorCode SOCIAL_USER_UNBIND_NOT_SELF = new ErrorCode(1002018001, "社交解绑失败,非当前用户绑定");
ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1002018002, "社交授权失败,找不到对应的用户");
// ========== 系统感词 1002019000 =========
// ========== 系统感词 1002019000 =========
ErrorCode SENSITIVE_WORD_NOT_EXISTS = new ErrorCode(1002019000, "系统敏感词在所有标签中都不存在");
ErrorCode SENSITIVE_WORD_EXISTS = new ErrorCode(1002019001, "系统敏感词已在标签中存在");
// ========== OAuth2 客户端 1002020000 =========
ErrorCode OAUTH2_CLIENT_NOT_EXISTS = new ErrorCode(1002020000, "OAuth2 客户端不存在");
ErrorCode OAUTH2_CLIENT_EXISTS = new ErrorCode(1002020001, "OAuth2 客户端编号已存在");
ErrorCode OAUTH2_CLIENT_DISABLE = new ErrorCode(1002020002, "OAuth2 客户端已禁用");
ErrorCode OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS = new ErrorCode(1002020003, "不支持该授权类型");
ErrorCode OAUTH2_CLIENT_SCOPE_OVER = new ErrorCode(1002020004, "授权范围过大");
ErrorCode OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH = new ErrorCode(1002020005, "无效 redirect_uri: {}");
ErrorCode OAUTH2_CLIENT_CLIENT_SECRET_ERROR = new ErrorCode(1002020006, "无效 client_secret: {}");
// ========== OAuth2 授权 1002021000 =========
ErrorCode OAUTH2_GRANT_CLIENT_ID_MISMATCH = new ErrorCode(1002021000, "client_id 不匹配");
ErrorCode OAUTH2_GRANT_REDIRECT_URI_MISMATCH = new ErrorCode(1002021001, "redirect_uri 不匹配");
ErrorCode OAUTH2_GRANT_STATE_MISMATCH = new ErrorCode(1002021002, "state 不匹配");
ErrorCode OAUTH2_GRANT_CODE_NOT_EXISTS = new ErrorCode(1002021003, "code 不存在");
// ========== OAuth2 授权 1002022000 =========
ErrorCode OAUTH2_CODE_NOT_EXISTS = new ErrorCode(1002022000, "code 不存在");
ErrorCode OAUTH2_CODE_EXPIRE = new ErrorCode(1002022000, "code 已过期");
// TODO @芋艿:需要重新搞下 mail 错误码
// ========== 邮箱账号 1002020000 ==========
ErrorCode MAIL_ACCOUNT_NOT_EXISTS = new ErrorCode(1002020000, "邮箱账号不存在");
ErrorCode MAIL_ACCOUNT_EXISTS = new ErrorCode(1002020001, "邮箱账号存在");

View File

@ -12,12 +12,10 @@ public enum LoginLogTypeEnum {
LOGIN_USERNAME(100), // 使用账号登录
LOGIN_SOCIAL(101), // 使用社交登录
LOGIN_MOCK(102), // 使用 Mock 登录
LOGIN_MOBILE(103), // 使用手机登陆
LOGIN_SMS(104), // 使用短信登陆
LOGOUT_SELF(200), // 自己主动登出
LOGOUT_TIMEOUT(201), // 超时登出
LOGOUT_DELETE(202), // 强制退出
;

View File

@ -16,7 +16,6 @@ public enum LoginResultEnum {
CAPTCHA_NOT_FOUND(30), // 图片验证码不存在
CAPTCHA_CODE_ERROR(31), // 图片验证码不正确
UNKNOWN_ERROR(100), // 未知异常
;
/**

View File

@ -0,0 +1,12 @@
package cn.iocoder.yudao.module.system.enums.oauth2;
/**
* OAuth2.0 客户端的通用枚举
*
* @author 芋道源码
*/
public interface OAuth2ClientConstants {
String CLIENT_ID_DEFAULT = "default";
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.system.enums.oauth2;
import cn.hutool.core.util.ArrayUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* OAuth2 授权类型(模式)的枚举
*
* @author 芋道源码
*/
@AllArgsConstructor
@Getter
public enum OAuth2GrantTypeEnum {
PASSWORD("password"), // 密码模式
AUTHORIZATION_CODE("authorization_code"), // 授权码模式
IMPLICIT("implicit"), // 简化模式
CLIENT_CREDENTIALS("client_credentials"), // 客户端模式
REFRESH_TOKEN("refresh_token"), // 刷新模式
;
private final String grantType;
public static OAuth2GrantTypeEnum getByGranType(String grantType) {
return ArrayUtil.firstMatch(o -> o.getGrantType().equals(grantType), values());
}
}

View File

@ -18,9 +18,9 @@ public enum SmsSceneEnum implements IntArrayValuable {
MEMBER_LOGIN(1, "user-sms-login", "会员用户 - 手机号登陆"),
MEMBER_UPDATE_MOBILE(2, "user-sms-reset-password", "会员用户 - 修改手机"),
MEMBER_FORGET_PASSWORD(3, "user-sms-update-mobile", "会员用户 - 忘记密码");
MEMBER_FORGET_PASSWORD(3, "user-sms-update-mobile", "会员用户 - 忘记密码"),
// 如果未来希望管理后台支持手机验证码登陆,可以通过添加 ADMIN_MEMBER_LOGIN 枚举
ADMIN_MEMBER_LOGIN(21, "admin-sms-login", "后台用户 - 手机号登录");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SmsSceneEnum::getScene).toArray();

View File

@ -6,9 +6,6 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 社交平台的类型枚举
@ -49,7 +46,7 @@ public enum SocialTypeEnum implements IntArrayValuable {
* 微信小程序
* 文档链接https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
*/
WECHAT_MINI_PROGRAM(33, "WECHAT_MINI_PROGRAM"),
WECHAT_MINI_APP(34, "WECHAT_MINI_APP"),
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SocialTypeEnum::getType).toArray();