Commit 7bdc7b3d by lijiabin

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

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