Files
blog/src/components/menu.vue
2025-08-07 16:39:37 +08:00

212 lines
6.0 KiB
Vue

<template>
<div ref="nav"
class="main-nav flex justify-between bg-white border-b border-gray-100 shadow-[0_2px_10px_rgba(173,21,21,0.05)]">
<!-- 网站Logo -->
<div class="px-5 flex items-center" slot="brand" @click="goHome">
<img src="@/logo/红色字体.png" alt="柚子的网站" class="h-9 align-middle" />
</div>
<!-- 主导航菜单 -->
<d-menu mode="horizontal" router class="ml-5 h-14 text-[16px]" :default-select-keys="[key]">
<d-menu-item key="home">
<d-icon :component="homeSvg" class="w-5 mr-1"></d-icon>
首页
</d-menu-item>
<d-menu-item key="gallery">
<d-icon :component="picSvg" class="w-5 mr-1"></d-icon>
画廊
</d-menu-item>
<d-menu-item key="article">
<d-icon :component="artiSvg" class="w-5 mr-1 "></d-icon>
文章
</d-menu-item>
<d-menu-item key="widget">
<d-icon :component="settingSvg" class="w-5 mr-1 "></d-icon>
工具
</d-menu-item>
<d-menu-item key="appshare">
<d-icon :component="downSvg" class="w-5 mr-1 "></d-icon>
软件分享
</d-menu-item>
<d-menu-item key="plink">
<d-icon :component="linkSvg" class="w-5 mr-1 "></d-icon>
友链
</d-menu-item>
</d-menu>
<!-- 用户区域 -->
<div class="!text-[#ec66ab] user-area flex items-center px-3">
<span class="flex items-center location-info ">
<d-icon color="#ec66ab" class="mr-1" name="location-new"></d-icon>
{{ locationInfo }}
</span>
<span class="mx-3 text-gray-300">|</span>
<span class="weather-info mr-2">{{ wea }}</span>
<i :class="'qiIcon qi-' + weaIcon + '-fill'"></i>
<span class="weather-info ml-4">{{ temp }}°C</span>
<d-avatar v-if="userinfo" :img-src="userinfo.ava_url" class="ml-20 cursor-pointer" alt="用户的头" />
<d-avatar v-else class="ml-20 cursor-pointer" @click="toLogin"></d-avatar>
</div>
</div>
</template>
<script setup lang="ts">
// 从@/icon/menu引入所有的svg文件
import artiSvg from '@/icon/menu/arti.svg';
import downSvg from '@/icon/menu/download.svg';
import homeSvg from '@/icon/menu/home.svg';
import linkSvg from '@/icon/menu/link.svg';
import picSvg from '@/icon/menu/pic.svg';
import settingSvg from '@/icon/menu/setting.svg';
import { onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const route = useRoute();
const router = useRouter();
const key = ref("home");
const locationInfo = ref("获取位置中...");
const latitude = ref<number | null>(null);
const longitude = ref<number | null>(null);
const wea = ref("")
const weaIcon = ref<string>("")
const temp = ref<number>(0);
const userinfo: any = ref(null)
const nav: any = useTemplateRef('nav')
const navx = $store.nav.useNavStore()
// 获取地理位置
const getLocation = () => {
if (!navigator.geolocation) {
locationInfo.value = "您的浏览器不支持地理位置定位";
return;
}
navigator.geolocation.getCurrentPosition(
async (position) => {
latitude.value = position.coords.latitude;
longitude.value = position.coords.longitude;
const jw = `${longitude.value.toFixed(2)},${latitude.value.toFixed(2)}`;
// 这里可以添加调用后端API获取具体位置名称的逻辑
handdleJw(jw);
},
async (error) => {
switch (error.code) {
case error.PERMISSION_DENIED:
locationInfo.value = "用户拒绝了位置请求";
break;
case error.POSITION_UNAVAILABLE:
locationInfo.value = "位置信息不可用";
break;
case error.TIMEOUT:
locationInfo.value = "获取位置超时";
break;
}
const res = await $http.mix.getIp();
latitude.value = res.data.lat;
longitude.value = res.data.lon;
const jw = `${longitude.value?.toFixed(2)},${latitude.value?.toFixed(2)}`;
// 这里可以添加调用后端API获取具体位置名称的逻辑
handdleJw(jw);
},
{
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 0
}
);
};
async function handdleJw(jw: string) {
const zxs = ['北京', '重庆', '天津', '上海']
// 根据经纬度获取物理位置
const loc = await $http.mix.getLocation({ location: jw });
console.log(loc);
if (loc.code == 200) {
const data = loc.data;
if (zxs.includes(data.adm2)) {
locationInfo.value = `${data.country}${data.adm1}${data.name}`;
} else {
locationInfo.value = `${data.adm1}${data.adm2}${data.name}`;
}
} else {
$msg.console.error(loc.msg);
return
}
const res = await $http.mix.getWeather({ location: jw });
console.log(res);
if (res.code == 200) {
wea.value = res.data.text;
weaIcon.value = res.data.icon;
temp.value = res.data.temp;
} else {
$msg.console.error(loc.msg);
}
}
watch(() => route.name, (newVal) => {
key.value = newVal as string
})
function goHome() {
if (route.name == 'home') return
router.push({ name: 'home' });
}
function toLogin() {
if ($cookies.get('token')) return
router.push('/login');
}
onMounted(() => {
console.log(route.name);
userinfo.value = $cookies.get('userinfo');
console.log('>>>>>>>>>>', userinfo.value);
key.value = route.name as string;
getLocation(); // 组件挂载时获取位置
const h: number = nav.value.clientHeight
navx.setNavH(h)
});
</script>
<style scoped>
/* :deep(svg) {
color: red;
} */
:deep(.devui-menu-horizontal .devui-menu-item:hover span .icon) {
color: var(--devui-brand, #5e7ce0) !important;
fill: var(--devui-brand, #5e7ce0) !important;
}
:deep(.devui-menu-item-select span svg) {
color: var(--devui-brand, #5e7ce0) !important;
fill: var(--devui-brand, #5e7ce0) !important;
line-height: 100% !important;
}
:deep(.devui-menu-item-select span) {
color: var(--devui-brand, #5e7ce0) !important;
}
:deep(.devui-menu-horizontal) {
padding: 14px 20px 6px;
}
:deep(.devui-menu-item span) {
display: flex;
align-items: center;
.devui-icon__container {
display: flex;
align-items: center;
}
}
</style>