Commit 741b36b7 by lijiabin

【需求 17679】 feat: 完成帖子(除视频外)二次编辑功能

parent a25a5702
......@@ -24,6 +24,7 @@
8
</div> -->
</div>
<div class="flex-1">
<div class="flex items-center gap-2">
<h3 class="font-semibold text-gray-800">{{ articleDetail?.createUserName }}</h3>
......@@ -38,7 +39,16 @@
· {{ articleDetail?.viewCount || 0 }} 阅读
</p>
</div>
<!-- 再次编辑按钮 -->
<el-link
v-if="isAuthor"
type="primary"
:underline="false"
@click="router.push(`/publishLongArticle/${articleDetail.type}?id=${articleDetail.id}`)"
class="text-sm"
>
编辑
</el-link>
<!-- 优化后的右侧内容 -->
<div class="flex items-center gap-3">
<span
......@@ -112,15 +122,30 @@ import type { ArticleItemDto } from '@/api'
import { articleTypeListOptions, ArticleTypeEnum } from '@/constants'
import ActionMore from '@/components/common/ActionMore/index.vue'
import { jumpToUserHomePage } from '@/utils'
import { useUserStore } from '@/stores/user'
import { storeToRefs } from 'pinia'
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const router = useRouter()
const { articleDetail } = defineProps<{
articleDetail: ArticleItemDto
isAudit: boolean // 是否是审核页面
}>()
const articleType = computed(() => {
return articleTypeListOptions.find((item) => item.value === articleDetail.type)?.label
})
// 是否是作者
const isAuthor = computed(() => {
return articleDetail.createUserId === userInfo.value.userId
})
// 如果类型是帖子 专栏 和 专访 就是html
const isHtml = computed(() => {
return articleDetail.content?.includes('<') || articleDetail.content?.includes('</')
return (
articleDetail.type === ArticleTypeEnum.POST ||
articleDetail.type === ArticleTypeEnum.COLUMN ||
articleDetail.type === ArticleTypeEnum.INTERVIEW
)
})
</script>
......@@ -17,8 +17,6 @@
</template>
<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { uploadFile } from '@/api'
const mode = 'default'
......@@ -29,15 +27,14 @@ const editorRef = shallowRef()
// 内容 HTML
const valueHtml = defineModel<string>()
// 模拟 ajax 异步获取内容
onMounted(() => {
setTimeout(() => {
valueHtml.value = '<p>模拟 Ajax 异步设置内容</p>'
}, 1500)
})
// 去掉上传视频的功能
const toolbarConfig = {}
const editorConfig = { placeholder: '请输入内容...', MENU_CONF: {} }
toolbarConfig.excludeKeys = ['group-video', 'group-more-video', 'group-more-video']
// 去掉上传视频
const editorConfig = {
placeholder: '请输入内容...',
MENU_CONF: {},
}
// 修改 uploadImage 菜单配置
......
......@@ -88,7 +88,6 @@
>专访</el-dropdown-item
>
</el-dropdown-menu>
<el-dropdown-item :command="ArticleTypeEnum.LONG_ARTICLE">长文章</el-dropdown-item>
</template>
</el-dropdown>
</div>
......@@ -143,23 +142,27 @@ const getSecondLevelKey = (route: RouteLocationNormalizedLoadedGeneric) => {
const key = Object.keys(route.params).length
? pathSegments.slice(0, 2).join('/')
: pathSegments.slice(0, 1).join('/')
console.log(key, '*********************')
// console.log(key, '*********************')
return key
}
const notShowPath = ['/videoDetail', '/articleDetail', '/questionDetail']
const showOnlineTime = computed(() => {
return !route.path.includes('/videoDetail') && !route.path.includes('/articleDetail')
return notShowPath.every((path) => !route.path.includes(path))
})
const handlePost = async (type: ArticleTypeEnum) => {
if (type === ArticleTypeEnum.VIDEO) {
router.push('/publishVideo')
} else if (type === ArticleTypeEnum.QUESTION) {
router.push(`/homePage/askTab#tabsRef?t=${Date.now()}`)
} else if (type === ArticleTypeEnum.LONG_ARTICLE) {
router.push('/publishLongArticle')
// router.push(`/homePage/askTab#tabsRef?t=${Date.now()}`)
router.push(`/publishLongArticle/${type}`)
} else if (type === ArticleTypeEnum.PRACTICE) {
router.push(`/publishLongArticle/${type}`)
// PublishDialogRef.value?.open(type)
} else {
PublishDialogRef.value?.open(type)
router.push(`/publishLongArticle/${type}`)
}
}
const isDropdownHover = ref(false)
......
......@@ -7,7 +7,7 @@
></ActionButtons>
<div class="lg:col-span-3">
<!-- 帖子主体 -->
<ArticleContent :articleDetail="articleDetail" />
<ArticleContent :articleDetail="articleDetail" :isAudit="false" />
<!-- 评论区 -->
<Comment
......@@ -29,7 +29,7 @@ import { ArticleTypeEnum } from '@/constants'
const commentRef = useTemplateRef<typeof Comment | null>('commentRef')
const route = useRoute()
const id = route.params.id as string
const id = Number(route.params.id)
const isReal = computed(() => {
return +(
......
<template>
<div v-loading="loading" class="px-20">
<div v-loading="loading">
<div class="lg:col-span-3 mb-20">
<ArticleContent :articleDetail="articleDetail" />
<ArticleContent :articleDetail="articleDetail" :isAudit="true" />
</div>
<!-- 底部fixed -->
<div class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 shadow-lg">
......
......@@ -6,7 +6,7 @@
class="bg-white rounded-lg p-6 shadow-[0_1px_3px_rgba(0,0,0,0.02)] border border-slate-100"
>
<!-- 顶部标签行 -->
<div class="flex flex-wrap gap-2 mb-4">
<div class="flex flex-wrap gap-2 mb-4 justify-between">
<span
v-for="tag in questionDetail.tagNameList"
:key="tag"
......@@ -14,6 +14,18 @@
>
#{{ tag }}
</span>
<!-- 后面加一个编辑 -->
<el-link
v-if="isAuthor"
type="primary"
:underline="false"
@click="
router.push(`/publishLongArticle/${questionDetail.type}?id=${questionDetail.id}`)
"
class="text-sm"
>
编辑
</el-link>
</div>
<!-- 标题:主要信息,黑重粗 -->
......@@ -78,6 +90,18 @@
</span>
</div>
</div>
<!-- 展示图片相关 -->
<div v-if="questionDetail.imgUrl" class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-6">
<el-image
v-for="item in questionDetail.imgUrl.split(',')"
:key="item"
:src="item"
fit="cover"
class="rounded-lg w-full h-64 hover:scale-105 transition-transform cursor-pointer"
:preview-src-list="questionDetail.imgUrl.split(',')"
:preview-teleported="true"
/>
</div>
</div>
<!-- 2. 列表控制栏 -->
......@@ -241,14 +265,23 @@ import { usePageSearch } from '@/hooks'
import Comment from '@/components/common/Comment/index.vue'
import CommentDialog from '@/components/common/CommentDialog/index.vue'
import dayjs from 'dayjs'
import { useUserStore } from '@/stores/user'
import { storeToRefs } from 'pinia'
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const route = useRoute()
const questionId = Number(route.params.id)
const router = useRouter()
const questionId = Number(route.params.id)
const commentRefList = ref<InstanceType<typeof Comment>[]>([])
const questionDetail = ref<ArticleItemDto>({} as ArticleItemDto)
const commentDialogRef = useTemplateRef<typeof CommentDialog>('commentDialogRef')
const isAuthor = computed(() => {
return questionDetail.value.createUserId === userInfo.value.userId
})
const questionContentRef = useTemplateRef<HTMLElement>('questionContentRef')
const isExpand = ref(false)
......
......@@ -53,6 +53,13 @@
@click="jumpToArticleDetailPage({ type: item.type, id: item.id })"
>查看</el-button
>
<el-button
v-if="item.type !== ArticleTypeEnum.VIDEO"
type="primary"
link
@click="jumpToEditPage({ type: item.type, id: item.id })"
>编辑</el-button
>
<el-button type="danger" link @click="handleDelete(item.id)">删除</el-button>
</div>
</div>
......@@ -93,6 +100,8 @@ import type { TabPaneName } from 'element-plus'
import { IS_REAL_KEY } from '@/constants/symbolKey'
import { jumpToArticleDetailPage } from '@/utils'
const router = useRouter()
const isReal = inject(IS_REAL_KEY)
const filterArticleType = computed(() => {
if (isReal?.value === 1) {
......@@ -131,6 +140,14 @@ const handleDelete = async (articleId: number) => {
ElMessage.success('删除成功')
}
const jumpToEditPage = (item: { type: ArticleTypeEnum; id: number }) => {
if (item.type === ArticleTypeEnum.VIDEO) {
router.push(`/publishVideo?id=${item.id}`)
} else {
router.push(`/publishLongArticle/${item.type}?id=${item.id}`)
}
}
defineExpose({
refresh: () => {
searchParams.value.type = filterArticleType.value[0]!.value
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment