首页
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m39s

This commit is contained in:
youzi 2024-12-26 11:34:13 +08:00
parent e657173bed
commit 37f969c4e6
13 changed files with 150 additions and 89 deletions

View File

@ -4,8 +4,11 @@
## 主要功能 ## 主要功能
### √ 1.登录注册功能 ### √ 1.登录注册功能
### √ 2.首页展示共享文章列表 ### √ 2.首页展示共享文章列表 × 首页大整改
### √ 3.画廊页面展示共享图片 ### √ 3.画廊页面展示共享图片
### √ 4.文章详情页展示文章内容
### × 5.导航功能整改,前后端
### × 6.友链--重新开发,力求精简
### × 4.控制台功能 --目前已完成:画廊上传共享 ### × 4.控制台功能 --目前已完成:画廊上传共享

View File

@ -1,10 +1,11 @@
import request from '@/util/request'; import request from '@/util/request';
// listNav // listNav
export function listNav() { export function listNav(params = {}) {
return request({ return request({
url: '/nav/menu', url: '/nav/menu',
method: 'get' method: 'get',
params
}); });
} }
@ -16,6 +17,21 @@ export function addMenu(data) {
}); });
} }
// deleteMenu
export function deleteMenu(id) {
return request({
url: '/nav/menu',
method: 'delete',
params:{
id
}
});
}
export function listClass(){ export function listClass(){
return request({ return request({
url: '/nav/class', url: '/nav/class',

View File

@ -1,4 +1,4 @@
@purple: #8a2be2; @purple: #a81b2b;
@orange: #ffa500; @orange: #ffa500;
@blue: #409eff; @blue: #409eff;
@dp: #f2e8fc; @dp: #f2e8fc;
@ -7,6 +7,3 @@
//#BE8AEF #B172EC #A45BE9 #9744E5 #8A2BE2 #7B1DD3 #6C19B9 #5C169F //#BE8AEF #B172EC #A45BE9 #9744E5 #8A2BE2 #7B1DD3 #6C19B9 #5C169F
@jb: linear-gradient(90deg,#BE8AEF,#409eff, #8A2BE2); @jb: linear-gradient(90deg,#BE8AEF,#409eff, #8A2BE2);
:root:root {
--van-primary-color: #8a2be2;
}

View File

@ -64,7 +64,7 @@ function onEnter(el, done) {
width: 90%; width: 90%;
margin: 0 0 20px 5%; margin: 0 0 20px 5%;
box-shadow: @ps; box-shadow: @ps;
background-color: #fafbfc; background-color: unset;
} }
:deep(.n-card__content) { :deep(.n-card__content) {

View File

@ -145,6 +145,7 @@ function logout() {
}, },
onNegativeClick: () => { onNegativeClick: () => {
push("/"); push("/");
location.reload(true);
}, },
}); });
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="info" @click="gotoWea"> <div class="info" @click="gotoWea">
<div class="loc flex items-center"> <div class="loc flex items-center">
<n-icon size="18" color="#8a2be2"> <n-icon size="18" color="#a81b2b">
<IosPin /> <IosPin />
</n-icon> </n-icon>
{{ addr }} {{ addr }}

View File

@ -1,15 +1,15 @@
const themeOverrides = { const themeOverrides = {
lightOverrides: { lightOverrides: {
common: { common: {
primaryColor: "#8a2be2", //默认颜色 primaryColor: "#a81b2b", //默认颜色
primaryColorHover: "#8a2be2", //hover颜色 primaryColorHover: "#a81b2b", //hover颜色
primaryColorPressed: "#8a2be2", //点击颜色 primaryColorPressed: "#a81b2b", //点击颜色
successColor: "#409EFF", successColor: "#409EFF",
successColorHover: "#409EFF", successColorHover: "#409EFF",
successColorPressed: "#409EFF", successColorPressed: "#409EFF",
infoColor: "#8a2be2", infoColor: "#a81b2b",
infoColorHover: "#8a2be2", infoColorHover: "#a81b2b",
infoColorPressed: "#8a2be2", infoColorPressed: "#a81b2b",
}, },
Radio: { Radio: {
buttonColorActive: "#FFA50040", buttonColorActive: "#FFA50040",

View File

@ -1,5 +1,5 @@
<template> <template>
<n-scrollbar class="bg-[#f8f9fa]" :on-scroll="onScroll" :style="{ maxHeight: contH + 'px' }"> <n-scrollbar class="" :on-scroll="onScroll" :style="{ maxHeight: contH + 'px' }">
<div class="w-[40vw] mx-auto my-6 md:w-[80vw]"> <div class="w-[40vw] mx-auto my-6 md:w-[80vw]">
<n-input-group> <n-input-group>
<n-input v-model:value="kw" placeholder="图片名 | 分享人" @keyup.enter.native="search" :style="{ width: '80%' }" /> <n-input v-model:value="kw" placeholder="图片名 | 分享人" @keyup.enter.native="search" :style="{ width: '80%' }" />

View File

@ -2,42 +2,25 @@
<div class="box flex flex-wrap px-8"> <div class="box flex flex-wrap px-8">
<n-card :style="{ height: boxH + 'px' }"> <n-card :style="{ height: boxH + 'px' }">
<n-scrollbar :class="`h-[${boxH}px]`" :style="{ height: boxH - 40 + 'px' }"> <n-scrollbar :class="`h-[${boxH}px]`" :style="{ height: boxH - 40 + 'px' }">
<n-collapse default-expanded-names="0" accordion> <div class="grid gridSpace gap-4 items-center justify-center">
<n-collapse-item v-for="(i, idx) in navList" :name="idx + ''" :key="i.menuClass"> <div class="w-[200px] my-4" v-for="(i, ii) in navList">
<template #arrow="{ collapsed }"> <n-button @click="link(i.menuLink)" class="btn w-full hover:text-[white]" type="primary" ghost>
<img :class="{ zhuan: !collapsed }" width="20" height="20" :src="i.icon" alt="">
</template>
<template #header>
<div class="ml-4" :style="{ color: i.color }">
{{ i.menuClass }}
</div>
</template>
<template #header-extra="{collapsed}">
<n-icon size="26" :color="i.color">
<IosArrowDropright :class="{extra_collapsed:!collapsed}" class="extra_collapse"></IosArrowDropright>
</n-icon>
</template>
<div class="flex flex-wrap items-center">
<div class="w-[200px] mr-20 my-4" v-for="(j,ii) in i.children">
<n-popover trigger="hover" animated :delay="1000" width="trigger">
<template #trigger>
<div>
<n-button @click="link(j.menuLink)" class="btn w-full hover:text-[white]" type="primary" ghost>
<template #icon> <template #icon>
<img v-if="!j.exp" width="20" height="20" class="mr-2" :src="j.menuIcon" alt="" @error="navList[idx].children[ii].exp=true"> <img v-if="!i.exp" width="20" height="20" class="mr-2" :src="i.menuIcon" alt="" @error="i.exp = true">
<div :style="{backgroundColor:j.color}" class="w-[20px] h-[20px] text-[12px] text-[white] rounded-full flex justify-center items-center" v-else>{{ j.menuName[0] }}</div> <div :style="{ backgroundColor: i.color }"
class="w-[20px] h-[20px] text-[12px] text-[white] rounded-full flex justify-center items-center"
v-else>{{ i.menuName[0] }}</div>
</template> </template>
{{ j.menuName }} {{ i.menuName }}
</n-button> </n-button>
</div> </div>
</template> <div class="w-[200px] my-4">
{{ j.menuDesc }} <n-button @click="addMenu" class="btn w-full hover:text-[white]" type="primary" ghost>
</n-popover> +
</n-button>
</div>
</div>
</div>
</div>
</n-collapse-item>
</n-collapse>
</n-scrollbar> </n-scrollbar>
</n-card> </n-card>
@ -45,52 +28,63 @@
</template> </template>
<script setup> <script setup>
import { IosArrowDropright } from "@vicons/ionicons4";
import { onMounted } from 'vue'; import { onMounted } from 'vue';
import cookie from "vue-cookies";
import { useRouter } from 'vue-router';
//mark import //mark import
//mark data //mark data
const navList = ref([]) const navList = ref([])
const isHaveIco = ref(true)
const size = $store.size.usesizeStore() const size = $store.size.usesizeStore()
const boxH = ref(0) const boxH = ref(0)
const token = cookie.get("token");
const userinfo = cookie.get("userinfo");
const router = useRouter()
const fullPath = router.currentRoute.value.fullPath
const { push } = router;
//mark method //mark method
function formatNav(list) { async function getNav() {
let menu = [] let res = {}
let result = [] if (!!token && !!userinfo) {
list.forEach(i => { res = await $http.nav.listNav({ username: userinfo.username })
i.isHaveIco = true
if (!menu.includes(i.menuClass)) {
menu.push(i.menuClass)
} }
else {
res = await $http.nav.listNav()
}
navList.value = res.data.map((item) => {
item.exp = false
return item
})
}
function addMenu() {
if (!!token && !!userinfo) {}
else {
$dialog.success({
title: "该功能能需要登录账号",
content: "未登录账号,是否去登录?",
positiveText: "登录",
negativeText: "返回",
onPositiveClick: () => {
push({
path: "/login",
query: {
redirect: fullPath,
},
});
},
}); });
menu.forEach(i => {
const children = list.filter(it => it.menuClass == i)
result.push({
menuClass: i,
children,
color: children[0].color,
icon: "https://www.hxyouzi.com/img/svg/menu/" + children[0].icon,
exp: false,
})
})
console.log(result);
return result
// return chunkArrayInGroups(result, 4)
} }
}
function link(url) { function link(url) {
window.open(url, "_blank") window.open(url, "_blank")
} }
//mark //mark
onMounted(async () => { onMounted(() => {
const res = await $http.nav.listNav() getNav()
navList.value = formatNav(res.data)
// //
const screenHeight = document.documentElement.clientHeight const screenHeight = document.documentElement.clientHeight
boxH.value = screenHeight - size.searchH - size.menuH - 24 - 66 boxH.value = screenHeight - size.searchH - size.menuH - 24 - 66
@ -105,6 +99,9 @@ onMounted(async () => {
} }
.gridSpace {
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
:deep(.n-collapse-item__header-main) { :deep(.n-collapse-item__header-main) {
font-size: 20px; font-size: 20px;
@ -135,20 +132,27 @@ onMounted(async () => {
animation: rotate 2s infinite; animation: rotate 2s infinite;
/* 播放名为bounce的动画循环无限次每次动画时长1秒 */ /* 播放名为bounce的动画循环无限次每次动画时长1秒 */
} }
.btn { .btn {
transition: transform .5s ease-in-out; transition: transform .5s ease-in-out;
/* 指定过渡属性,持续时长,过渡曲线,何时开始 */ /* 指定过渡属性,持续时长,过渡曲线,何时开始 */
&:hover { &:hover {
transform: translateX(10px); transform: translateX(10px);
background: linear-gradient(to right, #7FC6E7, #4CAF50); background: linear-gradient(to right, #dca4aa, #a81b2b, #dca4aa);
};
} }
;
}
.extra_collapse { .extra_collapse {
transform: rotate(0deg); transform: rotate(0deg);
} }
.extra_collapsed { .extra_collapsed {
transform: rotate(90deg); transform: rotate(90deg);
} }
:deep(.n-card) { :deep(.n-card) {
padding: 30px; padding: 30px;
background: #f1f2f370; background: #f1f2f370;

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<div id="plink" class="lianxi w-[80%] ml-[10%] mt-4 mb-4 bg-[#fafbfc] p-2"> <div id="plink" class="lianxi w-[80%] ml-[10%] mt-4 mb-4 p-2">
<div class="t"> <div class="t">
<n-divider title-placement="center"> <n-divider title-placement="center">
<div class="flex items-center" @click="isAdd = !isAdd"> <div class="flex items-center" @click="isAdd = !isAdd">
@ -43,7 +43,7 @@
</template> </template>
</div> </div>
<div class="lianxi w-[80%] ml-[10%] mt-4 mb-4 bg-[#fafbfc] p-2"> <div class="lianxi w-[80%] ml-[10%] mt-4 mb-4 p-2">
<div class="t"> <div class="t">
<n-divider title-placement="center"> <n-divider title-placement="center">
<div class="flex items-center" @click="isLink = !isLink"> <div class="flex items-center" @click="isLink = !isLink">
@ -265,4 +265,7 @@ onMounted(async () => {
:deep(.n-form-item){ :deep(.n-form-item){
align-items: center; align-items: center;
} }
:deep(.n-card) {
background: unset !important;
}
</style> </style>

View File

@ -71,4 +71,11 @@ onMounted(async () => {
</script> </script>
<style scoped></style> <style scoped>
:deep(.n-descriptions-table-wrapper) {
background: unset !important;
}
:deep(.n-descriptions-table-wrapper th) {
background: unset !important;
}
</style>

View File

@ -81,4 +81,8 @@ function handdleWidget(i) {
</script> </script>
<style scoped></style> <style scoped>
:deep(.n-card) {
background: unset !important;
}
</style>

View File

@ -18,6 +18,17 @@ module.exports = {
}, },
colors: { colors: {
pp: { pp: {
100: "#eed1d5",
200: "#dca4aa",
300: "#cb7680",
400: "#b94955",
500: "#a81b2b",
600: "#861622",
700: "#65101a",
800: "#430b11",
900: "#220509"
},
purple: {
100: "#BE8AEF", 100: "#BE8AEF",
200: "#B172EC", 200: "#B172EC",
300: "#A45BE9", 300: "#A45BE9",
@ -30,14 +41,29 @@ module.exports = {
default: "#8A2BE2", default: "#8A2BE2",
}, },
orange: { orange: {
100: "#ffedcc",
200: "#ffdb99",
300: "#ffc966",
400: "#ffb733",
500: "#ffa500", 500: "#ffa500",
600: "#cc8400",
700: "#996300",
800: "#664200",
900: "#332100",
default: "#ffa500" default: "#ffa500"
}, },
suc: { suc: {
100: "#dcf3d1",
200: "#bae7a3",
300: "#97dc76",
400: "#75d048",
500: "#52c41a", 500: "#52c41a",
600: "#429d15",
700: "#317610",
800: "#214e0a",
900: "#102705",
default: "#52c41a" default: "#52c41a"
},
}
}, },
}, },
plugins: [], plugins: [],