feat: 开发中...

This commit is contained in:
2023-04-06 08:52:04 +08:00
parent 2b507f9329
commit b5eb9b468e
15 changed files with 422 additions and 84 deletions

View File

@@ -43,6 +43,9 @@ onMounted(() => {
.app-container {
width: 100%;
height: 100%;
max-width: 1280px;
margin: 0 auto;
}
.app-header {

View File

@@ -26,7 +26,7 @@ export const api = {
console.log("current user info: ", vo.content);
} else {
globalStore.currentUserInfo = undefined;
console.warn("ckeck current user info failed!");
console.warn("ckeck current user info failed!", vo);
}
globalStore.save();
});

View File

@@ -11,6 +11,10 @@ function showBlog() {
router.push("/blog/" + props.blog.id + "/read/");
}
function showTags(tag: string) {
console.log("show tag blogs: " + tag);
}
function showCreator() {
console.log("showCreator");
}
@@ -24,26 +28,49 @@ function showUpdater() {
<el-card class="blog-card">
<template #header>
<div class="blog-card-header">
<p @click="showBlog" class="blog-card-title">{{ blog.title }}</p>
<div>
<h1 @click="showBlog" class="blog-card-title">{{ blog.title }}</h1>
<div style="flex-grow: 1"></div>
<div @click="showCreator" class="blog-card-creater">
<p>
<el-avatar :size="24" src="/favicon.ico" />
{{ blog.creator?.nickname }}
<el-avatar
:size="24"
src="/favicon.ico"
style="vertical-align: middle"
/>
{{ blog.creator.nickname }}
</p>
<p @click="showCreator" class="blog-card-creater">
{{ " 发表于:" + blog.updateTime?.toLocaleString() }}
<p>
{{ " 首次发表于:" + blog.updateTime.toLocaleString() }}
</p>
</div>
</div>
</template>
<div class="blog-card-body">
<div class="blog-card-abstract" v-html="blog.abstracts"></div>
<div class="blog-card-footer">
<div @click="showUpdater">
<p>
{{ " 最后修改于:" + blog.updateTime?.toLocaleString() }}
</p>
</div>
</div>
<div class="blog-card-footer">
<el-tag
style="margin-left: 5px"
v-for="tag in blog.tags"
type="info"
size="large"
@click="showTags(tag)"
>
{{ tag }}
</el-tag>
<div style="flex-grow: 1"></div>
<div @click="showUpdater" class="blog-card-updater">
<p>
<el-avatar
:size="24"
src="/favicon.ico"
style="vertical-align: middle"
/>
{{ blog.updater.nickname }}
</p>
<p>
{{ " 最后修改于:" + blog.updateTime?.toLocaleString() }}
</p>
</div>
</div>
</el-card>
@@ -52,40 +79,51 @@ function showUpdater() {
<style scoped>
.blog-card {
width: 100%;
cursor: pointer;
}
.blog-card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.blog-card-header :hover {
cursor: pointer;
text-decoration: underline;
}
.blog-card-title {
font-size: x-large;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.blog-card-creater {
font-size: medium;
text-align: right;
font-size: small;
white-space: nowrap;
}
.blog-card-abstract {
font-size: medium;
margin-bottom: 20px;
padding-bottom: 20px;
}
.blog-card-footer {
display: flex;
align-items: center;
padding-top: 20px;
border: 1px solid #ccc;
border-bottom-width: 0;
border-left-width: 0;
border-right-width: 0;
border-top: 1px solid #ccc;
}
.blog-card-footer :hover {
cursor: pointer;
text-decoration: underline;
}
.blog-card-updater {
text-align: right;
font-size: small;
white-space: nowrap;
}
</style>

View File

@@ -56,7 +56,7 @@ function onSelectMenu(index: string) {
{{ customMenu.text }}
</el-menu-item>
<div class="flex-grow" />
<div style="flex-grow: 1" />
<el-menu-item index="/login" v-if="!globalStore.currentUserInfo?.id">
登录
@@ -78,8 +78,4 @@ function onSelectMenu(index: string) {
</el-menu>
</template>
<style scoped>
.flex-grow {
flex-grow: 1;
}
</style>
<style scoped></style>

View File

@@ -0,0 +1,216 @@
<script setup lang="ts">
import { onMounted, ref } from "vue";
import type { BlogInfoResponseVO } from "@/swagger";
import { api } from "@/api";
import router from "@/router";
import { ElMessage } from "element-plus";
let pageIndex = ref(0);
let pageSize = 2;
let pageCount = 100;
const blogs = ref<Array<BlogInfoResponseVO>>();
onMounted(() => {
changePage(1);
});
function editBlog(blogID: number) {
router.push("/blog/" + blogID + "/edit/");
}
function deleteBlog(blogID: number) {
api.BlogController.removeBlog(blogID).then((resp) => {
const vo = resp.data;
if (vo.code === 200) {
ElMessage({
type: "success",
message: "删除博客成功!",
});
} else {
ElMessage({
type: "error",
message: "删除博客失败:" + vo.msg,
});
}
});
}
function showBlog(blogID: number) {
router.push("/blog/" + blogID + "/read/");
}
function showTags(tag: string) {
console.log("show tag blogs: " + tag);
}
function showCreator() {
console.log("showCreator");
}
function showUpdater() {
console.log("showUpdater");
}
function changePage(newPage: number) {
api.BlogController.getBlogInfoList(newPage - 1, pageSize).then((resp) => {
const vo = resp.data;
const page = vo.content;
for (let item of page?.elements ?? []) {
item.createTime = new Date(item?.createTime ?? 0);
item.updateTime = new Date(item?.updateTime ?? 0);
}
blogs.value = page?.elements;
pageCount = page?.totalPage;
pageIndex.value = newPage;
});
}
</script>
<template>
<div class="blog-container">
<div class="blog-card-container">
<el-card class="blog-card" v-for="blog in blogs">
<template #header>
<div class="blog-card-header">
<p @click="showBlog(blog.id)" class="blog-card-title">
{{ blog.title }}
</p>
<div style="flex-grow: 1"></div>
<div @click="showUpdater" class="blog-card-updater">
<p>
<el-avatar
:size="24"
src="/favicon.ico"
style="vertical-align: middle"
/>
{{ blog.updater.nickname }}
</p>
<p>
{{ " 最后修改于:" + blog.updateTime?.toLocaleString() }}
</p>
</div>
<div @click="showCreator" class="blog-card-creater">
<p>
<el-avatar
:size="24"
src="/favicon.ico"
style="vertical-align: middle"
/>
{{ blog.creator.nickname }}
</p>
<p>
{{ " 首次发表于:" + blog.updateTime.toLocaleString() }}
</p>
</div>
</div>
</template>
<div class="blog-card-body">
<div class="blog-card-abstract" v-html="blog.abstracts"></div>
</div>
<div class="blog-card-footer">
<el-tag
style="margin-left: 5px"
v-for="tag in blog.tags"
type="info"
size="large"
@click="showTags(tag)"
>
{{ tag }}
</el-tag>
<div style="flex-grow: 1"></div>
<div>
<el-button @click="editBlog(blog.id)" type="primary"
>编辑</el-button
>
<el-button @click="deleteBlog(blog.id)" type="danger"
>删除</el-button
>
</div>
</div>
</el-card>
</div>
<div style="display: flex">
<div style="flex-grow: 1"></div>
<el-pagination
class="pagination"
background
layout="prev, pager, next"
:hide-on-single-page="false"
:current-page="pageIndex"
:page-count="pageCount"
@update:current-page="changePage"
/>
<div style="flex-grow: 1"></div>
</div>
</div>
</template>
<style scoped>
.blog-container {
width: 100%;
}
.blog-card-container {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
.blog-card {
margin: 0 10px 10px 10px;
}
.blog-card-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.blog-card-header :hover {
cursor: pointer;
text-decoration: underline;
}
.blog-card-title {
font-size: x-large;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.blog-card-creater {
text-align: left;
font-size: small;
white-space: nowrap;
}
.blog-card-updater {
text-align: left;
font-size: small;
white-space: nowrap;
margin-right: 32px;
}
.blog-card-abstract {
font-size: medium;
padding-bottom: 20px;
}
.blog-card-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 20px;
border-top: 1px solid #ccc;
}
.blog-card-footer :hover {
cursor: pointer;
text-decoration: underline;
}
.pagination {
margin-bottom: 10px;
}
</style>

View File

@@ -35,6 +35,7 @@ function changeCustomCSS(cssText: string) {
<template>
<el-input
class="imput-line"
v-model="siteSetting.title"
placeholder="网站标题"
@change="changeSetting(siteSetting.keys.site.title, siteSetting.title)"
@@ -42,6 +43,7 @@ function changeCustomCSS(cssText: string) {
maxlength="10"
/>
<el-input
class="imput-line"
type="textarea"
show-word-limit
maxlength="1024"
@@ -50,6 +52,7 @@ function changeCustomCSS(cssText: string) {
@change="changeFooterHTML(siteSetting.footer)"
/>
<el-input
class="imput-line"
type="textarea"
autosize
v-model="siteSetting.css"
@@ -59,7 +62,7 @@ function changeCustomCSS(cssText: string) {
</template>
<style scoped>
.el-input {
.imput-line {
margin-bottom: 5px;
}
</style>

View File

@@ -10,9 +10,10 @@ import type {
IEditorConfig,
} from "@wangeditor/editor";
import { api, globalStore } from "@/api";
import type { BlogInfoResponseVO, BlogUpdateRequireVO } from "@/swagger";
import { ElMessage } from "element-plus";
import { api } from "@/api";
import type { BlogUpdateRequireVO } from "@/swagger";
import router from "@/router";
const editorRef = shallowRef();
@@ -24,7 +25,7 @@ const editBlog = reactive<BlogUpdateRequireVO>({
content: "",
tags: [],
});
let tags = ref<string>();
const tagInput = ref<string>("");
const blogID = parseInt(useRoute().params.id.toString());
onMounted(() => {
@@ -82,6 +83,29 @@ function cancelSave() {
router.push("/blog/" + blogID + "/read/");
}
function addTag() {
if (tagInput.value.length === 0) {
ElMessage({
type: "warning",
message: "请输入标签名称!",
});
return;
}
if (editBlog.tags.includes(tagInput.value)) {
ElMessage({
type: "warning",
message: "该博文已拥有相同的标签名称!",
});
return;
}
editBlog.tags.push(tagInput.value);
tagInput.value = "";
}
function removeTag(index: number) {
editBlog.tags.splice(index, 1);
}
function handleCreated(editor: IDomEditor) {
editorRef.value = editor; // 记录 editor 实例,重要!
}
@@ -122,11 +146,29 @@ function handleCreated(editor: IDomEditor) {
maxlength="512"
show-word-limit
type="textarea"
autosize
v-model="editBlog.abstracts"
/>
</el-form-item>
<el-form-item label="标签">
<el-input placeholder="用 '|' 隔开" v-model="tags" />
<el-form-item label="标签" style="display: flex">
<el-tag
style="margin-left: 5px"
v-for="(tag, index) in editBlog.tags"
:key="index"
closable
size="large"
@close="removeTag(index)"
>
{{ tag }}
</el-tag>
<div style="margin-left: 5px">
<el-input
style="margin: 0 5px 0 0; width: 100px"
v-model="tagInput"
/>
<el-button type="primary" @click="addTag">添加</el-button>
</div>
</el-form-item>
<el-form-item label="是否置顶">
<el-switch v-model="editBlog.top" />

View File

@@ -29,12 +29,7 @@ function deleteBlog() {
<el-container class="blog-container">
<el-header class="blog-header">
<el-row :gutter="20" style="height: 100%; padding: 0; margin: 0">
<el-col :span="4">
<div style="display: flex; width: 100% height: 100%">
<p>{{ blogInfo?.creator.nickname }}</p>
<div style="flex-grow: 1"></div>
</div>
</el-col>
<el-col :span="4"> </el-col>
<el-col :span="16">
<h1 class="blog-title">{{ blogInfo?.title }}</h1>
</el-col>
@@ -48,8 +43,8 @@ function deleteBlog() {
</el-row>
</el-header>
<el-main class="blog-main">
<el-scrollbar class="blog-content">
<div v-html="blogInfo?.content"></div>
<el-scrollbar class="blog-scrollbar">
<div class="blog-content" v-html="blogInfo?.content"></div>
</el-scrollbar>
</el-main>
</el-container>
@@ -69,24 +64,32 @@ function deleteBlog() {
margin: 0;
text-align: center;
width: 100%;
height: auto;
}
.blog-author {
font-size: x-large;
font-size: medium;
white-space: nowrap;
}
.blog-title {
font-size: x-large;
}
.blog-content {
height: 100%;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.blog-main {
width: 100%;
padding: 0;
}
.blog-scrollbar {
width: 100%;
}
.blog-content {
width: 100%;
overflow-x: hidden;
}
</style>

View File

@@ -53,13 +53,10 @@ function load() {
display: flex;
align-items: center;
justify-content: center;
/* height: 50px; */
background: var(--el-color-primary-light-9);
margin: 10px;
color: var(--el-color-primary);
}
.infinite-list .infinite-list-item + .list-item {
.infinite-list .infinite-list-item {
margin-top: 10px;
}
</style>

View File

@@ -34,31 +34,47 @@ const onSubmit = () => {
</script>
<template>
<el-card class="login-card">
<el-form :model="form" label-width="60px">
<el-form-item label="邮箱">
<el-input v-model="form.email" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="form.password" type="password" show-password />
</el-form-item>
<el-form-item>
<el-button class="login-button" type="primary" @click="onSubmit"
>登录</el-button
>
</el-form-item>
</el-form>
</el-card>
<div class="login-div">
<div style="flex-grow: 1"></div>
<el-card class="login-card">
<el-form :model="form" label-width="60px">
<h1 class="card-title"> </h1>
<el-form-item label="邮箱">
<el-input v-model="form.email" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="form.password" type="password" show-password />
</el-form-item>
<el-form-item>
<el-button class="login-button" type="primary" @click="onSubmit"
>登录</el-button
>
</el-form-item>
</el-form>
</el-card>
<div style="flex-grow: 1"></div>
</div>
</template>
<style scoped>
.login-div {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.login-card {
width: 480px;
margin: 0 auto;
max-width: 90%;
margin-bottom: 160px;
}
.card-title {
text-align: center;
margin-bottom: 32px;
padding-bottom: 12px;
border-bottom: 1px solid #ccc;
}
.login-button {

View File

@@ -3,14 +3,20 @@ import { onMounted, ref } from "vue";
import { globalStore } from "@/api";
import SiteManageComponent from "@/components/manage/SiteManageComponent.vue";
import BlogManageComponent from "@/components/manage/BlogManageComponent.vue";
const activeName = ref<string>("site");
onMounted(() => {
if (!globalStore.currentUserInfo?.id) {
location.pathname = "/";
console.log("not login!");
}
setTimeout(() => {
console.log("check current user info");
if (globalStore.currentUserInfo?.role === "ADMIN") {
console.log("current user is admin!");
} else {
location.pathname = "/";
console.warn("not admin user!");
}
}, 300);
});
</script>
@@ -19,7 +25,9 @@ onMounted(() => {
<el-tab-pane label="网站设置" name="site">
<SiteManageComponent />
</el-tab-pane>
<el-tab-pane label="博文设置" name="third">Role</el-tab-pane>
<el-tab-pane label="博文设置" name="third">
<BlogManageComponent />
</el-tab-pane>
<el-tab-pane label="用户设置" name="user">Config</el-tab-pane>
<el-tab-pane label="评论设置" name="test">Role</el-tab-pane>
</el-tabs>

View File

@@ -28,8 +28,10 @@ const onSubmit = () => {
<template>
<div class="register-div">
<el-card>
<div style="flex-grow: 1"></div>
<el-card class="register-card">
<el-form :model="form" label-width="60px">
<h1 class="card-title"> </h1>
<el-form-item label="邮箱">
<el-input v-model="form.email" />
</el-form-item>
@@ -46,17 +48,30 @@ const onSubmit = () => {
</el-form-item>
</el-form>
</el-card>
<div style="flex-grow: 1"></div>
</div>
</template>
<style scoped>
.register-div {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.el-card {
.register-card {
width: 480px;
margin: 0 auto;
max-width: 90%;
margin-bottom: 240px;
}
.card-title {
text-align: center;
margin-bottom: 32px;
padding-bottom: 12px;
border-bottom: 1px solid #ccc;
}
.register-button {