首页+登录页
This commit is contained in:
240
src/views/Home.vue
Normal file
240
src/views/Home.vue
Normal file
@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<div class="home-page" :style="contentStyle">
|
||||
<d-layout>
|
||||
<d-content class="main-content">
|
||||
<div class="pt-8 px-12">
|
||||
<d-input class="devui-input-demo__mt" size="lg" v-model="searchWord" @keyup.enter="search" placeholder="请输入">
|
||||
<template #prepend>
|
||||
<d-select class="w-48" size="lg" v-model="broswer" :options="options"></d-select>
|
||||
</template>
|
||||
<template #append>
|
||||
<d-icon name="search" style="font-size: inherit;" @click="search" />
|
||||
</template>
|
||||
</d-input>
|
||||
</div>
|
||||
<!-- 图片网格展示区域 -->
|
||||
<PerfectScrollbar class="" :style="navStyle">
|
||||
<div class="navcard grid-cols-4 gap-6 p-12">
|
||||
<d-card class="bg-[white] h-25" v-for="(item, index) in navlist" :key="index"
|
||||
@click="goExtra(item.menu_link)">
|
||||
<template #content>
|
||||
<div class="mt-2 w-full flex flex-col items-center cursor-pointer">
|
||||
<div :style="{ background: item.color }"
|
||||
class="w-8 h-8 rounded-full text-white flex items-center justify-center" v-if="item.icon_error">
|
||||
{{ item.first }}</div>
|
||||
<img v-else width="32" :src="item.menu_icon" @error="imgErr(index)" class="grid-image" />
|
||||
<div class="mt-1 w-full text-center">{{ item.menu_name || "" }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</d-card>
|
||||
<d-card class="bg-[white] h-25">
|
||||
<div @click="addNav" class="w-full h-full flex flex-col items-center justify-center cursor-pointer">
|
||||
<div :style="{ background: getRandomDarkColor() }"
|
||||
class="w-12 h-12 rounded-full text-2xl text-white flex items-center justify-center">
|
||||
+
|
||||
</div>
|
||||
</div>
|
||||
</d-card>
|
||||
</div>
|
||||
</PerfectScrollbar>
|
||||
|
||||
</d-content>
|
||||
<d-aside class="daside w-120">
|
||||
<homeSide></homeSide>
|
||||
</d-aside>
|
||||
</d-layout>
|
||||
|
||||
<!-- 新增导航弹窗 -->
|
||||
<d-modal class="!w-120" v-model="visible" title="新增导航">
|
||||
<d-form ref="formNav" layout="vertical" :data="navData">
|
||||
<d-form-item field="username">
|
||||
<d-input @blur="getIcon" v-model="navData.menu_link" placeholder="请输入单行链接(必填)" />
|
||||
|
||||
</d-form-item>
|
||||
<d-form-item field="password">
|
||||
<d-input v-model="navData.menu_name" placeholder="请输入导航名称(必填)" />
|
||||
</d-form-item>
|
||||
<d-form-item class="form-operation-wrap">
|
||||
<div class="flex">
|
||||
<d-input v-model="navData.menu_icon" placeholder="请输入图标链接" />
|
||||
<img class="ml-5" v-if="navData.menu_icon" width="30" height="30" :src="navData.menu_icon" alt="">
|
||||
<div v-else class="ml-5 w-[30px] h-[30px]"></div>
|
||||
</div>
|
||||
</d-form-item>
|
||||
</d-form>
|
||||
<div class="mt-10 w-full flex justify-between">
|
||||
<d-button @click="navCancel" variant="text" class="w-[49%] hover:bg-[#8a6684] hover:!text-white">取消</d-button>
|
||||
<span class="text-[20px]"> | </span>
|
||||
<d-button @click="navSubmit" variant="text" class="w-[49%] hover:bg-[#5c866a] hover:!text-white"
|
||||
color="primary">确定</d-button>
|
||||
</div>
|
||||
</d-modal>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import homeSide from '@/components/homeSide.vue'
|
||||
import { getDictValue } from '@/util/index.ts'
|
||||
// 新增导航弹窗
|
||||
const visible: any = ref(false)
|
||||
const navData: any = reactive({
|
||||
menu_link: '',
|
||||
menu_name: '',
|
||||
menu_icon: ''
|
||||
})
|
||||
const formNav: any = ref(null)
|
||||
|
||||
|
||||
// 首页逻辑
|
||||
const nav: any = $store.nav.useNavStore()
|
||||
const contentStyle: any = ref({})
|
||||
const navStyle: any = ref({})
|
||||
const searchWord: any = ref('')
|
||||
const broswer: any = ref('bing')
|
||||
const options = ref([
|
||||
{
|
||||
name: '必应',
|
||||
value: 'bing',
|
||||
url: 'https://cn.bing.com/search?q='
|
||||
},
|
||||
{
|
||||
name: '百度',
|
||||
value: 'baidu',
|
||||
url: 'https://www.baidu.com/s?wd='
|
||||
},
|
||||
{
|
||||
name: '谷歌',
|
||||
value: 'google',
|
||||
url: 'https://www.google.com/search?q='
|
||||
},
|
||||
{
|
||||
name: '翻译',
|
||||
value: 'trans',
|
||||
url: 'https://translate.volcengine.com?text='
|
||||
},
|
||||
|
||||
])
|
||||
|
||||
// 图片数据
|
||||
const navlist: any = ref([])
|
||||
|
||||
async function getNavList() {
|
||||
const res = await $http.nav.getNavList()
|
||||
|
||||
res.data.forEach((i: any) => {
|
||||
i.icon_error = false
|
||||
i.first = i.menu_name.at(0)
|
||||
i.color = getRandomDarkColor()
|
||||
});
|
||||
navlist.value = res.data
|
||||
console.log("&&&&&&&&&&&&&&", navlist.value);
|
||||
}
|
||||
|
||||
function imgErr(index: number) {
|
||||
navlist.value[index].icon_error = true
|
||||
}
|
||||
|
||||
function goExtra(link: string) {
|
||||
window.open(link, "_BLANK")
|
||||
}
|
||||
|
||||
function search() {
|
||||
const res = getDictValue(options.value, "value", broswer.value, "url")
|
||||
if (res) {
|
||||
window.open(res + searchWord.value, "_BLANK")
|
||||
}
|
||||
}
|
||||
|
||||
const getRandomDarkColor = (min: number = 30, max: number = 128): string => {
|
||||
// 确保最大值不超过255且最小值不小于0
|
||||
min = Math.max(0, min);
|
||||
max = Math.min(255, max);
|
||||
|
||||
// 确保最大值大于最小值
|
||||
if (max <= min) {
|
||||
max = min + 30;
|
||||
}
|
||||
|
||||
// 生成随机RGB值 (深色)
|
||||
const r = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
const g = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
const b = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
|
||||
// 转换为十六进制
|
||||
const toHex = (c: number) => {
|
||||
const hex = c.toString(16);
|
||||
return hex.length === 1 ? '0' + hex : hex;
|
||||
};
|
||||
|
||||
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
||||
}
|
||||
|
||||
function addNav() {
|
||||
if (!$cookies.get("token")) {
|
||||
$msg.error("请先登录");
|
||||
return
|
||||
}
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
async function getIcon() {
|
||||
if (!navData.menu_link) return
|
||||
const res = await $http.mix.getIcon({
|
||||
url: navData.menu_link
|
||||
})
|
||||
console.log('>>> --> getIcon --> res:', res)
|
||||
if (res.code == 200) {
|
||||
navData.menu_icon = res.data.url
|
||||
}
|
||||
}
|
||||
|
||||
function navCancel() {
|
||||
visible.value = false
|
||||
formNav.value.resetFields()
|
||||
}
|
||||
|
||||
async function navSubmit() {
|
||||
console.log('>>> --> navSubmit --> navData:', navData)
|
||||
if (!navData.menu_link || !navData.menu_name) {
|
||||
$msg.error('请输入链接和名称')
|
||||
return
|
||||
}
|
||||
const res = await $http.nav.addNav(navData)
|
||||
console.log('>>> --> navSubmit --> res:', res)
|
||||
|
||||
if (res.code == 200) {
|
||||
$msg.success('添加成功')
|
||||
visible.value = false
|
||||
formNav.value.resetFields()
|
||||
getNavList()
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
// console.log("&&&&&&&&&&&&&&", nav.navH);
|
||||
contentStyle.value = {
|
||||
height: `calc(100vh - ${nav.navH}px)`
|
||||
}
|
||||
navStyle.value = {
|
||||
height: `calc(100vh - ${nav.navH}px - 110px)`
|
||||
}
|
||||
getNavList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
/* 首页样式 */
|
||||
.navcard {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
:deep(.devui-input-slot__prepend) {
|
||||
width: 90px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user