🚧 add sidebar

This commit is contained in:
2024-12-03 00:49:16 +08:00
parent 594bd5b280
commit 2a1bb215ac
31 changed files with 440 additions and 99 deletions

17
components.d.ts vendored
View File

@@ -27,17 +27,16 @@ declare module 'vue' {
Alert: typeof import('./src/components/MyUI/Alert/Alert.vue')['default'] Alert: typeof import('./src/components/MyUI/Alert/Alert.vue')['default']
AList: typeof import('ant-design-vue/es')['List'] AList: typeof import('ant-design-vue/es')['List']
AListItem: typeof import('ant-design-vue/es')['ListItem'] AListItem: typeof import('ant-design-vue/es')['ListItem']
AllPhoto: typeof import('./src/views/Photograph/AllPhoto/AllPhoto.vue')['default']
AMenu: typeof import('ant-design-vue/es')['Menu'] AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal'] AModal: typeof import('ant-design-vue/es')['Modal']
AnimatedNature: typeof import('./src/components/AnimatedNature/AnimatedNature.vue')['default'] AnimatedNature: typeof import('./src/components/AnimatedNature/AnimatedNature.vue')['default']
AntDesignOutlined: typeof import('@ant-design/icons-vue')['AntDesignOutlined']
APagination: typeof import('ant-design-vue/es')['Pagination'] APagination: typeof import('ant-design-vue/es')['Pagination']
APopover: typeof import('ant-design-vue/es')['Popover'] APopover: typeof import('ant-design-vue/es')['Popover']
AQrcode: typeof import('ant-design-vue/es')['QRCode'] AQrcode: typeof import('ant-design-vue/es')['QRCode']
ARadio: typeof import('ant-design-vue/es')['Radio'] ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ARate: typeof import('ant-design-vue/es')['Rate']
ASkeleton: typeof import('ant-design-vue/es')['Skeleton'] ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
ASpace: typeof import('ant-design-vue/es')['Space'] ASpace: typeof import('ant-design-vue/es')['Space']
ASpin: typeof import('ant-design-vue/es')['Spin'] ASpin: typeof import('ant-design-vue/es')['Spin']
@@ -79,22 +78,18 @@ declare module 'vue' {
Ellipsis: typeof import('./src/components/MyUI/Ellipsis/Ellipsis.vue')['default'] Ellipsis: typeof import('./src/components/MyUI/Ellipsis/Ellipsis.vue')['default']
Empty: typeof import('./src/components/MyUI/Empty/Empty.vue')['default'] Empty: typeof import('./src/components/MyUI/Empty/Empty.vue')['default']
EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined'] EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined']
FileImageOutlined: typeof import('@ant-design/icons-vue')['FileImageOutlined']
Flex: typeof import('./src/components/MyUI/Flex/Flex.vue')['default'] Flex: typeof import('./src/components/MyUI/Flex/Flex.vue')['default']
FloatButton: typeof import('./src/components/MyUI/FloatButton/FloatButton.vue')['default'] FloatButton: typeof import('./src/components/MyUI/FloatButton/FloatButton.vue')['default']
ForgetPage: typeof import('./src/views/Forget/ForgetPage.vue')['default'] ForgetPage: typeof import('./src/views/Forget/ForgetPage.vue')['default']
GaugeChart: typeof import('./src/components/MyUI/GaugeChart/GaugeChart.vue')['default'] GaugeChart: typeof import('./src/components/MyUI/GaugeChart/GaugeChart.vue')['default']
GiteeOutlined: typeof import('@ant-design/icons-vue')['GiteeOutlined']
GithubOutlined: typeof import('@ant-design/icons-vue')['GithubOutlined']
GradientText: typeof import('./src/components/MyUI/GradientText/GradientText.vue')['default'] GradientText: typeof import('./src/components/MyUI/GradientText/GradientText.vue')['default']
Image: typeof import('./src/components/MyUI/Image/Image.vue')['default'] Image: typeof import('./src/components/MyUI/Image/Image.vue')['default']
ImageHoverEffect: typeof import('./src/components/ImageHoverEffect/imageHoverEffect.vue')['default']
ImageOverlaySlider: typeof import('./src/components/ImageOverlaySlider/imageOverlaySlider.vue')['default']
Input: typeof import('./src/components/MyUI/Input/Input.vue')['default'] Input: typeof import('./src/components/MyUI/Input/Input.vue')['default']
InputSearch: typeof import('./src/components/MyUI/InputSearch/InputSearch.vue')['default'] InputSearch: typeof import('./src/components/MyUI/InputSearch/InputSearch.vue')['default']
LandingPage: typeof import('./src/views/Landing/LandingPage.vue')['default'] LandingPage: typeof import('./src/views/Landing/LandingPage.vue')['default']
List: typeof import('./src/components/MyUI/List/List.vue')['default'] List: typeof import('./src/components/MyUI/List/List.vue')['default']
LoadingBar: typeof import('./src/components/MyUI/LoadingBar/LoadingBar.vue')['default'] LoadingBar: typeof import('./src/components/MyUI/LoadingBar/LoadingBar.vue')['default']
LocationAlbum: typeof import('./src/views/Album/LocationAlbum/LocationAlbum.vue')['default']
LockOutlined: typeof import('@ant-design/icons-vue')['LockOutlined'] LockOutlined: typeof import('@ant-design/icons-vue')['LockOutlined']
LoginFooter: typeof import('./src/views/Login/LoginFooter.vue')['default'] LoginFooter: typeof import('./src/views/Login/LoginFooter.vue')['default']
LoginPage: typeof import('./src/views/Login/LoginPage.vue')['default'] LoginPage: typeof import('./src/views/Login/LoginPage.vue')['default']
@@ -106,17 +101,20 @@ declare module 'vue' {
Notification: typeof import('./src/components/MyUI/Notification/Notification.vue')['default'] Notification: typeof import('./src/components/MyUI/Notification/Notification.vue')['default']
NumberAnimation: typeof import('./src/components/MyUI/NumberAnimation/NumberAnimation.vue')['default'] NumberAnimation: typeof import('./src/components/MyUI/NumberAnimation/NumberAnimation.vue')['default']
Pagination: typeof import('./src/components/MyUI/Pagination/Pagination.vue')['default'] Pagination: typeof import('./src/components/MyUI/Pagination/Pagination.vue')['default']
PeopleAlbum: typeof import('./src/views/Album/PeopleAlbum/PeopleAlbum.vue')['default']
Phoalbum: typeof import('./src/views/Album/Phoalbum/Phoalbum.vue')['default']
PictureOutlined: typeof import('@ant-design/icons-vue')['PictureOutlined'] PictureOutlined: typeof import('@ant-design/icons-vue')['PictureOutlined']
PlusOutlined: typeof import('@ant-design/icons-vue')['PlusOutlined'] PlusOutlined: typeof import('@ant-design/icons-vue')['PlusOutlined']
Popconfirm: typeof import('./src/components/MyUI/Popconfirm/Popconfirm.vue')['default'] Popconfirm: typeof import('./src/components/MyUI/Popconfirm/Popconfirm.vue')['default']
Popover: typeof import('./src/components/MyUI/Popover/Popover.vue')['default'] Popover: typeof import('./src/components/MyUI/Popover/Popover.vue')['default']
Progress: typeof import('./src/components/MyUI/Progress/Progress.vue')['default'] Progress: typeof import('./src/components/MyUI/Progress/Progress.vue')['default']
QqOutlined: typeof import('@ant-design/icons-vue')['QqOutlined']
QRCode: typeof import('./src/components/MyUI/QRCode/QRCode.vue')['default'] QRCode: typeof import('./src/components/MyUI/QRCode/QRCode.vue')['default']
QRLogin: typeof import('./src/views/QRLogin/QRLogin.vue')['default'] QRLogin: typeof import('./src/views/QRLogin/QRLogin.vue')['default']
QRLoginFooter: typeof import('./src/views/QRLogin/QRLoginFooter.vue')['default'] QRLoginFooter: typeof import('./src/views/QRLogin/QRLoginFooter.vue')['default']
Radio: typeof import('./src/components/MyUI/Radio/Radio.vue')['default'] Radio: typeof import('./src/components/MyUI/Radio/Radio.vue')['default']
Rate: typeof import('./src/components/MyUI/Rate/Rate.vue')['default'] Rate: typeof import('./src/components/MyUI/Rate/Rate.vue')['default']
RecentUpload: typeof import('./src/views/Photograph/RecentUpload/RecentUpload.vue')['default']
RecyclingBin: typeof import('./src/views/RecyclingBin/RecyclingBin.vue')['default']
ReplyInput: typeof import('./src/components/CommentReply/src/ReplyInput/ReplyInput.vue')['default'] ReplyInput: typeof import('./src/components/CommentReply/src/ReplyInput/ReplyInput.vue')['default']
ReplyList: typeof import('./src/components/CommentReply/src/ReplyList/ReplyList.vue')['default'] ReplyList: typeof import('./src/components/CommentReply/src/ReplyList/ReplyList.vue')['default']
ReplyReply: typeof import('./src/components/CommentReply/src/ReplyReplyInput/ReplyReply.vue')['default'] ReplyReply: typeof import('./src/components/CommentReply/src/ReplyReplyInput/ReplyReply.vue')['default']
@@ -126,6 +124,7 @@ declare module 'vue' {
Row: typeof import('./src/components/MyUI/Grid/Row.vue')['default'] Row: typeof import('./src/components/MyUI/Grid/Row.vue')['default']
SafetyOutlined: typeof import('@ant-design/icons-vue')['SafetyOutlined'] SafetyOutlined: typeof import('@ant-design/icons-vue')['SafetyOutlined']
Scrollbar: typeof import('./src/components/MyUI/Scrollbar/Scrollbar.vue')['default'] Scrollbar: typeof import('./src/components/MyUI/Scrollbar/Scrollbar.vue')['default']
SearchOutlined: typeof import('@ant-design/icons-vue')['SearchOutlined']
Segmented: typeof import('./src/components/MyUI/Segmented/Segmented.vue')['default'] Segmented: typeof import('./src/components/MyUI/Segmented/Segmented.vue')['default']
Select: typeof import('./src/components/MyUI/Select/Select.vue')['default'] Select: typeof import('./src/components/MyUI/Select/Select.vue')['default']
SendOutlined: typeof import('@ant-design/icons-vue')['SendOutlined'] SendOutlined: typeof import('@ant-design/icons-vue')['SendOutlined']
@@ -144,6 +143,7 @@ declare module 'vue' {
Tag: typeof import('./src/components/MyUI/Tag/Tag.vue')['default'] Tag: typeof import('./src/components/MyUI/Tag/Tag.vue')['default']
Textarea: typeof import('./src/components/MyUI/Textarea/Textarea.vue')['default'] Textarea: typeof import('./src/components/MyUI/Textarea/Textarea.vue')['default']
TextScroll: typeof import('./src/components/MyUI/TextScroll/TextScroll.vue')['default'] TextScroll: typeof import('./src/components/MyUI/TextScroll/TextScroll.vue')['default']
ThingAlbum: typeof import('./src/views/Album/ThingAlbum/ThingAlbum.vue')['default']
Timeline: typeof import('./src/components/MyUI/Timeline/Timeline.vue')['default'] Timeline: typeof import('./src/components/MyUI/Timeline/Timeline.vue')['default']
Tooltip: typeof import('./src/components/MyUI/Tooltip/Tooltip.vue')['default'] Tooltip: typeof import('./src/components/MyUI/Tooltip/Tooltip.vue')['default']
TreeChart: typeof import('./src/components/MyUI/TreeChart/TreeChart.vue')['default'] TreeChart: typeof import('./src/components/MyUI/TreeChart/TreeChart.vue')['default']
@@ -154,6 +154,5 @@ declare module 'vue' {
Video: typeof import('./src/components/MyUI/Video/Video.vue')['default'] Video: typeof import('./src/components/MyUI/Video/Video.vue')['default']
WarningOutlined: typeof import('@ant-design/icons-vue')['WarningOutlined'] WarningOutlined: typeof import('@ant-design/icons-vue')['WarningOutlined']
Waterfall: typeof import('./src/components/MyUI/Waterfall/Waterfall.vue')['default'] Waterfall: typeof import('./src/components/MyUI/Waterfall/Waterfall.vue')['default']
WechatOutlined: typeof import('@ant-design/icons-vue')['WechatOutlined']
} }
} }

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<link rel="icon" type="image/svg+xml" href="/logo.svg"/> <link rel="icon" type="image/svg+xml" href="/logo.svg"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=yes"/>
<title><%- title %></title> <title><%- title %></title>
</head> </head>
<body> <body>

View File

@@ -10,7 +10,7 @@
"docker-build": "docker build -t schisandra/schisandra-cloud-album-front ." "docker-build": "docker build -t schisandra/schisandra-cloud-album-front ."
}, },
"dependencies": { "dependencies": {
"@alova/adapter-axios": "^2.0.10", "@alova/adapter-axios": "^2.0.11",
"@ant-design/icons-vue": "^7.0.1", "@ant-design/icons-vue": "^7.0.1",
"@tensorflow/tfjs": "^4.22.0", "@tensorflow/tfjs": "^4.22.0",
"@types/animejs": "^3.1.12", "@types/animejs": "^3.1.12",
@@ -21,15 +21,16 @@
"@vuepic/vue-datepicker": "^10.0.0", "@vuepic/vue-datepicker": "^10.0.0",
"@vueuse/core": "^12.0.0", "@vueuse/core": "^12.0.0",
"@vueuse/integrations": "^12.0.0", "@vueuse/integrations": "^12.0.0",
"alova": "^3.2.5", "alova": "^3.2.6",
"animejs": "^3.2.2", "animejs": "^3.2.2",
"ant-design-vue": "^4.2.6", "ant-design-vue": "^4.2.6",
"autofit.js": "^3.2.2",
"axios": "^1.7.7", "axios": "^1.7.7",
"browser-image-compression": "^2.0.2", "browser-image-compression": "^2.0.2",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"echarts": "^5.5.1", "echarts": "^5.5.1",
"eslint": "9.15.0", "eslint": "9.16.0",
"go-captcha-vue": "^2.0.4", "go-captcha-vue": "^2.0.4",
"jsencrypt": "^3.3.2", "jsencrypt": "^3.3.2",
"json-stringify-safe": "^5.0.1", "json-stringify-safe": "^5.0.1",
@@ -53,10 +54,10 @@
"ws": "^8.18.0" "ws": "^8.18.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.15.0", "@eslint/js": "^9.16.0",
"@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue": "^5.2.1",
"eslint-plugin-vue": "^9.31.0", "eslint-plugin-vue": "^9.32.0",
"globals": "^15.12.0", "globals": "^15.13.0",
"sass": "^1.81.0", "sass": "^1.81.0",
"typescript": "^5.7.2", "typescript": "^5.7.2",
"typescript-eslint": "^8.15.0", "typescript-eslint": "^8.15.0",

View File

@@ -19,16 +19,4 @@ const app = useStore().theme;
const lang = useStore().lang; const lang = useStore().lang;
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.animation-enter {
opacity: 0; /* 初始透明 */
}
.animation-enter-active {
transition: opacity 0.2s; /* 渐入效果 */
}
.animation-leave-active {
transition: opacity 0.2s; /* 渐出效果 */
}
.animation-leave-to {
opacity: 0; /* 离开时透明 */
}
</style> </style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<AFlex :vertical="true" class="reply-item-child"> <AFlex :vertical="true" class="reply-item-child">
<ASpin :spinning="comment.replyLoading[item.id]" size="default"> <ASpin :delay="500" :spinning="comment.replyLoading[item.id]" size="default">
<AFlex :vertical="true" v-if="comment.replyVisibility[item.id]?.data.comments"> <AFlex :vertical="true" v-if="comment.replyVisibility[item.id]?.data.comments">
<AFlex :vertical="false" style="margin-top: 5px" <AFlex :vertical="false" style="margin-top: 5px"
v-for="(child, index) in comment.replyVisibility[item.id]?.data.comments" v-for="(child, index) in comment.replyVisibility[item.id]?.data.comments"

View File

@@ -1,33 +1,59 @@
<template> <template>
<header class="header-main"> <header class="header-main">
<div class="header-container"> <div class="header-container">
<AFlex :vertical="false" align="center" justify="flex-end" class="header-logo-container"> <AFlex :vertical="false" align="center" justify="flex-start" class="header-logo-container">
<AAvatar :size="50" shape="square" :src="logo" @click="router.push('/')"/> <AAvatar :size="50" shape="square" :src="logo" @click="router.push('/')"/>
<span class="header-logo-text" @click="router.push('/')">S.Album</span> <span class="header-logo-text" @click="router.push('/')">S.Album</span>
</AFlex> </AFlex>
<AFlex class="header-search-container" :vertical="false" align="center" justify="center">
<APopover :arrow="false" :overlayInnerStyle="{width: '28vw'}"
trigger="click">
<AInput size="large" class="header-search-input" placeholder="Search">
<template #suffix>
<AButton size="small" type="text" shape="circle" @click.prevent>
<template #icon>
<SearchOutlined style="font-size: 16px"/>
</template>
</AButton>
</template>
</AInput>
<template #content>
<AFlex :vertical="false" align="center" justify="space-between" class="header-search-content-header">
<span>搜索历史</span>
<AButton type="text" size="small" style="color: #707072">清空搜索历史</AButton>
</AFlex>
<div class="header-search-content-body">
<ATag :style="{
padding: '5px 15px',
fontSize: '15px',
marginTop: '20px',
}" :bordered="false" closable>搜索历史1
</ATag>
</div>
</template>
</APopover>
</AFlex>
<AFlex :vertical="false" align="center" justify="flex-end" class="header-menu-container"> <AFlex :vertical="false" align="center" justify="flex-end" class="header-menu-container">
<AFlex :vertical="false" align="center" justify="flex-start" class="header-menu-item"> <AFlex :vertical="false" align="center" justify="flex-start" class="header-menu-item">
<ABadge count="0" :numberStyle="{ <ABadge count="5" :numberStyle="{marginTop: '10px', marginRight: '5px'}">
marginTop: '5px',
}">
<AButton type="text" shape="circle" size="large" class="header-menu-item-btn" <AButton type="text" shape="circle" size="large" class="header-menu-item-btn"
:icon="h(BellOutlined)"/> :icon="h(BellOutlined)"/>
</ABadge> </ABadge>
</AFlex> </AFlex>
<AFlex :vertical="false" align="center" justify="flex-start" class="header-menu-item"> <!-- <AFlex :vertical="false" align="center" justify="flex-start" class="header-menu-item">-->
<ADropdown> <!-- <ADropdown>-->
<template #overlay> <!-- <template #overlay>-->
<AMenu @click="changeLang"> <!-- <AMenu @click="changeLang">-->
<AMenuItem key="zh">{{ t("landing.chinese") }}</AMenuItem> <!-- <AMenuItem key="zh">{{ t("landing.chinese") }}</AMenuItem>-->
<AMenuItem key="en">{{ t("landing.english") }}</AMenuItem> <!-- <AMenuItem key="en">{{ t("landing.english") }}</AMenuItem>-->
</AMenu> <!-- </AMenu>-->
</template> <!-- </template>-->
<AButton type="text" shape="circle" size="large" :icon="h(TranslationOutlined)"> <!-- <AButton type="text" shape="circle" size="large" :icon="h(TranslationOutlined)">-->
</AButton> <!-- </AButton>-->
</ADropdown> <!-- </ADropdown>-->
</AFlex> <!-- </AFlex>-->
<AFlex :vertical="false" align="center" justify="flex-start" class="header-user-container"> <AFlex :vertical="false" align="center" justify="flex-start" class="header-user-container">
<AAvatar :size="35" class="header-user-avatar" :src="user.user.avatar"/> <AAvatar :size="40" class="header-user-avatar" :src="user.user.avatar"/>
</AFlex> </AFlex>
</AFlex> </AFlex>
</div> </div>
@@ -36,23 +62,22 @@
<script lang="ts" setup> <script lang="ts" setup>
import logo from "@/assets/svgs/logo-album.svg"; import logo from "@/assets/svgs/logo-album.svg";
import useStore from "@/store"; import useStore from "@/store";
import {BellOutlined, TranslationOutlined} from "@ant-design/icons-vue"; import {BellOutlined} from "@ant-design/icons-vue";
import {h} from "vue"; import {h} from "vue";
import {useI18n} from "vue-i18n";
const user = useStore().user; const user = useStore().user;
const {t, locale} = useI18n(); // const lang = useStore().lang;
const lang = useStore().lang;
const router = useRouter(); const router = useRouter();
/** // /**
* 切换语言 // * 切换语言
* @param language // * @param language
*/ // */
async function changeLang(language: any) { // async function changeLang(language: any) {
lang.lang = language.key; // lang.lang = language.key;
locale.value = language.key; // locale.value = language.key;
} // }
</script> </script>
<style scoped lang="scss" src="./index.scss"> <style scoped lang="scss" src="./index.scss">

View File

@@ -1,19 +1,15 @@
.header-main { .header-main {
height: 60px; height: 70px;
width: 100%; width: 100%;
min-height: 70px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center;
background-color: rgba(255, 255, 255, 0.38); background-color: rgba(255, 255, 255, 0.38);
backdrop-filter: blur(20px); backdrop-filter: blur(20px);
transition: background-color 0.3s; transition: background-color 0.3s;
z-index: 3; z-index: 3;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
//border-radius: 20px; //border-radius: 20px;
position: fixed; //position: fixed;
top: 0;
left: 0;
.header-container { .header-container {
@@ -21,40 +17,65 @@
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
width: 1200px; width: 100%;
max-width: 1200px; height: 100%;
padding: 0 2%;
.header-logo-text { .header-logo-container {
margin-left: 10px; min-width: 30%;
font-size: 25px; cursor: pointer;
font-family: "Comic Sans MS", cursive; display: flex;
font-weight: bolder; flex-direction: row;
} align-items: center;
} justify-content: flex-start;
.header-logo-container { .header-logo-text {
min-width: 280px; margin-left: 2%;
cursor: pointer; font-size: 200%;
} font-family: "Comic Sans MS", cursive;
font-weight: bolder;
.header-menu-container {
width: 30%;
.header-menu-item {
min-width: 50px;
.header-menu-item-btn {
font-size: 16px;
} }
} }
.header-user-container { .header-search-container {
min-width: 130px; width: 30%;
.header-search-input {
border-radius: 20px;
}
.header-search-content-body {
margin-top: 10px;
.header-user-avatar {
cursor: pointer;
} }
} }
.header-menu-container {
width: 30%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.header-menu-item {
width: 85%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
}
.header-user-container {
.header-user-avatar {
cursor: pointer;
}
}
}
} }
} }

View File

@@ -0,0 +1,80 @@
<template>
<div>
<AMenu
v-model:selectedKeys="state.selectedKeys"
class="sidebar"
:selectable="true"
:multiple="false"
mode="vertical"
v-model:openKeys="state.openKeys"
:inlineIndent="30"
:inlineCollapsed="false"
:items="items"
@click="handleClick"
>
</AMenu>
</div>
</template>
<script lang="ts" setup>
import {VueElement, h, reactive} from 'vue';
import {
PictureOutlined,
TagsOutlined,
AppstoreOutlined,
UploadOutlined,
RestOutlined,
TagOutlined,
SmileOutlined,
EnvironmentOutlined,
AppstoreAddOutlined
} from '@ant-design/icons-vue';
import {ItemType} from 'ant-design-vue';
import {useI18n} from 'vue-i18n';
const {t} = useI18n();
const router = useRouter();
const state = reactive({
openKeys: [router.currentRoute.value.path.split('/').slice(-1)],
selectedKeys: [router.currentRoute.value.path.split('/').slice(-1)],
});
function getItem(
label: VueElement | string,
key: string,
icon?: any,
children?: ItemType[],
type?: 'group',
): ItemType {
return {
key,
icon,
children,
label,
type,
} as ItemType;
}
const items: ItemType[] = reactive([
getItem(t('album.photo'), 'photo', () => h(AppstoreOutlined), [
getItem(t('album.allAlbums'), 'all', () => h(PictureOutlined)),
getItem(t('album.recentUploads'), 'recent', () => h(UploadOutlined)),
]),
getItem(t('album.albums'), 'album', () => h(TagsOutlined), [
getItem(t('album.albums'), 'albums', () => h(TagOutlined)),
getItem(t('album.peopleAlbums'), 'people', () => h(SmileOutlined)),
getItem(t('album.locationAlbums'), 'location', () => h(EnvironmentOutlined)),
getItem(t('album.thingsAlbums'), 'thing', () => h(AppstoreAddOutlined)),
]),
getItem(t('album.recyclingBin'), 'recycling', () => h(RestOutlined)),
getItem('网盘导入', '10'),
]);
function handleClick({keyPath}) {
const path = keyPath.join('/');
router.push(`/main/${path}`);
}
</script>
<style scoped lang="scss" src="./index.scss">
</style>

View File

@@ -0,0 +1,6 @@
.sidebar {
width: 15vw;
height: calc(100vh - 70px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

View File

@@ -135,5 +135,15 @@ export default {
reportSeletion: 'Please select the reason for reporting the comment', reportSeletion: 'Please select the reason for reporting the comment',
view: 'look', view: 'look',
replies: 'replies', replies: 'replies',
},
album: {
photo: 'Photo',
allAlbums: 'All Albums',
recentUploads: 'Recent Uploads',
albums: 'Albums',
peopleAlbums: 'People',
locationAlbums: 'Location',
thingsAlbums: 'Things',
recyclingBin: 'Recycling Bin',
} }
}; };

View File

@@ -137,6 +137,16 @@ export default {
reportSeletion: '请选择举报原因', reportSeletion: '请选择举报原因',
view: '查看', view: '查看',
replies: '条回复', replies: '条回复',
},
album: {
photo: '照片',
allAlbums: '所有相册',
recentUploads: '最近上传',
albums: '相册',
peopleAlbums: '人物',
locationAlbums: '地点',
thingsAlbums: '事物',
recyclingBin: '回收站',
} }
}; };

View File

@@ -0,0 +1,43 @@
import Phoalbum from "@/views/Album/Phoalbum/Phoalbum.vue";
import PeopleAlbum from "@/views/Album/PeopleAlbum/PeopleAlbum.vue";
import LocationAlbum from "@/views/Album/LocationAlbum/LocationAlbum.vue";
import ThingAlbum from "@/views/Album/ThingAlbum/ThingAlbum.vue";
export default [
{
path: '/main/album/albums',
name: 'albums',
component: Phoalbum,
meta: {
requiresAuth: true,
title: '相册'
},
},
{
path: '/main/album/people',
name: 'people',
component: PeopleAlbum,
meta: {
requiresAuth: true,
title: '人物相册'
},
},
{
path: '/main/album/location',
name: 'location',
component: LocationAlbum,
meta: {
requiresAuth: true,
title: '地点相册'
},
},
{
path: '/main/album/thing',
name: 'thing',
component: ThingAlbum,
meta: {
requiresAuth: true,
title: '事物相册'
},
},
];

View File

@@ -1,11 +1,22 @@
import photo from "@/router/modules/photos.ts";
import albums from "@/router/modules/albums.ts";
import recycling_bin from "@/router/modules/recycling_bin.ts";
export default [ export default [
{ {
path: '/main', path: '/main',
name: 'main', name: 'main',
redirect: '/main/photos',
component: () => import('@/views/Main/MainPage.vue'), component: () => import('@/views/Main/MainPage.vue'),
meta: { meta: {
requiresAuth: true, requiresAuth: true,
title: '主页' title: '主页'
} },
children: [
...photo,
...albums,
...recycling_bin
]
} }
]; ];

View File

@@ -0,0 +1,23 @@
import AllPhoto from "@/views/Photograph/AllPhoto/AllPhoto.vue";
import RecentUpload from "@/views/Photograph/RecentUpload/RecentUpload.vue";
export default [
{
path: '/main/photo/all',
name: 'photos',
component: AllPhoto,
meta: {
requiresAuth: true,
title: '全部照片'
},
},
{
path: '/main/photo/recent',
name: 'recent',
component: RecentUpload,
meta: {
requiresAuth: true,
title: '最近上传'
},
},
];

View File

@@ -0,0 +1,13 @@
import RecyclingBin from "@/views/RecyclingBin/RecyclingBin.vue";
export default [
{
path: '/main/recycling',
name: 'recycling',
component: RecyclingBin,
meta: {
requiresAuth: true,
title: '回收站'
},
},
];

View File

@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
</template>
<style scoped lang="scss" src="./index.scss">
</style>

View File

View File

@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
</template>
<style scoped lang="scss" src="./index.scss">
</style>

View File

View File

@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
</template>
<style scoped lang="scss" src="./index.scss">
</style>

View File

View File

@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
</template>
<style scoped lang="scss" src="./index.scss">
</style>

View File

View File

@@ -1,21 +1,26 @@
<template> <template>
<div class="main-page"> <div class="main-page">
<Header/> <div class="main-header">
<Header/>
<div style="margin-top: 100px">
<CommentReply/>
</div> </div>
<div class="main-content">
<Sidebar/>
<div class="main-content-container">
<!-- <ACard class="main-container-card">-->
<router-view/>
<!-- </ACard>-->
</div>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import useStore from "@/store"; import useStore from "@/store";
import CommentReply from "@/components/CommentReply/index.vue";
import {h, onMounted, onUnmounted} from "vue"; import {h, onMounted, onUnmounted} from "vue";
import Header from "@/layout/default/Header/Header.vue"; import Header from "@/layout/default/Header/Header.vue";
import {notification} from "ant-design-vue"; import {notification} from "ant-design-vue";
import {SmileOutlined} from "@ant-design/icons-vue"; import {SmileOutlined} from "@ant-design/icons-vue";
import Sidebar from "@/layout/default/Sidebar/Sidebar.vue";
const websocket = useStore().websocket; const websocket = useStore().websocket;

View File

@@ -1,9 +1,35 @@
.main-page { .main-page {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; background-color: #eaeef6;
background-color: var(--background-color);
color: var(--text-color); color: var(--text-color);
width: 100%; width: 100%;
min-height: 100vh; min-height: 100vh;
.main-header {
}
.main-content {
display: flex;
flex-direction: row;
.main-content-container {
display: flex;
flex-direction: column;
//justify-content: center;
//align-items: center;
width: calc(100% - 15vw);
height: calc(100vh - 90px);
padding: 10px;
.main-container-card {
width: 100%;
height: 100%;
overflow: scroll;
}
}
}
} }

View File

@@ -0,0 +1,14 @@
<script setup lang="ts">
</script>
<template>
<div>
<p>AllPhoto</p>
</div>
</template>
<style scoped lang="scss" src="./index.scss">
</style>

View File

View File

@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
</template>
<style scoped lang="scss" src="./index.scss">
</style>

View File

@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
</template>
<style scoped lang="scss" src="./index.scss">
</style>

View File