完成帖子详情前端部分
This commit is contained in:
parent
cc4eb03592
commit
506dadb784
@ -19,7 +19,7 @@ public class TopicDetailVO {
|
|||||||
String username;
|
String username;
|
||||||
String avatar;
|
String avatar;
|
||||||
String desc;
|
String desc;
|
||||||
boolean gender;
|
Integer gender;
|
||||||
String qq;
|
String qq;
|
||||||
String wx;
|
String wx;
|
||||||
String phone;
|
String phone;
|
||||||
|
9
my-project-frontend/package-lock.json
generated
9
my-project-frontend/package-lock.json
generated
@ -14,6 +14,7 @@
|
|||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"element-plus": "^2.3.9",
|
"element-plus": "^2.3.9",
|
||||||
"pinia": "^2.1.6",
|
"pinia": "^2.1.6",
|
||||||
|
"quill-delta-to-html": "^0.12.1",
|
||||||
"quill-image-resize-vue": "^1.0.4",
|
"quill-image-resize-vue": "^1.0.4",
|
||||||
"quill-image-super-solution-module": "^2.0.1",
|
"quill-image-super-solution-module": "^2.0.1",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
@ -1827,6 +1828,14 @@
|
|||||||
"lodash.isequal": "^4.5.0"
|
"lodash.isequal": "^4.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/quill-delta-to-html": {
|
||||||
|
"version": "0.12.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/quill-delta-to-html/-/quill-delta-to-html-0.12.1.tgz",
|
||||||
|
"integrity": "sha512-QhpeMk9+5ge3HYbL5A0Ewz3pXCsbemqGvIF/kw5D6D4V68AtcUp7yt9xNUkzOk/0IQz43hKy3IkzBzRhLIE+oA==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash.isequal": "^4.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/quill-image-resize-vue": {
|
"node_modules/quill-image-resize-vue": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmmirror.com/quill-image-resize-vue/-/quill-image-resize-vue-1.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/quill-image-resize-vue/-/quill-image-resize-vue-1.0.4.tgz",
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"element-plus": "^2.3.9",
|
"element-plus": "^2.3.9",
|
||||||
"pinia": "^2.1.6",
|
"pinia": "^2.1.6",
|
||||||
|
"quill-delta-to-html": "^0.12.1",
|
||||||
"quill-image-resize-vue": "^1.0.4",
|
"quill-image-resize-vue": "^1.0.4",
|
||||||
"quill-image-super-solution-module": "^2.0.1",
|
"quill-image-super-solution-module": "^2.0.1",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
|
31
my-project-frontend/src/components/TopicTag.vue
Normal file
31
my-project-frontend/src/components/TopicTag.vue
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<script setup>
|
||||||
|
import {useStore} from "@/store";
|
||||||
|
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
type: Number
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="topic-type"
|
||||||
|
:style="{
|
||||||
|
color: store.findTypeById(type)?.color + 'EE',
|
||||||
|
'border-color': store.findTypeById(type)?.color + '77',
|
||||||
|
'background': store.findTypeById(type)?.color + '33'
|
||||||
|
}">
|
||||||
|
{{store.findTypeById(type)?.name}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.topic-type {
|
||||||
|
display: inline-block;
|
||||||
|
border: solid 0.5px grey;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0 5px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -27,6 +27,11 @@ const router = createRouter({
|
|||||||
path: '/index',
|
path: '/index',
|
||||||
name: 'index',
|
name: 'index',
|
||||||
component: () => import('@/views/IndexView.vue'),
|
component: () => import('@/views/IndexView.vue'),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
name: 'topics',
|
||||||
|
component: () => import('@/views/forum/Forum.vue'),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
@ -36,6 +41,8 @@ const router = createRouter({
|
|||||||
path: 'topic-detail/:tid',
|
path: 'topic-detail/:tid',
|
||||||
name: 'topic-detail',
|
name: 'topic-detail',
|
||||||
component: () => import('@/views/forum/TopicDetail.vue')
|
component: () => import('@/views/forum/TopicDetail.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
}, {
|
}, {
|
||||||
path: 'user-setting',
|
path: 'user-setting',
|
||||||
name: 'user-setting',
|
name: 'user-setting',
|
||||||
|
23
my-project-frontend/src/views/forum/Forum.vue
Normal file
23
my-project-frontend/src/views/forum/Forum.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script setup>
|
||||||
|
import {get} from "@/net";
|
||||||
|
import {useStore} from "@/store";
|
||||||
|
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
|
get('/api/forum/types', data => {
|
||||||
|
const array = []
|
||||||
|
array.push({name: '全部', id: 0, color: 'linear-gradient(45deg, white, red, orange, gold, green, blue)'})
|
||||||
|
data.forEach(d => array.push(d))
|
||||||
|
store.forum.types = array
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<router-view v-slot="{ Component }">
|
||||||
|
<transition name="el-fade-in-linear" mode="out-in">
|
||||||
|
<keep-alive include="TopicList">
|
||||||
|
<component :is="Component"/>
|
||||||
|
</keep-alive>
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
|
</template>
|
@ -1,20 +1,114 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {useRoute} from "vue-router";
|
import {useRoute} from "vue-router";
|
||||||
import {get} from "@/net";
|
import {get} from "@/net";
|
||||||
|
import axios from "axios";
|
||||||
|
import {computed, reactive} from "vue";
|
||||||
|
import {ArrowLeft, Female, Male} from "@element-plus/icons-vue";
|
||||||
|
import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html';
|
||||||
|
import Card from "@/components/Card.vue";
|
||||||
|
import router from "@/router";
|
||||||
|
import TopicTag from "@/components/TopicTag.vue";
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const tid = route.params.tid
|
const tid = route.params.tid
|
||||||
|
|
||||||
get(`api/forum/topic?tid=${tid}`, data => {
|
const topic = reactive({
|
||||||
console.info(data)
|
data: null,
|
||||||
|
comments: []
|
||||||
|
})
|
||||||
|
|
||||||
|
get(`api/forum/topic?tid=${tid}`, data => topic.data = data)
|
||||||
|
|
||||||
|
const content = computed(() => {
|
||||||
|
const ops = JSON.parse(topic.data.content).ops
|
||||||
|
const converter = new QuillDeltaToHtmlConverter(ops, { inlineStyles: true });
|
||||||
|
return converter.convert();
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<div class="topic-page" v-if="topic.data">
|
||||||
|
<div class="topic-main" style="position: sticky;top: 0;z-index: 10">
|
||||||
|
<card style="display: flex;width: 100%;">
|
||||||
|
<el-button :icon="ArrowLeft" type="info" size="small"
|
||||||
|
plain round @click="router.push('/index')">返回列表</el-button>
|
||||||
|
<div style="text-align: center;flex: 1">
|
||||||
|
<topic-tag :type="topic.data.type"/>
|
||||||
|
<span style="font-weight: bold;margin-left: 5px">{{topic.data.title}}</span>
|
||||||
|
</div>
|
||||||
|
</card>
|
||||||
|
</div>
|
||||||
|
<div class="topic-main">
|
||||||
|
<div class="topic-main-left">
|
||||||
|
<el-avatar :src="axios.defaults.baseURL + '/images' + topic.data.user.avatar" :size="60"/>
|
||||||
|
<div>
|
||||||
|
<div style="font-size: 18px;font-weight: bold">
|
||||||
|
{{topic.data.user.username}}
|
||||||
|
<span style="color: hotpink" v-if="topic.data.user.gender === 1">
|
||||||
|
<el-icon><Female/></el-icon>
|
||||||
|
</span>
|
||||||
|
<span style="color: dodgerblue" v-if="topic.data.user.gender === 0">
|
||||||
|
<el-icon><Male/></el-icon>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="desc">{{topic.data.user.email}}</div>
|
||||||
|
</div>
|
||||||
|
<el-divider style="margin: 10px 0"/>
|
||||||
|
<div style="text-align: left;margin: 0 5px">
|
||||||
|
<div class="desc">微信号: {{topic.data.user.wx || '已隐藏或未填写'}}</div>
|
||||||
|
<div class="desc">QQ号: {{topic.data.user.qq || '已隐藏或未填写'}}</div>
|
||||||
|
<div class="desc">手机号: {{topic.data.user.phone || '已隐藏或未填写'}}</div>
|
||||||
|
</div>
|
||||||
|
<el-divider style="margin: 10px 0"/>
|
||||||
|
<div class="desc" style="margin: 0 5px">{{topic.data.user.desc}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="topic-main-right">
|
||||||
|
<div class="topic-content" v-html="content"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.topic-page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topic-main {
|
||||||
|
display: flex;
|
||||||
|
border-radius: 7px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background-color: var(--el-bg-color);
|
||||||
|
width: 800px;
|
||||||
|
|
||||||
|
.topic-main-left {
|
||||||
|
width: 200px;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
border-right: solid 1px var(--el-border-color);
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
font-size: 12px;
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.topic-main-right {
|
||||||
|
width: 600px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
|
||||||
|
.topic-content {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -21,6 +21,7 @@ import {useStore} from "@/store";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import ColorDot from "@/components/ColorDot.vue";
|
import ColorDot from "@/components/ColorDot.vue";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
|
import TopicTag from "@/components/TopicTag.vue";
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
@ -45,12 +46,6 @@ const today = computed(() => {
|
|||||||
const date = new Date()
|
const date = new Date()
|
||||||
return `${date.getFullYear()} 年 ${date.getMonth() + 1} 月 ${date.getDate()} 日`
|
return `${date.getFullYear()} 年 ${date.getMonth() + 1} 月 ${date.getDate()} 日`
|
||||||
})
|
})
|
||||||
get('/api/forum/types', data => {
|
|
||||||
const array = []
|
|
||||||
array.push({name: '全部', id: 0, color: 'linear-gradient(45deg, white, red, orange, gold, green, blue)'})
|
|
||||||
data.forEach(d => array.push(d))
|
|
||||||
store.forum.types = array
|
|
||||||
})
|
|
||||||
get('/api/forum/top-topic', data => topics.top = data)
|
get('/api/forum/top-topic', data => topics.top = data)
|
||||||
function updateList(){
|
function updateList(){
|
||||||
if(topics.end) return
|
if(topics.end) return
|
||||||
@ -112,7 +107,7 @@ navigator.geolocation.getCurrentPosition(position => {
|
|||||||
</div>
|
</div>
|
||||||
</light-card>
|
</light-card>
|
||||||
<light-card style="margin-top: 10px;display: flex;flex-direction: column;gap: 10px">
|
<light-card style="margin-top: 10px;display: flex;flex-direction: column;gap: 10px">
|
||||||
<div v-for="item in topics.top" class="top-topic">
|
<div v-for="item in topics.top" class="top-topic" @click="router.push(`/index/topic-detail/${item.id}`)">
|
||||||
<el-tag type="info" size="small">置顶</el-tag>
|
<el-tag type="info" size="small">置顶</el-tag>
|
||||||
<div>{{item.title}}</div>
|
<div>{{item.title}}</div>
|
||||||
<div>{{new Date(item.time).toLocaleDateString()}}</div>
|
<div>{{new Date(item.time).toLocaleDateString()}}</div>
|
||||||
@ -147,14 +142,7 @@ navigator.geolocation.getCurrentPosition(position => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 5px">
|
<div style="margin-top: 5px">
|
||||||
<div class="topic-type"
|
<topic-tag :type="item.type"/>
|
||||||
:style="{
|
|
||||||
color: store.findTypeById(item.type)?.color + 'EE',
|
|
||||||
'border-color': store.findTypeById(item.type)?.color + '77',
|
|
||||||
'background': store.findTypeById(item.type)?.color + '33'
|
|
||||||
}">
|
|
||||||
{{store.findTypeById(item.type)?.name}}
|
|
||||||
</div>
|
|
||||||
<span style="font-weight: bold;margin-left: 7px">{{item.title}}</span>
|
<span style="font-weight: bold;margin-left: 7px">{{item.title}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="topic-content">{{item.text}}</div>
|
<div class="topic-content">{{item.text}}</div>
|
||||||
@ -285,15 +273,6 @@ navigator.geolocation.getCurrentPosition(position => {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topic-type {
|
|
||||||
display: inline-block;
|
|
||||||
border: solid 0.5px grey;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 0 5px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topic-image {
|
.topic-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user