no message

This commit is contained in:
kuaifan 2025-04-19 19:29:58 +08:00
parent 13e1415355
commit a4cb5d1b14
6 changed files with 176 additions and 178 deletions

View File

@ -2,6 +2,7 @@
namespace App\Http\Controllers\Api; namespace App\Http\Controllers\Api;
use App\Models\UserDevice;
use App\Models\WebSocketDialog; use App\Models\WebSocketDialog;
use App\Models\WebSocketDialogMsg; use App\Models\WebSocketDialogMsg;
use Request; use Request;
@ -1445,23 +1446,29 @@ class SystemController extends AbstractController
* *
* @apiSuccessExample {json} Success-Response: * @apiSuccessExample {json} Success-Response:
{ {
"version": "0.0.1", "device_count": 3, // 设备数量
"version": "0.0.1", // 服务端版本号
"publish": { "publish": {
"provider": "generic", "provider": "generic",
"url": "" "url": ""
} }
} }
// 如果header请求中存在version字段则返回数据包裹在 {ret:1,data:{},msg:"success"} 中
*/ */
public function version() public function version()
{ {
$url = url('');
$package = Base::getPackage(); $package = Base::getPackage();
$array = [ $array = [
'device_count' => 0,
'version' => Base::getVersion(), 'version' => Base::getVersion(),
'publish' => [], 'publish' => [],
]; ];
if (Doo::userId()) {
$array['device_count'] = UserDevice::whereUserid(Doo::userId())->count();
}
if (is_array($package['app'])) { if (is_array($package['app'])) {
$i = 0; $i = 0;
$url = url('');
foreach ($package['app'] as $item) { foreach ($package['app'] as $item) {
$urls = $item['urls'] && is_array($item['urls']) ? $item['urls'] : $item['url']; $urls = $item['urls'] && is_array($item['urls']) ? $item['urls'] : $item['url'];
if (is_array($item['publish']) && ($i === 0 || Base::hostContrast($url, $urls))) { if (is_array($item['publish']) && ($i === 0 || Base::hostContrast($url, $urls))) {
@ -1470,6 +1477,9 @@ class SystemController extends AbstractController
$i++; $i++;
} }
} }
if (Request::hasHeader('version')) {
return Base::retSuccess('success', $array);
}
return $array; return $array;
} }

View File

@ -2443,27 +2443,6 @@ class UsersController extends AbstractController
return Base::retSuccess('success', $data); return Base::retSuccess('success', $data);
} }
/**
* @api {get} api/users/device/count 38. 获取设备数量
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup users
* @apiName device__count
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function device__count()
{
$user = User::auth();
//
return Base::retSuccess('success', [
'count' => UserDevice::whereUserid($user->userid)->count()
]);
}
/** /**
* @api {get} api/users/device/list 39. 获取设备列表 * @api {get} api/users/device/list 39. 获取设备列表
* *

View File

@ -165,7 +165,7 @@ export default {
} }
} }
}).catch(_ => { }).catch(_ => {
// console.log('')
}) })
// //
this.__checkVersion && clearTimeout(this.__checkVersion) this.__checkVersion && clearTimeout(this.__checkVersion)

View File

@ -12,7 +12,7 @@
</div> </div>
<div class="time"> <div class="time">
<EPopover placement="bottom-start" trigger="click"> <EPopover placement="bottom-start" trigger="click">
<div class="time-popover"> <div class="setting-device-popover">
<p>{{$L('登录时间')}}: {{device.created_at}}</p> <p>{{$L('登录时间')}}: {{device.created_at}}</p>
<p>{{$L('更新时间')}}: {{device.updated_at}}</p> <p>{{$L('更新时间')}}: {{device.updated_at}}</p>
<p>{{$L('过期时间')}}: {{device.expired_at}}</p> <p>{{$L('过期时间')}}: {{device.expired_at}}</p>
@ -30,107 +30,6 @@
</div> </div>
</template> </template>
<style lang="scss" scoped>
.setting-device {
> ul {
display: flex;
flex-direction: column;
gap: 16px;
> li {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 8px;
padding: 24px;
border-radius: 12px;
background: rgba(79, 89, 102, .04);
.icon {
align-self: flex-start;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 24px;
> span {
width: 20px;
height: 20px;
}
}
.info {
flex: 1 1 auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 6px;
.title {
width: 100%;
font-size: 16px;
line-height: 24px;
display: flex;
flex-direction: row;
align-items: center;
gap: 2px;
justify-content: flex-start;
color: #262626;
.name {
font-weight: 500;
}
.device {
&:before {
content: "";
}
&:after {
content: "";
}
}
}
.time {
width: 100%;
font-size: 14px;
line-height: 22px;
color: #8a939d;
cursor: pointer;
}
}
.current {
color: #595959;
}
.ivu-btn {
background: #d9d9dd;
border-color: #d9d9dd;
color: #262626;
box-shadow: none;
height: 36px;
padding: 0 12px;
border-radius: 12px;
&:hover {
background: rgba(217, 217, 221, 0.8);
border-color: rgba(217, 217, 221, 0.8);
}
}
}
}
}
.time-popover {
> p {
line-height: 26px;
}
}
</style>
<script> <script>
export default { export default {
name: 'SettingDevice', name: 'SettingDevice',
@ -152,8 +51,8 @@ export default {
url: 'users/device/list', url: 'users/device/list',
}).then(({data}) => { }).then(({data}) => {
this.devices = data.list this.devices = data.list
if (typeof this.$parent.updateDeviceNum === "function") { if (typeof this.$parent.updateDeviceCount === "function") {
this.$parent.updateDeviceNum(this.devices.length); this.$parent.updateDeviceCount(this.devices.length);
} }
}).catch(() => { }).catch(() => {
this.devices = [] this.devices = []

View File

@ -19,14 +19,14 @@
@click="toggleRoute(item.path)"> @click="toggleRoute(item.path)">
<template v-if="item.path === 'device'"> <template v-if="item.path === 'device'">
<AutoTip>{{$L(item.name)}}</AutoTip> <AutoTip>{{$L(item.name)}}</AutoTip>
<span v-if="deviceNum > 0" class="op-8">{{deviceNum}}</span> <span v-if="deviceCount > 0" class="op-8">{{deviceCount}}</span>
</template> </template>
<template v-else-if="item.path === 'version'"> <template v-else-if="item.path === 'version'">
<AutoTip disabled>{{$L(item.name)}}</AutoTip> <AutoTip disabled>{{$L(item.name)}}</AutoTip>
<Badge v-if="!!clientNewVersion" :text="clientNewVersion"/> <Badge v-if="!!clientNewVersion" :text="clientNewVersion"/>
</template> </template>
<template v-else-if="item.path === 'version-show'"> <template v-else-if="item.path === 'version-show'">
<AutoTip>{{$L(item.name)}}: {{version}}</AutoTip> <AutoTip>{{$L(item.name)}}: {{clientVersion}}</AutoTip>
</template> </template>
<span v-else>{{$L(item.name)}}</span> <span v-else>{{$L(item.name)}}</span>
</li> </li>
@ -55,19 +55,20 @@ export default {
components: {MobileNavTitle}, components: {MobileNavTitle},
data() { data() {
return { return {
deviceNum: 0, deviceCount: 0,
version: window.systemInfo.version serverVersion: null,
clientVersion: window.systemInfo.version,
} }
}, },
mounted() { mounted() {
if (this.$isEEUiApp) { if (this.$isEEUiApp) {
this.version = `${window.systemInfo.version} (${$A.eeuiAppLocalVersion()})` this.clientVersion = `${window.systemInfo.version} (${$A.eeuiAppLocalVersion()})`
} }
}, },
activated() { activated() {
this.getDeviceNum(); this.getVersion();
}, },
computed: { computed: {
@ -221,15 +222,12 @@ export default {
const array = [ const array = [
`${this.$L('服务器')}: ${$A.getDomain($A.mainUrl())}` `${this.$L('服务器')}: ${$A.getDomain($A.mainUrl())}`
] ]
await this.$store.dispatch("showSpinner", 600) if (this.serverVersion) {
try { array.push(`${this.$L('服务器版本')}: v${this.serverVersion}`)
const version = await this.getServerVersion() } else {
array.push(`${this.$L('服务器版本')}: v${version}`)
} catch (e) {
array.push(`${this.$L('服务器版本')}: ` + this.$L('获取失败')) array.push(`${this.$L('服务器版本')}: ` + this.$L('获取失败'))
} }
await this.$store.dispatch("hiddenSpinner") array.push(`${this.$L('客户端版本')}: v${this.clientVersion}`)
array.push(`${this.$L('客户端版本')}: v${this.version}`)
// //
$A.modalInfo({ $A.modalInfo({
language: false, language: false,
@ -238,33 +236,23 @@ export default {
}) })
}, },
getDeviceNum() { getVersion() {
this.$store.dispatch("call", { this.versionTimer && clearTimeout(this.versionTimer)
url: 'users/device/count', this.versionTimer = setTimeout(() => {
}).then(({data}) => { this.$store.dispatch("call", {
this.updateDeviceNum(data.count) url: 'system/version',
}).catch(() => { }).then(({data}) => {
this.updateDeviceNum(0) this.serverVersion = data.version
}) this.deviceCount = data.device_count
}).catch(() => {
// console.log('')
})
}, this.versionTimer ? 1000 : 0)
}, },
updateDeviceNum(num) { updateDeviceCount(num) {
this.deviceNum = num this.deviceCount = num
}, },
getServerVersion() {
return new Promise((resolve, reject) => {
if (/^\d+\.\d+\.\d+$/.test(this.systemConfig.server_version)) {
resolve(this.systemConfig.server_version)
return;
}
axios.get($A.apiUrl('system/version')).then(({status, data}) => {
if (status === 200) {
resolve(data.version)
}
}).catch(reject)
})
}
} }
} }
</script> </script>

View File

@ -343,27 +343,126 @@
} }
.setting-device { .setting-device {
.icon { > ul {
> span { display: flex;
&.android { flex-direction: column;
background-image: url("../images/device/android.svg"); gap: 16px;
> li {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 8px;
padding: 24px;
border-radius: 12px;
background: rgba(79, 89, 102, .04);
.icon {
align-self: flex-start;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 24px;
> span {
width: 20px;
height: 20px;
&.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");
}
}
} }
&.apple {
background-image: url("../images/device/apple.svg"); .info {
flex: 1 1 auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 6px;
.title {
width: 100%;
font-size: 16px;
line-height: 24px;
display: flex;
flex-direction: row;
align-items: center;
gap: 2px;
justify-content: flex-start;
color: #262626;
.name {
font-weight: 500;
}
.device {
&:before {
content: "";
}
&:after {
content: "";
}
}
}
.time {
width: 100%;
font-size: 14px;
line-height: 22px;
color: #8a939d;
cursor: pointer;
}
} }
&.macos {
background-image: url("../images/device/macos.svg"); .current {
color: #595959;
} }
&.window {
background-image: url("../images/device/window.svg"); .ivu-btn {
} background: #d9d9dd;
&.web { border-color: #d9d9dd;
background-image: url("../images/device/web.svg"); color: #262626;
box-shadow: none;
height: 36px;
padding: 0 12px;
border-radius: 12px;
&:hover {
background: rgba(217, 217, 221, 0.8);
border-color: rgba(217, 217, 221, 0.8);
}
} }
} }
} }
} }
.setting-device-popover {
> p {
line-height: 26px;
}
}
body.window-portrait { body.window-portrait {
.page-setting { .page-setting {
background-color: #f8f8f8; background-color: #f8f8f8;
@ -469,4 +568,27 @@ body.window-portrait {
} }
} }
} }
.setting-device {
padding: 16px !important;
> ul {
> li {
padding: 20px;
.info {
.title {
flex-direction: column;
align-items: flex-start;
.device {
opacity: 0.6;
&:before,
&:after {
content: "";
}
}
}
}
}
}
}
} }