Commit 97019bbf by lijiabin

【需求 17679】 feat: 我的页面完成案例库页面,上传文件增加cacel功能等

parent f0fed940
import service from '@/utils/request/index'
import type { AddOrUpdateCaseDto } from './types'
import type { AddOrUpdateCaseDto, CaseDetailDto } from './types'
// 案例库相关的接口
......@@ -24,3 +24,23 @@ export const addOrUpdateCase = (data: AddOrUpdateCaseDto) => {
data,
})
}
/**
* 获取案例详情
*/
export const getCaseDetail = (id: number) => {
return service.request<CaseDetailDto>({
url: `/api/cultureCase/getCaseDetail?caseId=${id}`,
method: 'POST',
})
}
/**
* 删除案例库
*/
export const deleteCase = (id: number) => {
return service.request({
url: `/api/cultureCase/deleteCase?id=${id}`,
method: 'POST',
})
}
......@@ -19,3 +19,16 @@ export interface AddOrUpdateCaseDto {
tagRelationDtoList: TagItemDto[]
title: string
}
export interface CaseDetailDto {
id: number
title: string
content: string
caseTags: TagItemDto[]
depIdList: number[]
depNameList: string[]
isSync: BooleanFlag
cultureKeywordMain: string
cultureKeywordSub: string[]
sceneKeywordMain: string
sceneKeywordSub: string[]
}
......@@ -21,35 +21,55 @@
/**
* 暂时调用oa正式接口
*/
import axios from 'axios'
type UploadFileResponse = {
data: {
data: {
createTime: string
createUser: number
fileBucket: string
fileId: string
fileName: string
filePath: string
fileSizeKb: number
fileSuffix: string
finalName: string
realPath: string
updateTime: string
updateUser: string
}[]
}
import axios, { type AxiosRequestConfig } from 'axios'
type UploadFileResponseItem = {
createTime: string
createUser: number
fileBucket: string
fileId: string
fileName: string
filePath: string
fileSizeKb: number
fileSuffix: string
finalName: string
realPath: string
updateTime: string
updateUser: string
}
// 单个文件上传
export const uploadFile = (
file: File,
onProgress?: (progress: number) => void,
): Promise<UploadFileResponse> => {
options: {
onProgress?: (progress: number) => void
} = {},
): {
cancel: () => void
promise: Promise<UploadFileResponseItem>
} => {
const formData = new FormData()
formData.append('fileList', file)
return axios.post('http://47.112.96.71:8082/mobiles/uploadFile', formData, {
onUploadProgress: (progressEvent) => {
const { onProgress } = options
const controller = new AbortController()
const axiosOptions: AxiosRequestConfig = {
signal: controller.signal,
}
if (onProgress) {
axiosOptions.onUploadProgress = (progressEvent) => {
const percentCompleted = Math.round((progressEvent.loaded * 100) / (progressEvent.total || 1))
onProgress?.(percentCompleted)
}
}
return {
cancel: () => {
controller.abort()
},
})
promise: axios
.post('http://47.112.96.71:8082/mobiles/uploadFile', formData, axiosOptions)
.then((data) => data.data.data[0] as UploadFileResponseItem),
}
}
......@@ -20,8 +20,9 @@ import type {
ComplaintListItemDto,
AuditComplaintDto,
ComplaintListSearchParams,
SelfCaseSearchParams,
} from './types'
import type { BackendServicePageResult, PageSearchParams } from '@/utils/request/types'
import type { BackendServicePageResult } from '@/utils/request/types'
/**
* 更新用户信息
......@@ -92,7 +93,7 @@ export const getSelfPraiseList = (data: SelfPraiseSearchParams) => {
/**
* 获取我的案例库列表
*/
export const getSelfCaseList = (data: PageSearchParams) => {
export const getSelfCaseList = (data: SelfCaseSearchParams) => {
return service.request<BackendServicePageResult<SelfCaseItemDto>>({
url: '/api/personalCenter/selfCase',
method: 'POST',
......
......@@ -3,6 +3,7 @@ import {
AuditStatusEnum,
BooleanFlag,
CommentTypeEnum,
ReleaseStatusTypeEnum,
TaskDateLimitTypeEnum,
TaskTypeEnum,
} from '@/constants'
......@@ -61,6 +62,11 @@ export interface SelfPraiseSearchParams extends PageSearchParams {
type: ArticleTypeEnum
}
// 我的案例库搜索
export interface SelfCaseSearchParams extends PageSearchParams {
releaseStatus: ReleaseStatusTypeEnum
}
export interface SelfPraiseDetailDto {
collectionCount: number
content: string
......@@ -200,6 +206,7 @@ export interface SelfCaseItemDto {
deptName: string
id: number
integrity: number
isAudit: AuditStatusEnum
isDelete: number
isDispose: number
isUse: number
......
......@@ -76,7 +76,7 @@
<!-- 文章内容 -->
<div v-if="!isHtml" class="prose prose-lg max-w-none">
<div class="text-gray-700 leading-relaxed space-y-4 whitespace-pre-line">
<div class="text-gray-700 leading-relaxed space-y-4 whitespace-pre-line text-17px">
{{ articleDetail?.content }}
</div>
......
......@@ -271,8 +271,10 @@ const handleAddTag = () => {
const handleFileChange = async (e: Event) => {
const file = (e.target as HTMLInputElement).files?.[0]
if (file) {
const { data } = await uploadFile(file)
form.value.imgUrl.push(data.data[0]?.filePath || '')
const { promise } = uploadFile(file)
const data = await promise
console.log(data)
form.value.imgUrl.push(data.filePath)
}
}
......
......@@ -126,12 +126,15 @@ const handleChange: UploadProps['onChange'] = async (uploadFile, uploadFiles) =>
fileList.value[fileIndex]!.status = 'uploading'
}
const { data } = await uploadFileApi(uploadFile.raw, (progress) => {
console.log('progress', progress)
const { promise } = uploadFileApi(uploadFile.raw, {
onProgress: (progress) => {
console.log('progress', progress)
},
})
const data = await promise
console.log('data', data)
const url = data.data[0]?.filePath || ''
const name = data.data[0]?.finalName || ''
const url = data.filePath || ''
const name = data.finalName || ''
fileIndex = fileList.value.findIndex((file) => file.uid === uid)
......
......@@ -30,7 +30,7 @@
</div>
</div>
<el-progress :percentage="uploadProgress" :stroke-width="8" class="progress-bar" />
<el-button type="danger" size="small" @click="cancelUpload" class="cancel-btn">
<el-button type="danger" size="small" @click.stop="cancelUpload" class="cancel-btn">
取消上传
</el-button>
</div>
......@@ -163,6 +163,7 @@ const handleFileChange = async (file: UploadFile) => {
await startUpload()
}
let cancelUploadController = () => {}
// 开始上传
const startUpload = async () => {
if (!currentFile.value) return
......@@ -173,9 +174,14 @@ const startUpload = async () => {
uploadProgress.value = 0
// 调用你的上传方法
const { data } = await uploadFileApi(currentFile.value, (progress) => {
uploadProgress.value = progress
const { promise, cancel } = uploadFileApi(currentFile.value, {
onProgress: (progress) => {
uploadProgress.value = progress
},
})
cancelUploadController = cancel
const data = await promise
console.log(data)
// 获取视频元数据
......@@ -183,15 +189,15 @@ const startUpload = async () => {
// 根据你的 API 返回结构调整
const videoData: VideoInfo = {
url: data.data[0]?.filePath || '',
url: data.filePath || '',
// 暂时写死
// url: 'https://soundasia.oss-cn-shenzhen.aliyuncs.com/OA/readName/mp4/2025/11/12/Common/1762918987602.mp4',
name: currentFile.value.name,
size: currentFile.value.size,
duration: metadata.duration,
resolution: metadata.resolution,
poster: data.data[0]?.filePath || '',
fileId: data.data[0]?.fileId || '',
poster: data.filePath || '',
fileId: data.fileId || '',
}
videoInfo.value = videoData
......@@ -215,6 +221,7 @@ const startUpload = async () => {
// 取消上传
const cancelUpload = () => {
cancelUploadController()
uploading.value = false
uploadProgress.value = 0
ElMessage.info('已取消上传')
......@@ -233,6 +240,20 @@ const retryUpload = () => {
uploadError.value = ''
startUpload()
}
// reset
const reset = () => {
uploadRef.value = null
uploading.value = false
uploadProgress.value = 0
uploadError.value = ''
currentFile.value = null
videoInfo.value = null
modelValue.value = ''
}
defineExpose({
reset,
})
</script>
<style scoped>
......
......@@ -37,9 +37,9 @@ const editorConfig = {
MENU_CONF: {
uploadImage: {
customUpload: async (file: File, insertFn: (url: string) => void) => {
const { data } = await uploadFile(file)
console.log(data)
insertFn(data.data[0]?.filePath || '')
const { promise } = uploadFile(file)
const data = await promise
insertFn(data.filePath)
},
},
},
......
......@@ -107,7 +107,7 @@
</template>
<script setup lang="tsx">
import { addOrUpdateCase } from '@/api'
import { addOrUpdateCase, getCaseDetail } from '@/api'
import { useResetData } from '@/hooks'
import type { AddOrUpdateCaseDto } from '@/api'
import SelectTags from '@/components/common/SelectTags/index.vue'
......@@ -117,6 +117,7 @@ import { TagTypeEnum, TagLevelEnum, BooleanFlag, ReleaseStatusTypeEnum } from '@
import { selectDepOrUser } from '@/utils'
import { useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'
import type { ISelectDept } from '@/utils/wxUtil'
const router = useRouter()
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
......@@ -137,10 +138,7 @@ const [form, resetForm] = useResetData({
relatedScenariosMainTagId: '',
relatedScenariosSubTagIds: [],
isSync: BooleanFlag.NO,
releaseStatus: ReleaseStatusTypeEnum.PUBLISH,
deptId: '',
deptName: '',
departmentList: [],
departmentList: [] as ISelectDept[],
})
// 选择部门
......@@ -187,6 +185,7 @@ const transformData = (releaseStatus: ReleaseStatusTypeEnum): AddOrUpdateCaseDto
...rest,
releaseStatus,
tagRelationDtoList: [],
sourceUser: '',
}
// 添加文化标签内容
obj.tagRelationDtoList.push({
......@@ -302,8 +301,46 @@ const filterRelatedScenariosTagsFn = (allTags: TagItemDto[]) => {
return allTags.filter((tag) => tag.id !== Number(form.value.relatedScenariosMainTagId))
}
onActivated(() => {
showSubmissionGuide()
onDeactivated(() => {
// 重置表单
resetForm()
})
onActivated(async () => {
const id = Number(router.currentRoute.value.query.id)
if (id) {
// 编辑草稿箱
const { data } = await getCaseDetail(id)
const cultureTagList = data.caseTags.filter((i) => i.type === TagTypeEnum.CULTURE_TAG)
const relatedScenariosTagList = data.caseTags.filter((i) => i.type === TagTypeEnum.SCENE_TAG)
const obj = {
id: data.id,
title: data.title,
content: data.content,
mainTagId: String(
cultureTagList.find((i) => i.keywordType === TagLevelEnum.MAIN_TAG)?.tagId || '',
),
subTagIds: cultureTagList
.filter((i) => i.keywordType === TagLevelEnum.SUB_TAG)
.map((i) => i.tagId),
relatedScenariosMainTagId: String(
relatedScenariosTagList.find((i) => i.keywordType === TagLevelEnum.MAIN_TAG)?.tagId || '',
),
relatedScenariosSubTagIds: relatedScenariosTagList
.filter((i) => i.keywordType === TagLevelEnum.SUB_TAG)
.map((i) => i.tagId),
isSync: data.isSync,
departmentList: data.depIdList.map((id, index) => ({
id,
name: data.depNameList[index],
})),
}
form.value = obj
console.log('form', form.value)
} else {
showSubmissionGuide()
}
})
</script>
......
......@@ -430,6 +430,7 @@ const handleSubmit = async (releaseStatus: ReleaseStatusTypeEnum) => {
: await addOrUpdateArticle(transFormData(releaseStatus))
console.log(res)
drawerVisible.value = false
ElMessage.success(releaseStatus === ReleaseStatusTypeEnum.PUBLISH ? '发布成功' : '存草稿成功')
resetForm()
router.back()
// 发布成功后的逻辑...
......
......@@ -12,7 +12,11 @@
<h3 class="text-xl font-bold text-gray-800">上传视频</h3>
</div>
<el-form-item prop="videoUrl">
<UploadVideo v-model="form.videoUrl" @uploadSuccess="handleVideoChange" />
<UploadVideo
v-model="form.videoUrl"
@uploadSuccess="handleVideoChange"
ref="uploadVideoRef"
/>
</el-form-item>
</div>
......@@ -339,7 +343,7 @@
import UploadVideo from '@/components/common/UploadVideo/index.vue'
import { useResetData } from '@/hooks'
import { ArticleTypeEnum, ReleaseStatusTypeEnum, SendTypeEnum } from '@/constants'
import { addOrUpdateArticle, uploadFile, getArticleDetail } from '@/api'
import { addOrUpdateArticle, uploadFile } from '@/api'
import SelectTags from '@/components/common/SelectTags/index.vue'
import type { TagItemDto, AddOrUpdateVideoDto } from '@/api'
import { Camera, Picture } from '@element-plus/icons-vue'
......@@ -360,7 +364,7 @@ const router = useRouter()
const route = useRoute()
const formRef = useTemplateRef('formRef')
const coverInputRef = useTemplateRef('coverInputRef')
const uploadVideoRef = useTemplateRef('uploadVideoRef')
const [form, resetData] = useResetData<AddOrUpdateVideoDto>({
videoUrl: '',
title: '',
......@@ -467,8 +471,9 @@ const captureFrame = () => {
async (blob) => {
if (blob) {
// 直接在这里上传 不转为本地了
const { data } = await uploadFile(new File([blob], `video${Date.now()}.jpg`))
form.value.faceUrl = data.data[0].filePath
const { promise } = uploadFile(new File([blob], `video${Date.now()}.jpg`))
const data = await promise
form.value.faceUrl = data.filePath
ElMessage.success('封面截取成功')
}
},
......@@ -581,9 +586,15 @@ const handleFileChange = async (e: Event) => {
const target = e.target as HTMLInputElement
const file = target.files?.[0]
if (!file) return
const { data } = await uploadFile(file)
form.value.faceUrl = data.data[0].filePath
const { promise } = uploadFile(file)
const data = await promise
form.value.faceUrl = data.filePath
}
onDeactivated(() => {
// 清空页面的数据
resetPageData()
uploadVideoRef.value?.reset()
})
// const isEdit = computed(() => {
// return !!route.query.id
......
......@@ -63,7 +63,9 @@
</div> -->
</div>
<div class="text-gray-700 font-medium">举报理由:{{ item.reason }}</div>
<div class="text-gray-700 font-medium truncate line-clamp-1">
举报理由:{{ item.reason }}
</div>
</div>
</div>
</div>
......
......@@ -26,7 +26,9 @@
class="flex items-center p-2 rounded-lg hover:bg-gray-100 transition-colors cursor-pointer"
>
<div class="flex-1 min-w-0">
<div class="text-gray-900 font-medium truncate">{{ item.title }}</div>
<div class="text-gray-900 font-medium truncate line-clamp-1">
{{ item.title }}
</div>
<div class="text-gray-500 text-sm mt-1 truncate">
<span class="mr-2">
{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
......@@ -39,7 +41,7 @@
<el-button
type="primary"
link
@click="jumpToArticleDetailPage({ type: 'question', id: item.id })"
@click="jumpToArticleDetailPage({ type: ArticleTypeEnum.QUESTION, id: item.id })"
>去回复</el-button
>
</div>
......@@ -73,6 +75,7 @@ import { answerQuestionPage } from '@/api'
import { usePageSearch } from '@/hooks'
import dayjs from 'dayjs'
import { jumpToArticleDetailPage } from '@/utils'
import { ArticleTypeEnum } from '@/constants'
const { list, loading, searchParams, total, refresh, goToPage, changePageSize } = usePageSearch(
answerQuestionPage,
......
......@@ -54,7 +54,7 @@
</div>
<!-- 第二行:标题 -->
<div class="text-gray-700 font-medium">
<div class="text-gray-700 font-medium truncate line-clamp-1">
{{ item.title }}
</div>
</div>
......
......@@ -2,6 +2,24 @@
<div class="flex-1 flex flex-col" v-loading="loading">
<!-- List Container -->
<div class="flex-1 p-4 pt-1">
<div class="relative">
<el-tabs v-model="searchParams.releaseStatus" @tab-change="toggleTab">
<el-tab-pane
v-for="tab in caseTypeListOptions"
:key="tab.value"
:label="tab.label"
:name="tab.value"
/>
</el-tabs>
<div class="absolute right-0 top-2.5 z-1000">
<el-icon
size="15"
class="cursor-pointer hover:rotate-180 transition-all duration-300"
@click="refresh"
><Refresh
/></el-icon>
</div>
</div>
<div v-if="!list.length" class="flex flex-col items-center justify-center h-64">
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4">
<el-icon class="text-2xl text-gray-300"><Document /></el-icon>
......@@ -17,11 +35,25 @@
>
<!-- Content -->
<div class="flex-1 min-w-0">
<div class="text-gray-900 font-medium truncate">{{ item.title }}</div>
<div class="text-gray-900 font-medium truncate line-clamp-1">
{{ item.title }}
</div>
<div class="text-gray-500 text-sm mt-1 truncate">
<span class="mr-2">
{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<span class="mr-2">
<el-tag v-if="item.isAudit === AuditStatusEnum.UNAUDITED" type="warning"
>待审核</el-tag
>
<el-tag
v-else-if="item.isAudit === AuditStatusEnum.AGREED"
type="success"
size="small"
>已通过</el-tag
>
<el-tag v-else type="warning">已驳回</el-tag>
</span>
<!-- <span class="mr-2">浏览 {{ item.viewCount }}</span>
<span class="mr-2">点赞 {{ item.replyCount }}</span>
<span class="mr-2">评论 {{ item.collectionCount }}</span>
......@@ -31,8 +63,25 @@
<!-- Meta Info -->
<div class="flex items-center text-gray-400 text-sm ml-4">
<el-button type="primary" link>编辑</el-button>
<el-button type="danger" link>删除</el-button>
<el-button type="primary" link @click="handleEdit(item)">
{{
searchParams.releaseStatus === ReleaseStatusTypeEnum.PUBLISH &&
item.isAudit !== AuditStatusEnum.UNAUDITED
? '查看'
: '编辑'
}}
</el-button>
<el-button
v-if="
searchParams.releaseStatus === ReleaseStatusTypeEnum.DRAFT ||
(searchParams.releaseStatus === ReleaseStatusTypeEnum.PUBLISH &&
item.isAudit === AuditStatusEnum.UNAUDITED)
"
type="danger"
link
@click="handleDelete(item)"
>删除</el-button
>
</div>
</div>
</div>
......@@ -58,13 +107,167 @@
</div>
</template>
<script lang="ts" setup>
<script lang="tsx" setup>
import { Document } from '@element-plus/icons-vue'
import { getSelfCaseList } from '@/api'
import { getSelfCaseList, deleteCase, getCaseDetail } from '@/api'
import { usePageSearch } from '@/hooks'
import dayjs from 'dayjs'
import { ReleaseStatusTypeEnum, AuditStatusEnum } from '@/constants'
import type { TabPaneName } from 'element-plus'
import type { SelfCaseItemDto } from '@/api/user/types'
const router = useRouter()
const caseTypeListOptions = [
{ label: '已发布', value: ReleaseStatusTypeEnum.PUBLISH },
{ label: '草稿', value: ReleaseStatusTypeEnum.DRAFT },
]
const toggleTab = (key: TabPaneName) => {
searchParams.value.releaseStatus = key as ReleaseStatusTypeEnum
refresh()
}
const { list, loading, searchParams, total, goToPage, changePageSize, refresh } = usePageSearch(
getSelfCaseList,
{
defaultParams: {
releaseStatus: caseTypeListOptions[0]!.value,
},
immediate: false,
},
)
const handleEdit = async (item: SelfCaseItemDto) => {
if (
searchParams.value.releaseStatus === ReleaseStatusTypeEnum.PUBLISH &&
item.isAudit !== AuditStatusEnum.UNAUDITED
) {
// 根据 id获取详情数据
const { data } = await getCaseDetail(item.id)
console.log(data)
// 打开弹窗 查看详情
const formData = {
title: data.title,
content: data.content,
keywords: [data.cultureKeywordMain, ...(data.cultureKeywordSub || [])].filter(Boolean),
scenes: [data.sceneKeywordMain, ...(data.sceneKeywordSub || [])].filter(Boolean),
departments: data.depNameList.filter(Boolean),
syncPublish: data.isSync ? '是' : '否',
}
console.log(formData)
ElMessageBox({
title: '案例详情',
message: (
<div class="max-h-500px overflow-y-auto px-4">
{/* 标题 */}
<div class="mb-5">
<div class="text-13px text-gray-500 mb-2 flex items-center">
<span class="text-red-500 mr-1">*</span>
标题
</div>
<div class="bg-gray-50 rounded-lg px-4 py-3 text-gray-700">{formData.title}</div>
</div>
{/* 内容 */}
<div class="mb-5">
<div class="text-13px text-gray-500 mb-2 flex items-center">
<span class="text-red-500 mr-1">*</span>
内容
</div>
<div class="bg-gray-50 rounded-lg px-4 py-3 text-gray-700 min-h-80px whitespace-pre-wrap break-words">
{formData.content}
</div>
</div>
{/* 文化关键词 */}
<div class="mb-5">
<div class="text-13px text-gray-500 mb-2 flex items-center">
<span class="text-red-500 mr-1">*</span>
文化关键词
</div>
<div class="flex flex-wrap gap-2">
{formData.keywords.map((keyword, index) => (
<span key={index} class="px-3 py-1.5 bg-blue-50 text-blue-600 rounded-md text-13px">
{keyword}
</span>
))}
</div>
</div>
{/* 关联场景 */}
<div class="mb-5">
<div class="text-13px text-gray-500 mb-2">关联场景</div>
{formData.scenes.length > 0 ? (
<div class="flex flex-wrap gap-2">
{formData.scenes.map((scene, index) => (
<span
key={index}
class="px-3 py-1.5 bg-blue-50 text-blue-600 rounded-md text-13px"
>
{scene}
</span>
))}
</div>
) : (
<div class="text-gray-400 text-13px">暂无</div>
)}
</div>
{/* 关联部门 */}
<div class="mb-5">
<div class="text-13px text-gray-500 mb-2">关联部门</div>
{formData.departments.length > 0 ? (
<div class="flex flex-wrap gap-2">
{formData.departments.map((dept, index) => (
<span
key={index}
class="px-3 py-1.5 bg-gray-50 text-gray-700 rounded-md text-13px"
>
{dept}
</span>
))}
</div>
) : (
<div class="text-gray-400 text-13px">暂无</div>
)}
</div>
{/* 是否同步发布到实践 */}
<div>
<div class="text-13px text-gray-500 mb-2 flex items-center">
<span class="text-red-500 mr-1">*</span>
是否同步发布到实践
</div>
<div class="px-4 py-2.5 bg-gray-50 rounded-lg text-gray-700 inline-block">
{formData.syncPublish}
</div>
</div>
</div>
),
confirmButtonText: '确定',
showCancelButton: false,
width: '680px', // 从 520px 增加到 680px
customClass: 'form-detail-dialog',
})
} else {
router.push(`/publishCase?id=${item.id}`)
}
}
const handleDelete = async (item: SelfCaseItemDto) => {
await ElMessageBox.confirm('确定删除该案例吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
await deleteCase(item.id)
ElMessage.success('删除成功')
refresh()
}
const { list, loading, searchParams, total, goToPage, changePageSize } =
usePageSearch(getSelfCaseList)
onActivated(() => {
refresh()
})
</script>
......@@ -34,15 +34,15 @@
class="flex items-center p-2 rounded-lg hover:bg-gray-100 transition-colors cursor-pointer"
>
<div class="flex-1 min-w-0">
<div class="text-gray-900 font-medium truncate">{{ item.title }}</div>
<div class="text-gray-900 font-medium truncate line-clamp-1">{{ item.title }}</div>
<div class="text-gray-500 text-sm mt-1 truncate">
<span class="mr-2">
{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<span class="mr-2">浏览 {{ item.viewCount }}</span>
<span class="mr-2">点赞 {{ item.replyCount }}</span>
<span class="mr-2">评论 {{ item.collectionCount }}</span>
<span class="mr-2">收藏 {{ item.praiseCount }}</span>
<span class="mr-2">点赞 {{ item.praiseCount }}</span>
<span class="mr-2">评论 {{ item.replyCount }}</span>
<span class="mr-2">收藏 {{ item.collectionCount }}</span>
</div>
</div>
......@@ -113,6 +113,7 @@ const { list, loading, searchParams, total, refresh, goToPage, changePageSize }
defaultParams: {
type: filterArticleType.value[0]!.value,
},
immediate: false,
},
)
......
......@@ -50,7 +50,7 @@
>
<!-- Content -->
<div class="flex-1 min-w-0 space-y-1.5">
<div class="text-gray-900 font-medium text-base line-clamp-2">
<div class="text-gray-900 font-medium text-base line-clamp-1">
{{ item.title }}
</div>
<div class="text-gray-600 text-sm line-clamp-2">评论内容:{{ item.content }}</div>
......
......@@ -36,7 +36,7 @@
>
<!-- Content -->
<div class="flex-1 min-w-0">
<div class="text-gray-900 font-medium truncate">{{ item.title }}</div>
<div class="text-gray-900 font-medium truncate line-clamp-1">{{ item.title }}</div>
<div class="text-gray-500 text-sm mt-1 truncate">
<span class="mr-2">
{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
......@@ -113,6 +113,7 @@ const { list, loading, searchParams, total, refresh, goToPage, changePageSize }
defaultParams: {
type: filterArticleType.value[0]!.value,
},
immediate: false,
},
)
......
......@@ -33,7 +33,7 @@
class="flex items-center p-2 rounded-lg hover:bg-gray-100 transition-colors cursor-pointer"
>
<div class="flex-1 min-w-0">
<div class="text-gray-900 font-medium truncate">{{ item.title }}</div>
<div class="text-gray-900 font-medium truncate line-clamp-1">{{ item.title }}</div>
<div class="text-gray-500 text-sm mt-1 truncate">
<span class="mr-2">
{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
......@@ -111,6 +111,7 @@ const { list, loading, searchParams, total, refresh, goToPage, changePageSize }
defaultParams: {
type: filterArticleType.value[0]!.value,
},
immediate: false,
},
)
......
......@@ -34,15 +34,15 @@
class="flex items-center p-2 rounded-lg hover:bg-gray-100 transition-colors cursor-pointer"
>
<div class="flex-1 min-w-0">
<div class="text-gray-900 font-medium truncate">{{ item.title }}</div>
<div class="text-gray-900 font-medium truncate line-clamp-1">{{ item.title }}</div>
<div class="text-gray-500 text-sm mt-1 truncate">
<span class="mr-2">
{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</span>
<span class="mr-2">浏览 {{ item.viewCount }}</span>
<span class="mr-2">点赞 {{ item.replyCount }}</span>
<span class="mr-2">评论 {{ item.collectionCount }}</span>
<span class="mr-2">收藏 {{ item.praiseCount }}</span>
<span class="mr-2">点赞 {{ item.praiseCount }}</span>
<span class="mr-2">评论 {{ item.replyCount }}</span>
<span class="mr-2">收藏 {{ item.collectionCount }}</span>
</div>
</div>
......@@ -118,6 +118,7 @@ const { list, loading, searchParams, total, refresh, goToPage, changePageSize }
defaultParams: {
type: filterArticleType.value[0]!.value,
},
immediate: false,
},
)
......
......@@ -42,7 +42,7 @@
<!-- 主要内容区域 -->
<div class="relative -mt-20 p-6">
<div class="flex gap-6">
<div class="flex gap-6 w-100% flex-nowrap">
<!-- 左侧个人信息卡片 -->
<div class="w-300px">
<!-- 个人信息卡片 -->
......@@ -135,7 +135,7 @@
<!-- 左侧菜单 -->
</div>
<!-- 右侧内容区域 -->
<div class="flex-1">
<div class="flex-1 min-w-0">
<div class="bg-white rounded-lg shadow-sm min-h-500px">
<router-view v-slot="{ Component, route }">
<transition name="fade" mode="out-in">
......
......@@ -224,7 +224,13 @@
</div>
</div>
<Comment ref="commentRef" :id="videoId" v-model:total="videoDetail.replyCount" :isReal="0" />
<Comment
ref="commentRef"
:id="videoId"
v-model:total="videoDetail.replyCount"
:isReal="0"
class="mt-5"
/>
<RewardDialog ref="rewardDialogRef" v-model:rewardNum="videoDetail.rewardNum" />
</div>
</template>
......@@ -246,7 +252,7 @@ import ActionMore from '@/components/common/ActionMore/index.vue'
import { jumpToUserHomePage } from '@/utils'
const route = useRoute()
const videoId = route.params.id as string
const videoId = Number(route.params.id)
// 视频详情
const videoDetail = ref({} as ArticleItemDto)
......
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