Browse Source

add news

master
panda 9 months ago
parent
commit
a50369ae80
  1. 7
      src/App.vue
  2. 91
      src/components/admin/MainWrapper.vue
  3. 20
      src/components/admin/SignIn.vue
  4. 263
      src/components/blogs/HomePage.vue
  5. 5
      src/components/blogs/ceshi.vue
  6. 4
      src/main.ts

7
src/App.vue

@ -1,15 +1,16 @@
<template>
<RouterView/>
<!-- </Simplebar> -->
</template>
<script setup lang="ts">
import Simplebar from 'simplebar-vue';
import 'simplebar-vue/dist/simplebar.min.css';
</script>
<style>
html{
overflow: hidden;
}
#app>*{
height: 100vh;
overflow: auto;
}
</style>

91
src/components/admin/MainWrapper.vue

@ -1,25 +1,27 @@
<template>
<a-flex>
<div class="menu" :style="{ width: state.menuWidth }">
<div class="menu_header">
<Simplebar >
<div id="container">
<div class="leftSidebar" :style="{ width: state.menuWidth }">
<a-flex justify="center" align="center" style="height: 48px;">
<TitleOutLined :class="collapsed ? 'small' : 'large'" />
<span v-if="!collapsed">{{ state.name }}</span>
</div>
<a-menu class="menu_navigate" v-model:openKeys="state.openKeys" v-model:selectedKeys="state.selectedKeys"
mode="inline" theme="light" :inline-collapsed="state.collapsed" :items="items" style="border-inline-end: none;"
@click="menuItemclick">
</a-flex>
<a-menu v-model:openKeys="state.openKeys" v-model:selectedKeys="state.selectedKeys" mode="inline" theme="light"
:inline-collapsed="state.collapsed" :items="items" style="border-inline-end: none;" @click="menuItemclick">
</a-menu>
</div>
<div class="main" style="flex: 1;">
<div class="main_header">
<a-space>
<a-button @click="toggleCollapsed">
<MenuUnfoldOutlined v-if="state.collapsed" />
<MenuFoldOutlined v-else />
</a-button>
<a-button type="text" @click="jumpdashboard">首页</a-button>
</a-space>
<div class="user">
<div class="contentArea">
<div>
<a-flex>
<a-space>
<a-button @click="toggleCollapsed">
<MenuUnfoldOutlined v-if="state.collapsed" />
<MenuFoldOutlined v-else />
</a-button>
<a-button type="text" @click="jumpdashboard">首页</a-button>
</a-space>
</a-flex>
<a-flex align="center" gap="middle">
<span>{{ username }}</span>
<div>
<a-button type="primary" @click="showModal" danger>
@ -29,12 +31,12 @@
<p>确定要注销吗</p>
</a-modal>
</div>
</div>
</a-flex>
</div>
<RouterView />
</div>
</a-flex>
</div>
</Simplebar>
</template>
<script setup lang='ts'>
@ -139,13 +141,10 @@ onMounted(async () => {
)
username.value = userinfo.data.username
});
const open = ref<boolean>(false);
const showModal = () => {
open.value = true;
};
const handleOk = (e: MouseEvent) => {
console.log(e);
authStore.removeToken()
@ -155,30 +154,38 @@ const handleOk = (e: MouseEvent) => {
}, 2000);
open.value = false;
};
const handleCancel = (e: MouseEvent) => {
message.warn('取消注销');
}
</script>
<style scoped>
.menu {
#container {
display: flex;
}
.leftSidebar {
border-right: 1px solid rgba(5, 5, 5, 0.06);
font-size: 20px;
}
.main_header {
display: flex;
margin: 24px;
justify-content: space-between;
.leftSidebar>* {
margin: 12px 0;
}
.menu_header {
.leftSidebar>:first-child {
font-size: 20px;
}
.contentArea {
flex: 1;
}
.contentArea>:first-child{
margin: 24px;
display: flex;
justify-content: center;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 98px;
font-size: 20px;
}
.small {
@ -190,20 +197,4 @@ const handleCancel = (e: MouseEvent) => {
font-size: 50px;
margin: 0 10px 0 10px;
}
.navigate_button {
justify-content: space-between;
align-items: center;
border-block-end: 1px solid rgba(5, 5, 5, 0.06);
}
.user {
display: flex;
align-items: center;
}
.user>* {
padding: 0 5px;
}
</style>

20
src/components/admin/SignIn.vue

@ -2,7 +2,7 @@
<context-holder />
<div id="container">
<a-spin v-if="loading" tip="Loading..."></a-spin>
<a-form v-else :model="formState" name="normal_login" class="login-form" @submit.prevent="login">
<a-form v-else :model="formState" @submit.prevent="login">
<h2>博客管理系统</h2>
<a-form-item label="用户名" name="username" :rules="[{ required: true, validator: verifyName }]">
<a-input v-model:value="formState.username" placeholder="请输入用户名">
@ -11,12 +11,11 @@
</template>
</a-input>
</a-form-item>
<a-form-item label="密&nbsp;&nbsp;&nbsp;&nbsp;码" name="password"
:rules="[{ required: true, validator: verifyPassword }]">
<a-input-password v-model:value="formState.password" placeholder="请输入密码">
<template #prefix>
<LockOutlined class="site-form-item-icon" />
<LockOutlined />
</template>
</a-input-password>
</a-form-item>
@ -26,9 +25,8 @@
</a-form-item>
<a class="login-form-forgot" href="">忘记密码</a>
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit" class="login-form-button" :disabled="disabled">
<a-button type="primary" html-type="submit" :disabled="disabled">
</a-button>
Or
@ -140,16 +138,4 @@ h2 {
text-align: center;
color: rgba(41, 39, 51, 0.88);
}
#components-form-demo-normal-login .login-form {
max-width: 300px;
}
#components-form-demo-normal-login .login-form-forgot {
float: right;
}
#components-form-demo-normal-login .login-form-button {
width: 100%;
}
</style>

263
src/components/blogs/HomePage.vue

@ -1,107 +1,108 @@
<template>
<Simplebar style="height: 100vh;overflow: auto;" @scroll="handleScroll">
<div class="menu" v-if="show_menu">
<Simplebar @scroll="handleScroll">
<!-- 头部导航菜单 -->
<div class="headerMenu" v-if="show_menu">
<a-menu v-model:selectedKeys="current" mode="horizontal" :items="items" style="border-bottom: none;" />
<a-input-search v-model:value="value" placeholder="search" style="width: 200px" @search="onSearch" />
</div>
<div class="salon-light-text"></div>
<div class="carouse">
<div class="author"></div>
<!-- 轮播 -->
<div>
<a-carousel autoplay>
<div class="img"><img src="/src/assets/images/nav1.png" alt=""></div>
<div class="img"><img src="/src/assets/images/nav10.png" alt=""></div>
<div class="img"><img src="/src/assets/images/nav13.png" alt=""></div>
</a-carousel>
</div>
<a-button type="link" shape="circle" class="down_button" size="large" @click="downScroll">
<template #icon>
<DownCircleOutlined style="font-size: 35px;color: aliceblue;" spin />
</template>
</a-button>
<a-flex>
<a-flex vertical>
<a-card style="width: 350px;" hoverable>
<template #cover>
<img alt="example" :src="img" style="height: 350px;" />
<!-- 操作按钮滚动 -->
<div class="anchorDown">
<a-button type="link" shape="circle" size="large" @click="downScroll">
<template #icon>
<DownCircleOutlined style="font-size: 35px;color: aliceblue;" spin />
</template>
</a-button>
</div>
<!-- 主要内容区域 -->
<div class="mainContainer">
<a-card hoverable>
<img alt="example" :src="img" />
<a-card-meta title="SunFree" style="min-height: 100px">
<template #description>
<div class="cardtext"></div>
</template>
<a-card-meta title="SunFree" style="height: 100px">
<template #description>
<div class="cardtext"></div>
</template>
</a-card-meta>
<a-space wrap class="button-container">
<a-button shape="circle" size="large">
<GravatarLined />
</a-button>
<a-button shape="circle" size="large">
<QQLined />
</a-button>
<a-button shape="circle" size="large">
<WechatLined />
</a-button>
<a-button shape="circle" size="large">
<MusicLined />
</a-button>
<a-button shape="circle" size="large">
<GitHubLined />
</a-button>
</a-space>
<a-collapse class="custom-collapse" v-model:activeKey="activeKey" :bordered="false"
expandIconPosition="end">
<template #expandIcon="{ isActive }">
<caret-right-outlined :rotate="isActive ? 90 : 0" />
</template>
<a-collapse-panel key="1" header="内容1" :style="customStyle">
<p>{{ text }}</p>
</a-collapse-panel>
<a-collapse-panel key="2" header="内容2" :style="customStyle">
<p>{{ text }}</p>
</a-collapse-panel>
<a-collapse-panel key="3" header="内容3" :style="customStyle">
<p>{{ text }}</p>
</a-collapse-panel>
</a-collapse>
</a-card>
</a-flex>
<a-flex style="height: 500px;width: 60%;background-color: black;border: solid 1px red;">
</a-card-meta>
<a-space wrap>
<a-button shape="circle" size="large" @click="gravatarClick">
<GravatarLined />
</a-button>
<a-button shape="circle" size="large">
<QQLined />
</a-button>
<a-button shape="circle" size="large">
<WechatLined />
</a-button>
<a-button shape="circle" size="large">
<MusicLined />
</a-button>
<a-button shape="circle" size="large">
<GitHubLined />
</a-button>
</a-space>
<a-collapse v-model:activeKey="activeKey" :bordered="false" expandIconPosition="end">
<template #expandIcon="{ isActive }">
<caret-right-outlined :rotate="isActive ? 90 : 0" />
</template>
<a-collapse-panel key="1" header="内容1" :style="customStyle">
<p>{{ text }}</p>
</a-collapse-panel>
<a-collapse-panel key="2" header="内容2" :style="customStyle">
<p>{{ text }}</p>
</a-collapse-panel>
<a-collapse-panel key="3" header="内容3" :style="customStyle">
<p>{{ text }}</p>
</a-collapse-panel>
</a-collapse>
</a-card>
<div class="main">
<div></div>
</a-flex>
<a-flex>
<a-card hoverable style="width: 400px">
</div>
<div class="rightBar">
<a-card hoverable style="width: 400px;">
<template #cover>
<div id="aplayer" style="width: 400px"></div>
<div class="heatmap">
<div ref="heat" style="height: 100%;border-right: 1px solid #e9e9e9;"></div>
<div id="aplayer" style="width: 400px;"></div>
<div class="heatmap" style="border-right: rgba(0, 0, 0, 0.5);">
<div ref="heat" style="height: 100%;"></div>
</div>
<div class="statistic">
<a-row>
<a-col :span="8">
<a-statistic title="DAYS" :value="112893" />
<a-statistic title="DAYS" :value="112893" />
</a-col>
<a-col :span="8">
<a-statistic title="DIARYS" :value="112893" />
<a-statistic title="DIARYS" :value="112893" />
</a-col>
<a-col :span="8">
<a-statistic title="BLOGS" :value="112893" />
<a-statistic title="BLOGS" :value="112893" />
</a-col>
</a-row>
</div>
</template>
</a-card>
<a-card title="随机文章" :bordered="false" hoverable style="width: 400px;margin: 12px 0;">
sces
</a-card>
<a-card title="标签云" :bordered="false" hoverable style="width: 400px;margin: 12px 0;">
sces
</a-card>
</a-flex>
<!-- <a-flex>
<div id="aplayer"></div>
<div>
<div ref="heat" style="height: 200px;width: 500px;"></div>
</div>
</a-flex> -->
</a-flex>
</div>
</div>
</Simplebar>
</template>
<script lang="ts" setup>
import Simplebar from 'simplebar-vue';
import 'simplebar-vue/dist/simplebar.min.css';
import { h, reactive, ref } from 'vue';
import { MenuProps } from 'ant-design-vue/es/menu';
import { HomeOutlined, HighlightOutlined, ProfileOutlined, CameraOutlined, UsergroupDeleteOutlined, DownCircleOutlined } from '@ant-design/icons-vue';
@ -113,7 +114,8 @@ import 'APlayer/dist/APlayer.min.css';
import APlayer from 'APlayer';
import { createEcharts } from "@/hooks/intex"
import { SettingOutlined, EditOutlined, EllipsisOutlined } from '@ant-design/icons-vue';
import { useRouter } from 'vue-router'
const router = useRouter()
const heat = ref(null);
const activeKey = ref(['']);
const text = `A dog is a type of domesticated animal.Known for its loyalty and faithfulness,it can be found as a welcome guest in many households across the world.`;
@ -121,7 +123,7 @@ const customStyle =
'background: #f7f7f7;border-radius: 4px;margin-bottom: 12px;border: 0;overflow: hidden';
onMounted(() => {
// home
new Typed('.salon-light-text', {
new Typed('.author', {
strings: ['SunFree.'],
typeSpeed: 200,
backSpeed: 150,
@ -175,28 +177,35 @@ onMounted(() => {
const currentDate = new Date();
for (let i = 0; i < numDays; i++) {
const date = new Date(currentDate);
date.setDate(currentDate.getDate() + i);
date.setDate(currentDate.getDate() - i);
dates.push(
{ date: date.toISOString().split('T')[0], blogCount: 0 }
); //
}
return dates;
}
// 60
const data = generateDates(60);
console.log(`output->`, data)
data[3].blogCount = 5;
data[15].blogCount = 10;
data[25].blogCount = 3;
const formattedData = data.map((value, index) => [index % 15, Math.floor(index / 15), value.blogCount]);
//
const newData = [];
for (let i = 0; i < 60; i += 15) {
// 15
const chunk = data.slice(i, i + 15).reverse();
newData.push(...chunk);
}
const formattedData = newData.map((value, index) => [index % 15, Math.floor(index / 15), value.blogCount]);
const heatMapData = {
tooltip: {
position: 'top',
formatter: function (params) {
const item = data[params.dataIndex];
formatter: function (params: any) {
const item = newData[params.dataIndex];
if (item.blogCount > 0) {
return `${item.date}<br/>COMMENTS: ${item.blogCount}`;
} else {
@ -243,7 +252,7 @@ onMounted(() => {
type: 'heatmap',
data: formattedData,
itemStyle: {
borderColor: 'rgba(0, 0, 0, 0.4)', //
borderColor: 'rgba(0, 0, 0, 0.1)', //
borderWidth: 0.5, //
},
label: {
@ -259,7 +268,8 @@ onMounted(() => {
}
}]
};
createEcharts(heat, heatMapData)
createEcharts(heat, heatMapData);
})
const current = ref<string[]>(['mail']);
const show_menu = ref(false);
@ -346,14 +356,23 @@ const onSearch = (searchValue: string) => {
const img = ref("https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png")
const gravatarClick = () => {
window.open("https://www.baidu.com")
}
</script>
<style scoped>
.menu {
.simplebar-wrapper {
height: 100vh;
overflow: auto;
}
.headerMenu {
display: flex;
justify-content: center;
align-items: center;
padding: 10px 0;
width: 100%;
padding: 0 24px;
border-bottom: 1px solid rgba(5, 5, 5, 0.06);
position: fixed;
background-color: white;
@ -363,36 +382,12 @@ const img = ref("https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png")
z-index: 999;
}
.menu>* {
.headerMenu>* {
margin: 0 24px;
}
:deep(.slick-slide) {
text-align: center;
height: 100vh;
line-height: 160px;
background: #364d79;
overflow: hidden;
}
:deep(.slick-slide h3) {
color: #fff;
}
.down_button {
position: absolute;
bottom: 100px;
left: 50%;
border-style: hidden;
transform: translateX(-50%);
}
.Typewriter__wrapper {
font-size: 100px;
font-family: 'Courier New', Courier, monospace
}
.salon-light-text {
/* 作者名称 */
.author {
position: absolute;
display: inline-block;
font-size: 100px;
@ -423,6 +418,45 @@ const img = ref("https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png")
}
}
.anchorDown {
position: absolute;
bottom: 100px;
left: 50%;
border-style: hidden;
transform: translateX(-50%);
}
.mainContainer {
display: flex;
justify-content: center;
padding-top: 60px;
background-color: rgba(5, 5, 5, 0.08);
}
.mainContainer>:first-child {
width: 15%;
}
.mainContainer img{
width: 100%;
/* 图片宽度占满容器 */
aspect-ratio: 1/1;
/* 图片自适应容器并保持宽高比例 */
}
.main {
height: 500px;
width: 45%;
margin: 0 24px;
background-color: black;
border: solid 1px red;
}
.rightBar {
width: 20%;
}
.button-container button {
margin: 24px 6px;
}
@ -439,7 +473,12 @@ const img = ref("https://os.alipayobjects.com/rmsportal/QBnOOoLaAfKPirc.png")
.heatmap {
margin: 24px 0;
}
.statistic{
.statistic {
text-align: center;
}
.sitebar {
width: 400px;
}
</style>

5
src/components/blogs/ceshi.vue

@ -16,17 +16,18 @@ onMounted(() => {
const currentDate = new Date();
for (let i = 0; i < numDays; i++) {
const date = new Date(currentDate);
date.setDate(currentDate.getDate() + i);
date.setDate(currentDate.getDate() - i);
dates.push(
{ date: date.toISOString().split('T')[0], blogCount: 0 }
); //
}
return dates;
return dates.reverse();
}
// 60
const data = generateDates(60);
console.log(data)
data[3].blogCount = 5;
data[15].blogCount = 10;
data[25].blogCount = 3;

4
src/main.ts

@ -4,9 +4,11 @@ import "normalize.css"
import App from './App.vue'
import router from './router'
import Antd from 'ant-design-vue';
import Simplebar from 'simplebar-vue';
import 'simplebar-vue/dist/simplebar.min.css';
const app = createApp(App)
app.component('Simplebar', Simplebar);
app.use(createPinia())
app.use(router)
app.use(Antd)
app.mount('#app')
Loading…
Cancel
Save