feat: rewrite topic
This commit is contained in:
parent
7a8e11a5f2
commit
3ba1e92c44
|
@ -1,10 +1,11 @@
|
|||
import { fetchPost, fetchGet } from '@/utils/request'
|
||||
import { fetchPost, fetchGet, fetchPut } from '@/utils/request'
|
||||
import type * as Edit from './types/edit'
|
||||
// 将对象转为请求参数的函数
|
||||
import objectToQueryParams from '@/utils/objectToQueryParams'
|
||||
|
||||
const editURLs = {
|
||||
create: `/edit/topic`,
|
||||
createTopic: `/edit/topic`,
|
||||
updateTopic: `/edit/topic`,
|
||||
hotTags: `/tag/popular`,
|
||||
}
|
||||
|
||||
|
@ -14,7 +15,7 @@ export async function postEditNewTopicApi(
|
|||
): Promise<Edit.EditCreateTopicResponseData> {
|
||||
// 调用 fetchPost 函数
|
||||
const response = await fetchPost<Edit.EditCreateTopicResponseData>(
|
||||
editURLs.create,
|
||||
editURLs.createTopic,
|
||||
newTopicData
|
||||
)
|
||||
|
||||
|
@ -22,6 +23,18 @@ export async function postEditNewTopicApi(
|
|||
return response
|
||||
}
|
||||
|
||||
// 更新话题
|
||||
export async function updateEditNewTopicApi(
|
||||
requestData: Edit.EditUpdateTopicRequestData
|
||||
): Promise<Edit.EditUpdateTopicResponseData> {
|
||||
// 调用 fetchPost 函数
|
||||
const response = await fetchPut<Edit.EditUpdateTopicResponseData>(
|
||||
editURLs.updateTopic,
|
||||
requestData
|
||||
)
|
||||
return response
|
||||
}
|
||||
|
||||
// 获取 10 个热门 tag
|
||||
export async function getTopTagsApi(
|
||||
requestData: Edit.EditGetHotTagsRequestData
|
||||
|
|
|
@ -4,7 +4,6 @@ export interface EditCreateTopicRequestData {
|
|||
time: number
|
||||
tags: Array<string>
|
||||
category: Array<string>
|
||||
uid: number
|
||||
}
|
||||
|
||||
export interface EditKUNGalgameTopic {
|
||||
|
@ -28,6 +27,15 @@ export interface EditKUNGalgameTopic {
|
|||
// edited: number
|
||||
}
|
||||
|
||||
// 更新话题的请求数据格式
|
||||
export interface EditUpdateTopicRequestData {
|
||||
tid: number
|
||||
title: string
|
||||
content: string
|
||||
tags: string[]
|
||||
category: string[]
|
||||
}
|
||||
|
||||
// 获取热门 tag 的请求数据格式
|
||||
export interface EditGetHotTagsRequestData {
|
||||
limit: number
|
||||
|
@ -37,5 +45,8 @@ export interface EditGetHotTagsRequestData {
|
|||
export type EditCreateTopicResponseData =
|
||||
KUNGalgameResponseData<EditKUNGalgameTopic>
|
||||
|
||||
// 更新话题响应数据的格式
|
||||
export type EditUpdateTopicResponseData = KUNGalgameResponseData<{}>
|
||||
|
||||
// 热门 tag 的返回数据格式
|
||||
export type EditGetHotTagsResponseData = KUNGalgameResponseData<string[]>
|
||||
|
|
|
@ -28,6 +28,7 @@ export interface TopicDetail {
|
|||
rid: number[]
|
||||
status: number
|
||||
share: number[]
|
||||
category: string[]
|
||||
}
|
||||
|
||||
// 更新话题的请求数据
|
||||
|
|
|
@ -32,8 +32,15 @@ import DOMPurify from 'dompurify'
|
|||
import { debounce } from '@/utils/debounce'
|
||||
|
||||
// 话题编辑界面 store
|
||||
const { editorHeight, mode, theme, textCount, isSaveTopic, content } =
|
||||
storeToRefs(useKUNGalgameEditStore())
|
||||
const {
|
||||
editorHeight,
|
||||
mode,
|
||||
theme,
|
||||
textCount,
|
||||
isSaveTopic,
|
||||
content,
|
||||
topicRewrite,
|
||||
} = storeToRefs(useKUNGalgameEditStore())
|
||||
// 话题界面的 store,用于回复
|
||||
const { replyDraft } = storeToRefs(useKUNGalgameTopicStore())
|
||||
|
||||
|
@ -83,14 +90,27 @@ const isShowEditorToolbar = computed(() =>
|
|||
)
|
||||
|
||||
onBeforeMount(() => {
|
||||
/**
|
||||
* 编辑器处于编辑界面
|
||||
*/
|
||||
// 挂载之前载入话题数据,如果不保存,则不载入(并且当前必须在 Edit 界面)
|
||||
if (isSaveTopic.value && routeName.value === 'Edit') {
|
||||
valueHtml.value = content.value
|
||||
}
|
||||
/**
|
||||
* 编辑器处于回复界面
|
||||
*/
|
||||
// 挂载之前载入回复数据,如果不保存,则不载入(并且当前必须在 topic 界面)
|
||||
if (replyDraft.value.isSaveReply && routeName.value === 'Topic') {
|
||||
valueHtml.value = replyDraft.value.content
|
||||
}
|
||||
/**
|
||||
* 编辑器处于重新编辑的编辑界面
|
||||
*/
|
||||
// 挂载之前载入重新编辑话题的数据
|
||||
if (topicRewrite.value.isTopicRewriting && routeName.value === 'Edit') {
|
||||
valueHtml.value = topicRewrite.value.content
|
||||
}
|
||||
})
|
||||
|
||||
// 编辑器文本改变时自动保存数据
|
||||
|
@ -99,14 +119,27 @@ const handleTextChange = async () => {
|
|||
const purifiedHtml = DOMPurify.sanitize(editorRef.value?.getHTML())
|
||||
// 创建一个防抖处理函数
|
||||
const debouncedUpdateContent = debounce(() => {
|
||||
/**
|
||||
* 编辑器处于编辑界面
|
||||
*/
|
||||
// 如果是在 topic 界面则保存到回复的 store
|
||||
if (routeName.value === 'Topic') {
|
||||
replyDraft.value.content = purifiedHtml
|
||||
}
|
||||
/**
|
||||
* 编辑器处于回复界面
|
||||
*/
|
||||
// 否则保存在 edit 界面的 store
|
||||
if (routeName.value === 'Edit') {
|
||||
if (!topicRewrite.value.isTopicRewriting && routeName.value === 'Edit') {
|
||||
content.value = purifiedHtml
|
||||
}
|
||||
/**
|
||||
* 编辑器处于重新编辑的编辑界面
|
||||
*/
|
||||
// 挂载之前载入重新编辑话题的数据
|
||||
if (topicRewrite.value.isTopicRewriting && routeName.value === 'Edit') {
|
||||
topicRewrite.value.content = purifiedHtml
|
||||
}
|
||||
}, 1007)
|
||||
|
||||
// 调用防抖处理函数,会在延迟时间内只执行一次更新操作
|
||||
|
|
|
@ -8,7 +8,9 @@ import { storeToRefs } from 'pinia'
|
|||
// 导入防抖函数
|
||||
import { debounce } from '@/utils/debounce'
|
||||
|
||||
const { isSaveTopic, title } = storeToRefs(useKUNGalgameEditStore())
|
||||
const { isSaveTopic, title, topicRewrite } = storeToRefs(
|
||||
useKUNGalgameEditStore()
|
||||
)
|
||||
|
||||
// 话题标题的文字
|
||||
const topicTitle = ref('')
|
||||
|
@ -16,9 +18,19 @@ const topicTitle = ref('')
|
|||
const maxInputLength = 40
|
||||
|
||||
onBeforeMount(() => {
|
||||
/**
|
||||
* 编辑器处于编辑界面
|
||||
*/
|
||||
if (isSaveTopic.value) {
|
||||
topicTitle.value = title.value
|
||||
}
|
||||
/**
|
||||
* 编辑器处于重新编辑的编辑界面
|
||||
*/
|
||||
// 挂载之前载入重新编辑话题的数据
|
||||
if (topicRewrite.value.isTopicRewriting) {
|
||||
topicTitle.value = topicRewrite.value.title
|
||||
}
|
||||
})
|
||||
|
||||
// 处理用户输入
|
||||
|
@ -35,8 +47,21 @@ const handelInput = () => {
|
|||
|
||||
// 创建一个防抖处理函数
|
||||
const debouncedInput = debounce(() => {
|
||||
// 过滤 xss
|
||||
title.value = topicTitle.value
|
||||
/**
|
||||
* 编辑器处于回复界面
|
||||
*/
|
||||
// 不是重新编辑则保存在 edit 界面的 store
|
||||
if (!topicRewrite.value.isTopicRewriting) {
|
||||
// 过滤 xss
|
||||
title.value = topicTitle.value
|
||||
}
|
||||
/**
|
||||
* 编辑器处于重新编辑的编辑界面
|
||||
*/
|
||||
// 重新编辑则保存在重新编辑界面的 store
|
||||
if (topicRewrite.value.isTopicRewriting) {
|
||||
topicRewrite.value.title = topicTitle.value
|
||||
}
|
||||
}, 300)
|
||||
|
||||
// 调用防抖处理函数,会在延迟时间内只执行一次更新操作
|
||||
|
|
|
@ -166,6 +166,7 @@ export default {
|
|||
Technique: 'Technique',
|
||||
Others: 'Others',
|
||||
publish: 'Confirm Publish',
|
||||
rewrite: 'Confirm Rewrite',
|
||||
draft: 'Save Draft',
|
||||
},
|
||||
login: {
|
||||
|
|
|
@ -165,6 +165,7 @@ export default {
|
|||
Technique: '技术交流',
|
||||
Others: '其它',
|
||||
publish: '确认发布',
|
||||
rewrite: '确认 Rewrite',
|
||||
draft: '保存草稿',
|
||||
},
|
||||
login: {
|
||||
|
@ -209,6 +210,9 @@ export default {
|
|||
publish: '确认发布吗?',
|
||||
publishSuccess: '发布成功',
|
||||
publishCancel: '取消发布',
|
||||
rewrite: '确认 Rewrite 吗?',
|
||||
rewriteSuccess: 'Rewrite 成功',
|
||||
rewriteCancel: '取消 Rewrite',
|
||||
draft: '草稿已经保存成功!',
|
||||
},
|
||||
login: {
|
||||
|
|
|
@ -1,46 +1,24 @@
|
|||
/* 编辑区的 store */
|
||||
import { defineStore } from 'pinia'
|
||||
import { postEditNewTopicApi, getTopTagsApi } from '@/api/index'
|
||||
// api
|
||||
import {
|
||||
postEditNewTopicApi,
|
||||
updateEditNewTopicApi,
|
||||
getTopTagsApi,
|
||||
} from '@/api'
|
||||
// api 请求格式
|
||||
import {
|
||||
EditCreateTopicRequestData,
|
||||
EditCreateTopicResponseData,
|
||||
EditUpdateTopicRequestData,
|
||||
EditUpdateTopicResponseData,
|
||||
EditGetHotTagsRequestData,
|
||||
EditGetHotTagsResponseData,
|
||||
} from '@/api/index'
|
||||
|
||||
interface Topic {
|
||||
/**
|
||||
* 编辑器相关
|
||||
* @param {number} editorHeight - 编辑器高度
|
||||
* @param {'' | 'essential' | 'minimal' | 'full'} mode - 编辑器 toolbar 模式
|
||||
* @param {'snow' | 'bubble'} theme - 编辑器主题
|
||||
*/
|
||||
editorHeight: number
|
||||
textCount: number
|
||||
mode: '' | 'essential' | 'minimal' | 'full'
|
||||
theme: 'snow' | 'bubble'
|
||||
|
||||
/**
|
||||
* 话题相关
|
||||
* @param {string} title - 话题标题
|
||||
* @param {string} content - 话题内容(富文本)
|
||||
* @param {Array<string>} tags - 话题标签
|
||||
* @param {Array<string>} category - 话题类别
|
||||
* @param {boolean} isSave - 是否保存话题草稿
|
||||
*/
|
||||
// 话题标题
|
||||
title: string
|
||||
// 话题内容
|
||||
content: string
|
||||
// 话题标签
|
||||
tags: Array<string>
|
||||
// 话题分区
|
||||
category: Array<string>
|
||||
// 是否显示热门关键词
|
||||
isShowHotKeywords: boolean
|
||||
// 是否保存话题
|
||||
isSaveTopic: boolean
|
||||
}
|
||||
} from '@/api'
|
||||
// store interface
|
||||
import { Topic } from '../types/edit'
|
||||
// some utils to check topic publish data is valid
|
||||
import { checkTopicPublish } from '../utils/checkTopicPublish'
|
||||
|
||||
export const useKUNGalgameEditStore = defineStore({
|
||||
id: 'edit',
|
||||
|
@ -57,15 +35,36 @@ export const useKUNGalgameEditStore = defineStore({
|
|||
category: [],
|
||||
isShowHotKeywords: true,
|
||||
isSaveTopic: false,
|
||||
|
||||
topicRewrite: {
|
||||
tid: 0,
|
||||
title: '',
|
||||
content: '',
|
||||
tags: [],
|
||||
category: [],
|
||||
|
||||
isTopicRewriting: false,
|
||||
},
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
// 创建话题
|
||||
createNewTopic(
|
||||
createTopicRequestData: EditCreateTopicRequestData
|
||||
): Promise<EditCreateTopicResponseData> {
|
||||
createNewTopic(): Promise<EditCreateTopicResponseData> | undefined {
|
||||
// 当前话题的数据
|
||||
const requestData: EditCreateTopicRequestData = {
|
||||
title: this.title,
|
||||
content: this.content,
|
||||
time: Date.now(),
|
||||
tags: this.tags,
|
||||
category: this.category,
|
||||
}
|
||||
// 检查话题数据不合法直接返回
|
||||
if (!checkTopicPublish(this.textCount, requestData)) {
|
||||
return
|
||||
}
|
||||
// 合法则请求接口发布话题
|
||||
return new Promise((resolve, reject) => {
|
||||
postEditNewTopicApi(createTopicRequestData)
|
||||
postEditNewTopicApi(requestData)
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
|
@ -74,6 +73,17 @@ export const useKUNGalgameEditStore = defineStore({
|
|||
})
|
||||
})
|
||||
},
|
||||
// 更新话题
|
||||
async rewriteTopic(): Promise<EditUpdateTopicResponseData> {
|
||||
const requestData: EditUpdateTopicRequestData = {
|
||||
tid: this.topicRewrite.tid,
|
||||
title: this.topicRewrite.title,
|
||||
content: this.topicRewrite.content,
|
||||
tags: this.topicRewrite.tags,
|
||||
category: this.topicRewrite.category,
|
||||
}
|
||||
return await updateEditNewTopicApi(requestData)
|
||||
},
|
||||
// 获取热门 tags
|
||||
getHotTags(limit: number): Promise<EditGetHotTagsResponseData> {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -87,6 +97,7 @@ export const useKUNGalgameEditStore = defineStore({
|
|||
})
|
||||
})
|
||||
},
|
||||
// 重置话题草稿数据,用于发布时
|
||||
resetTopicData() {
|
||||
this.textCount = 0
|
||||
this.title = ''
|
||||
|
@ -96,5 +107,14 @@ export const useKUNGalgameEditStore = defineStore({
|
|||
|
||||
this.isSaveTopic = false
|
||||
},
|
||||
// 重置重新发布话题数据,用于重新编辑
|
||||
resetRewriteTopicData() {
|
||||
this.topicRewrite.title = ''
|
||||
this.topicRewrite.content = ''
|
||||
this.topicRewrite.tags = []
|
||||
this.topicRewrite.category = []
|
||||
|
||||
this.topicRewrite.isTopicRewriting = false
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
53
src/store/types/edit.d.ts
vendored
Normal file
53
src/store/types/edit.d.ts
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
// 啊哈哈哈,我就是要起 rewrite 这个名字,来打我呀
|
||||
interface TopicRewrite {
|
||||
// 话题 id
|
||||
tid: number
|
||||
// 话题标题
|
||||
title: string
|
||||
// 话题内容
|
||||
content: string
|
||||
// 话题标签
|
||||
tags: Array<string>
|
||||
// 话题分区
|
||||
category: Array<string>
|
||||
|
||||
// 是否正在重新编辑话题
|
||||
isTopicRewriting: boolean
|
||||
}
|
||||
|
||||
export interface Topic {
|
||||
/**
|
||||
* 编辑器相关
|
||||
* @param {number} editorHeight - 编辑器高度
|
||||
* @param {'' | 'essential' | 'minimal' | 'full'} mode - 编辑器 toolbar 模式
|
||||
* @param {'snow' | 'bubble'} theme - 编辑器主题
|
||||
*/
|
||||
editorHeight: number
|
||||
textCount: number
|
||||
mode: '' | 'essential' | 'minimal' | 'full'
|
||||
theme: 'snow' | 'bubble'
|
||||
|
||||
/**
|
||||
* 话题相关
|
||||
* @param {string} title - 话题标题
|
||||
* @param {string} content - 话题内容(富文本)
|
||||
* @param {Array<string>} tags - 话题标签
|
||||
* @param {Array<string>} category - 话题类别
|
||||
* @param {boolean} isSave - 是否保存话题草稿
|
||||
*/
|
||||
// 话题标题
|
||||
title: string
|
||||
// 话题内容
|
||||
content: string
|
||||
// 话题标签
|
||||
tags: Array<string>
|
||||
// 话题分区
|
||||
category: Array<string>
|
||||
// 是否显示热门关键词
|
||||
isShowHotKeywords: boolean
|
||||
// 是否保存话题
|
||||
isSaveTopic: boolean
|
||||
|
||||
/* 重新编辑话题 */
|
||||
topicRewrite: TopicRewrite
|
||||
}
|
34
src/store/utils/checkTopicPublish.ts
Normal file
34
src/store/utils/checkTopicPublish.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// api 请求格式
|
||||
import { EditCreateTopicRequestData } from '@/api'
|
||||
|
||||
// 全局消息组件(顶部)
|
||||
import message from '@/components/alert/Message'
|
||||
|
||||
// 发布时检测用户输入是否合法
|
||||
export const checkTopicPublish = (
|
||||
textCount: number,
|
||||
topicData: EditCreateTopicRequestData
|
||||
) => {
|
||||
if (!topicData.title.trim()) {
|
||||
// 标题为空的话,警告
|
||||
message('Title cannot be empty!', '标题不可为空!', 'warn')
|
||||
return false
|
||||
} else if (!textCount) {
|
||||
if (textCount > 100007) {
|
||||
message('Content max length is 100007!', '内容最大长度为100007!', 'warn')
|
||||
}
|
||||
// 内容为空的话,警告
|
||||
message('Content cannot be empty!', '内容不可为空!', 'warn')
|
||||
return false
|
||||
} else if (!topicData.tags.length) {
|
||||
message('Please use at least one tag!', '请至少使用一个标签!', 'warn')
|
||||
} else if (!topicData.category.length) {
|
||||
message(
|
||||
'Please select at least one category!',
|
||||
'请至少选择一个分类!',
|
||||
'warn'
|
||||
)
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -3,75 +3,26 @@
|
|||
import { useKUNGalgameMessageStore } from '@/store/modules/message'
|
||||
// 全局消息组件(顶部)
|
||||
import message from '@/components/alert/Message'
|
||||
// Vue 函数
|
||||
import { toRaw } from 'vue'
|
||||
// 导入编辑话题的 store
|
||||
import { useKUNGalgameEditStore } from '@/store/modules/edit'
|
||||
// 导入用户 store
|
||||
import { useKUNGalgameUserStore } from '@/store/modules/kungalgamer'
|
||||
import { storeToRefs } from 'pinia'
|
||||
// 导入路由
|
||||
import { useRouter } from 'vue-router'
|
||||
// 导入请求数据格式
|
||||
import {
|
||||
EditCreateTopicRequestData,
|
||||
EditCreateTopicResponseData,
|
||||
} from '@/api/index'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const { textCount, isSaveTopic } = storeToRefs(useKUNGalgameEditStore())
|
||||
const { isSaveTopic, topicRewrite } = storeToRefs(useKUNGalgameEditStore())
|
||||
const messageStore = useKUNGalgameMessageStore()
|
||||
|
||||
// 发布时检测用户输入是否合法
|
||||
const checkPublish = (topicData: EditCreateTopicRequestData) => {
|
||||
if (!topicData.title.trim()) {
|
||||
// 标题为空的话,警告
|
||||
message('Title cannot be empty!', '标题不可为空!', 'warn')
|
||||
return false
|
||||
} else if (!textCount) {
|
||||
if (textCount > 100007) {
|
||||
message('Content max length is 100007!', '内容最大长度为100007!', 'warn')
|
||||
}
|
||||
// 内容为空的话,警告
|
||||
message('Content cannot be empty!', '内容不可为空!', 'warn')
|
||||
return false
|
||||
} else if (!topicData.tags.length) {
|
||||
message('Please use at least one tag!', '请至少使用一个标签!', 'warn')
|
||||
} else if (!topicData.category.length) {
|
||||
message(
|
||||
'Please select at least one category!',
|
||||
'请至少选择一个分类!',
|
||||
'warn'
|
||||
)
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 发布话题
|
||||
const handlePublish = async () => {
|
||||
const res = await messageStore.alert('AlertInfo.edit.publish', true)
|
||||
// 这里实现用户的点击确认取消逻辑
|
||||
if (res) {
|
||||
// 坑,storeToRefs 不等于 vue 中的 ref 或者 reactive,不能用 toRaw
|
||||
const rawData = toRaw(useKUNGalgameEditStore().$state)
|
||||
|
||||
// 发送给后端的数据
|
||||
const topicToCreate = {
|
||||
title: rawData.title,
|
||||
content: rawData.content,
|
||||
time: Date.now(),
|
||||
tags: rawData.tags,
|
||||
category: rawData.category,
|
||||
uid: useKUNGalgameUserStore().uid,
|
||||
}
|
||||
|
||||
// 检查提交数据是否合法
|
||||
if (checkPublish(topicToCreate)) {
|
||||
// 后端返回的创建好的话题数据
|
||||
const createdTopic: EditCreateTopicResponseData =
|
||||
await useKUNGalgameEditStore().createNewTopic(topicToCreate)
|
||||
// 后端返回的创建好的话题数据
|
||||
const createdTopic = await useKUNGalgameEditStore().createNewTopic()
|
||||
|
||||
if (createdTopic) {
|
||||
// 获取创建好话题的 tid
|
||||
const tid = createdTopic.data.tid
|
||||
|
||||
|
@ -86,12 +37,43 @@ const handlePublish = async () => {
|
|||
messageStore.info('AlertInfo.edit.publishSuccess')
|
||||
// 清除数据,并不再保存数据,因为此时该话题已被发布
|
||||
useKUNGalgameEditStore().resetTopicData()
|
||||
} else {
|
||||
message('Failed to create new topic', '发布话题失败', 'error')
|
||||
}
|
||||
} else {
|
||||
messageStore.info('AlertInfo.edit.publishCancel')
|
||||
}
|
||||
}
|
||||
|
||||
// 重新编辑
|
||||
const handleRewrite = async () => {
|
||||
const res = await messageStore.alert('AlertInfo.edit.rewrite', true)
|
||||
// 这里实现用户的点击确认取消逻辑
|
||||
if (res) {
|
||||
// 更新话题
|
||||
const res = await useKUNGalgameEditStore().rewriteTopic()
|
||||
|
||||
console.log(res.data)
|
||||
|
||||
// 获取创建好话题的 tid
|
||||
const tid = topicRewrite.value.tid
|
||||
|
||||
// 将用户 push 进对应 tid 话题的详情页面
|
||||
router.push({
|
||||
name: 'Topic',
|
||||
params: {
|
||||
tid: tid,
|
||||
},
|
||||
})
|
||||
|
||||
messageStore.info('AlertInfo.edit.rewriteSuccess')
|
||||
// 清除数据,并不再保存数据,因为此时该话题已被更新
|
||||
useKUNGalgameEditStore().resetRewriteTopicData()
|
||||
} else {
|
||||
messageStore.info('AlertInfo.edit.rewriteCancel')
|
||||
}
|
||||
}
|
||||
|
||||
// 用户点击保存话题的逻辑
|
||||
const handleSave = () => {
|
||||
// 这个值为 true 的时候每次页面加载的时候都会预加载上一次的话题数据
|
||||
|
@ -104,11 +86,23 @@ const handleSave = () => {
|
|||
<!-- 按钮的容器 -->
|
||||
<div class="btn-container">
|
||||
<!-- 确认按钮 -->
|
||||
|
||||
<button class="confirm-btn" @click="handlePublish">
|
||||
<button
|
||||
v-if="!topicRewrite.isTopicRewriting"
|
||||
class="confirm-btn"
|
||||
@click="handlePublish"
|
||||
>
|
||||
{{ $tm('edit.publish') }}
|
||||
</button>
|
||||
|
||||
<!-- 重新编辑按钮 -->
|
||||
<button
|
||||
v-if="topicRewrite.isTopicRewriting"
|
||||
class="rewrite-btn"
|
||||
@click="handleRewrite"
|
||||
>
|
||||
{{ $tm('edit.rewrite') }}
|
||||
</button>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<button class="save-btn" @click="handleSave">
|
||||
{{ $tm('edit.draft') }}
|
||||
|
@ -148,8 +142,20 @@ const handleSave = () => {
|
|||
}
|
||||
.confirm-btn:hover {
|
||||
background-color: var(--kungalgame-blue-4);
|
||||
transition: 0.1s;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
/* 重新编辑按钮的样式 */
|
||||
.rewrite-btn {
|
||||
color: var(--kungalgame-red-4);
|
||||
background-color: var(--kungalgame-trans-red-1);
|
||||
border: 1px solid var(--kungalgame-red-4);
|
||||
}
|
||||
.rewrite-btn:hover {
|
||||
background-color: var(--kungalgame-red-4);
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
/* 保存按钮的样式 */
|
||||
.save-btn {
|
||||
color: var(--kungalgame-pink-4);
|
||||
|
@ -158,7 +164,7 @@ const handleSave = () => {
|
|||
}
|
||||
.save-btn:hover {
|
||||
background-color: var(--kungalgame-pink-4);
|
||||
transition: 0.1s;
|
||||
transition: 0.2s;
|
||||
}
|
||||
.save-btn:active {
|
||||
background-color: var(--kungalgame-pink-3);
|
||||
|
|
|
@ -8,17 +8,29 @@ import { useKUNGalgameEditStore } from '@/store/modules/edit'
|
|||
import { Category, topicCategory } from './category'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const { isSaveTopic, category } = storeToRefs(useKUNGalgameEditStore())
|
||||
const { isSaveTopic, category, topicRewrite } = storeToRefs(
|
||||
useKUNGalgameEditStore()
|
||||
)
|
||||
|
||||
// 定义被选中的分类的数组
|
||||
const selectedCategories = ref<string[]>([])
|
||||
|
||||
// 组件挂载之前载入 store 里的数据
|
||||
onBeforeMount(() => {
|
||||
/**
|
||||
* 编辑器处于编辑界面
|
||||
*/
|
||||
// 如果用户保存了草稿则载入
|
||||
if (isSaveTopic.value) {
|
||||
selectedCategories.value = category.value
|
||||
}
|
||||
/**
|
||||
* 编辑器处于重新编辑的编辑界面
|
||||
*/
|
||||
// 挂载之前载入重新编辑话题的数据
|
||||
if (topicRewrite.value.isTopicRewriting) {
|
||||
selectedCategories.value = topicRewrite.value.category
|
||||
}
|
||||
})
|
||||
|
||||
// 当用户点击分类时的逻辑
|
||||
|
|
|
@ -14,7 +14,7 @@ const route = useRoute()
|
|||
const routeName = computed(() => route.name as string)
|
||||
|
||||
// 话题编辑界面 store
|
||||
const { isShowHotKeywords, tags, isSaveTopic } = storeToRefs(
|
||||
const { isShowHotKeywords, tags, isSaveTopic, topicRewrite } = storeToRefs(
|
||||
useKUNGalgameEditStore()
|
||||
)
|
||||
// 话题界面的 store,用于回复
|
||||
|
@ -40,14 +40,27 @@ const canDeleteTag = ref(false)
|
|||
|
||||
// 组件挂载之前载入 store 里的数据
|
||||
onBeforeMount(() => {
|
||||
/**
|
||||
* 编辑器处于编辑界面
|
||||
*/
|
||||
// 挂载之前载入话题数据,如果不保存,则不载入(并且当前必须在 edit 界面)
|
||||
if (isSaveTopic.value && routeName.value === 'Edit') {
|
||||
selectedTags.value = tags.value
|
||||
}
|
||||
/**
|
||||
* 编辑器处于回复界面
|
||||
*/
|
||||
// 挂载之前载入回复数据,如果不保存,则不载入(并且当前必须在 topic 界面)
|
||||
if (replyDraft.value.isSaveReply && routeName.value === 'Topic') {
|
||||
selectedTags.value = replyDraft.value.tags
|
||||
}
|
||||
/**
|
||||
* 编辑器处于重新编辑的编辑界面
|
||||
*/
|
||||
// 挂载之前载入重新编辑话题的 tags
|
||||
if (topicRewrite.value.isTopicRewriting && routeName.value === 'Edit') {
|
||||
selectedTags.value = topicRewrite.value.tags
|
||||
}
|
||||
})
|
||||
|
||||
// 点击 tag 触发回调
|
||||
|
|
|
@ -34,9 +34,10 @@ const {
|
|||
tags,
|
||||
edited,
|
||||
user,
|
||||
rid,
|
||||
// rid,
|
||||
status,
|
||||
share,
|
||||
// share,
|
||||
category,
|
||||
} = topicData.topicData
|
||||
|
||||
// 话题的状态
|
||||
|
@ -93,9 +94,10 @@ const loliStatus = computed(() => {
|
|||
<Rewrite v-if="edited" :time="edited" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 话题的点赞数等信息 -->
|
||||
<!-- 话题的点赞数等信息,楼主的 floor 就是 0 -->
|
||||
<MasterFooter
|
||||
:info="{ views, likes, dislikes, upvotes, to_floor: 0 }"
|
||||
:info="{ tid, views, likes, dislikes, upvotes, to_floor: 0 }"
|
||||
:topic="{ tid, title, content, tags, category }"
|
||||
:r-user="user"
|
||||
/>
|
||||
</div>
|
||||
|
@ -113,8 +115,6 @@ const loliStatus = computed(() => {
|
|||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
/* TODO: */
|
||||
/* 楼主话题背景图 */
|
||||
}
|
||||
|
||||
/* 楼主话题内容区的容器 */
|
||||
|
|
|
@ -1,25 +1,27 @@
|
|||
<!-- 话题的底部区域,推话题,回复,点赞等 -->
|
||||
<script setup lang="ts">
|
||||
import { nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { TopicUserInfo } from '@/api'
|
||||
|
||||
// 导入编辑界面的 store
|
||||
import { useKUNGalgameEditStore } from '@/store/modules/edit'
|
||||
// 导入话题页面 store
|
||||
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
// 当前的话题 tid
|
||||
const tid = parseInt(useRoute().params.tid as string)
|
||||
|
||||
// 使用编辑界面的 store
|
||||
const { topicRewrite } = storeToRefs(useKUNGalgameEditStore())
|
||||
// 使用话题页面的 store
|
||||
const topicStore = useKUNGalgameTopicStore()
|
||||
const { isEdit, replyDraft } = storeToRefs(topicStore)
|
||||
const { isEdit, replyDraft } = storeToRefs(useKUNGalgameTopicStore())
|
||||
// 使用路由
|
||||
const router = useRouter()
|
||||
|
||||
// 接受父组件的传值
|
||||
const props = defineProps<{
|
||||
info: {
|
||||
tid: number
|
||||
views: number
|
||||
likes: number[]
|
||||
dislikes: number[]
|
||||
|
@ -27,29 +29,41 @@ const props = defineProps<{
|
|||
// 被回复人的 floor
|
||||
to_floor: number
|
||||
}
|
||||
topic: {
|
||||
tid: number
|
||||
title: string
|
||||
content: string
|
||||
tags: string[]
|
||||
category: string[]
|
||||
}
|
||||
rUser: TopicUserInfo
|
||||
}>()
|
||||
|
||||
// 保存必要信息
|
||||
const saveDraft = () => {
|
||||
replyDraft.value.tid = tid
|
||||
replyDraft.value.replyUserName = props.rUser.name
|
||||
replyDraft.value.to_uid = props.rUser.uid
|
||||
replyDraft.value.to_floor = props.info.to_floor
|
||||
}
|
||||
|
||||
// 点击回复打开回复面板
|
||||
const handelReply = async () => {
|
||||
// 保存必要信息,以便发表回复
|
||||
saveDraft()
|
||||
replyDraft.value.tid = props.info.tid
|
||||
// 被回复人就是发表人的 uid
|
||||
replyDraft.value.to_uid = props.rUser.uid
|
||||
replyDraft.value.to_floor = props.info.to_floor
|
||||
|
||||
isEdit.value = true
|
||||
}
|
||||
|
||||
// 重新编辑
|
||||
const handleClickEdit = () => {
|
||||
// 保存必要信息,以便更新话题
|
||||
saveDraft()
|
||||
// 保存数据
|
||||
topicRewrite.value.tid = props.topic.tid
|
||||
topicRewrite.value.title = props.topic.title
|
||||
topicRewrite.value.content = props.topic.content
|
||||
topicRewrite.value.tags = props.topic.tags
|
||||
topicRewrite.value.category = props.topic.category
|
||||
|
||||
// 设置正在重新编辑状态为真
|
||||
topicRewrite.value.isTopicRewriting = true
|
||||
|
||||
// 跳转到编辑界面
|
||||
router.push({ name: 'Edit' })
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -62,22 +76,22 @@ const handleClickEdit = () => {
|
|||
<!-- 推话题 -->
|
||||
<li>
|
||||
<span class="icon"><Icon icon="bi:rocket" /></span>
|
||||
{{ info?.upvotes?.length }}
|
||||
{{ info.upvotes.length }}
|
||||
</li>
|
||||
<!-- 查看数量 -->
|
||||
<li v-if="info.views">
|
||||
<li>
|
||||
<span class="icon"><Icon icon="ic:outline-remove-red-eye" /></span>
|
||||
{{ info.views }}
|
||||
</li>
|
||||
<!-- 点赞 -->
|
||||
<li>
|
||||
<span class="icon"><Icon icon="line-md:thumbs-up-twotone" /></span>
|
||||
{{ info?.likes?.length }}
|
||||
{{ info.likes.length }}
|
||||
</li>
|
||||
<!-- 踩 -->
|
||||
<li>
|
||||
<span class="icon"><Icon icon="line-md:thumbs-down-twotone" /></span>
|
||||
{{ info?.dislikes?.length }}
|
||||
{{ info.dislikes.length }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,44 @@
|
|||
<!-- 重新编辑话题信息显示 -->
|
||||
<!-- 我就要把这个组件拆出来!因为是!Rewrite!啊哈哈哈(我不会告诉你这个实际上应该命名 Reedit) -->
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/en' // 导入英文语言包
|
||||
|
||||
// 使用设置界面的 store,目的是获取网站整体的语言
|
||||
import { useKUNGalgameSettingsStore } from '@/store/modules/settings'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const props = defineProps<{
|
||||
time: number
|
||||
}>()
|
||||
|
||||
// 使用设置面板的 store
|
||||
const settingsStore = useKUNGalgameSettingsStore()
|
||||
const { showKUNGalgameLanguage } = storeToRefs(settingsStore)
|
||||
|
||||
// 设置使用英文语言
|
||||
dayjs.locale('en')
|
||||
const formattedCNDate = dayjs(props.time).format('YYYY年MM月DD日-HH:mm:ss')
|
||||
const formattedENDate = dayjs(props.time).format('M / D, YYYY - h:mm:ss A')
|
||||
|
||||
const loliTime = computed(() => {
|
||||
if (showKUNGalgameLanguage.value === 'en') {
|
||||
return formattedENDate
|
||||
}
|
||||
|
||||
if (showKUNGalgameLanguage.value === 'zh') {
|
||||
return formattedCNDate
|
||||
}
|
||||
|
||||
return ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 是否重新编辑 -->
|
||||
<span>在2019年10月7日10:07:00重新编辑</span>
|
||||
<!-- 为什么这里没有 i18n 呢,别问我为什么,问就是 Rewrite,啊哈哈哈 -->
|
||||
<span>{{ `Rewrite at ${loliTime}` }}</span>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
Loading…
Reference in a new issue