feat: 项目开发中...
This commit is contained in:
@@ -56,7 +56,8 @@ public class UserService implements IUserService {
|
|||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ResponseVO<UserInfoResponseVO> registerUser(@NotNull HttpServletRequest request, @NotNull UserCreateRequireVO requireVO) {
|
public @NotNull ResponseVO<UserInfoResponseVO> registerUser(@NotNull HttpServletRequest request,
|
||||||
|
@NotNull UserCreateRequireVO requireVO) {
|
||||||
UserEntity entity = userMapper.voToEntity(requireVO);
|
UserEntity entity = userMapper.voToEntity(requireVO);
|
||||||
entity.setEmail(entity.getEmail().toLowerCase());
|
entity.setEmail(entity.getEmail().toLowerCase());
|
||||||
|
|
||||||
@@ -77,7 +78,8 @@ public class UserService implements IUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ResponseVO<Void> loginUser(@NotNull HttpServletRequest request, @NotNull UserLoginRequireVO requireVO) {
|
public @NotNull ResponseVO<Void> loginUser(@NotNull HttpServletRequest request,
|
||||||
|
@NotNull UserLoginRequireVO requireVO) {
|
||||||
Authentication authenticate = authenticationManager.authenticate(
|
Authentication authenticate = authenticationManager.authenticate(
|
||||||
new UsernamePasswordAuthenticationToken(requireVO.getEmail(), requireVO.getPassword())
|
new UsernamePasswordAuthenticationToken(requireVO.getEmail(), requireVO.getPassword())
|
||||||
);
|
);
|
||||||
@@ -159,16 +161,19 @@ public class UserService implements IUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ResponseVO<PageableVO<BlogInfoResponseVO>> getUserBlogList(@NotNull UUID userID, @NotNull Pageable pageable) {
|
public @NotNull ResponseVO<PageableVO<BlogInfoResponseVO>> getUserBlogList(@NotNull UUID userID,
|
||||||
|
@NotNull Pageable pageable) {
|
||||||
return PageableVO.success(blogRepo.findByCreator_IdOrderByCreateTimeDesc(userID, pageable)
|
return PageableVO.success(blogRepo.findByCreator_IdOrderByCreateTimeDesc(userID, pageable)
|
||||||
.map(o -> blogMapper.entityToInfoVO(o))
|
.map(o -> blogMapper.entityToInfoVO(o))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull ResponseVO<PageableVO<AttachInfoResponseVO>> getUserAttachList(@NotNull UUID userID, @NotNull Pageable pageable) {
|
public @NotNull ResponseVO<PageableVO<AttachInfoResponseVO>> getUserAttachList(@NotNull UUID userID,
|
||||||
|
@NotNull Pageable pageable) {
|
||||||
return PageableVO.success(attachRepo.findByCreator_IdOrderByCreateTimeDesc(userID, pageable)
|
return PageableVO.success(attachRepo.findByCreator_IdOrderByCreateTimeDesc(userID, pageable)
|
||||||
.map(o -> attachMapper.entityToInfoVO(o))
|
.map(o -> attachMapper.entityToInfoVO(o))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -5,10 +5,23 @@ import { api, globalStore, siteSetting } from "@/api";
|
|||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { UserInfoResponseVORoleEnum } from "@/swagger";
|
import { UserInfoResponseVORoleEnum } from "@/swagger";
|
||||||
|
|
||||||
const menuIndex = ref<string>(document.location.pathname);
|
const menuIndex = ref<string>("/");
|
||||||
|
switch (document.location.pathname) {
|
||||||
|
case "/manage": {
|
||||||
|
menuIndex.value = "/manage";
|
||||||
|
}
|
||||||
|
case "/login": {
|
||||||
|
menuIndex.value = "/login";
|
||||||
|
}
|
||||||
|
case "/register": {
|
||||||
|
menuIndex.value = "/register";
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
menuIndex.value = "/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
menuIndex.value = document.location.pathname;
|
|
||||||
// 获取站点标题
|
// 获取站点标题
|
||||||
api.SettingController.getSettingContent(siteSetting.keys.site.title).then(
|
api.SettingController.getSettingContent(siteSetting.keys.site.title).then(
|
||||||
(response) => {
|
(response) => {
|
||||||
|
@@ -31,7 +31,7 @@ function loadPage(newPage: number) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadAttach(options: UploadRequestOptions) {
|
function createAttach(options: UploadRequestOptions) {
|
||||||
return api.AttachController.createAttachForm(options.file).then((resp) => {
|
return api.AttachController.createAttachForm(options.file).then((resp) => {
|
||||||
const vo = resp.data;
|
const vo = resp.data;
|
||||||
if (vo.code === 200) {
|
if (vo.code === 200) {
|
||||||
@@ -142,7 +142,7 @@ function deleteAttach(id: number) {
|
|||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
<p style="text-align: center; margin-top: 12px; margin-bottom: 12px">
|
<p style="text-align: center; margin-top: 12px; margin-bottom: 12px">
|
||||||
<el-upload :show-file-list="false" :http-request="uploadAttach">
|
<el-upload :show-file-list="false" :http-request="createAttach">
|
||||||
<el-button type="primary"> 上传新附件 </el-button>
|
<el-button type="primary"> 上传新附件 </el-button>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</p>
|
</p>
|
||||||
|
@@ -132,6 +132,11 @@ function loadPage(newPage: number) {
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
|
<p style="text-align: center; margin-bottom: 15px">
|
||||||
|
<el-button type="primary" @click="$router.push('/blog/create')">
|
||||||
|
发表博文
|
||||||
|
</el-button>
|
||||||
|
</p>
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
<div style="flex-grow: 1"></div>
|
<div style="flex-grow: 1"></div>
|
||||||
<el-pagination
|
<el-pagination
|
||||||
|
@@ -74,6 +74,7 @@ function changeCustomCSS(cssText: string) {
|
|||||||
.manage-container {
|
.manage-container {
|
||||||
margin-right: 32px;
|
margin-right: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.imput-line {
|
.imput-line {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
@@ -29,18 +29,29 @@ const router = createRouter({
|
|||||||
component: () => import("@/views/TagsView.vue"),
|
component: () => import("@/views/TagsView.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/blog/:id",
|
path: "/blog",
|
||||||
name: "blog",
|
name: "blog",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "read",
|
path: "create",
|
||||||
name: "read",
|
name: "create",
|
||||||
component: () => import("@/views/BlogReadView.vue"),
|
component: () => import("@/views/BlogCreateView.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "edit",
|
path: ":id",
|
||||||
name: "edit",
|
name: "blogID",
|
||||||
component: () => import("@/views/BlogEditView.vue"),
|
children: [
|
||||||
|
{
|
||||||
|
path: "read",
|
||||||
|
name: "read",
|
||||||
|
component: () => import("@/views/BlogReadView.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "edit",
|
||||||
|
name: "edit",
|
||||||
|
component: () => import("@/views/BlogEditView.vue"),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
175
blog-frontend/src/views/BlogCreateView.vue
Normal file
175
blog-frontend/src/views/BlogCreateView.vue
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref, shallowRef } from "vue";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
|
import "@wangeditor/editor/dist/css/style.css";
|
||||||
|
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
|
||||||
|
import type {
|
||||||
|
IDomEditor,
|
||||||
|
IToolbarConfig,
|
||||||
|
IEditorConfig,
|
||||||
|
} from "@wangeditor/editor";
|
||||||
|
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
import { api } from "@/api";
|
||||||
|
import type { BlogUpdateRequireVO } from "@/swagger";
|
||||||
|
import router from "@/router";
|
||||||
|
|
||||||
|
const editorRef = shallowRef();
|
||||||
|
const toolbarConfig: IToolbarConfig = {};
|
||||||
|
const editorConfig: IEditorConfig = {};
|
||||||
|
|
||||||
|
const editBlog = reactive<BlogUpdateRequireVO>({
|
||||||
|
title: "",
|
||||||
|
content: "在这里输入博文内容",
|
||||||
|
tags: [],
|
||||||
|
});
|
||||||
|
const tagInput = ref<string>("");
|
||||||
|
|
||||||
|
function saveBlog() {
|
||||||
|
api.BlogController.createBlog(editBlog).then((resp) => {
|
||||||
|
const vo = resp.data;
|
||||||
|
if (vo.code === 200) {
|
||||||
|
ElMessage({
|
||||||
|
type: "success",
|
||||||
|
message: "发表博文成功!",
|
||||||
|
});
|
||||||
|
console.log("create blog " + vo.content + " success!");
|
||||||
|
router.push("/blog/" + vo.content + "/read/");
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
type: "error",
|
||||||
|
message: "发表博文失败: " + vo.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelSave() {
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 实例,重要!
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-container class="edit-container">
|
||||||
|
<el-aside class="edit-content-side">
|
||||||
|
<div class="edit-content-toolbar">
|
||||||
|
<Toolbar
|
||||||
|
:editor="editorRef"
|
||||||
|
:defaultConfig="toolbarConfig"
|
||||||
|
mode="default"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<el-scrollbar class="edit-content-scrollbar">
|
||||||
|
<Editor
|
||||||
|
v-model="editBlog.content"
|
||||||
|
:defaultConfig="editorConfig"
|
||||||
|
mode="default"
|
||||||
|
@onCreated="handleCreated"
|
||||||
|
/>
|
||||||
|
</el-scrollbar>
|
||||||
|
</el-aside>
|
||||||
|
<el-main class="edit-form-side">
|
||||||
|
<el-form :model="editBlog">
|
||||||
|
<el-form-item label="博文标题">
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入博文标题"
|
||||||
|
maxlength="128"
|
||||||
|
show-word-limit
|
||||||
|
v-model="editBlog.title"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="博文摘要">
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入博文摘要"
|
||||||
|
maxlength="1024"
|
||||||
|
show-word-limit
|
||||||
|
type="textarea"
|
||||||
|
autosize
|
||||||
|
v-model="editBlog.abstracts"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<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
|
||||||
|
placeholder="输入新标签"
|
||||||
|
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" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否公开">
|
||||||
|
<el-switch v-model="editBlog.publish" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="saveBlog">保存</el-button>
|
||||||
|
<el-button @click="cancelSave">取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.edit-container {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0 20px 0 20px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-content-side {
|
||||||
|
height: 100%;
|
||||||
|
width: 61.8%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 1px 0 1px;
|
||||||
|
border-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-content-toolbar {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
</style>
|
@@ -133,7 +133,7 @@ function handleCreated(editor: IDomEditor) {
|
|||||||
<el-form :model="editBlog">
|
<el-form :model="editBlog">
|
||||||
<el-form-item label="博文标题">
|
<el-form-item label="博文标题">
|
||||||
<el-input
|
<el-input
|
||||||
placeholder="博文标题"
|
placeholder="请输入博文标题"
|
||||||
maxlength="128"
|
maxlength="128"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
v-model="editBlog.title"
|
v-model="editBlog.title"
|
||||||
@@ -141,7 +141,7 @@ function handleCreated(editor: IDomEditor) {
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="博文摘要">
|
<el-form-item label="博文摘要">
|
||||||
<el-input
|
<el-input
|
||||||
placeholder="博文摘要"
|
placeholder="请输入博文摘要"
|
||||||
maxlength="1024"
|
maxlength="1024"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
type="textarea"
|
type="textarea"
|
||||||
@@ -163,6 +163,7 @@ function handleCreated(editor: IDomEditor) {
|
|||||||
|
|
||||||
<div style="margin-left: 5px">
|
<div style="margin-left: 5px">
|
||||||
<el-input
|
<el-input
|
||||||
|
placeholder="输入新标签"
|
||||||
style="margin: 0 5px 0 0; width: 100px"
|
style="margin: 0 5px 0 0; width: 100px"
|
||||||
v-model="tagInput"
|
v-model="tagInput"
|
||||||
/>
|
/>
|
||||||
|
@@ -109,8 +109,7 @@ function deleteBlog() {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog-content > p,
|
.blog-content img {
|
||||||
img {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user