mirror of
https://github.com/mfish-qf/mfish-nocode.git
synced 2026-09-24 15:45:53 +08:00
feat: 数据查询接口类型优化
feat: 完善gitee、github登录异常逻辑
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
|
||||
## 架构图
|
||||
|
||||

|
||||

|
||||
|
||||
## 项目介绍
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
│ ├─数据源
|
||||
│ ├─代码生成
|
||||
│ ├─自助API
|
||||
│ └─自助大屏(开发中...)
|
||||
│ └─自助大屏
|
||||
├─系统管理
|
||||
│ ├─菜单管理
|
||||
│ ├─组织管理
|
||||
@@ -114,6 +114,10 @@
|
||||
<td><img src="https://mfish-pic.pages.dev/login.png" /></td>
|
||||
<td><img src="https://mfish-pic.pages.dev/menu.png" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://mfish-pic.pages.dev/screen.png" /></td>
|
||||
<td><img src="https://mfish-pic.pages.dev/screenConfig.png" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://mfish-pic.pages.dev/api.png" /></td>
|
||||
<td><img src="https://mfish-pic.pages.dev/flow.png" /></td>
|
||||
|
||||
+1
@@ -60,6 +60,7 @@ public class DataConstant {
|
||||
public static final String NUMBER = "NUMBER";
|
||||
public static final String DATETIME = "DATETIME";
|
||||
public static final String TIME = "TIME";
|
||||
public static final String TIMETZ = "TIMETZ";
|
||||
public static final String TIMESTAMP = "TIMESTAMP";
|
||||
public static final String DATETIMEOFFSET = "DATETIMEOFFSET";
|
||||
public static final String DATE = "DATE";
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -217,7 +218,7 @@ public class OkHttpUtils {
|
||||
* @return 构建好的OkHttpClient实例
|
||||
*/
|
||||
private static OkHttpClient buildOkHttpClient(String url, TimeOut timeOut) {
|
||||
OkHttpClient.Builder clientBuilder = new OkHttpClient().newBuilder();
|
||||
OkHttpClient.Builder clientBuilder = new OkHttpClient().newBuilder().protocols(List.of(Protocol.HTTP_1_1));
|
||||
if (timeOut != null) {
|
||||
clientBuilder.connectTimeout(timeOut.getConnectTimeOut(), timeOut.getTimeUnit())
|
||||
.readTimeout(timeOut.getReadTimeOut(), timeOut.getTimeUnit())
|
||||
|
||||
+2
@@ -2,6 +2,7 @@ package cn.com.mfish.common.dblink.db;
|
||||
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.dblink.entity.QueryParam;
|
||||
import cn.com.mfish.common.dblink.enums.DBType;
|
||||
import cn.com.mfish.common.dblink.page.BoundSql;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
@@ -39,6 +40,7 @@ public abstract class AbstractDBDialect implements DBDialect {
|
||||
*/
|
||||
protected BoundSql buildCondition(String sql, String dbName, String tableName) {
|
||||
BoundSql boundSql = new BoundSql();
|
||||
boundSql.setDbType(DBType.mysql);
|
||||
if (!StringUtils.isEmpty(tableName)) {
|
||||
sql += " and (table_name = ? or table_name = ?) ";
|
||||
boundSql.getParams().add(new QueryParam().setValue(tableName.toUpperCase()));
|
||||
|
||||
+2
@@ -2,6 +2,7 @@ package cn.com.mfish.common.dblink.db;
|
||||
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.dblink.entity.QueryParam;
|
||||
import cn.com.mfish.common.dblink.enums.DBType;
|
||||
import cn.com.mfish.common.dblink.page.BoundSql;
|
||||
|
||||
import java.util.Locale;
|
||||
@@ -56,6 +57,7 @@ public class OracleDBDialect implements DBDialect {
|
||||
|
||||
private BoundSql buildCondition(String sql, String tableName) {
|
||||
BoundSql boundSql = new BoundSql();
|
||||
boundSql.setDbType(DBType.oracle);
|
||||
if (!StringUtils.isEmpty(tableName)) {
|
||||
//这里虽然匹配大小写,但是建议oracle表名视图都创建大写名称,避免数据查询时无法查到
|
||||
sql += " and (a.TABLE_NAME = ? or a.TABLE_NAME = ?)";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.com.mfish.common.dblink.page;
|
||||
|
||||
import cn.com.mfish.common.dblink.entity.QueryParam;
|
||||
import cn.com.mfish.common.dblink.enums.DBType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
@@ -17,6 +18,8 @@ import java.util.List;
|
||||
@Accessors(chain = true)
|
||||
@Schema(description = "sql包装")
|
||||
public class BoundSql {
|
||||
@Schema(description = "数据库类型")
|
||||
private DBType dbType;
|
||||
@Schema(description = "查询SQL")
|
||||
private String sql;
|
||||
@Schema(description = "查询参数")
|
||||
@@ -42,6 +45,11 @@ public class BoundSql {
|
||||
* @param params 参数
|
||||
*/
|
||||
public BoundSql(String sql, List<QueryParam> params) {
|
||||
this(DBType.mysql, sql, params);
|
||||
}
|
||||
|
||||
public BoundSql(DBType dbType, String sql, List<QueryParam> params) {
|
||||
this.dbType = dbType;
|
||||
this.sql = sql;
|
||||
if (params == null) {
|
||||
params = new ArrayList<>();
|
||||
|
||||
+22
-15
@@ -1,21 +1,24 @@
|
||||
package cn.com.mfish.common.dblink.query;
|
||||
|
||||
import cn.com.mfish.common.core.constants.DataConstant;
|
||||
import cn.com.mfish.common.core.enums.DataType;
|
||||
import cn.com.mfish.common.core.exception.MyRuntimeException;
|
||||
import cn.com.mfish.common.core.utils.DataUtils;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.core.utils.Utils;
|
||||
import cn.com.mfish.common.core.utils.DataUtils;
|
||||
import cn.com.mfish.common.dataset.datatable.MetaDataHeader;
|
||||
import cn.com.mfish.common.dataset.datatable.MetaDataHeaders;
|
||||
import cn.com.mfish.common.dataset.datatable.MetaDataRow;
|
||||
import cn.com.mfish.common.dataset.datatable.MetaDataTable;
|
||||
import cn.com.mfish.common.dataset.enums.TargetType;
|
||||
import cn.com.mfish.common.core.constants.DataConstant;
|
||||
import cn.com.mfish.common.dblink.entity.DataSourceOptions;
|
||||
import cn.com.mfish.common.dblink.enums.DBType;
|
||||
import cn.com.mfish.common.dblink.manger.PoolManager;
|
||||
import cn.com.mfish.common.dblink.page.BoundSql;
|
||||
import com.github.pagehelper.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import oracle.sql.TIMESTAMP;
|
||||
import oracle.sql.TIMESTAMPTZ;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -54,7 +57,7 @@ public class BaseQuery {
|
||||
public MetaDataTable query(BoundSql boundSql) {
|
||||
return query(boundSql, rs -> {
|
||||
try {
|
||||
return getMetaDataTable(rs, getColHeaders(rs.getMetaData()));
|
||||
return getMetaDataTable(rs, getColHeaders(rs.getMetaData()), boundSql.getDbType());
|
||||
} catch (SQLException e) {
|
||||
log.error("获取metaData异常:{}", boundSql.getSql(), e);
|
||||
throw new MyRuntimeException(e);
|
||||
@@ -269,7 +272,7 @@ public class BaseQuery {
|
||||
* @return 返回元数据表格
|
||||
* @throws SQLException 异常
|
||||
*/
|
||||
protected MetaDataTable getMetaDataTable(final ResultSet rs, final MetaDataHeaders headers) throws SQLException {
|
||||
protected MetaDataTable getMetaDataTable(final ResultSet rs, final MetaDataHeaders headers, DBType dbType) throws SQLException {
|
||||
final MetaDataTable table = new MetaDataTable(headers);
|
||||
long start = System.currentTimeMillis();
|
||||
while (rs.next()) {
|
||||
@@ -279,10 +282,17 @@ public class BaseQuery {
|
||||
while (iterator.hasNext()) {
|
||||
String type = rs.getMetaData().getColumnTypeName(i).toUpperCase(Locale.ROOT);
|
||||
Object value = formatValue(type, rs.getObject(i));
|
||||
//MetaDataTable返回类型为日期时,强制格式为字符类型
|
||||
if (value instanceof java.util.Date) {
|
||||
//MetaDataTable返回类型日期强制格式为 yyyy-MM-dd HH:mm:ss
|
||||
if (type.equals(DataConstant.DataType.DATE)) {
|
||||
value = new SimpleDateFormat("yyyy-MM-dd").format(value);
|
||||
//oracle没有dateTime,time等类型不进行转换
|
||||
if (dbType != DBType.oracle) {
|
||||
if (type.equals(DataConstant.DataType.DATE)) {
|
||||
value = new SimpleDateFormat("yyyy-MM-dd").format(value);
|
||||
} else if (type.equals(DataConstant.DataType.TIME) || type.equals(DataConstant.DataType.TIMETZ)) {
|
||||
value = new SimpleDateFormat("HH:mm:ss").format(value);
|
||||
} else {
|
||||
value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value);
|
||||
}
|
||||
} else {
|
||||
value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value);
|
||||
}
|
||||
@@ -304,7 +314,7 @@ public class BaseQuery {
|
||||
* @param value 查询值
|
||||
* @return 返回格式化后的值
|
||||
*/
|
||||
public Object formatValue(String columnTypeName, Object value) {
|
||||
public Object formatValue(String columnTypeName, Object value) throws SQLException {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -319,13 +329,10 @@ public class BaseQuery {
|
||||
//LocalDateTime 转成Date类型
|
||||
value = value instanceof LocalDateTime ? Date.from(((LocalDateTime) value).atZone(ZoneId.systemDefault()).toInstant()) : value;
|
||||
} else if (columnTypeName.contains(DataConstant.DataType.TIMESTAMP)) {
|
||||
String time = value.toString();
|
||||
if (!StringUtils.isEmpty(time)) {
|
||||
try {
|
||||
value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time.substring(0, time.length() - 2));
|
||||
} catch (ParseException e) {
|
||||
log.error("错误:日期转换异常");
|
||||
}
|
||||
if (value instanceof TIMESTAMPTZ) {
|
||||
value = Date.from(((TIMESTAMPTZ) value).toLocalDateTime().atZone(ZoneId.systemDefault()).toInstant());
|
||||
} else if (value instanceof TIMESTAMP) {
|
||||
value = Date.from(((TIMESTAMP) value).toLocalDateTime().atZone(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
}
|
||||
return value;
|
||||
|
||||
+4
-4
@@ -48,7 +48,7 @@ public class QueryHandler {
|
||||
* @return 返回结果集
|
||||
*/
|
||||
public static MetaDataTable query(DataSourceOptions<?> dataSourceOptions, String strSql, List<QueryParam> params) {
|
||||
return query(dataSourceOptions, new BoundSql(strSql, params), null);
|
||||
return query(dataSourceOptions, new BoundSql(dataSourceOptions.getDbType(), strSql, params), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +75,7 @@ public class QueryHandler {
|
||||
* @return 返回结果集
|
||||
*/
|
||||
public static MetaDataTable query(DataSourceOptions<?> dataSourceOptions, String strSql, List<QueryParam> params, RowBounds rowBounds) {
|
||||
return query(dataSourceOptions, new BoundSql(strSql, params), rowBounds);
|
||||
return query(dataSourceOptions, new BoundSql(dataSourceOptions.getDbType(), strSql, params), rowBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ public class QueryHandler {
|
||||
* @return 返回翻页结果集
|
||||
*/
|
||||
public static <T> Page<T> queryT(DataSourceOptions<?> dataSourceOptions, String strSql, List<QueryParam> params, Class<T> cls) {
|
||||
return queryT(dataSourceOptions, new BoundSql(strSql, params), null, cls);
|
||||
return queryT(dataSourceOptions, new BoundSql(dataSourceOptions.getDbType(), strSql, params), null, cls);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,7 +136,7 @@ public class QueryHandler {
|
||||
* @return 返回翻页结果集
|
||||
*/
|
||||
public static <T> Page<T> queryT(DataSourceOptions<?> dataSourceOptions, String strSql, List<QueryParam> params, RowBounds rowBounds, Class<T> cls) {
|
||||
return queryT(dataSourceOptions, new BoundSql(strSql, params), rowBounds, cls);
|
||||
return queryT(dataSourceOptions, new BoundSql(dataSourceOptions.getDbType(), strSql, params), rowBounds, cls);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
@@ -28,11 +28,14 @@ public interface SsoUserService extends IService<SsoUser> {
|
||||
|
||||
Result<SsoUser> updateUser(SsoUser user);
|
||||
|
||||
void validateUser(SsoUser user, String operate);
|
||||
|
||||
boolean removeUser(String id);
|
||||
|
||||
SsoUser getUserByAccount(String account);
|
||||
|
||||
SsoUser getUserByGitee(String gitee);
|
||||
|
||||
SsoUser getUserByGithub(String github);
|
||||
|
||||
UserInfo getUserByAccountNoPwd(String account);
|
||||
|
||||
@@ -66,7 +66,7 @@ public class GiteeController {
|
||||
}
|
||||
result = loginService.login(result.getData(), token, SerConstant.LoginType.Gitee, "system", "false");
|
||||
if (!result.isSuccess()) {
|
||||
return Result.fail("错误:登录失败");
|
||||
return Result.fail(result.getMsg());
|
||||
}
|
||||
return Result.ok(0, "登录成功");
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public class GithubController {
|
||||
param.put("redirect_uri", redirectUri);
|
||||
Map<String, String> header = new HashMap<>();
|
||||
header.put("Accept", "application/json");
|
||||
Result<String> result = OkHttpUtils.postJson("https://github.com/login/oauth/access_token", JSON.toJSONString(param));
|
||||
Result<String> result = OkHttpUtils.postJson("https://github.com/login/oauth/access_token", JSON.toJSONString(param), header);
|
||||
JSONObject jsonObject;
|
||||
if (!result.isSuccess()) {
|
||||
return Result.fail("错误:请求github token失败");
|
||||
@@ -67,7 +67,7 @@ public class GithubController {
|
||||
}
|
||||
result = loginService.login(result.getData(), token, SerConstant.LoginType.Github, "system", "false");
|
||||
if (!result.isSuccess()) {
|
||||
return Result.fail("错误:登录失败");
|
||||
return Result.fail(result.getMsg());
|
||||
}
|
||||
return Result.ok(0, "登录成功");
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public class GitRealm extends AuthorizingRealm {
|
||||
if (null != user) return user;
|
||||
user = ssoUserService.getUserByAccount(username);
|
||||
String account;
|
||||
if (user == null) {
|
||||
if (user == null && StringUtils.isMatch("^[a-zA-Z0-9]+$", username)) {
|
||||
account = username;
|
||||
} else {
|
||||
account = IDBuild.getID("G");
|
||||
@@ -65,7 +65,11 @@ public class GitRealm extends AuthorizingRealm {
|
||||
SsoUser userInfo = new SsoUser();
|
||||
userInfo.setId(Utils.uuid32());
|
||||
userInfo.setAccount(account);
|
||||
userInfo.setGitee(username);
|
||||
if (myToken.getLoginType() == SerConstant.LoginType.Github) {
|
||||
userInfo.setGithub(username);
|
||||
} else {
|
||||
userInfo.setGitee(username);
|
||||
}
|
||||
userInfo.setNickname(json.getString("name"));
|
||||
userInfo.setEmail(json.getString("email"));
|
||||
userInfo.setHeadImgUrl(json.getString("avatar_url"));
|
||||
|
||||
@@ -75,7 +75,7 @@ public class LoginServiceImpl implements LoginService {
|
||||
* 本方法主要用于校验授权码(code)的有效性通过HTTP请求参数进行校验如果校验失败,
|
||||
* 会将错误信息添加到模型中并返回false否则,返回true表示校验成功
|
||||
*
|
||||
* @param model 用于存储属性值,在发生错误时用于存储错误信息
|
||||
* @param model 用于存储属性值,在发生错误时用于存储错误信息
|
||||
* @param request HTTP请求对象,用于获取请求参数
|
||||
* @return boolean 校验是否成功
|
||||
*/
|
||||
@@ -91,7 +91,7 @@ public class LoginServiceImpl implements LoginService {
|
||||
/**
|
||||
* web请求登录 构建model返回值
|
||||
*
|
||||
* @param model 用于存储属性值,在发生错误时用于存储错误信息
|
||||
* @param model 用于存储属性值,在发生错误时用于存储错误信息
|
||||
* @param request HTTP请求对象,用于获取请求参数
|
||||
* @return boolean 校验是否成功
|
||||
*/
|
||||
@@ -124,8 +124,8 @@ public class LoginServiceImpl implements LoginService {
|
||||
/**
|
||||
* 登录用户验证逻辑
|
||||
*
|
||||
* @param username 账号
|
||||
* @param password 密码
|
||||
* @param username 账号
|
||||
* @param password 密码
|
||||
* @param loginType 登陆类型
|
||||
* @return 返回登陆结果
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package cn.com.mfish.oauth.service.impl;
|
||||
|
||||
import cn.com.mfish.common.core.exception.MyRuntimeException;
|
||||
import cn.com.mfish.common.core.exception.OAuthValidateException;
|
||||
import cn.com.mfish.common.core.utils.AuthInfoUtils;
|
||||
import cn.com.mfish.common.core.utils.StringUtils;
|
||||
import cn.com.mfish.common.core.web.ReqPage;
|
||||
@@ -9,7 +8,6 @@ import cn.com.mfish.common.core.web.Result;
|
||||
import cn.com.mfish.common.oauth.api.entity.SsoOrg;
|
||||
import cn.com.mfish.common.oauth.api.entity.SsoTenant;
|
||||
import cn.com.mfish.common.oauth.api.vo.TenantVo;
|
||||
import cn.com.mfish.common.oauth.common.SerConstant;
|
||||
import cn.com.mfish.common.oauth.entity.SsoUser;
|
||||
import cn.com.mfish.common.oauth.service.SsoOrgService;
|
||||
import cn.com.mfish.common.oauth.service.SsoUserService;
|
||||
@@ -24,6 +22,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -220,11 +219,17 @@ public class SsoTenantServiceImpl extends ServiceImpl<SsoTenantMapper, SsoTenant
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createTenantUser(SsoUser ssoUser) {
|
||||
Result<SsoUser> result = ssoUserService.insertUser(ssoUser);
|
||||
Result<SsoUser> result;
|
||||
try {
|
||||
result = ssoUserService.insertUser(ssoUser);
|
||||
} catch (MyRuntimeException ex) {
|
||||
//包装成shiro异常,便于shiro统一处理
|
||||
throw new IncorrectCredentialsException(ex.getMessage());
|
||||
}
|
||||
if (!result.isSuccess()) {
|
||||
throw new OAuthValidateException(SerConstant.INVALID_NEW_USER_DESCRIPTION);
|
||||
throw new IncorrectCredentialsException(result.getMsg());
|
||||
}
|
||||
SsoTenant ssoTenant = new SsoTenant();
|
||||
ssoTenant.setUserId(ssoUser.getId());
|
||||
@@ -236,9 +241,14 @@ public class SsoTenantServiceImpl extends ServiceImpl<SsoTenantMapper, SsoTenant
|
||||
ssoTenant.setStatus(0);
|
||||
ssoTenant.setTenantType(0);
|
||||
ssoTenant.setRoleIds(List.of(AuthInfoUtils.PERSON_ROLE_ID));
|
||||
Result<SsoTenant> result1 = insertTenant(ssoTenant);
|
||||
Result<SsoTenant> result1;
|
||||
try {
|
||||
result1 = insertTenant(ssoTenant);
|
||||
} catch (MyRuntimeException ex) {
|
||||
throw new IncorrectCredentialsException(ex.getMessage());
|
||||
}
|
||||
if (!result1.isSuccess()) {
|
||||
throw new OAuthValidateException("错误:创建新租户失败");
|
||||
throw new IncorrectCredentialsException("错误:创建新租户失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,8 @@ public class SsoUserServiceImpl extends ServiceImpl<SsoUserMapper, SsoUser> impl
|
||||
* @param user 用户
|
||||
* @param operate 操作
|
||||
*/
|
||||
private void validateUser(SsoUser user, String operate) {
|
||||
@Override
|
||||
public void validateUser(SsoUser user, String operate) {
|
||||
if (isAccountExist(user.getAccount(), user.getId())) {
|
||||
throw new MyRuntimeException("错误:帐号已存在-" + operate + "失败!");
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ let app = new Vue({
|
||||
captchaKey: '',
|
||||
captchaUrl: '',
|
||||
phone: '',
|
||||
username: 'mfish',
|
||||
password: '!QAZ2wsx',
|
||||
username: '',
|
||||
password: '',
|
||||
loginType: '',
|
||||
loginTypeName: '帐号',
|
||||
errorMsg: '',
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
<div class="card fat">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title mb-3">{{loginTypeName}}登录</h4>
|
||||
<h6 style="color: red">演示环境,请使用最下方gitee账号一键登录</h6>
|
||||
<div v-show="userPasswordVisible">
|
||||
<form id="login" method="POST" class="enter-x">
|
||||
<div class="form-floating mb-3">
|
||||
@@ -173,7 +174,7 @@
|
||||
<div v-show="qrCodeVisible" class="enter-x">
|
||||
<form id="qrCodeLogin" method="post">
|
||||
<input type="hidden" v-model="qrCodeName" name="username"/>
|
||||
<input type="hiddean" v-model="qrCodeSecret" name="password"/>
|
||||
<input type="hidden" v-model="qrCodeSecret" name="password"/>
|
||||
<input type="hidden" v-model="loginType" name="loginType"/>
|
||||
</form>
|
||||
<div class="qrcode-img mb-3">
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user