|
@@ -1,124 +1,335 @@
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { useUserStore } from "@/stores";
|
|
|
|
|
|
|
+
|
|
|
|
|
+import { useUserStore, useNotificationStore } from "@/stores";
|
|
|
|
|
+
|
|
|
import { useI18n } from "vue-i18n";
|
|
import { useI18n } from "vue-i18n";
|
|
|
-import { createVNode, ref } from 'vue'
|
|
|
|
|
-const userStore = useUserStore();
|
|
|
|
|
|
|
+
|
|
|
|
|
+import { createVNode, ref, watch, onMounted } from "vue";
|
|
|
|
|
+
|
|
|
import {
|
|
import {
|
|
|
|
|
+
|
|
|
QuestionCircleOutlined,
|
|
QuestionCircleOutlined,
|
|
|
|
|
+
|
|
|
BellOutlined,
|
|
BellOutlined,
|
|
|
|
|
+
|
|
|
DownOutlined,
|
|
DownOutlined,
|
|
|
|
|
+
|
|
|
ExclamationCircleFilled,
|
|
ExclamationCircleFilled,
|
|
|
|
|
+
|
|
|
} from "@ant-design/icons-vue";
|
|
} from "@ant-design/icons-vue";
|
|
|
-import { Modal } from 'ant-design-vue';
|
|
|
|
|
-import { useRouter, useRoute } from 'vue-router'
|
|
|
|
|
|
|
+
|
|
|
|
|
+import { Modal } from "ant-design-vue";
|
|
|
|
|
+
|
|
|
|
|
+import { useRouter, useRoute } from "vue-router";
|
|
|
|
|
+
|
|
|
|
|
+import { getWsClient } from "@/utils/wsClient";
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const userStore = useUserStore();
|
|
|
|
|
+
|
|
|
|
|
+const notificationStore = useNotificationStore();
|
|
|
|
|
+
|
|
|
const { t } = useI18n();
|
|
const { t } = useI18n();
|
|
|
-const router = useRouter()
|
|
|
|
|
-const route = useRoute()
|
|
|
|
|
-const type = route.params?.type
|
|
|
|
|
-const visible = ref(false)
|
|
|
|
|
-console.log(route)
|
|
|
|
|
|
|
+
|
|
|
|
|
+const router = useRouter();
|
|
|
|
|
+
|
|
|
|
|
+const route = useRoute();
|
|
|
|
|
+
|
|
|
|
|
+const type = route.params?.type;
|
|
|
|
|
+
|
|
|
|
|
+const visible = ref(false);
|
|
|
|
|
+
|
|
|
|
|
+const wsClient = getWsClient();
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const handleBellClick = () => {
|
|
|
|
|
+
|
|
|
|
|
+ notificationStore.clearUnread();
|
|
|
|
|
+
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
const handleMenuClick = (e) => {
|
|
const handleMenuClick = (e) => {
|
|
|
|
|
+
|
|
|
if (e.key === "1") {
|
|
if (e.key === "1") {
|
|
|
- // 跳转到账户信息页面
|
|
|
|
|
- console.log("我的账户");
|
|
|
|
|
- router.push('/information')
|
|
|
|
|
|
|
+
|
|
|
|
|
+ router.push("/information");
|
|
|
|
|
+
|
|
|
visible.value = true;
|
|
visible.value = true;
|
|
|
|
|
+
|
|
|
} else if (e.key === "2") {
|
|
} else if (e.key === "2") {
|
|
|
- // 执行退出登录操作
|
|
|
|
|
|
|
+
|
|
|
Modal.confirm({
|
|
Modal.confirm({
|
|
|
- title: t('common.tip'),
|
|
|
|
|
- icon: createVNode(ExclamationCircleFilled),
|
|
|
|
|
- content: t('login.logoutTip'),
|
|
|
|
|
- centered: true,
|
|
|
|
|
- // okText: '确认',
|
|
|
|
|
- // cancelText: '取消',
|
|
|
|
|
- onOk: async () => {
|
|
|
|
|
- await userStore.logout()
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+
|
|
|
|
|
+ title: t("common.tip"),
|
|
|
|
|
+
|
|
|
|
|
+ icon: createVNode(ExclamationCircleFilled),
|
|
|
|
|
+
|
|
|
|
|
+ content: t("login.logoutTip"),
|
|
|
|
|
+
|
|
|
|
|
+ centered: true,
|
|
|
|
|
+
|
|
|
|
|
+ onOk: async () => {
|
|
|
|
|
+
|
|
|
|
|
+ wsClient.disconnect(true);
|
|
|
|
|
+
|
|
|
|
|
+ await userStore.logout();
|
|
|
|
|
+
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+watch(
|
|
|
|
|
+
|
|
|
|
|
+ () => userStore.getToken,
|
|
|
|
|
+
|
|
|
|
|
+ (token) => {
|
|
|
|
|
+
|
|
|
|
|
+ if (token) {
|
|
|
|
|
+
|
|
|
|
|
+ wsClient.connect(token);
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+
|
|
|
|
|
+ wsClient.disconnect(true);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ { immediate: true }
|
|
|
|
|
+
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+const initWebbsock = () => {
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+
|
|
|
|
|
+ const token = userStore.getToken;
|
|
|
|
|
+ console.log('token', token)
|
|
|
|
|
+ if (token) {
|
|
|
|
|
+
|
|
|
|
|
+ wsClient.connect(token);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
</script>
|
|
</script>
|
|
|
|
|
+
|
|
|
<template>
|
|
<template>
|
|
|
- <div class="flex items-center justify-between px-10 bg-white h-21">
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <div class="flex items-center justify-between px-10 bg-white h-21 haeder">
|
|
|
|
|
+
|
|
|
<div class="haeder-left">
|
|
<div class="haeder-left">
|
|
|
|
|
+
|
|
|
<span v-if="route.name == 'sceneomore'" class="haeder-left-name">
|
|
<span v-if="route.name == 'sceneomore'" class="haeder-left-name">
|
|
|
- <span class="cursor-pointer font-route" @click="$router.push(type == 'laser'?'/sceneobj': '/scenemesh')">{{type == 'laser'?$t('scene.obj'):$t('scene.mesh')}}</span>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <span
|
|
|
|
|
+
|
|
|
|
|
+ class="cursor-pointer font-route"
|
|
|
|
|
+
|
|
|
|
|
+ @click="$router.push(type == 'laser' ? '/sceneobj' : '/scenemesh')"
|
|
|
|
|
+
|
|
|
|
|
+ >{{ type == "laser" ? $t("scene.obj") : $t("scene.mesh") }}</span
|
|
|
|
|
+
|
|
|
|
|
+ >
|
|
|
|
|
+
|
|
|
<span class="font-fh">/</span>
|
|
<span class="font-fh">/</span>
|
|
|
- <span class="font-name">{{$t('scene.moreAction')}}</span>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <span class="font-name">{{ $t("scene.moreAction") }}</span>
|
|
|
|
|
+
|
|
|
</span>
|
|
</span>
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
<div class="flex items-center gap-4">
|
|
<div class="flex items-center gap-4">
|
|
|
- <div class="cursor-pointer haeder-right-item">
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <div
|
|
|
|
|
+
|
|
|
|
|
+ class="cursor-pointer haeder-right-item bell-wrap"
|
|
|
|
|
+
|
|
|
|
|
+ @click="handleBellClick"
|
|
|
|
|
+
|
|
|
|
|
+ >
|
|
|
|
|
+
|
|
|
<BellOutlined />
|
|
<BellOutlined />
|
|
|
|
|
+
|
|
|
|
|
+ <span v-if="notificationStore.hasUnread" class="bell-dot"></span>
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
<div class="cursor-pointer haeder-right-item">
|
|
<div class="cursor-pointer haeder-right-item">
|
|
|
|
|
+
|
|
|
<QuestionCircleOutlined />
|
|
<QuestionCircleOutlined />
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
<div
|
|
<div
|
|
|
|
|
+
|
|
|
class="cursor-pointer haeder-right-item haeder-right-head"
|
|
class="cursor-pointer haeder-right-item haeder-right-head"
|
|
|
|
|
+
|
|
|
:class="{ vip: userStore.incrementNum }"
|
|
:class="{ vip: userStore.incrementNum }"
|
|
|
|
|
+
|
|
|
:style="{ 'background-image': `url(${userStore.head})` }"
|
|
:style="{ 'background-image': `url(${userStore.head})` }"
|
|
|
|
|
+
|
|
|
@click="$router.push('/information')"
|
|
@click="$router.push('/information')"
|
|
|
- >
|
|
|
|
|
- <!-- <div class="user avatar" /> -->
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
|
|
|
- <a-dropdown v-model:open="visible" arrow placement="bottom">
|
|
|
|
|
|
|
+ ></div>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ <a-dropdown v-model:open="visible" arrow placement="bottom" :overlayStyle="{minWidth: '100px', textAlign: 'center'}">
|
|
|
|
|
+
|
|
|
<div class="flex items-center cursor-pointer">
|
|
<div class="flex items-center cursor-pointer">
|
|
|
|
|
+
|
|
|
<span class="mr-1">{{ userStore.nickName }}</span>
|
|
<span class="mr-1">{{ userStore.nickName }}</span>
|
|
|
|
|
+
|
|
|
<DownOutlined style="font-size: 10px" />
|
|
<DownOutlined style="font-size: 10px" />
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
<template #overlay>
|
|
<template #overlay>
|
|
|
|
|
+
|
|
|
<a-menu @click="handleMenuClick">
|
|
<a-menu @click="handleMenuClick">
|
|
|
- <a-menu-item key="1">{{ t('mall.myAccount') }}</a-menu-item>
|
|
|
|
|
- <a-menu-item key="2">{{ t('mall.logOut') }}</a-menu-item>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <a-menu-item key="1">{{ t("mall.myAccount") }}</a-menu-item>
|
|
|
|
|
+
|
|
|
|
|
+ <a-menu-item key="2">{{ t("mall.logOut") }}</a-menu-item>
|
|
|
|
|
+
|
|
|
</a-menu>
|
|
</a-menu>
|
|
|
|
|
+
|
|
|
</template>
|
|
</template>
|
|
|
|
|
+
|
|
|
</a-dropdown>
|
|
</a-dropdown>
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
<style lang="less" scoped>
|
|
<style lang="less" scoped>
|
|
|
|
|
+
|
|
|
.haeder {
|
|
.haeder {
|
|
|
|
|
+
|
|
|
font-weight: normal;
|
|
font-weight: normal;
|
|
|
|
|
+
|
|
|
font-size: 14px;
|
|
font-size: 14px;
|
|
|
|
|
+
|
|
|
color: #4e5969;
|
|
color: #4e5969;
|
|
|
|
|
+
|
|
|
.haeder-left {
|
|
.haeder-left {
|
|
|
|
|
+
|
|
|
font-weight: normal;
|
|
font-weight: normal;
|
|
|
|
|
+
|
|
|
font-size: 14px;
|
|
font-size: 14px;
|
|
|
|
|
+
|
|
|
color: #1d2129;
|
|
color: #1d2129;
|
|
|
- &-name{
|
|
|
|
|
|
|
+
|
|
|
|
|
+ &-name {
|
|
|
|
|
+
|
|
|
font-weight: normal;
|
|
font-weight: normal;
|
|
|
|
|
+
|
|
|
font-size: 14px;
|
|
font-size: 14px;
|
|
|
- color: #4E5969;
|
|
|
|
|
- .font-fh{
|
|
|
|
|
|
|
+
|
|
|
|
|
+ color: #4e5969;
|
|
|
|
|
+
|
|
|
|
|
+ .font-fh {
|
|
|
|
|
+
|
|
|
margin: 0 4px;
|
|
margin: 0 4px;
|
|
|
|
|
+
|
|
|
user-select: none;
|
|
user-select: none;
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
- .font-name{
|
|
|
|
|
- color: #1D2129;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ .font-name {
|
|
|
|
|
+
|
|
|
|
|
+ color: #1d2129;
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.haeder-right-item {
|
|
.haeder-right-item {
|
|
|
|
|
+
|
|
|
width: 32px;
|
|
width: 32px;
|
|
|
|
|
+
|
|
|
height: 32px;
|
|
height: 32px;
|
|
|
|
|
+
|
|
|
line-height: 32px;
|
|
line-height: 32px;
|
|
|
|
|
+
|
|
|
background: #f2f3f5;
|
|
background: #f2f3f5;
|
|
|
|
|
+
|
|
|
border-radius: 18px;
|
|
border-radius: 18px;
|
|
|
|
|
+
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .bell-wrap {
|
|
|
|
|
+
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .bell-dot {
|
|
|
|
|
+
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+
|
|
|
|
|
+ top: 4px;
|
|
|
|
|
+
|
|
|
|
|
+ right: 4px;
|
|
|
|
|
+
|
|
|
|
|
+ width: 8px;
|
|
|
|
|
+
|
|
|
|
|
+ height: 8px;
|
|
|
|
|
+
|
|
|
|
|
+ background: #f53f3f;
|
|
|
|
|
+
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+
|
|
|
|
|
+ border: 1px solid #fff;
|
|
|
|
|
+
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.haeder-right-head {
|
|
.haeder-right-head {
|
|
|
|
|
+
|
|
|
border: 1px solid #efefef;
|
|
border: 1px solid #efefef;
|
|
|
|
|
+
|
|
|
background: no-repeat center/cover;
|
|
background: no-repeat center/cover;
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
.vip {
|
|
.vip {
|
|
|
|
|
+
|
|
|
border-color: #d8af7c;
|
|
border-color: #d8af7c;
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
-</style>
|
|
|
|
|
|
|
+
|
|
|
|
|
+</style>
|
|
|
|
|
+
|
|
|
|
|
+
|