feat: 稿件详情处理
This commit is contained in:
@ -85,7 +85,7 @@
|
||||
<span class="cts num">{{ exactFormatTime(record[column.dataIndex]) }}</span>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'cover'" #cell="{ record }">
|
||||
<a-image :width="64" :height="64" :src="record.cover" class="!rounded-6px">
|
||||
<a-image :width="64" :height="64" :src="record.cover" class="!rounded-6px" fit="cover">
|
||||
<template #error>
|
||||
<img :src="icon4" class="w-full h-full" />
|
||||
</template>
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
<script lang="jsx">
|
||||
import { Button, Message as AMessage } from '@arco-design/web-vue';
|
||||
import { Button, Message as AMessage, Spin } from '@arco-design/web-vue';
|
||||
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { AuditStatus } from '@/views/creative-generation-workshop/manuscript/check-list/constants';
|
||||
import { getWorksDetail } from '@/api/all/generationWorkshop';
|
||||
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts';
|
||||
import { convertVideoUrlToCoverUrl, exactFormatTime } from '@/utils/tools.ts';
|
||||
|
||||
const DEFAULT_SOURCE_INFO = {
|
||||
title: '内容稿件列表',
|
||||
@ -16,36 +20,66 @@ export default {
|
||||
const workId = ref(route.params.id);
|
||||
const { source, audit_status } = route.query;
|
||||
|
||||
const sourceInfo = computed(() => SOURCE_MAP.get(source) ?? DEFAULT_SOURCE_INFO);
|
||||
console.log({ source });
|
||||
|
||||
// 视频播放相关状态
|
||||
const isPlaying = ref(false);
|
||||
const videoRef = ref(null);
|
||||
const videoUrl = ref('');
|
||||
const coverImageUrl = ref('');
|
||||
const isVideoLoaded = ref(false);
|
||||
const contentType = ref('video');
|
||||
const dataSource = ref({});
|
||||
const images = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
const isVideo = computed(() => contentType.value === 'video');
|
||||
const isVideo = computed(() => dataSource.value.type === EnumManuscriptType.Video);
|
||||
const sourceInfo = computed(() => SOURCE_MAP.get(source) ?? DEFAULT_SOURCE_INFO);
|
||||
|
||||
const onBack = () => {
|
||||
router.push({ name: sourceInfo.value.routeName });
|
||||
};
|
||||
|
||||
const initData = () => {
|
||||
const [fileOne, ...fileOthers] = dataSource.value.files ?? [];
|
||||
if (isVideo.value) {
|
||||
videoUrl.value = fileOne;
|
||||
coverImageUrl.value = convertVideoUrlToCoverUrl(fileOne);
|
||||
} else {
|
||||
coverImageUrl.value = fileOne;
|
||||
images.value = fileOthers;
|
||||
}
|
||||
};
|
||||
|
||||
const getData = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const { code, data } = await getWorksDetail(workId.value);
|
||||
if (code === 200) {
|
||||
dataSource.value = data;
|
||||
initData();
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const renderMainImg = () => {
|
||||
if (!coverImageUrl.value) return null;
|
||||
|
||||
if (isVideo.value) {
|
||||
return (
|
||||
<div class="main-img-box mb-16px relative overflow-hidden cursor-pointer" onClick={togglePlay}>
|
||||
<video ref={videoRef} class="w-100% h-100% object-cover" onEnded={onVideoEnded}></video>
|
||||
<img src={coverImageUrl.value} class="w-100% h-100% object-cover absolute z-0 top-0 left-0" />
|
||||
<div v-show={!isPlaying.value} class="play-icon"></div>
|
||||
<div class="main-video-box mb-16px relative overflow-hidden cursor-pointer" onClick={togglePlay}>
|
||||
<video ref={videoRef} class="w-100% h-100% object-contain" onEnded={onVideoEnded}></video>
|
||||
{!isPlaying.value && (
|
||||
<>
|
||||
<img src={coverImageUrl.value} class="w-100% h-100% object-contain absolute z-0 top-0 left-0" />
|
||||
<div v-show={!isPlaying.value} class="play-icon"></div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div class="main-img-box mb-16px relative overflow-hidden cursor-pointer">
|
||||
<img src={coverImageUrl.value} class="w-100% h-100% object-cover absolute z-0 top-0 left-0" />
|
||||
<img src={coverImageUrl.value} class="w-100% h-100% object-contain absolute z-0 top-0 left-0" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -54,10 +88,10 @@ export default {
|
||||
const togglePlay = () => {
|
||||
if (!videoRef.value) return;
|
||||
|
||||
console.log('togglePlay', videoRef.value);
|
||||
if (isPlaying.value) {
|
||||
videoRef.value.pause();
|
||||
} else {
|
||||
// 首次播放时才加载视频
|
||||
if (!isVideoLoaded.value) {
|
||||
videoRef.value.src = videoUrl.value;
|
||||
isVideoLoaded.value = true;
|
||||
@ -101,10 +135,13 @@ export default {
|
||||
);
|
||||
};
|
||||
|
||||
// 4. 修改模板部分,根据contentType条件渲染
|
||||
onMounted(() => {
|
||||
workId && getData();
|
||||
});
|
||||
|
||||
return () => (
|
||||
<>
|
||||
<div class="manuscript-detail-wrap">
|
||||
<Spin loading={loading.value} class="manuscript-detail-wrap" size={50}>
|
||||
<div class="h-full w-full flex flex-col">
|
||||
<div class="flex items-center mb-8px">
|
||||
<span class="cts color-#4E5969 cursor-pointer" onClick={onBack}>
|
||||
{sourceInfo.value.title}
|
||||
@ -114,38 +151,32 @@ export default {
|
||||
</div>
|
||||
<div class="flex-1 overflow-y-auto bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid py-32px">
|
||||
<div class="w-684px mx-auto flex flex-col items-center">
|
||||
<p class="mb-8px cts bold !text-28px !lh-40px !color-#211F24">
|
||||
挖到宝了!这个平价好物让我素颜出门都自信✨挖到宝了!这个平价
|
||||
</p>
|
||||
<p class="cts !text-12px !color-#737478 mb-32px w-full text-left">6月26日修改</p>
|
||||
<div class="flex justify-start flex-col w-full">
|
||||
<p class="mb-8px cts bold !text-28px !lh-40px !color-#211F24">{dataSource.value.title}</p>
|
||||
<p class="cts !text-12px !color-#737478 mb-32px w-full text-left">
|
||||
{exactFormatTime(dataSource.value.update_time)}修改
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{renderMainImg()}
|
||||
|
||||
<p class="cts !color-#211F24 ">
|
||||
谁懂啊!作为混干皮,每天素颜出门总被说 “气色好差”,直到被闺蜜按头安利这个 30 块的素颜霜 ——
|
||||
质地像冰淇淋一样推开就化,完全不卡粉!带一点自然提亮,黄黑皮涂完像天生好皮肤,连遮瑕都省了~
|
||||
最绝的是它还带轻微防晒值,早上洗完脸涂一层就能冲出门,懒人狂喜!我已经空罐 3
|
||||
瓶了,现在同事都以为我每天早起化妆,其实我多睡了 20 分钟 hhh
|
||||
(PS:油痘肌姐妹建议局部薄涂,后续补妆更服帖~)
|
||||
</p>
|
||||
<p class="cts !color-#211F24 ">{dataSource.value.content}</p>
|
||||
|
||||
{/* 仅图片类型显示图片列表 */}
|
||||
{!isVideo.value && (
|
||||
<div class="desc-img-wrap mt-40px">
|
||||
{new Array(5).fill(0).map((item, index) => (
|
||||
{images.value.map((item, index) => (
|
||||
<div class="desc-img-box" key={index}>
|
||||
<img src="" class="w-100% h-100%" />
|
||||
<img src={item} class="w-100% h-100% object-contain" />
|
||||
</div>
|
||||
))}
|
||||
<div class="desc-img-box">
|
||||
<img src="" class="w-100% h-100%" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end items-center px-16px py-20px w-full bg-#fff footer-row">{renderFooterRow()}</div>
|
||||
</>
|
||||
</Spin>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
$footer-height: 68px;
|
||||
.manuscript-detail-wrap {
|
||||
width: 100%;
|
||||
height: calc(100% - 72px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.cts {
|
||||
color: #939499;
|
||||
font-family: $font-family-regular;
|
||||
@ -14,11 +13,15 @@ $footer-height: 68px;
|
||||
font-family: $font-family-medium;
|
||||
}
|
||||
}
|
||||
.main-video-box {
|
||||
width: 320px;
|
||||
height: auto;
|
||||
background: #fff;
|
||||
}
|
||||
.main-img-box {
|
||||
width: 320px;
|
||||
height: 472px;
|
||||
height: auto;
|
||||
background: #fff;
|
||||
object-fit: contain;
|
||||
aspect-ratio: 3/4;
|
||||
}
|
||||
.desc-img-wrap {
|
||||
|
||||
@ -67,12 +67,18 @@ export default {
|
||||
const getData = async () => {
|
||||
const { code, data } = await getWorksDetail(workId.value);
|
||||
if (code === 200) {
|
||||
const { type, files } = data;
|
||||
const _data = { ...data, videoInfo: cloneDeep(INITIAL_VIDEO_INFO) };
|
||||
|
||||
if (type === EnumManuscriptType.Video && files.length) {
|
||||
_data.videoInfo.uploadStatus = 'end';
|
||||
}
|
||||
dataSource.value = cloneDeep(_data);
|
||||
remoteDataSource.value = cloneDeep(_data);
|
||||
}
|
||||
};
|
||||
const onChange = (val) => {
|
||||
console.log('onChange', val);
|
||||
dataSource.value = val;
|
||||
};
|
||||
const onUpdateVideoInfo = (newVideoInfo) => {
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
{{ exactFormatTime(record[column.dataIndex]) }}
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'cover'" #cell="{ record }">
|
||||
<a-image :width="64" :height="64" :src="record.cover" class="!rounded-6px">
|
||||
<a-image :width="64" :height="64" :src="record.cover" class="!rounded-6px" fit="cover">
|
||||
<template #error>
|
||||
<img :src="icon4" class="w-full h-full" />
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user