diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index b99f1325e..96c86ae8d 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -267,9 +267,20 @@ class UsersController extends AbstractController return Base::retSuccess('请求成功', $captcha); } + /** + * @api {get} api/users/logout 06. 退出登录 + * + * @apiVersion 1.0.0 + * @apiGroup users + * @apiName logout + * + * @apiSuccess {Number} ret 返回状态码(1正确、0错误) + * @apiSuccess {String} msg 返回信息(错误描述) + */ public function logout() { - $user = User::auth(); + UserDevice::forget(); + return Base::retSuccess('退出成功'); } /** @@ -2504,6 +2515,6 @@ class UsersController extends AbstractController } UserDevice::forget($userDevice->id); // - return Base::retSuccess('删除成功'); + return Base::retSuccess('操作成功'); } } diff --git a/app/Models/User.php b/app/Models/User.php index 8b004ebdd..74adcc123 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -444,8 +444,9 @@ class User extends AbstractModel { $user = self::authInfo(); if (!$user) { - if (Base::token()) { - UserDevice::forget(); + $token = Base::token(); + if ($token) { + UserDevice::forget($token); throw new ApiException('身份已失效,请重新登录', [], -1); } else { throw new ApiException('请登录后继续...', [], -1); diff --git a/resources/assets/js/pages/manage.vue b/resources/assets/js/pages/manage.vue index f59835ea0..21ed181af 100644 --- a/resources/assets/js/pages/manage.vue +++ b/resources/assets/js/pages/manage.vue @@ -838,7 +838,7 @@ export default { case 'logout': $A.modalConfirm({ title: '退出登录', - content: '你确定要登出系统?', + content: '你确定要登出系统吗?', onOk: () => { this.$store.dispatch("logout", false) } diff --git a/resources/assets/js/pages/manage/setting/device.vue b/resources/assets/js/pages/manage/setting/device.vue new file mode 100644 index 000000000..fdef8d9c7 --- /dev/null +++ b/resources/assets/js/pages/manage/setting/device.vue @@ -0,0 +1,212 @@ + + + + + + + + + + {{ getName(device.detail) }} + {{ device.detail.os }} + + + + + {{$L('登录时间')}}: {{device.created_at}} + {{$L('更新时间')}}: {{device.updated_at}} + {{$L('过期时间')}}: {{device.expired_at}} + + {{ device.updated_at }} + + + + + {{$L('当前设备')}} + {{$L('退出登录')}} + + + + + + + + + diff --git a/resources/assets/js/pages/manage/setting/index.vue b/resources/assets/js/pages/manage/setting/index.vue index 581e2f71e..457852fe1 100644 --- a/resources/assets/js/pages/manage/setting/index.vue +++ b/resources/assets/js/pages/manage/setting/index.vue @@ -17,7 +17,11 @@ :key="key" :class="classNameRoute(item.path, item.divided)" @click="toggleRoute(item.path)"> - + + {{$L(item.name)}} + {{deviceNum}} + + {{$L(item.name)}} @@ -51,6 +55,7 @@ export default { components: {MobileNavTitle}, data() { return { + deviceNum: 0, version: window.systemInfo.version } }, @@ -61,6 +66,10 @@ export default { } }, + activated() { + this.getDeviceNum(); + }, + computed: { ...mapState(['userInfo', 'userIsAdmin', 'clientNewVersion', 'systemConfig']), @@ -97,7 +106,8 @@ export default { menu.push(...[ {path: 'version', name: '更新日志', divided: true}, {path: 'version-show', name: '版本'}, - {path: 'clearCache', name: '清除缓存', divided: true}, + {path: 'device', name: '登录设备', divided: true}, + {path: 'clearCache', name: '清除缓存'}, {path: 'logout', name: '退出登录'}, ]) return menu; @@ -224,6 +234,20 @@ export default { }) }, + getDeviceNum() { + this.$store.dispatch("call", { + url: 'users/device/count', + }).then(({data}) => { + this.updateDeviceNum(data.count) + }).catch(() => { + this.updateDeviceNum(0) + }) + }, + + updateDeviceNum(num) { + this.deviceNum = num + }, + getServerVersion() { return new Promise((resolve, reject) => { if (/^\d+\.\d+\.\d+$/.test(this.systemConfig.server_version)) { diff --git a/resources/assets/js/routes.js b/resources/assets/js/routes.js index 332e51270..3f861a58f 100755 --- a/resources/assets/js/routes.js +++ b/resources/assets/js/routes.js @@ -94,6 +94,11 @@ export default [ path: 'system', component: () => import('./pages/manage/setting/system.vue'), }, + { + name: 'manage-setting-device', + path: 'device', + component: () => import('./pages/manage/setting/device.vue'), + }, { name: 'manage-setting-version', path: 'version', diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index 4185b66a0..e43997191 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -985,6 +985,11 @@ export default { * @param appendFrom */ logout({state, dispatch}, appendFrom = true) { + try { + dispatch("call", "users/logout") + } catch (e) { + console.log(e); + } dispatch("handleClearCache", {}).then(() => { let from = ["/", "/login"].includes(window.location.pathname) ? "" : encodeURIComponent(window.location.href); if (appendFrom === false) { diff --git a/resources/assets/sass/pages/page-setting.scss b/resources/assets/sass/pages/page-setting.scss index fba945d8a..a64609c50 100755 --- a/resources/assets/sass/pages/page-setting.scss +++ b/resources/assets/sass/pages/page-setting.scss @@ -82,6 +82,14 @@ align-items: center; } + .common-auto-tip { + flex: 1; + } + + .op-8 { + opacity: 0.8; + } + .ivu-badge { transform: scale(0.8); transform-origin: right center; @@ -334,6 +342,28 @@ } } +.setting-device { + .icon { + > span { + &.android { + background-image: url("../images/device/android.svg"); + } + &.apple { + background-image: url("../images/device/apple.svg"); + } + &.macos { + background-image: url("../images/device/macos.svg"); + } + &.window { + background-image: url("../images/device/window.svg"); + } + &.web { + background-image: url("../images/device/web.svg"); + } + } + } +} + body.window-portrait { .page-setting { background-color: #f8f8f8; diff --git a/resources/assets/statics/public/images/device/android.svg b/resources/assets/statics/public/images/device/android.svg new file mode 100644 index 000000000..dfb03ae22 --- /dev/null +++ b/resources/assets/statics/public/images/device/android.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/assets/statics/public/images/device/apple.svg b/resources/assets/statics/public/images/device/apple.svg new file mode 100644 index 000000000..572569b8d --- /dev/null +++ b/resources/assets/statics/public/images/device/apple.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/assets/statics/public/images/device/macos.svg b/resources/assets/statics/public/images/device/macos.svg new file mode 100644 index 000000000..f8f16fb8d --- /dev/null +++ b/resources/assets/statics/public/images/device/macos.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/assets/statics/public/images/device/web.svg b/resources/assets/statics/public/images/device/web.svg new file mode 100644 index 000000000..27d898980 --- /dev/null +++ b/resources/assets/statics/public/images/device/web.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/assets/statics/public/images/device/window.svg b/resources/assets/statics/public/images/device/window.svg new file mode 100644 index 000000000..e0d4716ec --- /dev/null +++ b/resources/assets/statics/public/images/device/window.svg @@ -0,0 +1 @@ + \ No newline at end of file
{{$L('登录时间')}}: {{device.created_at}}
{{$L('更新时间')}}: {{device.updated_at}}
{{$L('过期时间')}}: {{device.expired_at}}