迁移UI框架至naive-ui,重构组件和样式,添加Gallery和Mask组件
This commit is contained in:
@ -1,97 +1,99 @@
|
||||
<template>
|
||||
<div class="home-page" :style="contentStyle">
|
||||
<d-layout>
|
||||
<d-content class="main-content">
|
||||
<div class="home-page" :content-style="contentStyle">
|
||||
<n-layout has-sider>
|
||||
<n-layout-content class="main-content">
|
||||
<div class="pt-8 px-12 relative hidden lg:block">
|
||||
<d-input class="devui-input-demo__mt" size="lg" v-model="searchWord" @blur="cancelSbox" placeholder="请输入">
|
||||
<template #prepend>
|
||||
<d-select class="w-48" size="lg" v-model="broswer" :options="options" @click="cancelSbox"></d-select>
|
||||
</template>
|
||||
<template #append>
|
||||
<d-icon name="search" style="font-size: inherit;" @click="search" />
|
||||
</template>
|
||||
</d-input>
|
||||
<div v-if="searchBox" class="absolute left-34 mt-2 z-10 bg-white text-sm text-gray-500 max-h-40 rounded-md shadow-md px-4 py-2 max-w-80">
|
||||
<n-input-group class="shadow ">
|
||||
<n-select class="w-24" size="large" v-model:value="broswer" :options="options"
|
||||
@click="cancelSbox"></n-select>
|
||||
<n-input class="flex-1" size="large" v-model:value="searchWord" @blur="cancelSbox" placeholder="请输入">
|
||||
<template #suffix>
|
||||
<n-icon size="large">
|
||||
<icon-search />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-input>
|
||||
</n-input-group>
|
||||
<div v-if="searchBox"
|
||||
class="absolute left-34 mt-2 z-10 bg-white text-sm text-gray-500 rounded-md shadow-md px-4 py-2 max-w-80">
|
||||
<div class="flex p-2 pr-20 truncate rounded-md items-center hover:text-primary cursor-pointer"
|
||||
:class="selecedIdx === idx ? 'text-white bg-primary' : ''" v-for="(i, idx) in searchItems"
|
||||
:key="idx" @click="goExtra(i.menu_link)" @keyup.enter ="goExtra(i.menu_link)"
|
||||
><span v-if="idx">导航:</span> {{i.menu_name }}</div>
|
||||
:class="selecedIdx === idx ? 'text-white bg-primary' : ''" v-for="(i, idx) in searchItems" :key="idx"
|
||||
@click="goExtra(i.menu_link)" @keyup.enter="goExtra(i.menu_link)"><span v-if="idx">导航:</span>
|
||||
{{ i.menu_name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 标签组 -->
|
||||
<!-- <PerfectScrollbar class="w-full overflow-x-auto"> -->
|
||||
<div v-if="navlist.length" class="flex gap-6 px-2 mt-6 mb-3 flex-wrap lg:px-12">
|
||||
<d-tag class="cursor-pointer truncate" hideBeyondTags v-for="tag in tagList" :checked="tag.checked"
|
||||
:color="tag.color" @click="handdleTagClick(tag)">{{ tag.name }}</d-tag>
|
||||
</div>
|
||||
<!-- </PerfectScrollbar> -->
|
||||
<!-- 图片网格展示区域 -->
|
||||
<PerfectScrollbar class="" :style="navStyle">
|
||||
<n-scrollbar class="w-full overflow-x-auto" :style="navStyle">
|
||||
<div v-if="navlist.length" class="flex gap-6 px-2 mt-6 mb-3 flex-wrap lg:px-12">
|
||||
<d-tag class="cursor-pointer truncate" hideBeyondTags v-for="tag in tagList" :checked="tag.checked"
|
||||
:color="tag.color" @click="handdleTagClick(tag)">{{ tag.name }}</d-tag>
|
||||
</div>
|
||||
<!-- </PerfectScrollbar> -->
|
||||
<!-- 图片网格展示区域 -->
|
||||
<div ref="navcards"
|
||||
class="navcard grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6 gap-5 pt-3 pb-6 px-2 lg:px-12">
|
||||
<d-card class="bg-[#ffffff80] h-24" v-for="(item, index) in navlist" :key="index"
|
||||
@click="goExtra(item.menu_link)" @contextmenu.prevent="handdleContextMenu($event, item)">
|
||||
<template #content>
|
||||
<div class="mt-1 w-full flex flex-col items-center cursor-pointer hover:!text-primary">
|
||||
<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 class="grid-image w-8 h-8 rounded-full" v-else :src="item.menu_icon"
|
||||
@error="imgErr(index as number)" />
|
||||
<div class="mt-2 w-full text-center text-lg truncate">{{ item.menu_name || "" }}</div>
|
||||
<em class="absolute rounded-md top-0 left-0 px-2 text-white text-center text-sm"
|
||||
:style="{ background: getItemColor(item) }">{{ item.tag }}</em>
|
||||
</div>
|
||||
</template>
|
||||
</d-card>
|
||||
<d-card class="bg-[#ffffff80] h-25">
|
||||
<n-card embedded
|
||||
class="bg-[#ffffff80] h-24 shadow-md transition-transform duration-300 box-border hover:-translate-y-1.5"
|
||||
v-for="(item, index) in navlist" :key="index" @click="goExtra(item.menu_link)"
|
||||
@contextmenu.prevent="handdleContextMenu($event, item)">
|
||||
<div class="mt-1 w-full flex flex-col items-center cursor-pointer hover:!text-primary">
|
||||
<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 class="grid-image w-8 h-8 rounded-full" v-else :src="item.menu_icon"
|
||||
@error="imgErr(index as number)" />
|
||||
<div class="mt-2 w-full text-center text-lg truncate">{{ item.menu_name || "" }}</div>
|
||||
<em class="absolute rounded-md top-0 left-0 px-2 text-white text-center text-sm"
|
||||
:style="{ background: getItemColor(item) }">{{ item.tag }}</em>
|
||||
</div>
|
||||
</n-card>
|
||||
<n-card embedded
|
||||
class="bg-[#ffffff80] h-24 shadow-md transition-transform duration-300 box-border hover:-translate-y-1.5">
|
||||
<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">
|
||||
class="w-8 h-8 rounded-full text-2xl text-white flex items-center justify-center">
|
||||
+
|
||||
</div>
|
||||
<div class="mt-2 w-full text-center text-lg truncate text-primary">新增导航</div>
|
||||
</div>
|
||||
</d-card>
|
||||
</n-card>
|
||||
</div>
|
||||
</PerfectScrollbar>
|
||||
|
||||
</d-content>
|
||||
<d-aside class="daside hidden w-120 lg:block">
|
||||
</n-scrollbar>
|
||||
</n-layout-content>
|
||||
<n-layout-sider width="30rem">
|
||||
<homeSide></homeSide>
|
||||
</d-aside>
|
||||
</d-layout>
|
||||
</n-layout-sider>
|
||||
</n-layout>
|
||||
|
||||
<!-- 新增导航弹窗 -->
|
||||
<d-modal class="!w-120" v-model="visible" title="新增导航">
|
||||
<d-form ref="formNav" layout="vertical" :data="navData">
|
||||
<d-form-item class="h-8" field="username">
|
||||
<d-input @blur="getIcon" v-model="navData.menu_link" placeholder="请输入单行链接(必填)" />
|
||||
</d-form-item>
|
||||
<d-form-item class="h-8" field="password">
|
||||
<d-input v-model="navData.menu_name" placeholder="请输入导航名称(必填)" />
|
||||
</d-form-item>
|
||||
<d-form-item class="h-8" field="tag">
|
||||
<d-input v-model="navData.tag" placeholder="请自定义一个标签(必填,只取前四字)" />
|
||||
</d-form-item>
|
||||
<d-form-item class="h-8 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-14 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> -->
|
||||
<div class="mt-14 flex justify-between">
|
||||
<d-button class="w-[48%]" variant="solid" color="secondary" @click="navCancel">取消</d-button>
|
||||
<d-button class="w-[48%]" variant="solid" color="primary" @click="navSubmit">确定</d-button>
|
||||
</div>
|
||||
</d-modal>
|
||||
<maskX :visible="visible" :setVisible="navCancel">
|
||||
<n-form class="w-[500px] bg-white rounded-md p-8 shadow-md" ref="formNav" layout="vertical" :data="navData">
|
||||
<div class="text-center text-lg">新增导航</div>
|
||||
<n-form-item class="h-8" path="menu_link">
|
||||
<n-input @blur="getIcon" v-model:value="navData.menu_link" placeholder="请输入单行链接(必填)" />
|
||||
</n-form-item>
|
||||
<n-form-item class="h-8 mt-4" path="menu_name">
|
||||
<n-input v-model:value="navData.menu_name" placeholder="请输入导航名称(必填)" />
|
||||
</n-form-item>
|
||||
<n-form-item class="h-8 mt-4" path="tag">
|
||||
<n-input v-model:value="navData.tag" placeholder="请自定义一个标签(必填,只取前四字)" />
|
||||
</n-form-item>
|
||||
<n-form-item class="h-8 mt-4 form-operation-wrap">
|
||||
<!-- <div class="flex"> -->
|
||||
<n-input v-model:value="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> -->
|
||||
</n-form-item>
|
||||
<div class="mt-14 flex justify-between">
|
||||
<n-button class="w-[48%]" secondary variant="solid" @click="navCancel">取消</n-button>
|
||||
<n-button class="w-[48%]" type="primary" variant="solid" @click="navSubmit">确定</n-button>
|
||||
</div>
|
||||
</n-form>
|
||||
|
||||
|
||||
</maskX>
|
||||
|
||||
<!-- 音乐插件 -->
|
||||
<aplayer></aplayer>
|
||||
@ -116,25 +118,29 @@
|
||||
</contextMenu>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<d-modal class="!w-120" v-model="editModal" title="导航修改">
|
||||
<div class="mb-2">
|
||||
原
|
||||
<span class="text-primary" v-if="currentClickedItem === 1">导航名称:{{ currentItem.menu_name }}</span>
|
||||
<span class="text-primary" v-if="currentClickedItem === 2">导航链接:{{ currentItem.menu_link }}</span>
|
||||
<span class="text-primary" v-if="currentClickedItem === 3">导航标签:{{ currentItem.tag }}</span>
|
||||
<maskX :visible="editModal" :setVisible="navCancel">
|
||||
<div class="w-[500px] bg-white p-8 rounded-md">
|
||||
<div class="text-center text-lg mb-8">修改导航内容</div>
|
||||
<div class="mb-4">
|
||||
原
|
||||
<span class="text-primary" v-if="currentClickedItem === 1">导航名称:{{ currentItem?.menu_name }}</span>
|
||||
<span class="text-primary" v-if="currentClickedItem === 2">导航链接:{{ currentItem?.menu_link }}</span>
|
||||
<span class="text-primary" v-if="currentClickedItem === 3">导航标签:{{ currentItem?.tag }}</span>
|
||||
</div>
|
||||
<n-input v-model:value="editInput" placeholder="请输入修改内容"></n-input>
|
||||
<div class="mt-8 flex justify-between">
|
||||
<n-button class="w-[48%]" secondary @click="handdleItemCancel">取消</n-button>
|
||||
<n-button class="w-[48%]" type="primary" @click="handdleItemSubmit">确定</n-button>
|
||||
</div>
|
||||
</div>
|
||||
<d-input v-model="editInput" placeholder="请输入修改内容"></d-input>
|
||||
<div class="mt-8 flex justify-between">
|
||||
<d-button class="w-[48%]" variant="solid" color="secondary" @click="handdleItemCancel">取消</d-button>
|
||||
<d-button class="w-[48%]" variant="solid" color="primary" @click="handdleItemSubmit">确定</d-button>
|
||||
</div>
|
||||
</d-modal>
|
||||
</maskX>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import contextMenu from '@/components/contextMenu.vue';
|
||||
import maskX from '@/components/mask.vue';
|
||||
import { deepclone, getDictValue } from '@/util/index.ts';
|
||||
definePage({
|
||||
name: 'home',
|
||||
@ -144,24 +150,48 @@ definePage({
|
||||
})
|
||||
|
||||
|
||||
// 定义接口类型
|
||||
interface NavItem {
|
||||
nid?: number
|
||||
menu_link: string
|
||||
menu_name: string
|
||||
tag: string
|
||||
menu_icon: string
|
||||
icon_error?: boolean
|
||||
first?: string
|
||||
color?: string
|
||||
}
|
||||
|
||||
interface MenuItem {
|
||||
menu_name: string
|
||||
menu_link: string
|
||||
tag: string
|
||||
}
|
||||
|
||||
interface TagItem {
|
||||
name: string
|
||||
color: string
|
||||
checked: boolean
|
||||
}
|
||||
|
||||
// 右键菜单
|
||||
const menuShow = ref(false)
|
||||
const MenuOptions: any = reactive({});
|
||||
const currentItem = ref<any>(null);
|
||||
const menuS = '!m-0 py-3 px-6 text-sm text-gray-700 w-full flex items-center justify-center hover:bg-[#f5f0f0] hover:text-primary';
|
||||
const currentClickedItem = ref<number>(0);
|
||||
const editModal = ref<boolean>(false);
|
||||
const editInput = ref<string>('');
|
||||
const MenuOptions = reactive({ x: 0, y: 0 })
|
||||
const currentItem = ref<NavItem | null>(null)
|
||||
const menuS = '!m-0 py-3 px-6 text-sm text-gray-700 w-full flex items-center justify-center hover:bg-[#f5f0f0] hover:text-primary'
|
||||
const currentClickedItem = ref<number>(0)
|
||||
const editModal = ref<boolean>(false)
|
||||
const editInput = ref<string>('')
|
||||
// 新增导航弹窗
|
||||
const visible: any = ref<boolean>(false)
|
||||
const navData: any = reactive({
|
||||
const visible = ref<boolean>(false)
|
||||
const navData = reactive<NavItem>({
|
||||
menu_link: '',
|
||||
menu_name: '',
|
||||
tag: '',
|
||||
menu_icon: ''
|
||||
})
|
||||
const formNav: any = ref(null)
|
||||
const navcards: any = ref(null)
|
||||
const formNav = ref<any>(null)
|
||||
const navcards = ref<any>(null)
|
||||
|
||||
// 首页逻辑
|
||||
const nav: any = $store.nav.useNavStore()
|
||||
@ -174,22 +204,22 @@ const selecedIdx = ref(0)
|
||||
const searchBox = ref(false)
|
||||
const options = ref([
|
||||
{
|
||||
name: '必应',
|
||||
label: '必应',
|
||||
value: 'bing',
|
||||
url: 'https://cn.bing.com/search?q='
|
||||
},
|
||||
{
|
||||
name: '百度',
|
||||
label: '百度',
|
||||
value: 'baidu',
|
||||
url: 'https://www.baidu.com/s?wd='
|
||||
},
|
||||
{
|
||||
name: '谷歌',
|
||||
label: '谷歌',
|
||||
value: 'google',
|
||||
url: 'https://www.google.com/search?q='
|
||||
},
|
||||
{
|
||||
name: '翻译',
|
||||
label: '翻译',
|
||||
value: 'trans',
|
||||
url: 'https://translate.volcengine.com?text='
|
||||
},
|
||||
@ -197,9 +227,9 @@ const options = ref([
|
||||
])
|
||||
|
||||
|
||||
const navlist: any = ref([])
|
||||
let cloneNavlist: any = []
|
||||
const tagList: any = ref([
|
||||
const navlist = ref<NavItem[]>([])
|
||||
let cloneNavlist: NavItem[] = []
|
||||
const tagList = ref<TagItem[]>([
|
||||
{
|
||||
name: '全部',
|
||||
color: '',
|
||||
@ -209,11 +239,11 @@ const tagList: any = ref([
|
||||
|
||||
|
||||
const usrLog = $store.log.useLogStore()
|
||||
let timer: any = null;
|
||||
let timer: any = null
|
||||
|
||||
// 输入搜索内容时监听searchWord在navlist中模糊搜索
|
||||
watch(searchWord, () => {
|
||||
handdleInput()
|
||||
handleInput()
|
||||
})
|
||||
|
||||
function cancelSbox() {
|
||||
@ -224,7 +254,7 @@ function cancelSbox() {
|
||||
}, 200)
|
||||
}
|
||||
|
||||
function handdleInput() {
|
||||
function handleInput() {
|
||||
if (!searchWord.value) {
|
||||
searchItems.value = []
|
||||
searchBox.value = false
|
||||
@ -234,24 +264,23 @@ function handdleInput() {
|
||||
searchBox.value = true
|
||||
selecedIdx.value = 0
|
||||
const keyword = searchWord.value.toLowerCase()
|
||||
searchItems.value = navlist.value.filter((item: any) =>
|
||||
searchItems.value = navlist.value.filter((item) =>
|
||||
item.menu_name.toLowerCase().includes(keyword) ||
|
||||
item.menu_link.toLowerCase().includes(keyword) ||
|
||||
item.tag.toLowerCase().includes(keyword)
|
||||
)
|
||||
// 在searchItems第一个位置插入一条原本搜索
|
||||
searchItems.value.unshift({
|
||||
menu_name: `在${getDictValue(options.value, "value", broswer.value, "name")}中搜索"${searchWord.value}"`,
|
||||
menu_name: `在${getDictValue(options.value, "value", broswer.value, "label")}中搜索"${searchWord.value}"`,
|
||||
menu_link: getDictValue(options.value, "value", broswer.value, "url") + searchWord.value,
|
||||
tag: ''
|
||||
})
|
||||
}
|
||||
|
||||
function handdleKeyup(e: any) {
|
||||
function handleKeyup(e: KeyboardEvent) {
|
||||
if (!searchBox.value) return
|
||||
// console.log('>>> --> haddleDown --> idx:', e.keyCode)
|
||||
// 向下箭头
|
||||
if (e.keyCode == 40) {
|
||||
if (e.keyCode === 40) {
|
||||
if (selecedIdx.value < searchItems.value.length - 1) {
|
||||
selecedIdx.value += 1
|
||||
} else {
|
||||
@ -259,7 +288,7 @@ function handdleKeyup(e: any) {
|
||||
}
|
||||
}
|
||||
// 向上箭头
|
||||
else if (e.keyCode == 38) {
|
||||
else if (e.keyCode === 38) {
|
||||
if (selecedIdx.value > 0) {
|
||||
selecedIdx.value -= 1
|
||||
} else {
|
||||
@ -267,7 +296,7 @@ function handdleKeyup(e: any) {
|
||||
}
|
||||
}
|
||||
// 回车键
|
||||
else if (e.keyCode == 13) {
|
||||
else if (e.keyCode === 13) {
|
||||
if (searchItems.value.length > 0) {
|
||||
const selectedItem = searchItems.value[selecedIdx.value]
|
||||
window.open(selectedItem.menu_link, "_BLANK")
|
||||
@ -281,19 +310,23 @@ function handdleKeyup(e: any) {
|
||||
|
||||
// 2秒后自动隐藏菜单
|
||||
const hideMenu = () => {
|
||||
if (timer) clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
menuShow.value = false
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
const removeTimer = () => {
|
||||
clearTimeout(timer)
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
timer = null
|
||||
}
|
||||
}
|
||||
|
||||
function handdleMenuItem(type: number) {
|
||||
function handleMenuItem(type: number) {
|
||||
menuShow.value = false
|
||||
currentClickedItem.value = type
|
||||
if (type == 4) {
|
||||
if (type === 4) {
|
||||
// 删除导航
|
||||
if (!currentItem.value) return
|
||||
$modal({
|
||||
@ -302,9 +335,8 @@ function handdleMenuItem(type: number) {
|
||||
cancelText: '取消',
|
||||
submitText: '删除',
|
||||
handdleSubmit: async () => {
|
||||
const res = await $http.nav.deleteNav(currentItem.value.nid)
|
||||
console.log('>>> --> handdleMenuItem --> res:', res)
|
||||
if (res.code == 200) {
|
||||
const res = await $http.nav.deleteNav(currentItem.value?.nid)
|
||||
if (res.code === 200) {
|
||||
$msg.success('删除成功')
|
||||
getNavList()
|
||||
}
|
||||
@ -315,27 +347,26 @@ function handdleMenuItem(type: number) {
|
||||
editModal.value = true
|
||||
}
|
||||
|
||||
function handdleItemCancel() {
|
||||
function handleItemCancel() {
|
||||
editModal.value = false
|
||||
editInput.value = ''
|
||||
}
|
||||
|
||||
async function handdleItemSubmit() {
|
||||
async function handleItemSubmit() {
|
||||
if (!editInput.value) {
|
||||
$msg.error('请输入修改内容')
|
||||
return
|
||||
}
|
||||
let updateData: any = {}
|
||||
if (currentClickedItem.value == 1) {
|
||||
let updateData: Partial<NavItem> = {}
|
||||
if (currentClickedItem.value === 1) {
|
||||
updateData.menu_name = editInput.value
|
||||
} else if (currentClickedItem.value == 2) {
|
||||
} else if (currentClickedItem.value === 2) {
|
||||
updateData.menu_link = editInput.value
|
||||
} else if (currentClickedItem.value == 3) {
|
||||
} else if (currentClickedItem.value === 3) {
|
||||
updateData.tag = editInput.value.slice(0, 4)
|
||||
}
|
||||
const res = await $http.nav.editNav(currentItem.value.nid, updateData)
|
||||
console.log('>>> --> handdleItemSubmit --> res:', res)
|
||||
if (res.code == 200) {
|
||||
const res = await $http.nav.editNav(currentItem.value!.nid!, updateData)
|
||||
if (res.code === 200) {
|
||||
$msg.success('修改成功')
|
||||
editModal.value = false
|
||||
editInput.value = ''
|
||||
@ -350,23 +381,30 @@ async function getNavList() {
|
||||
return
|
||||
}
|
||||
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
|
||||
if (!res.data) return
|
||||
|
||||
console.log("&&&&&&&&&&&&&&", navlist.value);
|
||||
// 合并两个循环,提高性能
|
||||
res.data.forEach((i: any) => {
|
||||
if (!tagList.value.find((t: any) => t.name == i.tag))
|
||||
tagList.value.push({ name: i.tag.substring(0, 4), color: getRandomDarkColor(30, 128), checked: false })
|
||||
})
|
||||
i.icon_error = false
|
||||
i.first = i.menu_name?.at(0) || ''
|
||||
i.color = getRandomDarkColor()
|
||||
|
||||
// 同时处理标签列表
|
||||
if (!tagList.value.find((t) => t.name === i.tag)) {
|
||||
tagList.value.push({
|
||||
name: i.tag.substring(0, 4),
|
||||
color: getRandomDarkColor(30, 128),
|
||||
checked: false
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
navlist.value = res.data
|
||||
cloneNavlist = deepclone(res.data)
|
||||
}
|
||||
|
||||
function getItemColor(item: any) {
|
||||
const tag = tagList.value.find((t: any) => t.name == item.tag)
|
||||
function getItemColor(item: NavItem) {
|
||||
const tag = tagList.value.find((t) => t.name === item.tag)
|
||||
return tag ? tag.color : getRandomDarkColor(30, 128)
|
||||
}
|
||||
|
||||
@ -453,6 +491,8 @@ function addNav() {
|
||||
}
|
||||
|
||||
async function getIcon() {
|
||||
console.log(11111);
|
||||
|
||||
if (!navData.menu_link) return
|
||||
const res = await $http.mix.getIcon({
|
||||
url: navData.menu_link
|
||||
@ -463,9 +503,15 @@ async function getIcon() {
|
||||
}
|
||||
}
|
||||
|
||||
function resetNav() {
|
||||
navData.menu_link = ''
|
||||
navData.menu_name = ''
|
||||
navData.tag = ''
|
||||
navData.menu_icon = ''
|
||||
}
|
||||
function navCancel() {
|
||||
visible.value = false
|
||||
formNav.value.resetFields()
|
||||
resetNav()
|
||||
}
|
||||
|
||||
async function navSubmit() {
|
||||
@ -481,14 +527,10 @@ async function navSubmit() {
|
||||
if (res.code == 200) {
|
||||
$msg.success('添加成功')
|
||||
visible.value = false
|
||||
formNav.value.resetFields()
|
||||
getNavList()
|
||||
}
|
||||
// 清空navData
|
||||
navData.menu_link = ''
|
||||
navData.menu_name = ''
|
||||
navData.tag = ''
|
||||
navData.menu_icon = ''
|
||||
resetNav()
|
||||
}
|
||||
// 处理右键菜单
|
||||
function handdleContextMenu(event: MouseEvent, item: any) {
|
||||
@ -503,7 +545,7 @@ function handdleContextMenu(event: MouseEvent, item: any) {
|
||||
|
||||
|
||||
// 监听store的登录状态
|
||||
watch(() => usrLog.isLogin, (newVal) => {
|
||||
watch(() => usrLog.isLogin, (newVal: any) => {
|
||||
console.log('********** --> watch --> newVal:', newVal)
|
||||
if (newVal) {
|
||||
getNavList()
|
||||
@ -511,17 +553,97 @@ watch(() => usrLog.isLogin, (newVal) => {
|
||||
navlist.value = []
|
||||
}
|
||||
})
|
||||
function handdleKeyup(e: any) {
|
||||
if (!searchBox.value) return
|
||||
// console.log('>>> --> haddleDown --> idx:', e.keyCode)
|
||||
// 向下箭头
|
||||
if (e.keyCode == 40) {
|
||||
if (selecedIdx.value < searchItems.value.length - 1) {
|
||||
selecedIdx.value += 1
|
||||
} else {
|
||||
selecedIdx.value = 0
|
||||
}
|
||||
}
|
||||
// 向上箭头
|
||||
else if (e.keyCode == 38) {
|
||||
if (selecedIdx.value > 0) {
|
||||
selecedIdx.value -= 1
|
||||
} else {
|
||||
selecedIdx.value = searchItems.value.length - 1
|
||||
}
|
||||
}
|
||||
// 回车键
|
||||
else if (e.keyCode == 13) {
|
||||
if (searchItems.value.length > 0) {
|
||||
const selectedItem = searchItems.value[selecedIdx.value]
|
||||
window.open(selectedItem.menu_link, "_BLANK")
|
||||
searchBox.value = false
|
||||
selecedIdx.value = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
function handdleItemCancel() {
|
||||
editModal.value = false
|
||||
editInput.value = ''
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function handdleItemSubmit() {
|
||||
if (!editInput.value) {
|
||||
$msg.error('请输入修改内容')
|
||||
return
|
||||
}
|
||||
let updateData: any = {}
|
||||
if (currentClickedItem.value == 1) {
|
||||
updateData.menu_name = editInput.value
|
||||
} else if (currentClickedItem.value == 2) {
|
||||
updateData.menu_link = editInput.value
|
||||
} else if (currentClickedItem.value == 3) {
|
||||
updateData.tag = editInput.value.slice(0, 4)
|
||||
}
|
||||
const res = await $http.nav.editNav(currentItem.value?.nid, updateData)
|
||||
console.log('>>> --> handdleItemSubmit --> res:', res)
|
||||
if (res.code == 200) {
|
||||
$msg.success('修改成功')
|
||||
editModal.value = false
|
||||
editInput.value = ''
|
||||
getNavList()
|
||||
}
|
||||
}
|
||||
function handdleMenuItem(type: number) {
|
||||
menuShow.value = false
|
||||
currentClickedItem.value = type
|
||||
if (type == 4) {
|
||||
// 删除导航
|
||||
if (!currentItem.value) return
|
||||
$modal({
|
||||
title: '删除导航',
|
||||
content: `确定要删除【${currentItem.value.menu_name}】吗?删除后不可恢复哦~`,
|
||||
cancelText: '取消',
|
||||
submitText: '删除',
|
||||
handdleSubmit: async () => {
|
||||
const res = await $http.nav.deleteNav(currentItem.value?.nid)
|
||||
console.log('>>> --> handdleMenuItem --> res:', res)
|
||||
if (res.code == 200) {
|
||||
$msg.success('删除成功')
|
||||
getNavList()
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
editModal.value = true
|
||||
}
|
||||
const navHeight: any = ref(0)
|
||||
onMounted(() => {
|
||||
console.log("&&&&&&&&&&&&&&", nav.navH);
|
||||
contentStyle.value = {
|
||||
height: `${window.innerHeight - nav.navH}px)`
|
||||
}
|
||||
console.log('>>> --> onMounted --> navcards.value.getBoundingClientRect().y:', navcards.value.getBoundingClientRect().y)
|
||||
navHeight.value = window.innerHeight - navcards.value.getBoundingClientRect().y
|
||||
navStyle.value = {
|
||||
// height: `calc(100vh - ${navcards.value.getBoundingClientRect().y}px - ${nav.navH}px)`,
|
||||
height: `${window.innerHeight - navcards.value.getBoundingClientRect().y - 20}px`
|
||||
height: `${window.innerHeight - navcards.value.getBoundingClientRect().y}px`
|
||||
}
|
||||
tagList.value = [
|
||||
{
|
||||
@ -536,7 +658,7 @@ onMounted(() => {
|
||||
height: `calc(100vh - ${nav.navH}px)`
|
||||
}
|
||||
navStyle.value = {
|
||||
height: `${window.innerHeight - navcards.value.getBoundingClientRect().top - 20}px`
|
||||
height: `${navHeight.value}px`
|
||||
}
|
||||
});
|
||||
window.addEventListener('keyup', (e: Event) => {
|
||||
|
||||
Reference in New Issue
Block a user