Files
front-pc/pages/down-drawe-detail/index.vue
2025-08-26 16:25:58 +08:00

351 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<KlNavTab />
<div class="ml-auto mr-auto mt-20px w1440">
<div class="flex items-center">
<div class="box-border h-60px w-1019px flex items-center justify-between border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] px-27px py-24px">
<div class="text-20px text-[#333333] font-normal"> {{ detail.title }}</div>
<div class="flex items-center">
<img :src="detail.ownedUserIdInfo?.avatar" alt="" srcset="" class="h-30px w-30px rd-50%" />
<span class="ml-12px color-#999999">by {{ detail.ownedUserIdInfo?.nickName }}</span>
</div>
</div>
<div class="ml-23px flex flex-1 text-18px text-[#FFFFFF] font-normal">
<div class="h-60px w-160px flex cursor-pointer items-center justify-center rounded-8px bg-[#1A65FF]" @click="handleDownload">
<img src="~/assets/images/download.png" alt="" srcset="" class="mr-4px h-22px w-27px" />
{{ detail.points === 0 ? '免费下载' : '立即下载' }}
</div>
<div
v-if="!detail.favoriteId"
class="ml-11px h-60px flex flex-1 cursor-pointer items-center justify-center rounded-8px bg-[#E7B03B]"
@click="handleCollect"
><img src="~/assets/images/collect.png" alt="" srcset="" class="mr-4px h-24px w-24px" /> 收藏</div
>
<div v-else class="ml-11px h-60px flex flex-1 cursor-pointer items-center justify-center rounded-8px bg-[#E7B03B]" @click="handleCollect"
><img src="~/assets/images/wjx2.png" alt="" srcset="" class="mr-4px h-18px w-18px" /> 已收藏</div
>
<div class="ml-11px h-60px flex flex-1 cursor-pointer items-center justify-center rounded-8px bg-[#F56C6C]" @click="handleReport"
><el-icon class="mr-4px mt-4px"><Warning /></el-icon> 举报</div
>
</div>
</div>
</div>
<!-- -->
<div class="ma-auto mt-21px flex">
<div class="w-1019px">
<div>
<ThumBnail :data="detail.coverImages" :type="detail.type" @change-swiper="changeSwiper" @next-swiper="nextSwiper"></ThumBnail>
</div>
<div class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div><span class="ml-10px">{{ detail.title }}描述</span></div
>
<div class="box-border min-h-90px w-1019px border border-[#EEEEEE] rounded-6px border-solid bg-[#FFFFFF] pa-24px text-14px text-[#333333] font-normal">
{{ detail.description }}
</div>
<div id="section1" class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div><span class="ml-10px">{{ detail.title }}附件</span></div
>
<div class="box-border w-1019px border border-[#EEEEEE] rounded-6px border-solid bg-[#FFFFFF] pa-24px">
<div class="border-b-1px border-b-[#eee] border-b-solid p-b-10px">
{{ detail.type === 1 ? '图纸' : detail.type === 2 ? '文本' : '模型' }}中包含的文件
</div>
<div>
<div v-for="item in detail.files" :key="item.id" class="flex items-center justify-between border-b-1px border-b-[#eee] border-b-solid py-10px">
<!-- <img src="~/assets/images/avater.png" alt="" srcset="" class="h-30px w-30px" /> -->
<div>
<span class="ml-10px cursor-pointer" @click="handleDownloadPreview(item)">{{ item.title }}</span>
<span v-if="item.size" class="ml-200px color-#999">{{ item.size || '-' }}</span>
</div>
<el-button
v-if="detail.downloadId || detail.points === 0"
type="text"
tag="a"
target="download"
:href="item.url"
@click="handleDownloadFile(item.url, item.title)"
>
下载
</el-button>
</div>
</div>
</div>
<!-- 关联项目 -->
<div class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div
><span class="ml-10px">关联{{ detail.type === 1 ? '图纸' : detail.type === 2 ? '文本' : '模型' }}</span></div
>
<el-row :gutter="20">
<el-col v-for="(item, index) in detail.relationDraws" :key="index" :span="12">
<CardPicture :item-info="item" />
</el-col>
</el-row>
<el-empty v-if="!detail.relationDraws?.length" description="暂无数据"></el-empty>
<!-- 关联模型 -->
<div class="mb-20px mt-34px flex items-center text-16px text-[#333333] font-normal">
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div
><span class="ml-10px">相关{{ detail.type === 1 ? '图纸' : detail.type === 2 ? '文本' : '模型' }}推荐</span></div
>
<el-row :gutter="20">
<el-col v-for="(item, index) in relationRecommend" :key="index" :span="12">
<CardPicture :item-info="item" />
</el-col>
</el-row>
<!-- 评论 -->
<CommentSection :relation-id="detail.id" :project-id="detail.projectId" />
</div>
<div class="ml-22px">
<div class="box-border h-269px w-397px border border-[#EEEEEE] rounded-12px border-solid bg-[#FFFFFF] pa-22px">
<div class="mb-10px">图纸ID: {{ detail.id }}</div>
<div class="mb-10px">文件大小{{ detail.filesInfo?.fileSize || 0 }} </div>
<!-- <div class="mb-10px">图纸版本{{ detail.editionsName }} </div> -->
<div class="mb-10px">图纸格式{{ detail.formatType?.toString() }}</div>
<div class="mb-10px">所需金币{{ detail.points }}金币</div>
<div class="mb-10px">发布时间{{ dayjs(detail.createTime).format('YYYY-MM-DD HH:mm:ss') }}</div>
<div class="mb-10px">图纸参数{{ detail.editTypeName }}</div>
<div class="mb-10px">图纸分类{{ detail.projectTypeName }}</div>
<div class="mb-10px">软件分类{{ detail.editionsName }}</div>
</div>
<div class="mt-20px w-398px border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid bg-[#FFFFFF]">
<img src="~/assets/images/banner.png" alt="" srcset="" class="w-100%" />
<div class="box-border border border-[#EEEEEE] border-rd-[10px_10px_0px_0px] border-solid border-t-none bg-[#FFFFFF] pa-18px">
<div class="flex flex-wrap items-start">
<div v-if="userInfo.nickname" class="mt-10px text-18px text-[#333333] font-bold">{{ userInfo.nickname }}</div>
<div
v-for="item in userInfo.labels"
:key="item"
class="mb-10px ml-10px box-border border border-[#1A65FF] rounded-13px border-solid px-8px py-3px color-#1a65ff"
>{{ item }}</div
>
</div>
<div v-if="userInfo.description" class="mb-20px text-14px text-[#333333] font-normal">{{ userInfo.description }}</div>
<!-- 显示作品 粉丝 荣誉证书 -->
<div class="flex items-center gap-40px">
<div class="flex items-center">
<div class="h-20px">
<img src="~/assets/images/folder.png" alt="works" class="w-80%" />
</div>
<div class="ml-8px mt--4px text-14px text-[#666] font-normal">作品: {{ userInfo.projectCount || 0 }}</div>
</div>
<div class="flex items-center">
<div class="h-20px">
<img src="~/assets/images/user4.png" alt="fans" class="w-80% rounded-full vertical-top" />
</div>
<div class="relative top--3px ml-8px text-14px text-[#666] font-normal">粉丝: {{ userInfo.fansCount || 0 }}</div>
</div>
</div>
<!-- 3个图片一排 超过换下一行 -->
<div v-if="userInfo.files?.length" class="mt-20px flex flex-wrap gap-16px">
<div v-for="i in userInfo.files" :key="i" class="flex-1">
<div
class="box-border h-200px w-full overflow-hidden border border-[#E5E7EB] rounded-8px border-solid from-[#FFFFFF] to-[#F5F7FA] bg-gradient-to-b p-16px"
>
<el-image :src="i.url" fit="cover" alt="" srcset="" class="h-full object-cover" />
</div>
</div>
</div>
<div class="mt-20px h-1px w-336px rounded-1px bg-[#EEEEEE]"></div>
<div class="mt-20px flex items-center">
<div class="h-24px w-4px rounded-1px bg-[#1A65FF]"></div>
<span class="ml-10px text-16px">最新发布</span>
</div>
<div class="mt-10px">
<div
v-for="item in mainWork"
:key="item.id"
class="flex cursor-pointer items-center justify-between px-10px py-10px hover:bg-#f5f5f5"
@click="handleClick(item.id)"
>
<div class="ellipsis text-15px text-[#333333] font-normal">{{ item.title }}</div>
<span class="ml-10px flex-shrink-0 color-#999999">{{ dayjs(item.createTime).format('MM-DD') }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import dayjs from 'dayjs'
import { downloadFile } from '~/utils/utils'
import { useMessage } from '~/utils/useMessage'
import { Warning } from '@element-plus/icons-vue'
import CardPicture from '~/components/kl-card-picture/index.vue'
import { getDetail, getRelationRecommend, report, getUserInfo, getMainWork, createContent, createUserProject, deleteProject } from '~/api/drawe-detail/index'
import KlNavTab from '~/components/kl-nav-tab/index.vue'
import ThumBnail from './components/swiper.vue'
import CommentSection from '~/components/comment-section/index.vue'
import { useRoute } from 'vue-router'
import { ref } from 'vue'
import type { ProjectRespVO, ProjectDrawPageRespVO, UserExtendSimpleRespDTO, ProjectDrawMemberRespVO } from '~/api/drawe-detail/types'
import useUserStore from '~/stores/user'
const message = useMessage()
const userStore = useUserStore()
// 获取路由参数
const route = useRoute()
const id = route.query.id as string
// 获取详情
const detail = ref<ProjectRespVO>({} as ProjectRespVO)
const init = () => {
getDetail({ id }).then((res) => {
if (res.code === 0) {
detail.value = res.data
// 获取推荐信息
getRelationRecommendList()
// 获取用户信息
handleGetUserInfo()
// 最新发布
handleGetMainWork()
}
})
}
init()
// 获取最新发布
const mainWork = ref<ProjectDrawMemberRespVO[]>([])
const handleGetMainWork = () => {
getMainWork({ id: detail.value.id, limit: 10, memberId: detail.value.ownedUserId }).then((res) => {
if (res.code === 0) {
mainWork.value = res.data
}
})
}
// 获取用户信息
const userInfo = ref<UserExtendSimpleRespDTO>({} as UserExtendSimpleRespDTO)
const handleGetUserInfo = () => {
getUserInfo({ id: detail.value.id }).then((res) => {
if (res.code === 0) {
userInfo.value = res.data
}
})
}
// 获取关联推荐
const relationRecommend = ref<ProjectDrawPageRespVO[]>([])
const getRelationRecommendList = () => {
getRelationRecommend({ type: detail.value.type, projectType: detail.value.projectType[0] }).then((res) => {
if (res.code === 0) {
relationRecommend.value = res.data
}
})
}
const changeSwiper = (index: number) => {
console.log(index)
}
const nextSwiper = (val: any) => {
console.log(val)
}
const handleDownloadPreview = (item: any) => {
// 预览pdf
navigateTo(`/pdf-preview?url=${item.url}`)
}
/** 获取下载类型 */
const getType = (type: number) => {
if (type === 1 || type === 2 || type === 3) {
// 图纸 文本 模型都传1
return 1
}
// 工具箱传
return 2
}
const handleDownload = async () => {
if (!userStore.token) {
ElMessage.error('请先登录')
return
}
if (detail.value.points === 0) {
scrollTo()
return
}
if (detail.value.downloadId) {
ElMessage.success('您已获取下载权限')
scrollTo()
return
}
const res = await message.confirm(`是否花费${detail.value.points}金币下载此资源,是否继续?`, '提示')
if (res) {
createUserProject({ relationId: detail.value.id, type: getType(detail.value.type) }).then((res) => {
if (res.code === 0) {
ElMessage.success('获取下载权限成功')
detail.value.downloadId = res.data
scrollTo()
}
})
}
}
const scrollTo = () => {
const element = document.getElementById('section1')
if (element) {
element.scrollIntoView({
behavior: 'smooth',
})
}
}
const handleReport = () => {
if (!userStore.token) {
ElMessage.error('请先登录')
return
}
console.log('举报')
ElMessageBox.prompt('说明内容', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPlaceholder: '请输入举报内容',
inputErrorMessage: '请输入举报内容',
}).then(({ value }) => {
report({
id: detail.value.id,
title: detail.value.title,
files: detail.value.files,
comments: value,
projectId: detail.value.projectId,
drawId: detail.value.id,
}).then((res) => {
if (res.code === 0) {
ElMessage.success('举报成功')
}
})
})
}
const handleCollect = async () => {
if (!userStore.token) {
ElMessage.error('请先登录')
return
}
const res = detail.value.favoriteId
? await deleteProject({ id: detail.value.favoriteId })
: await createContent({
projectId: detail.value.projectId,
drawId: detail.value.id,
})
if (res.code === 0) {
ElMessage.success(`${detail.value.favoriteId ? '取消' : '收藏'}成功`)
init()
}
}
const handleClick = (id: string | number) => {
navigateTo(`/down-drawe-detail?id=${id}`) // 修改为在新窗口打开
}
const handleDownloadFile = (url: string, name: string) => {
downloadFile(url, name)
}
</script>