feat: 客户分享链接列表
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-config-provider :locale="zhCN" size="small" :theme="redTheme">
|
<a-config-provider :locale="zhCN" size="small" :theme="redTheme">
|
||||||
<router-view v-if="$route.path === '/login'" />
|
<router-view v-if="$route.path === '/login' || ['ExploreList', 'ExploreDetail'].includes($route.name)" />
|
||||||
<LayoutBasic v-else />
|
<LayoutBasic v-else />
|
||||||
</a-config-provider>
|
</a-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -77,3 +77,46 @@ export const putWorkAuditsAuditPass = (params = {}) => {
|
|||||||
const { id: auditId, ...rest } = params as { id: string; [key: string]: any };
|
const { id: auditId, ...rest } = params as { id: string; [key: string]: any };
|
||||||
return Http.put(`/v1/work-audits/${auditId}/audit-pass`, rest);
|
return Http.put(`/v1/work-audits/${auditId}/audit-pass`, rest);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 内容稿件-列表(客户)
|
||||||
|
export const getShareWorksList = (shareCode: string) => {
|
||||||
|
return Http.get(
|
||||||
|
'/v1/share/works/list',
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
headers: { 'share-code': shareCode },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 内容稿件-详情(客户)
|
||||||
|
export const getShareWorksDetail = (id: string, shareCode: string) => {
|
||||||
|
return Http.get(
|
||||||
|
`/v1/share/works/${id}`,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
headers: { 'share-code': shareCode },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 内容稿件-确认(客户)
|
||||||
|
export const patchShareWorksConfirm = (id: string, params = {}, shareCode: string) => {
|
||||||
|
return Http.patch(`/v1/share/works/${id}/confirm`, params, {
|
||||||
|
headers: { 'share-code': shareCode },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 内容稿件-评论(客户)
|
||||||
|
export const postShareWorksComments = (id: string, params = {}, shareCode: string) => {
|
||||||
|
return Http.post(`/v1/share/works/${id}/comments`, params, {
|
||||||
|
headers: { 'share-code': shareCode },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 内容稿件-删除评论(客户)
|
||||||
|
export const deleteShareWorksComments = (id: string, commentId: string, shareCode: string) => {
|
||||||
|
return Http.delete(`/v1/share/works/${id}/comments/${commentId}`, {
|
||||||
|
headers: { 'share-code': shareCode },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
BIN
src/assets/img/creative-generation-workshop/icon-confirm.png
Normal file
BIN
src/assets/img/creative-generation-workshop/icon-confirm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Author: RenXiaoDong
|
|
||||||
* @Date: 2025-06-19 01:45:53
|
|
||||||
*/
|
|
||||||
import { appRoutes } from '../routes';
|
|
||||||
|
|
||||||
const mixinRoutes = [...appRoutes];
|
|
||||||
|
|
||||||
const appClientMenus = mixinRoutes.map((el) => {
|
|
||||||
const { name, path, meta, redirect, children } = el;
|
|
||||||
return {
|
|
||||||
name,
|
|
||||||
path,
|
|
||||||
meta,
|
|
||||||
redirect,
|
|
||||||
children,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
export default mixinRoutes;
|
|
||||||
@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
import { createRouter, createWebHistory } from 'vue-router';
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
import { appRoutes } from './routes';
|
import { appRoutes } from './routes';
|
||||||
import { NOT_FOUND_ROUTE } from './routes/base';
|
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
import { MENU_GROUP_IDS } from './constants';
|
import { MENU_GROUP_IDS } from './constants';
|
||||||
@ -35,27 +34,18 @@ export const router = createRouter({
|
|||||||
id: MENU_GROUP_IDS.WORK_BENCH_ID,
|
id: MENU_GROUP_IDS.WORK_BENCH_ID,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
...appRoutes,
|
||||||
{
|
{
|
||||||
path: '/permission',
|
path: '/:pathMatch(.*)*',
|
||||||
name: 'permission',
|
name: 'notFound',
|
||||||
component: () => import('@/views/components/permission/choose-enterprise.vue'),
|
component: () => import('@/layouts/NotFound.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: false,
|
requiresAuth: false,
|
||||||
requireLogin: true,
|
hideInMenu: true,
|
||||||
|
hideSidebar: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// path: '/auth',
|
|
||||||
// name: 'auth',
|
|
||||||
// component: () => import('@/views/components/permission/auth.vue'),
|
|
||||||
// meta: {
|
|
||||||
// requiresAuth: false,
|
|
||||||
// requireLogin: true,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
...appRoutes,
|
|
||||||
// REDIRECT_MAIN,
|
|
||||||
NOT_FOUND_ROUTE,
|
|
||||||
],
|
],
|
||||||
scrollBehavior() {
|
scrollBehavior() {
|
||||||
return { top: 0 };
|
return { top: 0 };
|
||||||
|
|||||||
@ -1,35 +0,0 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
|
||||||
import { REDIRECT_ROUTE_NAME } from '@/router/constants';
|
|
||||||
|
|
||||||
// export const REDIRECT_MAIN: RouteRecordRaw = {
|
|
||||||
// path: '/redirect',
|
|
||||||
// name: 'redirect',
|
|
||||||
// meta: {
|
|
||||||
// requiresAuth: false,
|
|
||||||
// requireLogin: false,
|
|
||||||
// hideInMenu: true,
|
|
||||||
// },
|
|
||||||
// children: [
|
|
||||||
// {
|
|
||||||
// path: '/redirect/:path',
|
|
||||||
// name: REDIRECT_ROUTE_NAME,
|
|
||||||
// component: () => import('@/layouts/Basic.vue'),
|
|
||||||
// meta: {
|
|
||||||
// requiresAuth: false,
|
|
||||||
// requireLogin: false,
|
|
||||||
// hideInMenu: true,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// };
|
|
||||||
|
|
||||||
export const NOT_FOUND_ROUTE: RouteRecordRaw = {
|
|
||||||
path: '/:pathMatch(.*)*',
|
|
||||||
name: 'notFound',
|
|
||||||
component: () => import('@/layouts/NotFound.vue'),
|
|
||||||
meta: {
|
|
||||||
requiresAuth: false,
|
|
||||||
hideInMenu: true,
|
|
||||||
hideSidebar: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@ -111,6 +111,28 @@ const COMPONENTS: AppRouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/explore/list/:shareCode',
|
||||||
|
name: 'ExploreList',
|
||||||
|
meta: {
|
||||||
|
locale: '分享链接列表',
|
||||||
|
requiresAuth: false,
|
||||||
|
requireLogin: false,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
component: () => import('@/views/creative-generation-workshop/explore/list/index.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/explore/detail/:shareCode/:id',
|
||||||
|
name: 'ExploreDetail',
|
||||||
|
meta: {
|
||||||
|
locale: '分享链接详情',
|
||||||
|
requiresAuth: false,
|
||||||
|
requireLogin: false,
|
||||||
|
roles: ['*'],
|
||||||
|
},
|
||||||
|
component: () => import('@/views/creative-generation-workshop/explore/detail/index.vue'),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default COMPONENTS;
|
export default COMPONENTS;
|
||||||
|
|||||||
@ -131,101 +131,101 @@ export function getVideoInfo(file: File): Promise<{ duration: number; firstFrame
|
|||||||
video.style.position = 'fixed'; // 确保视频元素在DOM中
|
video.style.position = 'fixed'; // 确保视频元素在DOM中
|
||||||
video.style.top = '-1000px'; // 但不可见
|
video.style.top = '-1000px'; // 但不可见
|
||||||
document.body.appendChild(video); // 添加到DOM
|
document.body.appendChild(video); // 添加到DOM
|
||||||
|
|
||||||
let hasResolved = false;
|
let hasResolved = false;
|
||||||
|
|
||||||
// 先获取元数据(时长)
|
// 先获取元数据(时长)
|
||||||
video.onloadedmetadata = function () {
|
video.onloadedmetadata = function () {
|
||||||
// 视频时长
|
// 视频时长
|
||||||
const duration = video.duration;
|
const duration = video.duration;
|
||||||
|
|
||||||
// 尝试将视频定位到非常小的时间点,确保有帧可捕获
|
// 尝试将视频定位到非常小的时间点,确保有帧可捕获
|
||||||
if (duration > 0) {
|
if (duration > 0) {
|
||||||
video.currentTime = Math.min(0.1, duration / 2);
|
video.currentTime = Math.min(0.1, duration / 2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 当视频定位完成后尝试捕获首帧
|
// 当视频定位完成后尝试捕获首帧
|
||||||
video.onseeked = function () {
|
video.onseeked = function () {
|
||||||
if (hasResolved) return;
|
if (hasResolved) return;
|
||||||
|
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = video.videoWidth;
|
canvas.width = video.videoWidth;
|
||||||
canvas.height = video.videoHeight;
|
canvas.height = video.videoHeight;
|
||||||
|
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理
|
// 清理
|
||||||
window.URL.revokeObjectURL(video.src);
|
window.URL.revokeObjectURL(video.src);
|
||||||
document.body.removeChild(video);
|
document.body.removeChild(video);
|
||||||
|
|
||||||
// 返回结果
|
// 返回结果
|
||||||
hasResolved = true;
|
hasResolved = true;
|
||||||
resolve({
|
resolve({
|
||||||
duration: video.duration,
|
duration: video.duration,
|
||||||
firstFrame: canvas.toDataURL('image/jpeg', 0.9) // 提高质量
|
firstFrame: canvas.toDataURL('image/jpeg', 0.9), // 提高质量
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 作为备选方案,监听loadeddata事件
|
// 作为备选方案,监听loadeddata事件
|
||||||
video.onloadeddata = function () {
|
video.onloadeddata = function () {
|
||||||
if (hasResolved) return;
|
if (hasResolved) return;
|
||||||
|
|
||||||
// 尝试捕获帧
|
// 尝试捕获帧
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = video.videoWidth;
|
canvas.width = video.videoWidth;
|
||||||
canvas.height = video.videoHeight;
|
canvas.height = video.videoHeight;
|
||||||
|
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否捕获到有效帧(非全黑)
|
// 检查是否捕获到有效帧(非全黑)
|
||||||
const imageData = ctx?.getImageData(0, 0, canvas.width, canvas.height);
|
const imageData = ctx?.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
if (imageData) {
|
if (imageData) {
|
||||||
let isAllBlack = true;
|
let isAllBlack = true;
|
||||||
for (let i = 0; i < imageData.data.length; i += 4) {
|
for (let i = 0; i < imageData.data.length; i += 4) {
|
||||||
if (imageData.data[i] > 10 || imageData.data[i+1] > 10 || imageData.data[i+2] > 10) {
|
if (imageData.data[i] > 10 || imageData.data[i + 1] > 10 || imageData.data[i + 2] > 10) {
|
||||||
isAllBlack = false;
|
isAllBlack = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isAllBlack) {
|
if (!isAllBlack) {
|
||||||
// 清理
|
// 清理
|
||||||
window.URL.revokeObjectURL(video.src);
|
window.URL.revokeObjectURL(video.src);
|
||||||
document.body.removeChild(video);
|
document.body.removeChild(video);
|
||||||
|
|
||||||
// 返回结果
|
// 返回结果
|
||||||
hasResolved = true;
|
hasResolved = true;
|
||||||
resolve({
|
resolve({
|
||||||
duration: video.duration,
|
duration: video.duration,
|
||||||
firstFrame: canvas.toDataURL('image/jpeg', 0.9)
|
firstFrame: canvas.toDataURL('image/jpeg', 0.9),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果是全黑帧,尝试定位到0.1秒
|
// 如果是全黑帧,尝试定位到0.1秒
|
||||||
if (video.duration > 0) {
|
if (video.duration > 0) {
|
||||||
video.currentTime = 0.1;
|
video.currentTime = 0.1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 设置视频源以触发加载
|
// 设置视频源以触发加载
|
||||||
video.src = URL.createObjectURL(file);
|
video.src = URL.createObjectURL(file);
|
||||||
|
|
||||||
// 设置超时,防止长时间无响应
|
// 设置超时,防止长时间无响应
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!hasResolved) {
|
if (!hasResolved) {
|
||||||
document.body.removeChild(video);
|
document.body.removeChild(video);
|
||||||
resolve({
|
resolve({
|
||||||
duration: 0,
|
duration: 0,
|
||||||
firstFrame: ''
|
firstFrame: '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 5000); // 5秒超时
|
}, 5000); // 5秒超时
|
||||||
@ -266,7 +266,7 @@ export const formatUploadSpeed = (bytesPerSecond: number): string => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function convertVideoUrlToCoverUrl(videoUrl: string): string {
|
export function convertVideoUrlToCoverUrl(videoUrl: string): string {
|
||||||
if (!videoUrl || typeof videoUrl !== 'string') {
|
if (!videoUrl || typeof videoUrl !== 'string') {
|
||||||
console.error('Invalid video URL');
|
console.error('Invalid video URL');
|
||||||
return '';
|
return '';
|
||||||
@ -281,3 +281,20 @@ export const formatUploadSpeed = (bytesPerSecond: number): string => {
|
|||||||
|
|
||||||
return urlWithCovers + '.jpg';
|
return urlWithCovers + '.jpg';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成包含协议、域名和参数的完整URL
|
||||||
|
*/
|
||||||
|
export const generateFullUrl = (pathTemplate: string, params: Record<string, string | number> = {}): string => {
|
||||||
|
const protocol = window.location.protocol;
|
||||||
|
const hostname = window.location.hostname;
|
||||||
|
const port = window.location.port ? `:${window.location.port}` : '';
|
||||||
|
const baseUrl = `${protocol}//${hostname}${port}`;
|
||||||
|
|
||||||
|
let path = pathTemplate;
|
||||||
|
Object.entries(params).forEach(([key, value]) => {
|
||||||
|
path = path.replace(`:${key}`, String(value));
|
||||||
|
});
|
||||||
|
|
||||||
|
return `${baseUrl}${path}`;
|
||||||
|
};
|
||||||
|
|||||||
213
src/views/creative-generation-workshop/explore/detail/index.vue
Normal file
213
src/views/creative-generation-workshop/explore/detail/index.vue
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
<script lang="jsx">
|
||||||
|
import { Image, Spin, Button } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
import { getShareWorksDetail } from '@/api/all/generationWorkshop.ts';
|
||||||
|
import { convertVideoUrlToCoverUrl, exactFormatTime } from '@/utils/tools.ts';
|
||||||
|
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts';
|
||||||
|
|
||||||
|
import icon1 from '@/assets/logo.svg';
|
||||||
|
import icon2 from '@/assets/img/creative-generation-workshop/icon-confirm.png';
|
||||||
|
import icon3 from '@/assets/img/creative-generation-workshop/icon-line.png';
|
||||||
|
|
||||||
|
const RESULT_LIST = [
|
||||||
|
{
|
||||||
|
label: '合规程度',
|
||||||
|
value: 'compliance_degree',
|
||||||
|
class: '!color-#6d4cfe',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '检验项',
|
||||||
|
value: 'compliance',
|
||||||
|
class: '!color-#211F24',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '高风险',
|
||||||
|
value: 'high_risk',
|
||||||
|
class: '!color-#F64B31',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '中风险',
|
||||||
|
value: 'medium_risk',
|
||||||
|
class: '!color-#FFAE00',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup(props, { emit, expose }) {
|
||||||
|
const route = useRoute();
|
||||||
|
const dataSource = ref({});
|
||||||
|
const isExpand = ref(true);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const isPlaying = ref(false);
|
||||||
|
const videoRef = ref(null);
|
||||||
|
const videoUrl = ref('');
|
||||||
|
const coverImageUrl = ref('');
|
||||||
|
const isVideoLoaded = ref(false);
|
||||||
|
const images = ref([]);
|
||||||
|
|
||||||
|
const isVideo = computed(() => dataSource.value.type === EnumManuscriptType.Video);
|
||||||
|
|
||||||
|
const initData = () => {
|
||||||
|
const [fileOne, ...fileOthers] = dataSource.value.files ?? [];
|
||||||
|
if (isVideo.value) {
|
||||||
|
videoUrl.value = fileOne.url;
|
||||||
|
coverImageUrl.value = convertVideoUrlToCoverUrl(fileOne.url);
|
||||||
|
} else {
|
||||||
|
coverImageUrl.value = fileOne.url;
|
||||||
|
images.value = fileOthers;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDetail = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const { id, shareCode } = route.params;
|
||||||
|
const { code, data } = await getShareWorksDetail(id, shareCode);
|
||||||
|
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-video-box mb-16px relative overflow-hidden cursor-pointer" onClick={togglePlay}>
|
||||||
|
<video ref={videoRef} class="w-100% h-100% object-cover" onEnded={onVideoEnded}></video>
|
||||||
|
{!isPlaying.value && (
|
||||||
|
<>
|
||||||
|
<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>
|
||||||
|
);
|
||||||
|
} 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" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const togglePlay = () => {
|
||||||
|
if (!videoRef.value) return;
|
||||||
|
|
||||||
|
if (isPlaying.value) {
|
||||||
|
videoRef.value.pause();
|
||||||
|
} else {
|
||||||
|
if (!isVideoLoaded.value) {
|
||||||
|
videoRef.value.src = videoUrl.value;
|
||||||
|
isVideoLoaded.value = true;
|
||||||
|
}
|
||||||
|
videoRef.value.play();
|
||||||
|
}
|
||||||
|
isPlaying.value = !isPlaying.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onVideoEnded = () => {
|
||||||
|
isPlaying.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDetail();
|
||||||
|
});
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (videoRef.value) {
|
||||||
|
videoRef.value.pause();
|
||||||
|
videoRef.value = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
return (
|
||||||
|
<div class="explore-page">
|
||||||
|
<header class="page-header">
|
||||||
|
<div class="content w-full px-24px flex items-center bg-#fff">
|
||||||
|
<img src={icon1} alt="" width={130} />
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{loading.value ? (
|
||||||
|
<Spin spinning={loading.value} class="h-500px w-full flex justify-center items-center" size={60} />
|
||||||
|
) : (
|
||||||
|
<div class={`page-wrap relative ${isExpand.value ? 'expand' : ''}`}>
|
||||||
|
<div class="fold-box cursor-pointer" onClick={() => (isExpand.value = true)}>
|
||||||
|
<icon-menu-fold size={20} class="color-#55585F hover:color-#6D4CFE" />
|
||||||
|
</div>
|
||||||
|
<section class="explore-detail-wrap pt-32px pb-52px flex flex-col items-center">
|
||||||
|
<div class="flex justify-start flex-col w-full relative">
|
||||||
|
<p class="title mb-8px">{dataSource.value.title}</p>
|
||||||
|
<p class="cts color-#737478 mb-32px">
|
||||||
|
{exactFormatTime(dataSource.value.last_modified_at, 'YYYY年MM月DD日')}修改
|
||||||
|
</p>
|
||||||
|
{dataSource.value.customer_opinion === 1 && (
|
||||||
|
<img src={icon2} width={92} height={92} class="absolute right-0 bottom-0" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{renderMainImg()}
|
||||||
|
<p class="cts !color-#211F24">{dataSource.value.content}</p>
|
||||||
|
|
||||||
|
{/* 仅图片类型显示图片列表 */}
|
||||||
|
{!isVideo.value && (
|
||||||
|
<div class="desc-img-wrap mt-40px">
|
||||||
|
{images.value.map((item, index) => (
|
||||||
|
<div class="desc-img-box" key={index}>
|
||||||
|
<img src={item.url} class="w-100% h-100% object-cover" />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
{isExpand.value && (
|
||||||
|
<section class="py-16px absolute right-16px w-440px h-full">
|
||||||
|
<div class="ai-suggest-box p-24px">
|
||||||
|
<div class="mb-16px w-full flex justify-between">
|
||||||
|
<div class="mb-24px relative w-fit">
|
||||||
|
<span class="ai-text">AI 审核建议</span>
|
||||||
|
<img src={icon3} class="w-80px h-10.8px absolute bottom-1px left--9px" />
|
||||||
|
</div>
|
||||||
|
<icon-menu-unfold
|
||||||
|
size={20}
|
||||||
|
class="color-#55585F cursor-pointer hover:color-#6D4CFE"
|
||||||
|
onClick={() => (isExpand.value = false)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="result-box p-16px rounded-8px mb-16px">
|
||||||
|
<div class="flex items-center justify-between mb-16px">
|
||||||
|
<p class="cts bold !color-#000 !text-16px">审核结果</p>
|
||||||
|
<Button type="text" class="!color-#6D4CFE hover:!color-#8A70FE">
|
||||||
|
展开详情
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
{RESULT_LIST.map((item, index) => (
|
||||||
|
<div class="flex flex-col justify-center items-center flex-1 result-item" key={index}>
|
||||||
|
<span class={`s1 ${item.class}`}>30</span>
|
||||||
|
<span class="cts mt-4px !lh-20px !text-12px !color-#737478">{item.label}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import './style.scss';
|
||||||
|
</style>
|
||||||
151
src/views/creative-generation-workshop/explore/detail/style.scss
Normal file
151
src/views/creative-generation-workshop/explore/detail/style.scss
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
.explore-page {
|
||||||
|
position: relative;
|
||||||
|
padding-top: $navbar-height;
|
||||||
|
min-width: 1200px;
|
||||||
|
height: 100vh;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.page-header {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
min-width: 1200px;
|
||||||
|
.content {
|
||||||
|
height: $navbar-height;
|
||||||
|
border-bottom: 1px solid var(--Border-1, #d7d7d9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cts {
|
||||||
|
color: #939499;
|
||||||
|
font-family: $font-family-regular;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px;
|
||||||
|
&.bold {
|
||||||
|
font-family: $font-family-medium;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-wrap {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
.explore-detail-wrap {
|
||||||
|
min-height: 500px;
|
||||||
|
width: 684px;
|
||||||
|
.title {
|
||||||
|
color: var(--Text-1, #211f24);
|
||||||
|
font-family: $font-family-medium;
|
||||||
|
font-size: 28px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 40px; /* 142.857% */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fold-box {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 30px;
|
||||||
|
border: 1px solid var(--Border-1, #d7d7d9);
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
position: absolute;
|
||||||
|
right: 16px;
|
||||||
|
top: 32px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.main-video-box {
|
||||||
|
width: 320px;
|
||||||
|
height: auto;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.main-img-box {
|
||||||
|
width: 347px;
|
||||||
|
height: auto;
|
||||||
|
background: #fff;
|
||||||
|
aspect-ratio: 3/4;
|
||||||
|
}
|
||||||
|
.desc-img-wrap {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 24px;
|
||||||
|
.desc-img-box {
|
||||||
|
width: 212px;
|
||||||
|
height: 283px;
|
||||||
|
background: #fff;
|
||||||
|
object-fit: contain;
|
||||||
|
aspect-ratio: 3/4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.play-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 222;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
background-image: url('@/assets/img/creative-generation-workshop/icon-play.png');
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
transition: background-image 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-icon:hover {
|
||||||
|
background-image: url('@/assets/img/creative-generation-workshop/icon-play-hover.png');
|
||||||
|
}
|
||||||
|
.ai-suggest-box {
|
||||||
|
width: 440px;
|
||||||
|
height: fit-content;
|
||||||
|
max-height: 100%;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: linear-gradient(126deg, #eef2fd 8.36%, #f5ebfe 49.44%, #fdebf3 90.52%);
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
.ai-text {
|
||||||
|
font-family: $font-family-medium;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 24px;
|
||||||
|
background: linear-gradient(85deg, #7d419d 4.56%, #31353d 94.75%);
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
.result-box {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
.result-item {
|
||||||
|
.s1 {
|
||||||
|
color: var(--Brand-6, #6d4cfe);
|
||||||
|
font-family: $font-family-manrope-regular;
|
||||||
|
font-size: 24px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 32px; /* 133.333% */
|
||||||
|
}
|
||||||
|
&:first-child {
|
||||||
|
position: relative;
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
right: 0;
|
||||||
|
width: 1px;
|
||||||
|
height: 32px;
|
||||||
|
background: var(--Border-1, #d7d7d9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
102
src/views/creative-generation-workshop/explore/list/index.vue
Normal file
102
src/views/creative-generation-workshop/explore/list/index.vue
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<script lang="jsx">
|
||||||
|
import TextOverTips from '@/components/text-over-tips';
|
||||||
|
import { Image, Spin } from '@arco-design/web-vue';
|
||||||
|
|
||||||
|
import { exactFormatTime } from '@/utils/tools';
|
||||||
|
import { getShareWorksList } from '@/api/all/generationWorkshop';
|
||||||
|
|
||||||
|
import icon1 from '@/assets/img/error-img.png';
|
||||||
|
import icon2 from '@/assets/logo.svg';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup(props, { emit, expose }) {
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const dataSource = ref({});
|
||||||
|
const loading = ref(false);
|
||||||
|
const works = computed(() => dataSource.value.works ?? []);
|
||||||
|
const shareCode = computed(() => route.params.shareCode);
|
||||||
|
|
||||||
|
const onClickItem = (item) => {
|
||||||
|
router.push({
|
||||||
|
path: `/explore/detail/${shareCode.value}/${item.id}`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getShareWorks = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const { code, data } = await getShareWorksList(shareCode.value);
|
||||||
|
if (code === 200) {
|
||||||
|
dataSource.value = data;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
getShareWorks();
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
return (
|
||||||
|
<div class="explore-page">
|
||||||
|
<header class="page-header">
|
||||||
|
<div class="content w-full px-24px flex items-center bg-#fff">
|
||||||
|
<img src={icon2} alt="" width={130} />
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{loading.value ? (
|
||||||
|
<Spin spinning={loading.value} class="h-500px w-full flex justify-center items-center" size={60} />
|
||||||
|
) : (
|
||||||
|
<section class="page-wrapper flex justify-center">
|
||||||
|
<div class="explore-container">
|
||||||
|
<div class="explore-list-wrap pt-24px pb-28px">
|
||||||
|
<TextOverTips context={`${works.value[0]?.title}等${works.value.length}个文件`} class="mb-8px" />
|
||||||
|
<p class="cts !color-#939499 mb-24px">
|
||||||
|
{`分享时间:${exactFormatTime(dataSource.value.created_at, 'YYYY-MM-DD HH:mm:ss')} 有效期${
|
||||||
|
dataSource.value.days
|
||||||
|
}天`}
|
||||||
|
</p>
|
||||||
|
<div class="card-container">
|
||||||
|
{works.value.map((item) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class="card-item rounded-8px overflow-hidden"
|
||||||
|
key={item.id}
|
||||||
|
onClick={() => onClickItem(item)}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={item.cover}
|
||||||
|
width={'100%'}
|
||||||
|
height={300}
|
||||||
|
preview={false}
|
||||||
|
fit="cover"
|
||||||
|
v-slots={{
|
||||||
|
error: () => <img src={icon1} class="w-full h-full" />,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div class="p-16px">
|
||||||
|
<TextOverTips context={item.title} class=" !lh-24px !text-16px mb-8px bold" />
|
||||||
|
<p class="cts color-#737478">
|
||||||
|
{exactFormatTime(item.last_modified_at, 'YYYY年MM月DD日')}修改
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import './style.scss';
|
||||||
|
</style>
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
.explore-page {
|
||||||
|
position: relative;
|
||||||
|
padding-top: $navbar-height;
|
||||||
|
min-width: 1200px;
|
||||||
|
background: #fff;
|
||||||
|
.page-header {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
min-width: 1200px;
|
||||||
|
.content {
|
||||||
|
height: $navbar-height;
|
||||||
|
border-bottom: 1px solid var(--Border-1, #d7d7d9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.page-wrapper {
|
||||||
|
min-height: 500px;
|
||||||
|
.explore-container {
|
||||||
|
width: 1200px;
|
||||||
|
.explore-list-wrap {
|
||||||
|
.cts {
|
||||||
|
font-family: $font-family-regular;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
:deep(.overflow-text) {
|
||||||
|
color: var(--Text-1, #211f24);
|
||||||
|
font-family: $font-family-regular;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px;
|
||||||
|
&.bold {
|
||||||
|
font-family: $font-family-medium;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 24px;
|
||||||
|
.card-item {
|
||||||
|
border: 1px solid var(--Border-1, #d7d7d9);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s;
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
border: 1.01px solid var(--Border-1, #d7d7d9);
|
||||||
|
border-radius: 8.08px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -39,7 +39,7 @@ export default {
|
|||||||
<span class="mr-8px cts bold">批量审核列表</span>
|
<span class="mr-8px cts bold">批量审核列表</span>
|
||||||
<span class="mr-8px cts !lh-22px">{`共${dataSource.value.length}个`}</span>
|
<span class="mr-8px cts !lh-22px">{`共${dataSource.value.length}个`}</span>
|
||||||
</div>
|
</div>
|
||||||
<icon-menu-unfold size={16} class="color-##55585F cursor-pointer" onClick={onClose} />
|
<icon-menu-unfold size={16} class="color-##55585F cursor-pointer hover:color-#6D4CFE" onClick={onClose} />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 overflow-y-auto px-24px">
|
<div class="flex-1 overflow-y-auto px-24px">
|
||||||
{dataSource.value.map((item) => (
|
{dataSource.value.map((item) => (
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import 'swiper/css/navigation';
|
|||||||
import { Navigation } from 'swiper/modules';
|
import { Navigation } from 'swiper/modules';
|
||||||
import { FORM_RULES, enumTab, TAB_LIST, RESULT_LIST } from './constants';
|
import { FORM_RULES, enumTab, TAB_LIST, RESULT_LIST } from './constants';
|
||||||
import { getImagePreSignedUrl } from '@/api/all/common';
|
import { getImagePreSignedUrl } from '@/api/all/common';
|
||||||
|
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants';
|
||||||
|
|
||||||
import icon1 from '@/assets/img/creative-generation-workshop/icon-magic.png';
|
import icon1 from '@/assets/img/creative-generation-workshop/icon-magic.png';
|
||||||
import icon2 from '@/assets/img/creative-generation-workshop/icon-line.png';
|
import icon2 from '@/assets/img/creative-generation-workshop/icon-line.png';
|
||||||
@ -53,6 +54,12 @@ export default {
|
|||||||
const modules = [Navigation];
|
const modules = [Navigation];
|
||||||
const checkLoading = ref(false);
|
const checkLoading = ref(false);
|
||||||
|
|
||||||
|
const tabList = computed(() => {
|
||||||
|
if (props.modelValue.type === EnumManuscriptType.Image) {
|
||||||
|
return TAB_LIST;
|
||||||
|
}
|
||||||
|
return TAB_LIST.filter((item) => item.value !== enumTab.IMAGE);
|
||||||
|
});
|
||||||
const isTextTab = computed(() => activeTab.value === enumTab.TEXT);
|
const isTextTab = computed(() => activeTab.value === enumTab.TEXT);
|
||||||
|
|
||||||
const onAiReplace = () => {
|
const onAiReplace = () => {
|
||||||
@ -336,7 +343,7 @@ export default {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-16px suggestion-box p-12px rounded-8px bg-#F7F8FA flex flex-col">
|
<div class="mb-16px suggestion-box p-12px rounded-8px bg-#F7F8FA flex flex-col">
|
||||||
<div class=" mb-24px relative w-fit">
|
<div class="mb-24px relative w-fit">
|
||||||
<span class="ai-text">AI 审核建议</span>
|
<span class="ai-text">AI 审核建议</span>
|
||||||
<img src={icon2} class="w-80px h-10.8px absolute bottom-1px left-1px" />
|
<img src={icon2} class="w-80px h-10.8px absolute bottom-1px left-1px" />
|
||||||
</div>
|
</div>
|
||||||
@ -434,7 +441,7 @@ export default {
|
|||||||
<div class="flex-2 left-box mr-24px flex flex-col">
|
<div class="flex-2 left-box mr-24px flex flex-col">
|
||||||
<div class="flex-1 mb-12px rounded-8px border-1px pt-8px flex flex-col pb-16px bg-#F7F8FA border-#E6E6E8 border-solid">
|
<div class="flex-1 mb-12px rounded-8px border-1px pt-8px flex flex-col pb-16px bg-#F7F8FA border-#E6E6E8 border-solid">
|
||||||
<Tabs v-model={activeTab.value} onTabClick={handleTabClick} class="mb-16px">
|
<Tabs v-model={activeTab.value} onTabClick={handleTabClick} class="mb-16px">
|
||||||
{TAB_LIST.map((item) => (
|
{tabList.value.map((item) => (
|
||||||
<TabPane key={item.value} title={item.label}></TabPane>
|
<TabPane key={item.value} title={item.label}></TabPane>
|
||||||
))}
|
))}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
@ -17,18 +17,13 @@ export default {
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
modelValue: {
|
|
||||||
type: Object,
|
|
||||||
default: {},
|
|
||||||
},
|
|
||||||
selectCardInfo: {
|
selectCardInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue', 'cardClick'],
|
emits: ['cardClick', 'platformChange'],
|
||||||
setup(props, { emit, expose }) {
|
setup(props, { emit, expose }) {
|
||||||
const selectedPlatform = ref(1);
|
|
||||||
const modules = [Navigation];
|
const modules = [Navigation];
|
||||||
const handleCardClick = (item) => {
|
const handleCardClick = (item) => {
|
||||||
// emit('update:modelValue', item);
|
// emit('update:modelValue', item);
|
||||||
@ -94,15 +89,15 @@ export default {
|
|||||||
<div
|
<div
|
||||||
key={item.value}
|
key={item.value}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
selectedPlatform.value = item.value;
|
emit('platformChange', item.value);
|
||||||
}}
|
}}
|
||||||
class={`w-100px flex items-center mr-16px py-8px px-12px flex border-1px border-solid border-transparent transition-all
|
class={`w-100px flex items-center mr-16px py-8px px-12px flex border-1px border-solid border-transparent transition-all
|
||||||
items-center rounded-8px cursor-pointer bg-#F2F3F5 hover:bg-#E6E6E8 ${
|
items-center rounded-8px cursor-pointer bg-#F2F3F5 hover:bg-#E6E6E8 ${
|
||||||
selectedPlatform.value === item.value ? '!bg-#F0EDFF !border-#6D4CFE' : ''
|
props.selectCardInfo.platform === item.value ? '!bg-#F0EDFF !border-#6D4CFE' : ''
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<img src={item.icon} alt="" width={20} height={20} class="mr-4px" />
|
<img src={item.icon} alt="" width={20} height={20} class="mr-4px" />
|
||||||
<span class={`cts !color-#211F24 ${selectedPlatform.value === item.value ? 'bold' : ''}`}>
|
<span class={`cts !color-#211F24 ${props.selectCardInfo.platform === item.value ? 'bold' : ''}`}>
|
||||||
{item.label}
|
{item.label}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -64,10 +64,15 @@ export default {
|
|||||||
const getWorkAudits = async () => {
|
const getWorkAudits = async () => {
|
||||||
const { code, data } = await getWorkAuditsBatchDetail({ ids: workIds.value });
|
const { code, data } = await getWorkAuditsBatchDetail({ ids: workIds.value });
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
dataSource.value = data ?? [];
|
const _data = (data ?? []).map((item) => ({
|
||||||
remoteDataSource.value = cloneDeep(data ?? []);
|
...item,
|
||||||
selectCardInfo.value = cloneDeep(data?.[0] ?? {});
|
platform: item.platform === 0 ? 1 : item.platform,
|
||||||
selectedImageInfo.value = data?.[0].files?.[0] ?? {};
|
}));
|
||||||
|
|
||||||
|
dataSource.value = _data;
|
||||||
|
remoteDataSource.value = cloneDeep(_data);
|
||||||
|
selectCardInfo.value = cloneDeep(_data?.[0] ?? {});
|
||||||
|
selectedImageInfo.value = cloneDeep(_data?.[0].files?.[0] ?? {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,6 +82,9 @@ export default {
|
|||||||
resolve(!isEqual(selectCardInfo.value, _item) && !isSaved.value);
|
resolve(!isEqual(selectCardInfo.value, _item) && !isSaved.value);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const onPlatformChange = (platform) => {
|
||||||
|
selectCardInfo.value.platform = platform;
|
||||||
|
};
|
||||||
|
|
||||||
const onExit = async () => {
|
const onExit = async () => {
|
||||||
const isModified = await isSelectCardModified();
|
const isModified = await isSelectCardModified();
|
||||||
@ -165,13 +173,18 @@ export default {
|
|||||||
class="check-list-icon"
|
class="check-list-icon"
|
||||||
onClick={() => checkListDrawerRef.value.open(dataSource.value, selectCardInfo.value)}
|
onClick={() => checkListDrawerRef.value.open(dataSource.value, selectCardInfo.value)}
|
||||||
>
|
>
|
||||||
<icon-menu-fold size={16} class="color-#55585F mr-4px" />
|
<icon-menu-fold size={16} class="color-#55585F mr-4px hover:color-#6D4CFE" />
|
||||||
<span class="cts !color-#211F24">审核列表</span>
|
<span class="cts !color-#211F24">审核列表</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="flex-1 flex flex-col overflow-hidden bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid">
|
<div class="flex-1 flex flex-col overflow-hidden bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid">
|
||||||
<HeaderCard dataSource={dataSource.value} selectCardInfo={selectCardInfo.value} onCardClick={onCardClick} />
|
<HeaderCard
|
||||||
|
dataSource={dataSource.value}
|
||||||
|
selectCardInfo={selectCardInfo.value}
|
||||||
|
onCardClick={onCardClick}
|
||||||
|
onPlatformChange={onPlatformChange}
|
||||||
|
/>
|
||||||
<section class="flex-1 overflow-hidden">
|
<section class="flex-1 overflow-hidden">
|
||||||
<ContentCard
|
<ContentCard
|
||||||
ref={contentCardRef}
|
ref={contentCardRef}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import CommonSelect from '@/components/common-select';
|
|||||||
|
|
||||||
import { useClipboard } from '@vueuse/core';
|
import { useClipboard } from '@vueuse/core';
|
||||||
import { postShareLinksGenerate } from '@/api/all/generationWorkshop';
|
import { postShareLinksGenerate } from '@/api/all/generationWorkshop';
|
||||||
|
import { generateFullUrl } from '@/utils/tools';
|
||||||
|
|
||||||
const INITIAL_FORM = {
|
const INITIAL_FORM = {
|
||||||
work_ids: [],
|
work_ids: [],
|
||||||
@ -44,6 +45,7 @@ export default {
|
|||||||
const formRef = ref(null);
|
const formRef = ref(null);
|
||||||
const formData = ref(cloneDeep(INITIAL_FORM));
|
const formData = ref(cloneDeep(INITIAL_FORM));
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const { copy } = useClipboard({ source: formData.value.link });
|
const { copy } = useClipboard({ source: formData.value.link });
|
||||||
|
|
||||||
@ -63,9 +65,13 @@ export default {
|
|||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const { code, data } = await postShareLinksGenerate(formData.value);
|
const { code, data } = await postShareLinksGenerate(formData.value);
|
||||||
if (!code) {
|
if (code === 200) {
|
||||||
onClose();
|
onClose();
|
||||||
copy(data.code);
|
|
||||||
|
const url = router.resolve({
|
||||||
|
path: `/explore/list/${data.code}`,
|
||||||
|
}).href;
|
||||||
|
copy(generateFullUrl(url));
|
||||||
AMessage.success('复制成功!');
|
AMessage.success('复制成功!');
|
||||||
emit('close');
|
emit('close');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user