mirror of
https://gitee.com/ssssssss-team/magic-boot.git
synced 2025-02-22 10:42:48 +08:00
在线用户,验证码,bug修复,代码优化
This commit is contained in:
parent
6401c76e65
commit
bdea28e66e
10
data/magic-api/api/后台/在线用户/group.json
Normal file
10
data/magic-api/api/后台/在线用户/group.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"properties" : { },
|
||||||
|
"id" : "d95a58e77d314370862ffc4cdfdb8283",
|
||||||
|
"name" : "在线用户",
|
||||||
|
"type" : "api",
|
||||||
|
"parentId" : "02df51e4d7184780a98b632f43dc5848",
|
||||||
|
"path" : "/online",
|
||||||
|
"paths" : [ ],
|
||||||
|
"options" : [ ]
|
||||||
|
}
|
126
data/magic-api/api/后台/在线用户/列表.ms
Normal file
126
data/magic-api/api/后台/在线用户/列表.ms
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
{
|
||||||
|
"properties" : { },
|
||||||
|
"id" : "d5ccf62c6d2c482e995ce7fe237e9ed3",
|
||||||
|
"script" : null,
|
||||||
|
"groupId" : "d95a58e77d314370862ffc4cdfdb8283",
|
||||||
|
"name" : "列表",
|
||||||
|
"createTime" : null,
|
||||||
|
"updateTime" : 1647396892675,
|
||||||
|
"lock" : null,
|
||||||
|
"createBy" : null,
|
||||||
|
"updateBy" : null,
|
||||||
|
"path" : "/list",
|
||||||
|
"method" : "POST",
|
||||||
|
"parameters" : [ ],
|
||||||
|
"options" : [ ],
|
||||||
|
"requestBody" : "",
|
||||||
|
"headers" : [ ],
|
||||||
|
"paths" : [ ],
|
||||||
|
"responseBody" : "{\n \"code\": 200,\n \"message\": \"success\",\n \"data\": [\"cb63a01c-63d7-4722-a2c4-48fffa4b3502\", \"876dd178-0065-42d5-989a-a6ef460113b1\"],\n \"timestamp\": 1647396771372,\n \"executeTime\": 11\n}",
|
||||||
|
"description" : null,
|
||||||
|
"requestBodyDefinition" : null,
|
||||||
|
"responseBodyDefinition" : {
|
||||||
|
"name" : "",
|
||||||
|
"value" : "",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Object",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "code",
|
||||||
|
"value" : "200",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Integer",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "message",
|
||||||
|
"value" : "success",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "data",
|
||||||
|
"value" : "",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Object",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "",
|
||||||
|
"value" : "cb63a01c-63d7-4722-a2c4-48fffa4b3502",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"name" : "timestamp",
|
||||||
|
"value" : "1647396771372",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Long",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "executeTime",
|
||||||
|
"value" : "11",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Object",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
================================
|
||||||
|
import cn.dev33.satoken.stp.StpUtil
|
||||||
|
var tokens = StpUtil.searchTokenValue("", -1, 0).map(it => it.replace('token:login:token:', ''))
|
||||||
|
|
||||||
|
return db.page("""
|
||||||
|
select
|
||||||
|
su.username,
|
||||||
|
so.name office_name,
|
||||||
|
sll.token,
|
||||||
|
sll.ip,
|
||||||
|
sll.browser,
|
||||||
|
sll.os,
|
||||||
|
sll.create_date
|
||||||
|
from sys_login_log sll left join sys_user su on sll.username = su.username left join sys_office so on su.office_id = so.id
|
||||||
|
where sll.token in (#{tokens})
|
||||||
|
?{username, and su.username like concat('%', #{username}, '%')}
|
||||||
|
?{ip, and sll.ip like concat('%', #{ip}, '%')}
|
||||||
|
order by sll.create_date desc
|
||||||
|
""")
|
26
data/magic-api/api/后台/在线用户/踢人.ms
Normal file
26
data/magic-api/api/后台/在线用户/踢人.ms
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"properties" : { },
|
||||||
|
"id" : "01fb971510764df3be20209905e86fab",
|
||||||
|
"script" : null,
|
||||||
|
"groupId" : "d95a58e77d314370862ffc4cdfdb8283",
|
||||||
|
"name" : "踢人",
|
||||||
|
"createTime" : null,
|
||||||
|
"updateTime" : 1647397091507,
|
||||||
|
"lock" : null,
|
||||||
|
"createBy" : null,
|
||||||
|
"updateBy" : null,
|
||||||
|
"path" : "/logout",
|
||||||
|
"method" : "GET",
|
||||||
|
"parameters" : [ ],
|
||||||
|
"options" : [ ],
|
||||||
|
"requestBody" : "",
|
||||||
|
"headers" : [ ],
|
||||||
|
"paths" : [ ],
|
||||||
|
"responseBody" : null,
|
||||||
|
"description" : null,
|
||||||
|
"requestBodyDefinition" : null,
|
||||||
|
"responseBodyDefinition" : null
|
||||||
|
}
|
||||||
|
================================
|
||||||
|
import cn.dev33.satoken.stp.StpUtil
|
||||||
|
return StpUtil.logoutByTokenValue(token);
|
@ -5,13 +5,49 @@
|
|||||||
"groupId" : "1952f25c81084e24b55b11385767dc38",
|
"groupId" : "1952f25c81084e24b55b11385767dc38",
|
||||||
"name" : "登录",
|
"name" : "登录",
|
||||||
"createTime" : null,
|
"createTime" : null,
|
||||||
"updateTime" : 1646544815203,
|
"updateTime" : 1647396539380,
|
||||||
"lock" : "0",
|
"lock" : "0",
|
||||||
"createBy" : null,
|
"createBy" : null,
|
||||||
"updateBy" : null,
|
"updateBy" : null,
|
||||||
"path" : "/login",
|
"path" : "/login",
|
||||||
"method" : "POST",
|
"method" : "POST",
|
||||||
"parameters" : [ ],
|
"parameters" : [ {
|
||||||
|
"name" : "username",
|
||||||
|
"value" : null,
|
||||||
|
"description" : null,
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : null,
|
||||||
|
"error" : null,
|
||||||
|
"expression" : null,
|
||||||
|
"children" : null
|
||||||
|
}, {
|
||||||
|
"name" : "password",
|
||||||
|
"value" : null,
|
||||||
|
"description" : null,
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : null,
|
||||||
|
"error" : null,
|
||||||
|
"expression" : null,
|
||||||
|
"children" : null
|
||||||
|
}, {
|
||||||
|
"name" : "code",
|
||||||
|
"value" : null,
|
||||||
|
"description" : null,
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : null,
|
||||||
|
"error" : null,
|
||||||
|
"expression" : null,
|
||||||
|
"children" : null
|
||||||
|
} ],
|
||||||
"options" : [ {
|
"options" : [ {
|
||||||
"name" : "require_login",
|
"name" : "require_login",
|
||||||
"value" : "false",
|
"value" : "false",
|
||||||
@ -28,7 +64,7 @@
|
|||||||
"requestBody" : "{\r\n \"username\": \"admin\",\r\n \"password\": \"123456\"\r\n}",
|
"requestBody" : "{\r\n \"username\": \"admin\",\r\n \"password\": \"123456\"\r\n}",
|
||||||
"headers" : [ ],
|
"headers" : [ ],
|
||||||
"paths" : [ ],
|
"paths" : [ ],
|
||||||
"responseBody" : "{\"code\":200,\"message\":\"success\",\"data\":\"60f0ddf8-c42c-4b3e-802f-7482f6bd1075\",\"timestamp\":1646493023758,\"executeTime\":316}",
|
"responseBody" : "{\n \"code\": 200,\n \"message\": \"success\",\n \"data\": \"cb63a01c-63d7-4722-a2c4-48fffa4b3502\",\n \"timestamp\": 1647395770056,\n \"executeTime\": 20\n}",
|
||||||
"description" : null,
|
"description" : null,
|
||||||
"requestBodyDefinition" : {
|
"requestBodyDefinition" : {
|
||||||
"name" : "",
|
"name" : "",
|
||||||
@ -104,10 +140,10 @@
|
|||||||
"children" : [ ]
|
"children" : [ ]
|
||||||
}, {
|
}, {
|
||||||
"name" : "data",
|
"name" : "data",
|
||||||
"value" : "60f0ddf8-c42c-4b3e-802f-7482f6bd1075",
|
"value" : "cb63a01c-63d7-4722-a2c4-48fffa4b3502",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"dataType" : "String",
|
"dataType" : "Object",
|
||||||
"type" : null,
|
"type" : null,
|
||||||
"defaultValue" : null,
|
"defaultValue" : null,
|
||||||
"validateType" : "",
|
"validateType" : "",
|
||||||
@ -116,7 +152,7 @@
|
|||||||
"children" : [ ]
|
"children" : [ ]
|
||||||
}, {
|
}, {
|
||||||
"name" : "timestamp",
|
"name" : "timestamp",
|
||||||
"value" : "1646493023758",
|
"value" : "1647395770056",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"dataType" : "Long",
|
"dataType" : "Long",
|
||||||
@ -128,7 +164,7 @@
|
|||||||
"children" : [ ]
|
"children" : [ ]
|
||||||
}, {
|
}, {
|
||||||
"name" : "executeTime",
|
"name" : "executeTime",
|
||||||
"value" : "316",
|
"value" : "20",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"dataType" : "Integer",
|
"dataType" : "Integer",
|
||||||
@ -147,6 +183,15 @@ import 'cn.dev33.satoken.secure.SaSecureUtil';
|
|||||||
import 'cn.dev33.satoken.stp.StpUtil';
|
import 'cn.dev33.satoken.stp.StpUtil';
|
||||||
import env;
|
import env;
|
||||||
import request;
|
import request;
|
||||||
|
import org.ssssssss.magicboot.model.CodeCacheMap
|
||||||
|
import cn.hutool.http.useragent.UserAgentUtil
|
||||||
|
import cn.hutool.http.useragent.UserAgent
|
||||||
|
|
||||||
|
UserAgent ua = UserAgentUtil.parse(request.getHeaders("User-Agent")[0])
|
||||||
|
|
||||||
|
if(body.code != CodeCacheMap.get(body.uuid)){
|
||||||
|
exit 0, '验证码错误'
|
||||||
|
}
|
||||||
|
|
||||||
var user
|
var user
|
||||||
if(env.get('super-password') == body.password){
|
if(env.get('super-password') == body.password){
|
||||||
@ -158,15 +203,21 @@ if(env.get('super-password') == body.password){
|
|||||||
var loginLog = {
|
var loginLog = {
|
||||||
username: body.username,
|
username: body.username,
|
||||||
type: '成功',
|
type: '成功',
|
||||||
ip: request.getClientIP()
|
ip: request.getClientIP(),
|
||||||
|
browser: ua.getBrowser().toString(),
|
||||||
|
os: ua.getOs().toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!user){
|
if(!user){
|
||||||
loginLog.failPassword = body.password
|
loginLog.failPassword = body.password
|
||||||
|
loginLog.type = '失败'
|
||||||
db.table("sys_login_log").primary("id").save(loginLog);
|
db.table("sys_login_log").primary("id").save(loginLog);
|
||||||
exit 0,'用户名或密码错误'
|
exit 0,'用户名或密码错误'
|
||||||
}
|
}
|
||||||
db.table("sys_login_log").primary("id").save(loginLog);
|
|
||||||
|
|
||||||
StpUtil.login(user.id)
|
StpUtil.login(user.id)
|
||||||
|
var token = StpUtil.getTokenValueByLoginId(user.id)
|
||||||
|
loginLog.token = token
|
||||||
|
db.table("sys_login_log").primary("id").save(loginLog);
|
||||||
|
CodeCacheMap.remove(body.uuid)
|
||||||
return StpUtil.getTokenValueByLoginId(user.id)
|
return StpUtil.getTokenValueByLoginId(user.id)
|
149
data/magic-api/api/后台/安全/验证码.ms
Normal file
149
data/magic-api/api/后台/安全/验证码.ms
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
{
|
||||||
|
"properties" : { },
|
||||||
|
"id" : "be89865140ab409085db6d0cc6d82452",
|
||||||
|
"script" : null,
|
||||||
|
"groupId" : "1952f25c81084e24b55b11385767dc38",
|
||||||
|
"name" : "验证码",
|
||||||
|
"createTime" : null,
|
||||||
|
"updateTime" : 1647333578623,
|
||||||
|
"lock" : null,
|
||||||
|
"createBy" : null,
|
||||||
|
"updateBy" : null,
|
||||||
|
"path" : "/verification/code",
|
||||||
|
"method" : "GET",
|
||||||
|
"parameters" : [ ],
|
||||||
|
"options" : [ {
|
||||||
|
"name" : "require_login",
|
||||||
|
"value" : "false",
|
||||||
|
"description" : "该接口需要登录才允许访问",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : null,
|
||||||
|
"error" : null,
|
||||||
|
"expression" : null,
|
||||||
|
"children" : null
|
||||||
|
} ],
|
||||||
|
"requestBody" : "",
|
||||||
|
"headers" : [ ],
|
||||||
|
"paths" : [ ],
|
||||||
|
"responseBody" : "{\n \"code\": 200,\n \"message\": \"success\",\n \"data\": {\n \"img\": \"data:image/png;base64,[B@65617f6d\",\n \"uuid\": \"9a080e570e0346bf8b80c035c977c888\"\n },\n \"timestamp\": 1647333558240,\n \"executeTime\": 15\n}",
|
||||||
|
"description" : null,
|
||||||
|
"requestBodyDefinition" : null,
|
||||||
|
"responseBodyDefinition" : {
|
||||||
|
"name" : "",
|
||||||
|
"value" : "",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Object",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "code",
|
||||||
|
"value" : "200",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Integer",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "message",
|
||||||
|
"value" : "success",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "data",
|
||||||
|
"value" : "",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Object",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ {
|
||||||
|
"name" : "img",
|
||||||
|
"value" : "data:image/png;base64,[B@65617f6d",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "uuid",
|
||||||
|
"value" : "9a080e570e0346bf8b80c035c977c888",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "String",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
"name" : "timestamp",
|
||||||
|
"value" : "1647333558240",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Long",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
}, {
|
||||||
|
"name" : "executeTime",
|
||||||
|
"value" : "15",
|
||||||
|
"description" : "",
|
||||||
|
"required" : false,
|
||||||
|
"dataType" : "Integer",
|
||||||
|
"type" : null,
|
||||||
|
"defaultValue" : null,
|
||||||
|
"validateType" : "",
|
||||||
|
"error" : "",
|
||||||
|
"expression" : "",
|
||||||
|
"children" : [ ]
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
================================
|
||||||
|
import cn.hutool.captcha.LineCaptcha
|
||||||
|
import cn.hutool.captcha.CaptchaUtil
|
||||||
|
import log
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.OutputStream
|
||||||
|
import org.ssssssss.magicboot.model.CodeCacheMap
|
||||||
|
|
||||||
|
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 48);
|
||||||
|
var uuid = UUID.randomUUID().toString().replace('-', '')
|
||||||
|
CodeCacheMap.put(uuid, lineCaptcha.getCode())
|
||||||
|
OutputStream bOut = new ByteArrayOutputStream();
|
||||||
|
lineCaptcha.write(bOut)
|
||||||
|
var bytes = bOut.toByteArray()
|
||||||
|
return {
|
||||||
|
img: bytes,
|
||||||
|
uuid: uuid
|
||||||
|
}
|
@ -23,10 +23,6 @@
|
|||||||
border: 1px solid #efefef
|
border: 1px solid #efefef
|
||||||
}
|
}
|
||||||
body{
|
body{
|
||||||
--el-dialog__wrapper-bottom: 15vh;
|
|
||||||
--el-dialog__wrapper-top: 15vh;
|
|
||||||
--el-dialog__body-max-height: 60vh;
|
|
||||||
|
|
||||||
--mb-main-color: #409EFF;
|
--mb-main-color: #409EFF;
|
||||||
--mb-sidebar-width: 240px;
|
--mb-sidebar-width: 240px;
|
||||||
--mb-main-icon-color: #909399;
|
--mb-main-icon-color: #909399;
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
import {ref, reactive, getCurrentInstance, defineExpose } from 'vue'
|
import {ref, reactive, getCurrentInstance, defineExpose } from 'vue'
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const rules = reactive(getRules())
|
const rules = reactive(getRules())
|
||||||
const formData = ref(getFormData())
|
const formData = ref(initFormData())
|
||||||
const dataForm = ref()
|
const dataForm = ref()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
form: {
|
form: {
|
||||||
@ -42,14 +42,14 @@
|
|||||||
proxy.$common.setDefaultValue(props.form.props, 'labelPosition', 'right')
|
proxy.$common.setDefaultValue(props.form.props, 'labelPosition', 'right')
|
||||||
proxy.$common.setDefaultValue(props.form.props, 'labelWidth', '120px')
|
proxy.$common.setDefaultValue(props.form.props, 'labelWidth', '120px')
|
||||||
|
|
||||||
if(props.detail.formData){
|
if(props.detail && props.detail.formData){
|
||||||
if(props.detail.handlerFormData){
|
if(props.detail.handlerFormData){
|
||||||
props.detail.handlerFormData(props.detail.formData)
|
props.detail.handlerFormData(props.detail.formData)
|
||||||
}
|
}
|
||||||
formData.value = props.detail.formData
|
formData.value = props.detail.formData
|
||||||
}
|
}
|
||||||
|
|
||||||
if(props.detail.request){
|
if(props.detail && props.detail.request){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,16 +65,21 @@
|
|||||||
return _rules
|
return _rules
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormData() {
|
function initFormData() {
|
||||||
var data = {}
|
var data = {}
|
||||||
props.form.rows.forEach(row => {
|
props.form.rows.forEach(row => {
|
||||||
row.cols.forEach(col => {
|
row.cols.forEach(col => {
|
||||||
data[col.name] = col.defaultValue === null ? col.defaultValue : col.defaultValue || ''
|
// data[col.name] = col.defaultValue === null ? col.defaultValue : col.defaultValue || ''
|
||||||
|
data[col.name] = undefined
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFormData(){
|
||||||
|
return formData.value
|
||||||
|
}
|
||||||
|
|
||||||
function save(d) {
|
function save(d) {
|
||||||
dataForm.value.validate((valid) => {
|
dataForm.value.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
@ -87,7 +92,7 @@
|
|||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 2000
|
duration: 2000
|
||||||
})
|
})
|
||||||
if(props.detail.formData){
|
if(props.detail && props.detail.formData){
|
||||||
props.detail.formData = {}
|
props.detail.formData = {}
|
||||||
}
|
}
|
||||||
d.hide()
|
d.hide()
|
||||||
@ -109,6 +114,6 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ save, getDetail })
|
defineExpose({ save, getDetail, getFormData })
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
|
||||||
<mb-search v-if="table.where" :where="table.where" :no-reset="search.noReset" @search="reload" />
|
<mb-search v-if="table.where" :where="table.where" :no-reset="search && search.noReset" @search="reload" />
|
||||||
|
|
||||||
<el-row class="toolbar-container">
|
<el-row class="toolbar-container">
|
||||||
<div v-for="(it, i) in tools" :key="i">
|
<div v-for="(it, i) in tools" :key="i">
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :fullscreen="fullscreen" :width="width" :title="title" v-model="dialogVisible" :close-on-click-modal="false" :key="dialogKey" :append-to-body="true" draggable @opened="opened">
|
<el-dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:custom-class="customClass"
|
||||||
|
:fullscreen="fullscreen"
|
||||||
|
:width="width"
|
||||||
|
:title="title"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:destroy-on-close="destroyOnClose"
|
||||||
|
:append-to-body="true"
|
||||||
|
draggable
|
||||||
|
@open="$emit('open')"
|
||||||
|
@close="$emit('close')"
|
||||||
|
>
|
||||||
<slot name="content" />
|
<slot name="content" />
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<slot name="btns">
|
<slot name="btns">
|
||||||
<el-button @click="dialogVisible = false">
|
<el-button @click="hide">
|
||||||
关闭
|
关闭
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" :loading="confirmLoading" @click="confirmClick">
|
<el-button type="primary" :loading="confirmLoading" @click="confirmClick">
|
||||||
@ -17,9 +29,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ['confirm-click'],
|
emits: ['confirm-click', 'open', 'close'],
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -33,11 +44,7 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
opened: {
|
destroyOnClose: {
|
||||||
type: Function,
|
|
||||||
default: () => {}
|
|
||||||
},
|
|
||||||
autoKey: {
|
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
@ -46,19 +53,20 @@ export default {
|
|||||||
return {
|
return {
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
dialogKey: 'mbDialog',
|
customClass: 'mbDialog' + this.$common.uuid()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
dialogVisible(value) {
|
||||||
|
if(value){
|
||||||
|
this.addStyle()
|
||||||
|
}else{
|
||||||
|
this.removeStyle()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.fullscreen) {
|
this.addStyle()
|
||||||
document.body.style.setProperty('--el-dialog__wrapper-bottom', '0vh')
|
|
||||||
document.body.style.setProperty('--el-dialog__wrapper-top', '0vh')
|
|
||||||
document.body.style.setProperty('--el-dialog__body-max-height', '100vh')
|
|
||||||
} else {
|
|
||||||
document.body.style.setProperty('--el-dialog__wrapper-bottom', '15vh')
|
|
||||||
document.body.style.setProperty('--el-dialog__wrapper-top', '15vh')
|
|
||||||
document.body.style.setProperty('--el-dialog__body-max-height', '60vh')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
confirmClick() {
|
confirmClick() {
|
||||||
@ -71,33 +79,43 @@ export default {
|
|||||||
this.confirmLoading = false
|
this.confirmLoading = false
|
||||||
},
|
},
|
||||||
show() {
|
show() {
|
||||||
if(this.autoKey){
|
|
||||||
this.dialogKey = Math.random()
|
|
||||||
}
|
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
hide() {
|
hide() {
|
||||||
this.dialogVisible = false
|
this.dialogVisible = false
|
||||||
|
},
|
||||||
|
addStyle(){
|
||||||
|
var componentStyle = document.createElement("style");
|
||||||
|
var cc = this.customClass
|
||||||
|
if (this.fullscreen) {
|
||||||
|
componentStyle.innerHTML = `
|
||||||
|
.${cc}{
|
||||||
|
margin-top: 0vh;
|
||||||
|
margin-bottom: 0vh;
|
||||||
|
}
|
||||||
|
.${cc} .el-dialog__body{
|
||||||
|
max-height: 100vh;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
} else {
|
||||||
|
componentStyle.innerHTML = `
|
||||||
|
.${cc}{
|
||||||
|
margin-top: 10vh;
|
||||||
|
margin-bottom: 10vh;
|
||||||
|
}
|
||||||
|
.${cc} .el-dialog__body{
|
||||||
|
max-height: 60vh;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
componentStyle.id = cc
|
||||||
|
document.head.appendChild(componentStyle);
|
||||||
|
},
|
||||||
|
removeStyle(){
|
||||||
|
document.getElementById(this.customClass) && document.getElementById(this.customClass).remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
.el-dialog__wrapper{
|
|
||||||
padding-bottom: var(--el-dialog__wrapper-bottom);
|
|
||||||
padding-top: var(--el-dialog__wrapper-top);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.el-dialog__wrapper >>> .el-dialog{
|
|
||||||
margin-top: 0vh!important;
|
|
||||||
}
|
|
||||||
.el-dialog__wrapper >>> .el-dialog__body{
|
|
||||||
max-height: var(--el-dialog__body-max-height);
|
|
||||||
overflow: auto;
|
|
||||||
padding: 25px!important;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-radio-group v-model="modelValue" v-bind="props.props">
|
|
||||||
<el-radio-button v-for="it in options" :label="it.value" :disabled="it.disabled" :name="it.disabled">{{ it.label }}</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { watch } from 'vue'
|
|
||||||
const emit = defineEmits(['update:modelValue'])
|
|
||||||
const props = defineProps({
|
|
||||||
modelValue: String,
|
|
||||||
options: Array
|
|
||||||
})
|
|
||||||
watch(() => props.modelValue, (value) => {
|
|
||||||
emit('update:modelValue', value)
|
|
||||||
})
|
|
||||||
</script>
|
|
@ -1,3 +0,0 @@
|
|||||||
<template>
|
|
||||||
|
|
||||||
</template>
|
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
import { nextTick, watch } from 'vue'
|
import { nextTick, watch, onMounted } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
where: {
|
where: {
|
||||||
@ -60,7 +60,7 @@ watch(() => props.where,() => {
|
|||||||
console.log(props.where)
|
console.log(props.where)
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['search'])
|
const emit = defineEmits(['search', 'mounted'])
|
||||||
|
|
||||||
function input(input){
|
function input(input){
|
||||||
if(input){
|
if(input){
|
||||||
@ -101,6 +101,10 @@ function reset() {
|
|||||||
nextTick(() => emit('search'))
|
nextTick(() => emit('search'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
emit('mounted')
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
v-bind="col.props"
|
||||||
:key="col.field"
|
:key="col.field"
|
||||||
:label="col.label"
|
:label="col.label"
|
||||||
:prop="col.field"
|
:prop="col.field"
|
||||||
|
94
magic-boot-ui/src/components/magic/form/mb-checkbox.vue
Normal file
94
magic-boot-ui/src/components/magic/form/mb-checkbox.vue
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<template>
|
||||||
|
<el-checkbox-group
|
||||||
|
v-model="modelValue"
|
||||||
|
:size="size"
|
||||||
|
:disabled="disabled"
|
||||||
|
:min="min"
|
||||||
|
:max="max"
|
||||||
|
:text-color="textColor"
|
||||||
|
:fill="fill"
|
||||||
|
@change="change"
|
||||||
|
>
|
||||||
|
<el-checkbox-button v-if="button" v-for="it in options" v-bind="it" :label="it[valueField]">
|
||||||
|
{{ it[labelField] }}
|
||||||
|
</el-checkbox-button>
|
||||||
|
<el-checkbox v-if="!button" v-for="it in options" v-bind="it" :label="it[valueField]">
|
||||||
|
{{ it[labelField] }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {watch, ref, getCurrentInstance} from "vue";
|
||||||
|
import request from '@/scripts/request'
|
||||||
|
const emit = defineEmits(['update:modelValue', 'change'])
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
type: String,
|
||||||
|
button: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
options: Array,
|
||||||
|
url: String,
|
||||||
|
params: Object,
|
||||||
|
method: {
|
||||||
|
type: String,
|
||||||
|
default: 'get'
|
||||||
|
},
|
||||||
|
labelField: {
|
||||||
|
type: String,
|
||||||
|
default: 'label'
|
||||||
|
},
|
||||||
|
valueField: {
|
||||||
|
type: String,
|
||||||
|
default: 'value'
|
||||||
|
},
|
||||||
|
size: String,
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
min: Number,
|
||||||
|
max: Number,
|
||||||
|
textColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#fff'
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
type: String,
|
||||||
|
default: '#409EFF'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const options = ref([])
|
||||||
|
|
||||||
|
if(props.type){
|
||||||
|
options.value = proxy.$common.getDictType(props.type)
|
||||||
|
}else if(props.url){
|
||||||
|
request({
|
||||||
|
url: props.url,
|
||||||
|
method: props.method,
|
||||||
|
params: props.params,
|
||||||
|
data: props.params
|
||||||
|
}).then(res => {
|
||||||
|
options.value = res.data.list || res.data
|
||||||
|
})
|
||||||
|
}else if(props.options){
|
||||||
|
options.value = props.options
|
||||||
|
}
|
||||||
|
|
||||||
|
function change(value){
|
||||||
|
emit('change', value)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.modelValue, (value) => {
|
||||||
|
console.log(value)
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
})
|
||||||
|
</script>
|
@ -12,7 +12,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { watch } from 'vue'
|
import { watch, ref } from 'vue'
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: String,
|
modelValue: String,
|
||||||
@ -23,11 +23,7 @@
|
|||||||
},
|
},
|
||||||
format: {
|
format: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'yyyy-MM-dd'
|
default: 'YYYY-MM-DD'
|
||||||
},
|
|
||||||
valueFormat: {
|
|
||||||
type: String,
|
|
||||||
default: 'yyyy-MM-dd'
|
|
||||||
},
|
},
|
||||||
startPlaceholder: {
|
startPlaceholder: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -39,6 +35,7 @@
|
|||||||
},
|
},
|
||||||
props: Object
|
props: Object
|
||||||
})
|
})
|
||||||
|
const valueFormat = ref(props.format)
|
||||||
watch(() => props.modelValue, (value) => {
|
watch(() => props.modelValue, (value) => {
|
||||||
emit('update:modelValue', value)
|
emit('update:modelValue', value)
|
||||||
})
|
})
|
86
magic-boot-ui/src/components/magic/form/mb-radio.vue
Normal file
86
magic-boot-ui/src/components/magic/form/mb-radio.vue
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<el-radio-group
|
||||||
|
v-model="modelValue"
|
||||||
|
:size="size"
|
||||||
|
:disabled="disabled"
|
||||||
|
:text-color="textColor"
|
||||||
|
:fill="fill"
|
||||||
|
@change="change"
|
||||||
|
>
|
||||||
|
<el-radio-button v-if="button" v-for="it in options" v-bind="it" :label="it[valueField]">
|
||||||
|
{{ it[labelField] }}
|
||||||
|
</el-radio-button>
|
||||||
|
<el-radio v-if="!button" v-for="it in options" v-bind="it" :label="it[valueField]">
|
||||||
|
{{ it[labelField] }}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {watch, ref, getCurrentInstance} from "vue";
|
||||||
|
import request from '@/scripts/request'
|
||||||
|
const emit = defineEmits(['update:modelValue', 'change'])
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: String | Number | Boolean,
|
||||||
|
type: String,
|
||||||
|
button: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
options: Array,
|
||||||
|
url: String,
|
||||||
|
params: Object,
|
||||||
|
method: {
|
||||||
|
type: String,
|
||||||
|
default: 'get'
|
||||||
|
},
|
||||||
|
labelField: {
|
||||||
|
type: String,
|
||||||
|
default: 'label'
|
||||||
|
},
|
||||||
|
valueField: {
|
||||||
|
type: String,
|
||||||
|
default: 'value'
|
||||||
|
},
|
||||||
|
size: String,
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
textColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#fff'
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
type: String,
|
||||||
|
default: '#409EFF'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const options = ref([])
|
||||||
|
|
||||||
|
if(props.type){
|
||||||
|
options.value = proxy.$common.getDictType(props.type)
|
||||||
|
}else if(props.url){
|
||||||
|
request({
|
||||||
|
url: props.url,
|
||||||
|
method: props.method,
|
||||||
|
params: props.params,
|
||||||
|
data: props.params
|
||||||
|
}).then(res => {
|
||||||
|
options.value = res.data.list || res.data
|
||||||
|
})
|
||||||
|
}else if(props.options){
|
||||||
|
options.value = props.options
|
||||||
|
}
|
||||||
|
|
||||||
|
function change(value){
|
||||||
|
emit('change', value)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.modelValue, (value) => {
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
})
|
||||||
|
</script>
|
@ -11,9 +11,12 @@
|
|||||||
import { watch } from 'vue'
|
import { watch } from 'vue'
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: String,
|
modelValue: {
|
||||||
activeValue: String,
|
type: Boolean,
|
||||||
inactiveValue: String,
|
default: false
|
||||||
|
},
|
||||||
|
activeValue: Boolean | String | Number,
|
||||||
|
inactiveValue: Boolean | String | Number,
|
||||||
props: Object
|
props: Object
|
||||||
})
|
})
|
||||||
watch(() => props.modelValue, (value) => {
|
watch(() => props.modelValue, (value) => {
|
@ -26,11 +26,11 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
import { watch, ref, reactive, defineExpose, nextTick, getCurrentInstance, onBeforeMount } from 'vue'
|
import { watch, ref, reactive, defineExpose, nextTick, getCurrentInstance, onBeforeMount, onMounted } from 'vue'
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
const emit = defineEmits(['update:select-values', 'check-change', 'node-click'])
|
const emit = defineEmits(['update:select-values', 'check-change', 'node-click', 'mounted'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
@ -75,6 +75,10 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(() => props.checkedIds, (value) => {
|
||||||
|
console.log(value)
|
||||||
|
})
|
||||||
|
|
||||||
const tree = ref()
|
const tree = ref()
|
||||||
const treeData = ref([])
|
const treeData = ref([])
|
||||||
const searchData = ref([])
|
const searchData = ref([])
|
||||||
@ -91,6 +95,10 @@ onBeforeMount(async () => {
|
|||||||
await loadTreeData()
|
await loadTreeData()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
emit('mounted')
|
||||||
|
})
|
||||||
|
|
||||||
watch(() => props.selectValues, async () => {
|
watch(() => props.selectValues, async () => {
|
||||||
await loadTreeData()
|
await loadTreeData()
|
||||||
checkedAll(searchData.value, false)
|
checkedAll(searchData.value, false)
|
1
magic-boot-ui/src/icons/verification-code.svg
Normal file
1
magic-boot-ui/src/icons/verification-code.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1647393180960" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3075" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M522.854 33.884L902.47 164.732c14.1 4.85 23.54 18.113 23.54 33.011v402.218c-10.714 238.49-386.18 383.703-402.118 389.764A34.91 34.91 0 0 1 511.505 992c-4.217 0-8.439-0.767-12.387-2.275C483.147 983.664 107.648 838.452 97 601.502V197.743c0-14.898 9.442-28.16 23.503-33.011L500.121 33.884a35.24 35.24 0 0 1 22.733 0z m243.984 299.804c-29.29-29.29-76.777-29.29-106.066 0L459.246 535.213l-95.46-95.46c-29.289-29.289-76.776-29.289-106.065 0-29.29 29.29-29.29 76.777 0 106.067l148.492 148.492c14.645 14.645 33.839 21.967 53.033 21.967l1.152-0.009c18.808-0.287 37.53-7.606 51.881-21.958l254.559-254.558c29.289-29.29 29.289-76.777 0-106.066z" fill="#909399" p-id="3076"></path></svg>
|
After Width: | Height: | Size: 1.0 KiB |
@ -56,7 +56,6 @@ import Sidebar from './sidebar/sidebar.vue'
|
|||||||
import { logout } from '@/scripts/auth'
|
import { logout } from '@/scripts/auth'
|
||||||
import { getCurrentInstance } from 'vue'
|
import { getCurrentInstance } from 'vue'
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
console.log(proxy.$global.user.info.headPortrait)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -47,6 +47,8 @@ export function login(data){
|
|||||||
var token = res.data
|
var token = res.data
|
||||||
setToken(token)
|
setToken(token)
|
||||||
resolve(token)
|
resolve(token)
|
||||||
|
}).catch((e) => {
|
||||||
|
reject(e)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
132
magic-boot-ui/src/views/examples/test-mb-form.vue
Normal file
132
magic-boot-ui/src/views/examples/test-mb-form.vue
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<template>
|
||||||
|
<mb-form ref="magicForm" v-bind="formOptions" />
|
||||||
|
<el-button @click="getFormData">获取表单数据</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, getCurrentInstance } from 'vue'
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
const magicForm = ref()
|
||||||
|
const formOptions = reactive({
|
||||||
|
form: {
|
||||||
|
request: {
|
||||||
|
url: "user/save",
|
||||||
|
method: "post"
|
||||||
|
},
|
||||||
|
rows: [{
|
||||||
|
gutter: 24,
|
||||||
|
cols: [{
|
||||||
|
span: 12,
|
||||||
|
name: 'input',
|
||||||
|
label: 'input'
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'switch',
|
||||||
|
component: 'switch',
|
||||||
|
label: 'switch',
|
||||||
|
props: {
|
||||||
|
activeValue: '1',
|
||||||
|
inactiveValue: '0'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'checkbox',
|
||||||
|
component: 'checkbox',
|
||||||
|
label: 'checkbox',
|
||||||
|
props: {
|
||||||
|
type: 'office_type'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'checkboxButton',
|
||||||
|
component: 'checkbox',
|
||||||
|
label: 'checkboxButton',
|
||||||
|
props: {
|
||||||
|
type: 'office_type',
|
||||||
|
button: true
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'radio',
|
||||||
|
component: 'radio',
|
||||||
|
label: 'radio',
|
||||||
|
props: {
|
||||||
|
type: 'is_login'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'radioButton',
|
||||||
|
component: 'radio',
|
||||||
|
label: 'radioButton',
|
||||||
|
props: {
|
||||||
|
type: 'is_login',
|
||||||
|
button: true
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'date',
|
||||||
|
component: 'date',
|
||||||
|
label: 'date',
|
||||||
|
props: {
|
||||||
|
type: 'date'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'datetime',
|
||||||
|
component: 'date',
|
||||||
|
label: 'datetime',
|
||||||
|
props: {
|
||||||
|
type: 'datetime',
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'daterange',
|
||||||
|
component: 'date',
|
||||||
|
label: 'daterange',
|
||||||
|
props: {
|
||||||
|
type: 'daterange'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'datetimerange',
|
||||||
|
component: 'date',
|
||||||
|
label: 'datetimerange',
|
||||||
|
props: {
|
||||||
|
type: 'datetimerange',
|
||||||
|
format: 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
component: 'treeselect',
|
||||||
|
span: 12,
|
||||||
|
name: 'treeselect',
|
||||||
|
label: 'treeselect',
|
||||||
|
rules: [{ required: true, message: '请选择组织机构', trigger: 'change' }],
|
||||||
|
props: {
|
||||||
|
url: 'user/offices'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
component: 'select',
|
||||||
|
span: 12,
|
||||||
|
name: 'select',
|
||||||
|
label: 'select',
|
||||||
|
rules: [{ required: true, message: '请选择角色', trigger: 'change' }],
|
||||||
|
props: {
|
||||||
|
url: 'role/all',
|
||||||
|
placeholder: '请选择角色',
|
||||||
|
el: { multiple: true }
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
span: 12,
|
||||||
|
name: 'head',
|
||||||
|
component: 'upload-image',
|
||||||
|
label: '头像',
|
||||||
|
rules: [{ required: true, message: '请选择头像', trigger: 'change' }]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
function getFormData(){
|
||||||
|
console.log(magicForm.value.getFormData())
|
||||||
|
}
|
||||||
|
</script>
|
@ -51,25 +51,25 @@ const listOptions = reactive({
|
|||||||
cols: [
|
cols: [
|
||||||
{
|
{
|
||||||
field: 'username',
|
field: 'username',
|
||||||
title: '登录名称',
|
label: '登录名称',
|
||||||
sortable: 'custom'
|
sortable: 'custom'
|
||||||
}, {
|
}, {
|
||||||
field: 'name',
|
field: 'name',
|
||||||
title: '姓名/昵称',
|
label: '姓名/昵称',
|
||||||
sortable: 'custom'
|
sortable: 'custom'
|
||||||
}, {
|
}, {
|
||||||
field: 'officeName',
|
field: 'officeName',
|
||||||
title: '所属机构'
|
label: '所属机构'
|
||||||
}, {
|
}, {
|
||||||
field: 'roles',
|
field: 'roles',
|
||||||
title: '角色'
|
label: '角色'
|
||||||
}, {
|
}, {
|
||||||
field: 'phone',
|
field: 'phone',
|
||||||
title: '手机号',
|
label: '手机号',
|
||||||
sortable: 'custom'
|
sortable: 'custom'
|
||||||
}, {
|
}, {
|
||||||
field: 'isLogin',
|
field: 'isLogin',
|
||||||
title: '禁止登录',
|
label: '禁止登录',
|
||||||
type: 'switch',
|
type: 'switch',
|
||||||
width: 100,
|
width: 100,
|
||||||
change: (row) => {
|
change: (row) => {
|
||||||
@ -80,17 +80,17 @@ const listOptions = reactive({
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
field: 'createDate',
|
field: 'createDate',
|
||||||
title: '创建时间',
|
label: '创建时间',
|
||||||
width: 180
|
width: 180
|
||||||
}, {
|
}, {
|
||||||
title: '操作',
|
label: '操作',
|
||||||
type: 'btns',
|
type: 'btns',
|
||||||
width: 140,
|
width: 140,
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
btns: [
|
btns: [
|
||||||
{
|
{
|
||||||
permission: 'user:save',
|
permission: 'user:save',
|
||||||
title: '修改',
|
label: '修改',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
icon: 'ElEdit',
|
icon: 'ElEdit',
|
||||||
click: (row) => {
|
click: (row) => {
|
||||||
@ -101,7 +101,7 @@ const listOptions = reactive({
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
permission: 'user:delete',
|
permission: 'user:delete',
|
||||||
title: '删除',
|
label: '删除',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
icon: 'ElDelete',
|
icon: 'ElDelete',
|
||||||
click: (row) => {
|
click: (row) => {
|
||||||
@ -136,6 +136,12 @@ const formOptions = reactive({
|
|||||||
rows: [{
|
rows: [{
|
||||||
gutter: 24,
|
gutter: 24,
|
||||||
cols: [{
|
cols: [{
|
||||||
|
span: 12,
|
||||||
|
name: 'head',
|
||||||
|
component: 'upload-image',
|
||||||
|
label: '头像',
|
||||||
|
rules: [{ required: true, message: '请选择头像', trigger: 'change' }]
|
||||||
|
},{
|
||||||
span: 12,
|
span: 12,
|
||||||
name: 'username',
|
name: 'username',
|
||||||
label: '登录名称',
|
label: '登录名称',
|
||||||
@ -170,7 +176,6 @@ const formOptions = reactive({
|
|||||||
span: 12,
|
span: 12,
|
||||||
name: 'officeId',
|
name: 'officeId',
|
||||||
label: '组织机构',
|
label: '组织机构',
|
||||||
defaultValue: null,
|
|
||||||
rules: [{ required: true, message: '请选择组织机构', trigger: 'change' }],
|
rules: [{ required: true, message: '请选择组织机构', trigger: 'change' }],
|
||||||
props: {
|
props: {
|
||||||
url: 'user/offices'
|
url: 'user/offices'
|
||||||
@ -180,7 +185,6 @@ const formOptions = reactive({
|
|||||||
span: 12,
|
span: 12,
|
||||||
name: 'roles',
|
name: 'roles',
|
||||||
label: '选择角色',
|
label: '选择角色',
|
||||||
defaultValue: null,
|
|
||||||
rules: [{ required: true, message: '请选择角色', trigger: 'change' }],
|
rules: [{ required: true, message: '请选择角色', trigger: 'change' }],
|
||||||
props: {
|
props: {
|
||||||
url: 'role/all',
|
url: 'role/all',
|
||||||
|
@ -12,6 +12,11 @@
|
|||||||
<mb-icon icon="password"/>
|
<mb-icon icon="password"/>
|
||||||
<input class="magic-input" ref="password" v-model="loginForm.password" type="password" placeholder="密码" name="password" tabindex="2" auto-complete="on" @keyup.enter.native="handleLogin" />
|
<input class="magic-input" ref="password" v-model="loginForm.password" type="password" placeholder="密码" name="password" tabindex="2" auto-complete="on" @keyup.enter.native="handleLogin" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="magic-login-row">
|
||||||
|
<mb-icon icon="verification-code"/>
|
||||||
|
<input class="magic-input code" ref="code" v-model="loginForm.code" placeholder="验证码" name="code" tabindex="3" @keyup.enter.native="handleLogin" />
|
||||||
|
<img class="code-img" :src="codeImg" @click="refreshCode">
|
||||||
|
</div>
|
||||||
<div class="magic-login-row">
|
<div class="magic-login-row">
|
||||||
<button :loading="loading" class="magic-button" type="primary" size="medium" @click.native.prevent="handleLogin">登录</button>
|
<button :loading="loading" class="magic-button" type="primary" size="medium" @click.native.prevent="handleLogin">登录</button>
|
||||||
</div>
|
</div>
|
||||||
@ -24,12 +29,20 @@
|
|||||||
import { reactive, ref, getCurrentInstance } from 'vue'
|
import { reactive, ref, getCurrentInstance } from 'vue'
|
||||||
import { login } from '@/scripts/auth'
|
import { login } from '@/scripts/auth'
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
const codeImg = ref(import.meta.env.VITE_APP_BASE_API + '/security/verification/code')
|
||||||
const loginForm = reactive({
|
const loginForm = reactive({
|
||||||
username: '',
|
username: '',
|
||||||
password: ''
|
password: '',
|
||||||
|
code: ''
|
||||||
})
|
})
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
function refreshCode(){
|
||||||
|
proxy.$get('/security/verification/code').then(res => {
|
||||||
|
codeImg.value = 'data:image/png;base64,' + res.data.img
|
||||||
|
loginForm.uuid = res.data.uuid
|
||||||
|
})
|
||||||
|
}
|
||||||
|
refreshCode()
|
||||||
function handleLogin() {
|
function handleLogin() {
|
||||||
if(!loginForm.username){
|
if(!loginForm.username){
|
||||||
proxy.$message({
|
proxy.$message({
|
||||||
@ -47,12 +60,21 @@
|
|||||||
showClose: true
|
showClose: true
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
}else if(!loginForm.code){
|
||||||
|
proxy.$message({
|
||||||
|
message: '请输入验证码',
|
||||||
|
type: 'error',
|
||||||
|
duration: 2000,
|
||||||
|
showClose: true
|
||||||
|
})
|
||||||
|
return
|
||||||
}else{
|
}else{
|
||||||
loading.value = true
|
loading.value = true
|
||||||
login(loginForm).then((res) => {
|
login(loginForm).then((res) => {
|
||||||
proxy.$router.push({ path: '/home' })
|
proxy.$router.push({ path: '/home' })
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
refreshCode()
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -63,6 +85,15 @@
|
|||||||
*{
|
*{
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
.code{
|
||||||
|
width: 283px;
|
||||||
|
float: left;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
.code-img{
|
||||||
|
border: 1px solid #D9D9D9;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
input{
|
input{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,26 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'type',
|
field: 'type',
|
||||||
label: '登录状态'
|
label: '登录状态',
|
||||||
|
templet: (row) => {
|
||||||
|
return row.type == '成功' ? '<b style="color: #409EFF">成功</b>' : '<b style="color: red">失败</b>'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'ip',
|
field: 'ip',
|
||||||
label: 'ip'
|
label: 'ip'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'browser',
|
||||||
|
label: '浏览器'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'os',
|
||||||
|
label: '系统',
|
||||||
|
props: {
|
||||||
|
"show-overflow-tooltip": true
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'createDate',
|
field: 'createDate',
|
||||||
label: '操作时间'
|
label: '操作时间'
|
||||||
|
113
magic-boot-ui/src/views/system/monitor/online-user.vue
Normal file
113
magic-boot-ui/src/views/system/monitor/online-user.vue
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<mb-list ref="magicList" v-bind="listOptions" />
|
||||||
|
<!-- <mb-dialog ref="magicDialog" title="提示" width="600px" @confirm-click="disable">-->
|
||||||
|
<!-- <template #content>-->
|
||||||
|
<!-- <el-row :gutter="24">-->
|
||||||
|
<!-- <el-col :span="24">-->
|
||||||
|
<!-- 确定要踢“{{currRow.username}}”下线并临时封禁吗?-->
|
||||||
|
<!-- </el-col>-->
|
||||||
|
<!-- <el-col :span="24">-->
|
||||||
|
<!-- <mb-radio v-model="time" :options="options"></mb-radio>-->
|
||||||
|
<!-- </el-col>-->
|
||||||
|
<!-- </el-row>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- </mb-dialog>-->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {reactive, ref, getCurrentInstance} from "vue";
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
const magicList = ref()
|
||||||
|
// const magicDialog = ref()
|
||||||
|
// const currRow = ref()
|
||||||
|
// const time = ref(0)
|
||||||
|
// const options = reactive([{
|
||||||
|
// label: '不封禁',
|
||||||
|
// value: 0
|
||||||
|
// },{
|
||||||
|
// label: '1分钟',
|
||||||
|
// value: 60
|
||||||
|
// },{
|
||||||
|
// label: '10分钟',
|
||||||
|
// value: 10 * 60
|
||||||
|
// },{
|
||||||
|
// label: '1小时',
|
||||||
|
// value: 1 * 60 *60
|
||||||
|
// },{
|
||||||
|
// label: '5小时',
|
||||||
|
// value: 5 * 60 *60
|
||||||
|
// },{
|
||||||
|
// label: '永久',
|
||||||
|
// value: -1
|
||||||
|
// }])
|
||||||
|
const listOptions = reactive({
|
||||||
|
table: {
|
||||||
|
url: 'online/list',
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
label: '登录名称',
|
||||||
|
},
|
||||||
|
ip: {
|
||||||
|
label: 'IP',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cols: [
|
||||||
|
{
|
||||||
|
field: 'username',
|
||||||
|
label: '登录名称'
|
||||||
|
}, {
|
||||||
|
field: 'officeName',
|
||||||
|
label: '所属机构'
|
||||||
|
}, {
|
||||||
|
field: 'ip',
|
||||||
|
label: 'IP'
|
||||||
|
}, {
|
||||||
|
field: 'browser',
|
||||||
|
label: '浏览器'
|
||||||
|
}, {
|
||||||
|
field: 'os',
|
||||||
|
label: '操作系统',
|
||||||
|
props: {
|
||||||
|
"show-overflow-tooltip": true
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
field: 'createDate',
|
||||||
|
label: '登录时间'
|
||||||
|
}, {
|
||||||
|
label: '操作',
|
||||||
|
type: 'btns',
|
||||||
|
width: 140,
|
||||||
|
fixed: 'right',
|
||||||
|
btns: [
|
||||||
|
{
|
||||||
|
permission: 'online:logout',
|
||||||
|
label: '踢人',
|
||||||
|
type: 'text',
|
||||||
|
icon: 'ElBicycle',
|
||||||
|
click: (row) => {
|
||||||
|
// currRow.value = row
|
||||||
|
// magicDialog.value.show()
|
||||||
|
proxy.$alert(`确定要踢“${row.username}”下线吗?`, '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
proxy.$get('online/logout',{ token: row.token }).then(() => {
|
||||||
|
magicList.value.reload()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// function disable(){
|
||||||
|
// proxy.$get('online/logout',{ id: currRow.value.id, time: time.value }).then(() => {
|
||||||
|
// magicDialog.value.hide()
|
||||||
|
// magicList.value.reload()
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
</script>
|
@ -40,7 +40,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'userAgent',
|
field: 'userAgent',
|
||||||
label: '用户代理'
|
label: '用户代理',
|
||||||
|
props: {
|
||||||
|
"show-overflow-tooltip": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'username',
|
field: 'username',
|
||||||
|
@ -196,7 +196,10 @@ const tableOptions = reactive({
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
icon: 'ElUserFilled',
|
icon: 'ElUserFilled',
|
||||||
click: (row) => {
|
click: (row) => {
|
||||||
proxy.$router.push({ path: `/system/user/user-list?officeId=${row.id}` })
|
proxy.$router.push({
|
||||||
|
path: '/system/user/user-list',
|
||||||
|
query: { officeId: row.id }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -13,11 +13,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<mb-tree url="office/tree" :el="{ 'expand-on-click-node': false,'show-checkbox': true }" :checked-ids="[tableOptions.where.officeId]" :expand="false" :search="true" search-width="100%" :checked="false" @check-change="checkChange" />
|
<mb-tree
|
||||||
|
url="office/tree"
|
||||||
|
:el="{ 'expand-on-click-node': false,'show-checkbox': true }"
|
||||||
|
:checked-ids="[tableOptions.where.officeId]"
|
||||||
|
:expand="false"
|
||||||
|
:search="true"
|
||||||
|
search-width="100%"
|
||||||
|
:checked="false"
|
||||||
|
@check-change="checkChange"
|
||||||
|
@mounted="treeMounted"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
|
|
||||||
<mb-search :where="tableOptions.where" @search="reloadTable">
|
<mb-search :where="tableOptions.where" @search="reloadTable" @mounted="searchMounted">
|
||||||
<template #btns>
|
<template #btns>
|
||||||
<el-button :loading="downloadLoading" class="filter-item" icon="ElDownload" @click="handleDownload">
|
<el-button :loading="downloadLoading" class="filter-item" icon="ElDownload" @click="handleDownload">
|
||||||
导出
|
导出
|
||||||
@ -71,13 +81,13 @@ const tableOptions = reactive({
|
|||||||
roleId: {
|
roleId: {
|
||||||
type: 'select',
|
type: 'select',
|
||||||
label: '角色',
|
label: '角色',
|
||||||
value: proxy.$route.query.roleId,
|
value: '',
|
||||||
properties: {
|
properties: {
|
||||||
url: 'role/all',
|
url: 'role/all',
|
||||||
el: { multiple: true }
|
el: { multiple: true }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
officeId: proxy.$route.query.officeId
|
officeId: ''
|
||||||
},
|
},
|
||||||
cols: [
|
cols: [
|
||||||
{
|
{
|
||||||
@ -159,20 +169,17 @@ const userFormDialog = ref()
|
|||||||
const table = ref()
|
const table = ref()
|
||||||
const userForm = ref()
|
const userForm = ref()
|
||||||
|
|
||||||
// onMounted(() => {
|
function searchMounted(){
|
||||||
// setTimeout(function(){
|
if(proxy.$route.query.roleId){
|
||||||
// nextTick(() => {
|
tableOptions.where.roleId.value = proxy.$route.query.roleId
|
||||||
// console.log(proxy.$route.query.roleId)
|
}
|
||||||
// if(proxy.$route.query.roleId){
|
}
|
||||||
// tableOptions.where.roleId.value = proxy.$route.query.roleId
|
|
||||||
// }
|
|
||||||
// if(proxy.$route.query.officeId){
|
|
||||||
// tableOptions.where.officeId = proxy.$route.query.officeId
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// },1000)
|
function treeMounted(){
|
||||||
// })
|
if(proxy.$route.query.officeId){
|
||||||
|
tableOptions.where.officeId = proxy.$route.query.officeId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkChange(values) {
|
function checkChange(values) {
|
||||||
tableOptions.where.officeId = values
|
tableOptions.where.officeId = values
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<description>magic-boot</description>
|
<description>magic-boot</description>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<magic-api.version>2.0.0-beta.3</magic-api.version>
|
<magic-api.version>2.0.0</magic-api.version>
|
||||||
<druid.version>1.1.10</druid.version>
|
<druid.version>1.1.10</druid.version>
|
||||||
<hutool-all.version>5.7.13</hutool-all.version>
|
<hutool-all.version>5.7.13</hutool-all.version>
|
||||||
<sa-token.version>1.26.0</sa-token.version>
|
<sa-token.version>1.26.0</sa-token.version>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package org.ssssssss.magicboot.config;
|
package org.ssssssss.magicboot.configuration;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
@ -0,0 +1,22 @@
|
|||||||
|
package org.ssssssss.magicboot.model;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CodeCacheMap {
|
||||||
|
|
||||||
|
private static Map<String, String> map = new HashMap<String, String>();
|
||||||
|
|
||||||
|
public static void put(String key, String value){
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove(String key){
|
||||||
|
map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String get(String key){
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.ssssssss.magicboot.provider;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.exception.DisableLoginException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.ssssssss.magicapi.core.context.RequestEntity;
|
||||||
|
import org.ssssssss.magicapi.core.interceptor.ResultProvider;
|
||||||
|
import org.ssssssss.magicapi.core.model.JsonBean;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ExceptionResultProvider implements ResultProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object buildResult(RequestEntity requestEntity, int code, String message, Object data) {
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
return new JsonBean<>(code, message, data, (int) (timestamp - requestEntity.getRequestTime()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object buildException(RequestEntity requestEntity, Throwable throwable) {
|
||||||
|
if(throwable.getCause() instanceof DisableLoginException){
|
||||||
|
return buildResult(requestEntity, 500, "此账号已被临时封禁,请联系管理员");
|
||||||
|
}
|
||||||
|
return buildResult(requestEntity, 500, "系统内部出现错误");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user