From bdea28e66e0e9d065b5c206e226d476b1a39633c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=95=E9=87=91=E6=B3=BD?= <1098696801@qq.com> Date: Wed, 16 Mar 2022 10:38:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E7=94=A8=E6=88=B7=EF=BC=8C?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=EF=BC=8Cbug=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=EF=BC=8C=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/magic-api/api/后台/在线用户/group.json | 10 ++ data/magic-api/api/后台/在线用户/列表.ms | 126 +++++++++++++++ data/magic-api/api/后台/在线用户/踢人.ms | 26 +++ data/magic-api/api/后台/安全/登录.ms | 69 ++++++-- data/magic-api/api/后台/安全/验证码.ms | 149 ++++++++++++++++++ magic-boot-ui/src/assets/css/common.css | 4 - .../src/components/magic/advanced/mb-form.vue | 19 ++- .../src/components/magic/advanced/mb-list.vue | 2 +- .../src/components/magic/basic/mb-dialog.vue | 98 +++++++----- .../magic/basic/mb-radio-button.vue | 17 -- .../src/components/magic/basic/mb-radio.vue | 3 - .../src/components/magic/basic/mb-search.vue | 8 +- .../magic/basic/mb-table-column.vue | 1 + .../src/components/magic/form/mb-checkbox.vue | 94 +++++++++++ .../magic/{basic => form}/mb-date.vue | 9 +- .../magic/{basic => form}/mb-input.vue | 0 .../src/components/magic/form/mb-radio.vue | 86 ++++++++++ .../magic/{basic => form}/mb-select.vue | 0 .../magic/{basic => form}/mb-switch.vue | 9 +- .../magic/{basic => form}/mb-tree.vue | 12 +- .../magic/{basic => form}/mb-treeselect.vue | 0 .../magic/{basic => form}/mb-upload-file.vue | 0 .../magic/{basic => form}/mb-upload-image.vue | 0 magic-boot-ui/src/icons/verification-code.svg | 1 + magic-boot-ui/src/layout/layout.vue | 3 +- magic-boot-ui/src/scripts/auth.js | 2 + .../src/views/examples/test-mb-form.vue | 132 ++++++++++++++++ .../src/views/examples/test-mb-list.vue | 28 ++-- magic-boot-ui/src/views/login.vue | 35 +++- .../src/views/system/monitor/login-log.vue | 16 +- .../src/views/system/monitor/online-user.vue | 113 +++++++++++++ .../src/views/system/monitor/oper-log.vue | 5 +- .../src/views/system/office/office-list.vue | 5 +- .../src/views/system/user/user-list.vue | 41 +++-- magic-boot/pom.xml | 2 +- .../WebConfiguration.java | 2 +- .../magicboot/model/CodeCacheMap.java | 22 +++ .../provider/ExceptionResultProvider.java | 25 +++ 38 files changed, 1042 insertions(+), 132 deletions(-) create mode 100644 data/magic-api/api/后台/在线用户/group.json create mode 100644 data/magic-api/api/后台/在线用户/列表.ms create mode 100644 data/magic-api/api/后台/在线用户/踢人.ms create mode 100644 data/magic-api/api/后台/安全/验证码.ms delete mode 100644 magic-boot-ui/src/components/magic/basic/mb-radio-button.vue delete mode 100644 magic-boot-ui/src/components/magic/basic/mb-radio.vue create mode 100644 magic-boot-ui/src/components/magic/form/mb-checkbox.vue rename magic-boot-ui/src/components/magic/{basic => form}/mb-date.vue (86%) rename magic-boot-ui/src/components/magic/{basic => form}/mb-input.vue (100%) create mode 100644 magic-boot-ui/src/components/magic/form/mb-radio.vue rename magic-boot-ui/src/components/magic/{basic => form}/mb-select.vue (100%) rename magic-boot-ui/src/components/magic/{basic => form}/mb-switch.vue (72%) rename magic-boot-ui/src/components/magic/{basic => form}/mb-tree.vue (95%) rename magic-boot-ui/src/components/magic/{basic => form}/mb-treeselect.vue (100%) rename magic-boot-ui/src/components/magic/{basic => form}/mb-upload-file.vue (100%) rename magic-boot-ui/src/components/magic/{basic => form}/mb-upload-image.vue (100%) create mode 100644 magic-boot-ui/src/icons/verification-code.svg create mode 100644 magic-boot-ui/src/views/examples/test-mb-form.vue create mode 100644 magic-boot-ui/src/views/system/monitor/online-user.vue rename magic-boot/src/main/java/org/ssssssss/magicboot/{config => configuration}/WebConfiguration.java (95%) create mode 100644 magic-boot/src/main/java/org/ssssssss/magicboot/model/CodeCacheMap.java create mode 100644 magic-boot/src/main/java/org/ssssssss/magicboot/provider/ExceptionResultProvider.java diff --git a/data/magic-api/api/后台/在线用户/group.json b/data/magic-api/api/后台/在线用户/group.json new file mode 100644 index 0000000..b551373 --- /dev/null +++ b/data/magic-api/api/后台/在线用户/group.json @@ -0,0 +1,10 @@ +{ + "properties" : { }, + "id" : "d95a58e77d314370862ffc4cdfdb8283", + "name" : "在线用户", + "type" : "api", + "parentId" : "02df51e4d7184780a98b632f43dc5848", + "path" : "/online", + "paths" : [ ], + "options" : [ ] +} \ No newline at end of file diff --git a/data/magic-api/api/后台/在线用户/列表.ms b/data/magic-api/api/后台/在线用户/列表.ms new file mode 100644 index 0000000..799dc53 --- /dev/null +++ b/data/magic-api/api/后台/在线用户/列表.ms @@ -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 +""") \ No newline at end of file diff --git a/data/magic-api/api/后台/在线用户/踢人.ms b/data/magic-api/api/后台/在线用户/踢人.ms new file mode 100644 index 0000000..f1134f5 --- /dev/null +++ b/data/magic-api/api/后台/在线用户/踢人.ms @@ -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); \ No newline at end of file diff --git a/data/magic-api/api/后台/安全/登录.ms b/data/magic-api/api/后台/安全/登录.ms index 5ddb4d7..b247be8 100644 --- a/data/magic-api/api/后台/安全/登录.ms +++ b/data/magic-api/api/后台/安全/登录.ms @@ -5,13 +5,49 @@ "groupId" : "1952f25c81084e24b55b11385767dc38", "name" : "登录", "createTime" : null, - "updateTime" : 1646544815203, + "updateTime" : 1647396539380, "lock" : "0", "createBy" : null, "updateBy" : null, "path" : "/login", "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" : [ { "name" : "require_login", "value" : "false", @@ -28,7 +64,7 @@ "requestBody" : "{\r\n \"username\": \"admin\",\r\n \"password\": \"123456\"\r\n}", "headers" : [ ], "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, "requestBodyDefinition" : { "name" : "", @@ -104,10 +140,10 @@ "children" : [ ] }, { "name" : "data", - "value" : "60f0ddf8-c42c-4b3e-802f-7482f6bd1075", + "value" : "cb63a01c-63d7-4722-a2c4-48fffa4b3502", "description" : "", "required" : false, - "dataType" : "String", + "dataType" : "Object", "type" : null, "defaultValue" : null, "validateType" : "", @@ -116,7 +152,7 @@ "children" : [ ] }, { "name" : "timestamp", - "value" : "1646493023758", + "value" : "1647395770056", "description" : "", "required" : false, "dataType" : "Long", @@ -128,7 +164,7 @@ "children" : [ ] }, { "name" : "executeTime", - "value" : "316", + "value" : "20", "description" : "", "required" : false, "dataType" : "Integer", @@ -147,6 +183,15 @@ import 'cn.dev33.satoken.secure.SaSecureUtil'; import 'cn.dev33.satoken.stp.StpUtil'; import env; 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 if(env.get('super-password') == body.password){ @@ -158,15 +203,21 @@ if(env.get('super-password') == body.password){ var loginLog = { username: body.username, type: '成功', - ip: request.getClientIP() + ip: request.getClientIP(), + browser: ua.getBrowser().toString(), + os: ua.getOs().toString() } if(!user){ loginLog.failPassword = body.password + loginLog.type = '失败' db.table("sys_login_log").primary("id").save(loginLog); exit 0,'用户名或密码错误' } -db.table("sys_login_log").primary("id").save(loginLog); 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) \ No newline at end of file diff --git a/data/magic-api/api/后台/安全/验证码.ms b/data/magic-api/api/后台/安全/验证码.ms new file mode 100644 index 0000000..ebdeb61 --- /dev/null +++ b/data/magic-api/api/后台/安全/验证码.ms @@ -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 +} \ No newline at end of file diff --git a/magic-boot-ui/src/assets/css/common.css b/magic-boot-ui/src/assets/css/common.css index 97effd6..39377ea 100644 --- a/magic-boot-ui/src/assets/css/common.css +++ b/magic-boot-ui/src/assets/css/common.css @@ -23,10 +23,6 @@ border: 1px solid #efefef } body{ - --el-dialog__wrapper-bottom: 15vh; - --el-dialog__wrapper-top: 15vh; - --el-dialog__body-max-height: 60vh; - --mb-main-color: #409EFF; --mb-sidebar-width: 240px; --mb-main-icon-color: #909399; diff --git a/magic-boot-ui/src/components/magic/advanced/mb-form.vue b/magic-boot-ui/src/components/magic/advanced/mb-form.vue index 9789724..52fd2ee 100644 --- a/magic-boot-ui/src/components/magic/advanced/mb-form.vue +++ b/magic-boot-ui/src/components/magic/advanced/mb-form.vue @@ -24,7 +24,7 @@ import {ref, reactive, getCurrentInstance, defineExpose } from 'vue' const { proxy } = getCurrentInstance() const rules = reactive(getRules()) - const formData = ref(getFormData()) + const formData = ref(initFormData()) const dataForm = ref() const props = defineProps({ form: { @@ -42,14 +42,14 @@ proxy.$common.setDefaultValue(props.form.props, 'labelPosition', 'right') proxy.$common.setDefaultValue(props.form.props, 'labelWidth', '120px') - if(props.detail.formData){ + if(props.detail && props.detail.formData){ if(props.detail.handlerFormData){ props.detail.handlerFormData(props.detail.formData) } formData.value = props.detail.formData } - if(props.detail.request){ + if(props.detail && props.detail.request){ } @@ -65,16 +65,21 @@ return _rules } - function getFormData() { + function initFormData() { var data = {} props.form.rows.forEach(row => { 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 } + function getFormData(){ + return formData.value + } + function save(d) { dataForm.value.validate((valid) => { if (valid) { @@ -87,7 +92,7 @@ type: 'success', duration: 2000 }) - if(props.detail.formData){ + if(props.detail && props.detail.formData){ props.detail.formData = {} } d.hide() @@ -109,6 +114,6 @@ }) } - defineExpose({ save, getDetail }) + defineExpose({ save, getDetail, getFormData }) diff --git a/magic-boot-ui/src/components/magic/advanced/mb-list.vue b/magic-boot-ui/src/components/magic/advanced/mb-list.vue index a28cc72..7279dc5 100644 --- a/magic-boot-ui/src/components/magic/advanced/mb-list.vue +++ b/magic-boot-ui/src/components/magic/advanced/mb-list.vue @@ -1,7 +1,7 @@