feat: topic reply
This commit is contained in:
parent
3cff276230
commit
0b77abf35a
|
@ -8,6 +8,9 @@ import { IDomEditor } from '@wangeditor/editor'
|
||||||
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue'
|
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue'
|
||||||
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||||
|
|
||||||
|
const props = defineProps(['height'])
|
||||||
|
const editorHeight = `height: ${props.height}px`
|
||||||
|
|
||||||
const editorRef = shallowRef<IDomEditor | undefined>(undefined)
|
const editorRef = shallowRef<IDomEditor | undefined>(undefined)
|
||||||
|
|
||||||
const valueHtml = ref('<p>hello</p>')
|
const valueHtml = ref('<p>hello</p>')
|
||||||
|
@ -19,9 +22,6 @@ const editorConfig = {
|
||||||
MENU_CONF: {
|
MENU_CONF: {
|
||||||
uploadImage: {
|
uploadImage: {
|
||||||
server: 'http://127.0.0.1:10007/upload/img',
|
server: 'http://127.0.0.1:10007/upload/img',
|
||||||
// server: '/api/upload-img-10s', // test timeout
|
|
||||||
// server: '/api/upload-img-failed', // test failed
|
|
||||||
// server: '/api/xxx', // test 404
|
|
||||||
|
|
||||||
timeout: 5 * 1000, // 5s
|
timeout: 5 * 1000, // 5s
|
||||||
|
|
||||||
|
@ -33,27 +33,6 @@ const editorConfig = {
|
||||||
maxFileSize: 10 * 1024 * 1024, // 10M
|
maxFileSize: 10 * 1024 * 1024, // 10M
|
||||||
|
|
||||||
base64LimitSize: 5 * 1024, // insert base64 format, if file's size less than 5kb
|
base64LimitSize: 5 * 1024, // insert base64 format, if file's size less than 5kb
|
||||||
|
|
||||||
// onBeforeUpload(file) {
|
|
||||||
// console.log('onBeforeUpload', file)
|
|
||||||
|
|
||||||
// return file // will upload this file
|
|
||||||
// // return false // prevent upload
|
|
||||||
// },
|
|
||||||
// onProgress(progress) {
|
|
||||||
// console.log('onProgress', progress)
|
|
||||||
// },
|
|
||||||
// onSuccess(file, res) {
|
|
||||||
// console.log('onSuccess', file, res)
|
|
||||||
// },
|
|
||||||
// onFailed(file, res) {
|
|
||||||
// alert(res.message)
|
|
||||||
// console.log('onFailed', file, res)
|
|
||||||
// },
|
|
||||||
// onError(file, err, res) {
|
|
||||||
// alert(err.message)
|
|
||||||
// console.error('onError', file, err, res)
|
|
||||||
// },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -82,7 +61,7 @@ onBeforeUnmount(() => {
|
||||||
<div class="editor—wrapper">
|
<div class="editor—wrapper">
|
||||||
<Toolbar class="toolbar-container" :editor="editorRef" />
|
<Toolbar class="toolbar-container" :editor="editorRef" />
|
||||||
<Editor
|
<Editor
|
||||||
style="height: 400px"
|
:style="editorHeight"
|
||||||
v-model="valueHtml"
|
v-model="valueHtml"
|
||||||
:defaultConfig="editorConfig"
|
:defaultConfig="editorConfig"
|
||||||
@onCreated="handleCreated"
|
@onCreated="handleCreated"
|
||||||
|
|
|
@ -97,7 +97,6 @@ const handelCloseSettingsPanel = () => {
|
||||||
display: flex;
|
display: flex;
|
||||||
color: var(--kungalgame-font-color-3);
|
color: var(--kungalgame-font-color-3);
|
||||||
border: 1px solid var(--kungalgame-blue-1);
|
border: 1px solid var(--kungalgame-blue-1);
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -3,12 +3,29 @@
|
||||||
// 导入动画
|
// 导入动画
|
||||||
import 'animate.css'
|
import 'animate.css'
|
||||||
|
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
|
|
||||||
import { currBackground } from '@/hooks/useBackgroundPicture'
|
import { currBackground } from '@/hooks/useBackgroundPicture'
|
||||||
|
|
||||||
import KUNGalgameTopBar from '@/components/TopBar/KUNGalgameTopBar.vue'
|
import KUNGalgameTopBar from '@/components/TopBar/KUNGalgameTopBar.vue'
|
||||||
|
|
||||||
|
// 导入帖子页面 store
|
||||||
|
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
|
// 异步导入帖子页回复面板,提升首页加载速度
|
||||||
|
const ReplyPanel = defineAsyncComponent(
|
||||||
|
() => import('@/views/topic/content/components/ReplyPanel.vue')
|
||||||
|
)
|
||||||
|
|
||||||
|
// 使用帖子页面的 store
|
||||||
|
const settingsStore = useKUNGalgameTopicStore()
|
||||||
|
const { isEdit } = storeToRefs(settingsStore)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<!-- 回复面板组件 -->
|
||||||
|
<ReplyPanel :isReply="!isEdit" v-if="isEdit" />
|
||||||
<!-- #default 是 v-slot 的简写,route 就是路由,Component 是一个 v-node -->
|
<!-- #default 是 v-slot 的简写,route 就是路由,Component 是一个 v-node -->
|
||||||
<div class="app" :style="{ backgroundImage: currBackground }">
|
<div class="app" :style="{ backgroundImage: currBackground }">
|
||||||
<div class="top-bar">
|
<div class="top-bar">
|
||||||
|
|
29
src/store/modules/topic.ts
Normal file
29
src/store/modules/topic.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* 帖子详情的 store */
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
interface Tag {
|
||||||
|
index: number
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Topic {
|
||||||
|
// 是否正在被编辑
|
||||||
|
isEdit: boolean
|
||||||
|
// 帖子标题
|
||||||
|
title: string
|
||||||
|
// 帖子内容
|
||||||
|
article: string
|
||||||
|
// 帖子标签
|
||||||
|
tags: Tag[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useKUNGalgameTopicStore = defineStore({
|
||||||
|
id: 'topic',
|
||||||
|
persist: true,
|
||||||
|
state: (): Topic => ({
|
||||||
|
isEdit: false,
|
||||||
|
title: '',
|
||||||
|
article: '',
|
||||||
|
tags: [],
|
||||||
|
}),
|
||||||
|
})
|
|
@ -39,7 +39,7 @@ const submit = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 编辑器 -->
|
<!-- 编辑器 -->
|
||||||
<WangEditor class="editor" />
|
<WangEditor class="editor" :height="400" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 内容区的底部 -->
|
<!-- 内容区的底部 -->
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useKUNGalgameMessageStore } from '@/store/modules/message'
|
import { useKUNGalgameMessageStore } from '@/store/modules/message'
|
||||||
|
|
||||||
|
// 导入帖子分区选择
|
||||||
|
import Partition from './Partition.vue'
|
||||||
|
|
||||||
const info = useKUNGalgameMessageStore()
|
const info = useKUNGalgameMessageStore()
|
||||||
|
|
||||||
import { button } from './button'
|
import { button } from './button'
|
||||||
|
@ -29,21 +32,7 @@ const handleSave = () => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 话题分类的容器 -->
|
<!-- 话题分类的容器 -->
|
||||||
<div class="topic-group">
|
<Partition />
|
||||||
<div>点击选择帖子的分区(可多选):</div>
|
|
||||||
<!-- 分类容器的按钮集合 -->
|
|
||||||
<div class="group-btn" :class="buttonStatus ? 'selected-btn' : ''">
|
|
||||||
<span
|
|
||||||
class="btn"
|
|
||||||
v-for="kun in button"
|
|
||||||
:key="kun.index"
|
|
||||||
@click="kun.isActive.value = !kun.isActive.value"
|
|
||||||
:class="{ active: kun.isActive.value }"
|
|
||||||
>
|
|
||||||
{{ kun.name }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 按钮的容器 -->
|
<!-- 按钮的容器 -->
|
||||||
<div class="btn-container">
|
<div class="btn-container">
|
||||||
<!-- 确认按钮 -->
|
<!-- 确认按钮 -->
|
||||||
|
@ -56,31 +45,6 @@ const handleSave = () => {
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
/* 话题分类的容器 */
|
|
||||||
.topic-group {
|
|
||||||
width: 100%;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
/* 分类容器的按钮集合 */
|
|
||||||
.group-btn {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
/* 单个按钮的样式 */
|
|
||||||
.btn {
|
|
||||||
height: 30px;
|
|
||||||
width: 20%;
|
|
||||||
font-size: 17px;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid var(--kungalgame-blue-1);
|
|
||||||
background-color: var(--kungalgame-trans-blue-0);
|
|
||||||
color: var(--kungalgame-blue-4);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
/* 按钮的容器 */
|
/* 按钮的容器 */
|
||||||
.btn-container {
|
.btn-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -127,11 +91,4 @@ const handleSave = () => {
|
||||||
background-color: var(--kungalgame-pink-3);
|
background-color: var(--kungalgame-pink-3);
|
||||||
transform: scale(0.8);
|
transform: scale(0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 被选中按钮的样式 */
|
|
||||||
.active {
|
|
||||||
transition: 0.2s;
|
|
||||||
background-color: var(--kungalgame-blue-4);
|
|
||||||
color: var(--kungalgame-white);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
61
src/views/edit/components/Partition.vue
Normal file
61
src/views/edit/components/Partition.vue
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { button } from './button'
|
||||||
|
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const buttonStatus = ref(false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<!-- 话题分类的容器 -->
|
||||||
|
<div class="topic-group">
|
||||||
|
<div>点击选择帖子的分区(可多选):</div>
|
||||||
|
<!-- 分类容器的按钮集合 -->
|
||||||
|
<div class="group-btn" :class="buttonStatus ? 'selected-btn' : ''">
|
||||||
|
<span
|
||||||
|
class="btn"
|
||||||
|
v-for="kun in button"
|
||||||
|
:key="kun.index"
|
||||||
|
@click="kun.isActive.value = !kun.isActive.value"
|
||||||
|
:class="{ active: kun.isActive.value }"
|
||||||
|
>
|
||||||
|
{{ kun.name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
/* 话题分类的容器 */
|
||||||
|
.topic-group {
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
/* 分类容器的按钮集合 */
|
||||||
|
.group-btn {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
/* 单个按钮的样式 */
|
||||||
|
.btn {
|
||||||
|
height: 30px;
|
||||||
|
width: 20%;
|
||||||
|
font-size: 17px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid var(--kungalgame-blue-1);
|
||||||
|
background-color: var(--kungalgame-trans-blue-0);
|
||||||
|
color: var(--kungalgame-blue-4);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 被选中按钮的样式 */
|
||||||
|
.active {
|
||||||
|
transition: 0.2s;
|
||||||
|
background-color: var(--kungalgame-blue-4);
|
||||||
|
color: var(--kungalgame-white);
|
||||||
|
}
|
||||||
|
</style>
|
47
src/views/topic/content/components/ReplyPanel.vue
Normal file
47
src/views/topic/content/components/ReplyPanel.vue
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Tags from '@/views/edit/components/Tags.vue'
|
||||||
|
import Button from '@/views/edit/components/Button.vue'
|
||||||
|
import WangEditor from '@/components/WangEditor.vue'
|
||||||
|
|
||||||
|
const props = defineProps(['isReply'])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Teleport to="body" :disabled="props.isReply">
|
||||||
|
<div class="root">
|
||||||
|
<div class="container">
|
||||||
|
<!-- 回复面板回复给谁 -->
|
||||||
|
<div class="title">回复给@啊这可海星(楼主)</div>
|
||||||
|
<!-- 回复的编辑器 -->
|
||||||
|
<div class="content">
|
||||||
|
<WangEditor :height="200" />
|
||||||
|
</div>
|
||||||
|
<!-- 回复的页脚 -->
|
||||||
|
<div class="footer">
|
||||||
|
<Tags style="margin-top: 10px" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.root {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
opacity: 0.92;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 77%;
|
||||||
|
color: var(--kungalgame-font-color-3);
|
||||||
|
background-color: var(--kungalgame-white);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid var(--kungalgame-blue-4);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -3,10 +3,24 @@
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
// 引入流光环绕的特效
|
// 引入流光环绕的特效
|
||||||
import '@/styles/effect/effect.scss'
|
import '@/styles/effect/effect.scss'
|
||||||
|
|
||||||
|
// 导入帖子页面 store
|
||||||
|
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
|
||||||
|
|
||||||
|
// 使用帖子页面的 store
|
||||||
|
const settingsStore = useKUNGalgameTopicStore()
|
||||||
|
const { isEdit } = storeToRefs(settingsStore)
|
||||||
|
|
||||||
// 接受父组件的传值
|
// 接受父组件的传值
|
||||||
const props = defineProps(['isOthersTopic'])
|
const props = defineProps(['isOthersTopic'])
|
||||||
|
|
||||||
const isOthersTopic = props.isOthersTopic
|
const isOthersTopic = props.isOthersTopic
|
||||||
|
|
||||||
|
const handelReply = () => {
|
||||||
|
isEdit.value = !isEdit.value
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -37,7 +51,7 @@ const isOthersTopic = props.isOthersTopic
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<!-- 对所有此类元素应用样式 -->
|
<!-- 对所有此类元素应用样式 -->
|
||||||
<div class="kungalgame-comet-surround">
|
<div class="kungalgame-comet-surround" @click="handelReply">
|
||||||
<span></span>
|
<span></span>
|
||||||
<span></span>
|
<span></span>
|
||||||
<span></span>
|
<span></span>
|
||||||
|
|
Loading…
Reference in a new issue