Commit 7bdc7b3d by lijiabin

【需求 17679】 perf: 优化实践相关的内容

parent 61a43a4a
...@@ -5,32 +5,21 @@ ...@@ -5,32 +5,21 @@
<div class="flex gap-3 mb-2 items-start"> <div class="flex gap-3 mb-2 items-start">
<!-- 用户头像 --> <!-- 用户头像 -->
<el-avatar :size="48" :src="userAvatar" class="flex-shrink-0"> <el-avatar :size="48" :src="userAvatar" class="flex-shrink-0">
<el-icon><User /></el-icon> <el-icon>
<User />
</el-icon>
</el-avatar> </el-avatar>
<!-- 输入区域 --> <!-- 输入区域 -->
<div class="flex-1"> <div class="flex-1">
<!-- 话题标签输入 --> <!-- 话题标签输入 -->
<div class="mb-4"> <div class="mb-4">
<el-input <el-input v-model="form.title" :placeholder="textMap[type].title" class="tag-input" clearable />
v-model="form.title"
:placeholder="textMap[type].title"
class="tag-input"
clearable
/>
</div> </div>
<!-- 主要内容输入 --> <!-- 主要内容输入 -->
<div class="relative mb-3"> <div class="relative mb-3">
<el-input <el-input type="textarea" :placeholder="textMap[type].content" :rows="6" :maxlength="maxLength"
type="textarea" show-word-limit resize="none" class="main-textarea" v-model="form.content" />
:placeholder="textMap[type].content"
:rows="6"
:maxlength="500"
show-word-limit
resize="none"
class="main-textarea"
v-model="form.content"
/>
<!-- 字符计数 --> <!-- 字符计数 -->
<!-- <div class="absolute bottom-3 right-3 text-xs text-gray-400">1/30</div> --> <!-- <div class="absolute bottom-3 right-3 text-xs text-gray-400">1/30</div> -->
</div> </div>
...@@ -38,12 +27,10 @@ ...@@ -38,12 +27,10 @@
<div class="mb-2"> <div class="mb-2">
<!-- 选择的标签内容 --> <!-- 选择的标签内容 -->
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span v-if="mainTagText" class="text-sm text-gray-500" <span v-if="mainTagText" class="text-sm text-gray-500">主标签:
>主标签:
<el-tag>{{ mainTagText }}</el-tag> <el-tag>{{ mainTagText }}</el-tag>
</span> </span>
<span v-if="subTagTextList.length > 0" class="text-sm text-gray-500" <span v-if="subTagTextList.length > 0" class="text-sm text-gray-500">副标签:
>副标签:
<el-tag class="mr-2" v-for="tag in subTagTextList" :key="tag">{{ tag }}</el-tag> <el-tag class="mr-2" v-for="tag in subTagTextList" :key="tag">{{ tag }}</el-tag>
</span> </span>
</div> </div>
...@@ -51,24 +38,15 @@ ...@@ -51,24 +38,15 @@
<!-- 图片相关 --> <!-- 图片相关 -->
<div v-if="form.imgUrl.length" class="flex flex-wrap gap-2"> <div v-if="form.imgUrl.length" class="flex flex-wrap gap-2">
<!-- 删除图片 --> <!-- 删除图片 -->
<div <div class="relative w-20 h-20 rounded-lg overflow-hidden group" v-for="img in form.imgUrl" :key="img">
class="relative w-20 h-20 rounded-lg overflow-hidden group"
v-for="img in form.imgUrl"
:key="img"
>
<div <div
class="absolute top-1 right-1 z-10 w-5 h-5 flex items-center justify-center bg-black/60 rounded-full cursor-pointer opacity-0 group-hover:opacity-100 transition-all duration-200 hover:bg-black/80 hover:scale-110" class="absolute top-1 right-1 z-10 w-5 h-5 flex items-center justify-center bg-black/60 rounded-full cursor-pointer opacity-0 group-hover:opacity-100 transition-all duration-200 hover:bg-black/80 hover:scale-110"
@click="handleDeleteImg(img)" @click="handleDeleteImg(img)">
>
<el-icon class="text-white text-xs"> <el-icon class="text-white text-xs">
<Close /> <Close />
</el-icon> </el-icon>
</div> </div>
<el-image <el-image :src="img" class="w-full h-full rounded-lg border border-gray-200" fit="cover" />
:src="img"
class="w-full h-full rounded-lg border border-gray-200"
fit="cover"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -79,27 +57,23 @@ ...@@ -79,27 +57,23 @@
<!-- 左侧工具按钮 --> <!-- 左侧工具按钮 -->
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<el-tooltip content="添加标签" placement="top" :visible="visibleTagTooltip"> <el-tooltip content="添加标签" placement="top" :visible="visibleTagTooltip">
<el-button <el-button ref="tagButtonRef" text
ref="tagButtonRef" class="w-10 h-10 text-gray-500 hover:bg-gray-100 hover:text-gray-700 rounded-lg" @click="handleAddTag"
text @mouseenter="visibleTagTooltip = true" @mouseleave="visibleTagTooltip = false">
class="w-10 h-10 text-gray-500 hover:bg-gray-100 hover:text-gray-700 rounded-lg" <el-icon size="18">
@click="handleAddTag" <CollectionTag />
@mouseenter="visibleTagTooltip = true" </el-icon>
@mouseleave="visibleTagTooltip = false"
>
<el-icon size="18"><CollectionTag /></el-icon>
</el-button> </el-button>
</el-tooltip> </el-tooltip>
<!-- 隐藏上传文件的input --> <!-- 隐藏上传文件的input -->
<input type="file" class="hidden" ref="fileInputRef" @change="handleFileChange" /> <input type="file" class="hidden" ref="fileInputRef" @change="handleFileChange" />
<el-tooltip content="添加图片" placement="top"> <el-tooltip content="添加图片" placement="top">
<el-button <el-button text class="w-10 h-10 text-gray-500 hover:bg-gray-100 hover:text-gray-700 rounded-lg"
text @click="fileInputRef?.click()">
class="w-10 h-10 text-gray-500 hover:bg-gray-100 hover:text-gray-700 rounded-lg" <el-icon size="18">
@click="fileInputRef?.click()" <Picture />
> </el-icon>
<el-icon size="18"><Picture /></el-icon>
</el-button> </el-button>
</el-tooltip> </el-tooltip>
...@@ -111,7 +85,7 @@ ...@@ -111,7 +85,7 @@
<el-icon size="18"><VideoPlay /></el-icon> <el-icon size="18"><VideoPlay /></el-icon>
</el-button> </el-button>
</el-tooltip> </el-tooltip>
<el-tooltip content="添加附件" placement="top"> <el-tooltip content="添加附件" placement="top">
<el-button <el-button
text text
...@@ -126,27 +100,19 @@ ...@@ -126,27 +100,19 @@
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<el-button <el-button
class="px-4 py-2 text-gray-600 hover:text-gray-800 hover:bg-gray-50 rounded-lg border border-gray-200 text-sm" class="px-4 py-2 text-gray-600 hover:text-gray-800 hover:bg-gray-50 rounded-lg border border-gray-200 text-sm"
@click="handlePublish(ReleaseStatusTypeEnum.DRAFT)" @click="handlePublish(ReleaseStatusTypeEnum.DRAFT)">
>
存草稿 存草稿
</el-button> </el-button>
<el-button <el-button type="primary" :disabled="disabledSubmit"
type="primary"
:disabled="disabledSubmit"
class="px-6 py-2 bg-blue-500 hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed rounded-lg text-white text-sm font-medium shadow-sm hover:shadow-md transition-all duration-200" class="px-6 py-2 bg-blue-500 hover:bg-blue-600 disabled:opacity-50 disabled:cursor-not-allowed rounded-lg text-white text-sm font-medium shadow-sm hover:shadow-md transition-all duration-200"
@click="handlePublish(ReleaseStatusTypeEnum.PUBLISH)" @click="handlePublish(ReleaseStatusTypeEnum.PUBLISH)">
>
发布 {{ type === ArticleTypeEnum.QUESTION ? '问题' : '实践' }} 发布 {{ type === ArticleTypeEnum.QUESTION ? '问题' : '实践' }}
</el-button> </el-button>
</div> </div>
</div> </div>
</div> </div>
<SelectTagsDialog <SelectTagsDialog v-model:mainTagId="form.mainTagId" v-model:tagList="form.tagList" ref="selectTagsDialogRef" />
v-model:mainTagId="form.mainTagId"
v-model:tagList="form.tagList"
ref="selectTagsDialogRef"
/>
<el-tour v-model="openTour" :mask="false" placement="left-start" type="primary"> <el-tour v-model="openTour" :mask="false" placement="left-start" type="primary">
<el-tour-step :target="tagButtonRef?.$el" description="在这里选择标签" placement="top" /> <el-tour-step :target="tagButtonRef?.$el" description="在这里选择标签" placement="top" />
...@@ -168,13 +134,13 @@ import type { AddOrUpdatePracticeDto } from '@/api' ...@@ -168,13 +134,13 @@ import type { AddOrUpdatePracticeDto } from '@/api'
import type { BooleanFlag } from '@/constants' import type { BooleanFlag } from '@/constants'
import type { ElButton } from 'element-plus' import type { ElButton } from 'element-plus'
import { useAnimate } from '@vueuse/core' import { useAnimate } from '@vueuse/core'
import { isVisible } from 'element-plus/es/utils/index.mjs'
type ArticleType = ArticleTypeEnum.QUESTION | ArticleTypeEnum.PRACTICE type ArticleType = ArticleTypeEnum.QUESTION | ArticleTypeEnum.PRACTICE
const { type, isReal } = defineProps<{ const { type, isReal, maxLength = 500 } = defineProps<{
type: ArticleType type: ArticleType
isReal: BooleanFlag isReal: BooleanFlag
maxLength?: number
}>() }>()
const textMap: Record< const textMap: Record<
......
...@@ -23,7 +23,6 @@ export default defineComponent((_, { expose }) => { ...@@ -23,7 +23,6 @@ export default defineComponent((_, { expose }) => {
const rules = { const rules = {
title: [{ required: true, message: '请输入实践标题', trigger: 'blur' }], title: [{ required: true, message: '请输入实践标题', trigger: 'blur' }],
content: [{ required: true, message: '请输入实践内容', trigger: 'blur' }], content: [{ required: true, message: '请输入实践内容', trigger: 'blur' }],
imgUrl: [{ required: true, message: '请上传实践图片', trigger: 'change' }],
releaseStatus: [{ required: true, message: '请选择发布时间', trigger: 'blur' }], releaseStatus: [{ required: true, message: '请选择发布时间', trigger: 'blur' }],
mainTagId: [{ required: true, message: '请选择主标签', trigger: 'blur' }], mainTagId: [{ required: true, message: '请选择主标签', trigger: 'blur' }],
sendType: [{ required: true, message: '请选择发布类型', trigger: 'blur' }], sendType: [{ required: true, message: '请选择发布类型', trigger: 'blur' }],
...@@ -98,7 +97,7 @@ export default defineComponent((_, { expose }) => { ...@@ -98,7 +97,7 @@ export default defineComponent((_, { expose }) => {
class="content-input" class="content-input"
/> />
</el-form-item> </el-form-item>
<el-form-item label="图片" prop="imgUrl"> <el-form-item label="图片">
{/* @ts-ignore */} {/* @ts-ignore */}
<UploadFile v-model={form.value.imgUrl} /> <UploadFile v-model={form.value.imgUrl} />
</el-form-item> </el-form-item>
......
<template> <template>
<div> <div>
<!-- 发布区域 --> <!-- 发布区域 -->
<PublishPractice :type="ArticleTypeEnum.PRACTICE" :isReal="1" /> <PublishPractice :type="ArticleTypeEnum.PRACTICE" :isReal="1" :maxLength="2000" />
<!-- 标签导航 --> <!-- 标签导航 -->
<div class="bg-white p-4 mb-6 rounded-lg shadow-sm"> <div class="bg-white p-4 mb-6 rounded-lg shadow-sm">
<div class="flex flex-wrap gap-2 mb-2"> <div class="flex flex-wrap gap-2 mb-2">
<el-tag <el-tag v-for="tag in filterOptions" :key="tag.id"
v-for="tag in filterOptions"
:key="tag.id"
:type="tag.id === searchParams.sortLogic ? 'primary' : 'info'" :type="tag.id === searchParams.sortLogic ? 'primary' : 'info'"
:effect="tag.id === searchParams.sortLogic ? 'dark' : 'plain'" :effect="tag.id === searchParams.sortLogic ? 'dark' : 'plain'" class="cursor-pointer"
class="cursor-pointer" @click="toggleFilter(tag.id)">
@click="toggleFilter(tag.id)"
>
{{ tag.title }} {{ tag.title }}
</el-tag> </el-tag>
</div> </div>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<el-tag <el-tag v-for="tag in tagList" :key="tag.id"
v-for="tag in tagList"
:key="tag.id"
:type="searchParams.tagIdList?.includes(tag.id) ? 'primary' : 'info'" :type="searchParams.tagIdList?.includes(tag.id) ? 'primary' : 'info'"
:effect="searchParams.tagIdList?.includes(tag.id) ? 'dark' : 'plain'" :effect="searchParams.tagIdList?.includes(tag.id) ? 'dark' : 'plain'" class="cursor-pointer"
class="cursor-pointer" @click="toggleTag(tag.id)">
@click="toggleTag(tag.id)"
>
{{ tag.title }} {{ tag.title }}
</el-tag> </el-tag>
</div> </div>
...@@ -41,53 +33,40 @@ ...@@ -41,53 +33,40 @@
{{ filterText }} {{ filterText }}
</h2> </h2>
</div> </div>
<div <div class="text-#999 cursor-pointer text-sm" @click="
class="text-#999 cursor-pointer text-sm" router.push({
@click=" path: '/searchPage',
router.push({ query: {
path: '/searchPage', type: ArticleTypeEnum.PRACTICE,
query: { },
type: ArticleTypeEnum.PRACTICE, })
}, ">
})
"
>
查看更多 >> 查看更多 >>
</div> </div>
</div> </div>
<el-divider class="my-1!" />
<div class="divide-y bg-#fff"> <div class="divide-y bg-#fff">
<div <div @click="openArticleDetail(item.id)" v-for="item in list" :key="item.id"
@click="openArticleDetail(item.id)" class="p-4 hover:bg-gray-50 transition-colors cursor-pointer pl-8" >
v-for="item in list" <div class="flex gap-3 items-center h-100%" style="border-bottom: 1.5px solid #ddd;">
:key="item.id"
class="p-4 hover:bg-gray-50 transition-colors cursor-pointer"
>
<div class="flex gap-3 items-center">
<!-- 左侧内容 --> <!-- 左侧内容 -->
<div class="flex-1"> <div class="flex-1">
<h2 class="font-medium text-gray-900 mb-2 leading-relaxed line-clamp-1"> <h1 class="font-medium text-gray-900 mb-2 leading-relaxed line-clamp-1 text-18px">
{{ item.title }} {{ item.title }}
</h2> </h1>
<!-- 带图片的内容 --> <!-- 带图片的内容 -->
<div class="flex gap-3 mb-3"> <div class="flex gap-3 mb-3 align-center" style="border-right: 1.5px solid #ddd;">
<img <img v-if="item.faceUrl" :src="item.faceUrl" :alt="item.title"
v-if="item.faceUrl" class="w-40 h-25 object-cover rounded-lg flex-shrink-0" />
:src="item.faceUrl" <div class="flex-1 mr-4">
:alt="item.title" <div class="text-gray-600 text-sm leading-relaxed line-clamp-4">
class="w-20 h-20 object-cover rounded-lg flex-shrink-0"
/>
<div class="flex-1">
<div class="text-gray-600 text-sm leading-relaxed line-clamp-3">
{{ item.content }} {{ item.content }}
</div> </div>
</div> </div>
</div> </div>
<!-- 互动数据 --> <!-- 互动数据 -->
<div class="flex items-center gap-4 text-gray-400 text-sm"> <div class="flex items-center gap-5 text-gray-400 text-base mb-3">
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<el-icon class="text-sm"> <el-icon class="text-sm">
<View /> <View />
...@@ -100,7 +79,7 @@ ...@@ -100,7 +79,7 @@
</el-icon> </el-icon>
<span>{{ item.replyCount }}</span> <span>{{ item.replyCount }}</span>
</div> </div>
<div class="flex items-center gap-1"> <div class="flex items-center gap-1 mr-2">
<el-icon class="text-sm"> <el-icon class="text-sm">
<Star /> <Star />
</el-icon> </el-icon>
...@@ -109,11 +88,13 @@ ...@@ -109,11 +88,13 @@
<div>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm') }}</div> <div>{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm') }}</div>
</div> </div>
</div> </div>
<!-- 加一个el-divider -->
<el-divider class="my-1! h-100%!" direction="vertical" />
<!-- 右侧头像 --> <!-- 右侧头像 -->
<div class="flex flex-col items-center gap-1 flex-shrink-0"> <div class="flex flex-col items-center gap-1 flex-shrink-0 pr-8">
<el-avatar :size="40" :src="item.showAvatar" /> <el-avatar :size="45" :src="item.showAvatar" />
<div class="text-xs text-gray-500">{{ item.showName }}</div> <div class="text-xs text-gray-600 mt-2">{{ item.showName }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -130,23 +111,14 @@ ...@@ -130,23 +111,14 @@
<!-- 右侧:分页器 --> <!-- 右侧:分页器 -->
<div class="right"> <div class="right">
<div <div class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3">
class="pagination-wrapper bg-white rounded-lg shadow-sm border border-gray-100 p-3" <el-pagination v-model:current-page="searchParams.current" v-model:page-size="searchParams.size"
> :page-sizes="[5, 20, 1]" layout="prev, pager, next, jumper, total" :total="total"
<el-pagination class="custom-pagination" @current-change="
v-model:current-page="searchParams.current"
v-model:page-size="searchParams.size"
:page-sizes="[5, 20, 1]"
layout="prev, pager, next, jumper, total"
:total="total"
class="custom-pagination"
@current-change="
(e) => { (e) => {
;(handleBackTop(), goToPage(e)) ; (handleBackTop(), goToPage(e))
} }
" " @size-change="changePageSize" />
@size-change="changePageSize"
/>
</div> </div>
</div> </div>
</div> </div>
......
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