mcwl-pc/app/components/PersonalCenterCard.vue

409 lines
11 KiB
Vue

<script setup lang="ts">
import {
CircleAlert,
Download,
EllipsisVertical,
Play
} from 'lucide-vue-next';
import { NConfigProvider, NMessageProvider } from "naive-ui";
import { nextTick, ref } from 'vue';
import { useRouter } from 'vue-router';
const props = defineProps({
item: {
type: Object,
default: () => ({}),
},
currentType: {
type: String,
default: '',
},
currentState: {
type: String,
default: '',
},
})
// 定义 emit
const emit = defineEmits(['topedRefresh'])
const router = useRouter()
// 跳转详情
function toDetails() {
if (props.currentType === '0') {
router.push(`/model-details/${props.item.id}`)
}
else if (props.currentType === '1') {
// console.log('object', 111);
router.push(`/workflow-details/${props.item.id}`)
}else if(props.currentType === '2'){
onEditPicture()
}
}
// 获取图片详情进行编辑
const publishPictureData = ref<any>({})
async function getPublishPicture() {
try {
const res = await request.get(`/image/detail?id=${props.item.id}`)
if (res.code === 200) {
publishPictureData.value = res.data
publishPictureData.value.imagePaths = res.data.imagePaths.split(',')
// publishPictureData.value.tags = res.data.tags.split(',')
}
}
catch (e) {
console.log(e)
}
}
// 处理下拉菜单选项 编辑/删除/置顶
function handleSelect(event: Event, key: string) {
event.stopPropagation() // 阻止事件冒泡
if (key === 'top') {
handleTop()
}
else if (key === 'delete') {
handleDelete()
}
else if (key === 'edit') {
if (props.currentType === '2') { // 图片
getPublishPicture()
showPublishImg()
}
else if (props.currentType === '1') { // 工作流
router.push({
path: `/publish-workflow`,
query: {
type: 'edit',
id: props.item.id,
},
})
}
else if (props.currentType === '0') { // 模型
router.push({
path: `/publish-model`,
query: {
type: 'edit',
id: props.item.id,
},
})
}
}
}
// 置顶
interface TopUrlType {
[key: string | number]: string
}
const topUrl = ref<TopUrlType>({
0: 'model',
1: 'WorkFlow',
2: 'image',
})
async function handleTop() {
try {
const res = await request.get(
`/${topUrl.value[props.currentType]}/${props.item.id}/top?isTop=${!props.item
.isTop}`,
)
if (res.code === 200) {
// 刷新列表
emit('topedRefresh')
}
}
catch (e) {}
}
// 删除
interface Response {
code: number
}
async function handleDelete(): Promise<void> {
const { currentType, item } = props
let url: string
switch (currentType) {
case '0':
url = `/model/delete?id=${item.id}`
break
case '1':
url = `/WorkFlow/deleteWorkFlow?id=${item.id}`
break
default:
url = `/image/delete?id=${item.id}`
break
}
try {
const res: Response = await request.get(url)
if (res.code === 200) {
// 刷新列表
emit('topedRefresh')
}
}
catch (e) {
// 统一处理错误
console.error('删除操作失败:', e)
}
}
function getFirstImagePath(imagePaths: string): string {
if (!imagePaths)
return ''
return imagePaths.split(',')[0] || ''
}
// 关闭图片
const isShowPublishPicture = ref<boolean>(false)
const PublishPictureRef = ref<Payment | null>(null)
function showPublishImg() {
isShowPublishPicture.value = true
if (PublishPictureRef.value) {
PublishPictureRef.value.isVisible = true
}
}
function closePublishImg() {
isShowPublishPicture.value = false
if (PublishPictureRef.value) {
PublishPictureRef.value.isVisible = false
}
}
// 显示图片的编辑
const isShowEditorPicture = ref(false)
interface EditUserInfoType {
isVisible: boolean
}
const editUserInfoRef = ref<EditUserInfoType | null>(null)
function onEditPicture() {
isShowEditorPicture.value = true
nextTick(()=>{
if(editUserInfoRef.value){
editUserInfoRef.value.isVisible = true
}
})
}
function closeEditorPicture(){
isShowEditorPicture.value = false
}
function updateLike(type:number){
if (props.item.isLike === 1) {
props.item.isLike = 0;
props.item.likeNum -= 1;
} else {
props.item.isLike = 1;
props.item.likeNum += 1;
}
}
</script>
<template>
<div>
<div v-if="currentState === 'like' && currentType === '2'">
<div
class="h-80 rounded-2xl border border-solid border-[#e5e7eb] overflow-hidden cursor-pointer relative group"
@click="toDetails"
>
<img
class="w-full h-full object-cover block"
:src="getFirstImagePath(item.imagePaths)"
alt=""
>
<div
class="absolute w-full h-full top-0 left-0 flex justify-between px-4 py-4 box-border bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300"
>
<div class="flex items-center h-6">
<img
class="w-6 h-6 rounded-full"
:src="item.userAvatar"
alt="头像"
>
<span class="ml-2 h-5 text-gray-300 text-[12px]">{{ item.userName }}</span>
</div>
<div class="flex items-center h-7 justify-center rounded-xl bg-[#fceceb] p-2">
<img
src="@/assets/img/heart.png"
class="w-3 h-3 mr-1"
alt="❤️"
>
<span class="text-xs text-[#000]">{{ item.likeNum }}</span>
</div>
</div>
</div>
</div>
<div v-else>
<div
class="h-80 rounded-2xl overflow-hidden cursor-pointer relative border border-solid border-[#e5e7eb]"
@click="toDetails"
>
<img v-if="currentType === '0'" class="w-full h-full object-cover block" :src="item.surfaceUrl" alt="">
<img v-if="currentType === '1'" class="w-full h-full object-cover block" :src="item.coverPath" alt="">
<img v-if="currentType === '2'" class="w-full h-full object-cover block" :src="getFirstImagePath(item.imagePaths)" alt="">
<div
v-if="currentState === 'mallProduct' && item.isTop === 1"
class="text-[#58c08e] border-[#58c08e] border-solid border-[1px] bg-white rounded-lg px-1 w-10 text-[12px] ml-2 text-center absolute top-4 right-8"
>
置顶
</div>
<!-- 在发布中 auditStatus等于代表没有审批通过 -->
<div
v-if="currentState === 'mallProduct' && item.auditStatus === 4 || item.auditStatus === 3"
class="absolute top-0 left-0 w-full h-full text-gray-400 bg-black/50 flex justify-center items-center flex-col"
>
<component
:is="CircleAlert"
class="h-[40px] w-[40px] text-white menu-icon m-1 text-gray-400"
/>
{{ item.auditStatus === 3 ? '审核中' : '未通过' }}
</div>
<div
class="modelSelectByUserIdModel w-full h-full top-0 left-0 flex px-4 py-4 box-border"
>
<div
v-if="currentState === 'mallProduct' && currentType === '0'"
class="text-white text-[12px] px-3 bg-[#000] bg-opacity-40 rounded-lg h-[20px] leading-relaxed"
>
<span>
{{ item.modelType }}
</span>
</div>
<div
v-if="currentState === 'mallProduct' && currentType === '1'"
class="text-white text-[12px] px-3 bg-[#000] bg-opacity-40 rounded-lg h-[20px] leading-relaxed"
>
工作流
</div>
<div
v-if="currentState === 'mallProduct'"
class="modelSelectByUserIdModel-mask h-1/3 absolute top-0 left-0 bg-gradient-to-b from-black/100 to-transparent px-4 py-4 text-white box-border flex justify-end"
>
<div class="menu-content">
<component
:is="EllipsisVertical"
class="h-[18px] w-[18px] text-white menu-icon"
/>
<div
class="menu-group text-[#000000] text-[12px] bg-white rounded-lg text-center w-20 mt-2 hidden"
>
<div class="menu-item" @click="(event) => handleSelect(event, 'edit')">
编辑
</div>
<div
class="menu-item text-red-600"
@click="(event) => handleSelect(event, 'delete')"
>
删除
</div>
<div class="menu-item" @click="(event) => handleSelect(event, 'top')">
{{ item.isTop === 1 ? "取消置顶" : "置顶" }}
</div>
</div>
</div>
</div>
<div
v-if="currentType !== '2'"
class="absolute bottom-0 left-0 px-4 py-2 text-white box-border flex justify-between items-center"
>
<component :is="Play" class="h-[14px] w-[14px] text-white menu-icon m-1" />
<span v-if="currentType === '0'">
{{ item.reals || 0 }}
</span>
<span v-if="currentType === '1'">
{{ item.useNumber || 0 }}
</span>
<component
:is="Download"
class="h-[14px] w-[14px] text-white menu-icon m-1"
/>
<span v-if="currentType === '0'">
{{ item.numbers || 0 }}
</span>
<span v-if="currentType === '1'">
{{ item.downloadNumber || 0 }}
</span>
<!-- <component
:is="ImagePlay"
class="h-[14px] w-[14px] text-white menu-icon m-1"
/>0 -->
</div>
</div>
</div>
<div v-if="currentType !== '2'" class="mt-2 text-[12px] text-[#67787e]">
<div class="text-[#19191c] text-[14px]">
<span v-if="currentType === '0'">
{{ item.modelName }}
</span>
<span v-if="currentType === '1'">
{{ item.workflowName }}
</span>
<!-- <span>{{ item.userName }}</span> -->
</div>
<div class="flex mt-1">
<img
class="block w-4 h-4 rounded-full mr-2"
:src="item.userAvatar"
alt=""
>
<span class="text-xs text-gray-500">{{ item.userName }} </span>
</div>
</div>
</div>
<NConfigProvider>
<NMessageProvider>
<div v-if="isShowEditorPicture">
<PictureDetail @close-editor-picture="closeEditorPicture" ref="editUserInfoRef" :item="item" @update-like="updateLike"/>
</div>
<Publish-picture v-if="isShowPublishPicture" type="edit" ref="PublishPictureRef" :form-data="publishPictureData" @close-publish-img="closePublishImg" />
</NMessageProvider>
</NConfigProvider>
</div>
</template>
<style lang="scss">
.modelSelectByUserIdModel {
position: absolute;
&:hover {
.modelSelectByUserIdModel-mask {
display: block;
}
}
.modelSelectByUserIdModel-mask {
position: absolute;
width: 100%;
display: none;
.menu-content {
width: 20px;
height: 30px;
position: absolute;
right: 10px;
}
.menu-content:hover {
.menu-group {
display: block;
}
}
.menu-group {
position: absolute;
top: 10px;
right: 0;
.menu-item {
padding: 4px 0 4px 0;
margin: 4px;
border-radius: 2px;
&:hover {
background-color: #eeeded;
// border: solid;
}
}
}
}
}
</style>