Merge pull request 'feature/v1.2灵机空间-内容上传审核_rxd' (#31) from feature/v1.2灵机空间-内容上传审核_rxd into main

Reviewed-on: ai-team/lingji-work-fe#31
This commit is contained in:
2025-08-15 09:40:38 +00:00
71 changed files with 685 additions and 408 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

View File

@ -12,7 +12,7 @@
:disabled="!props.src" :disabled="!props.src"
> >
<template #content> <template #content>
<div class="preview-container" :style="containerStyle"> <div class="preview-container">
<img :src="props.src" alt="preview" class="preview-image" /> <img :src="props.src" alt="preview" class="preview-image" />
</div> </div>
</template> </template>
@ -22,9 +22,9 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue'; // import { computed, onMounted, ref, watch } from 'vue';
import type { ImageOrientation } from '@/utils/tools'; // import type { ImageOrientation } from '@/utils/tools';
import { getImageOrientationByUrl } from '@/utils/tools'; // import { getImageOrientationByUrl } from '@/utils/tools';
interface Props { interface Props {
src: string; src: string;
@ -39,30 +39,30 @@ const props = withDefaults(defineProps<Props>(), {
leaveDelay: 200, leaveDelay: 200,
}); });
const orientation = ref<ImageOrientation>('landscape'); // const orientation = ref<ImageOrientation>('landscape');
const resolveOrientation = async () => { // const resolveOrientation = async () => {
if (!props.src) { // if (!props.src) {
orientation.value = 'landscape'; // orientation.value = 'landscape';
return; // return;
} // }
const o = await getImageOrientationByUrl(props.src); // const o = await getImageOrientationByUrl(props.src);
orientation.value = o === 'square' ? 'landscape' : o; // orientation.value = o === 'square' ? 'landscape' : o;
}; // };
onMounted(resolveOrientation); // onMounted(resolveOrientation);
watch(() => props.src, resolveOrientation); // watch(() => props.src, resolveOrientation);
const containerStyle = computed(() => { // const containerStyle = computed(() => {
// 竖图: 306x400横图: 400x251 // // 竖图: 306x400横图: 400x251
const isPortrait = orientation.value === 'portrait'; // const isPortrait = orientation.value === 'portrait';
const width = isPortrait ? 306 : 400; // const width = isPortrait ? 306 : 400;
const height = isPortrait ? 400 : 251; // const height = isPortrait ? 400 : 251;
return { // return {
width: `${width}px`, // width: `${width}px`,
height: `${height}px`, // height: `${height}px`,
} as Record<string, string>; // } as Record<string, string>;
}); // });
</script> </script>
<style lang="scss"> <style lang="scss">
@ -85,9 +85,9 @@ const containerStyle = computed(() => {
} }
.preview-image { .preview-image {
width: 100%; max-width: 368px;
height: 100%; max-height: 368px;
object-fit: contain; object-fit: scale-down;
} }
} }
</style> </style>

View File

@ -36,10 +36,13 @@ export default function useGetAiReviewResult({
startStatusPolling(); startStatusPolling();
} }
}; };
const handleAgainCheck = async () => { const resetAiReviewInfo = () => {
checkResult.value = {}; checkResult.value = {};
ticket.value = ''; ticket.value = '';
clearStatusPollingTimer(); clearStatusPollingTimer();
};
const handleAgainCheck = async () => {
resetAiReviewInfo();
handleStartCheck(); handleStartCheck();
}; };
const startStatusPolling = () => { const startStatusPolling = () => {
@ -76,5 +79,6 @@ export default function useGetAiReviewResult({
checkResult, checkResult,
checkLoading, checkLoading,
ticket, ticket,
resetAiReviewInfo,
}; };
} }

View File

@ -118,6 +118,8 @@ const COMPONENTS: AppRouteRecordRaw[] = [
locale: '分享链接列表', locale: '分享链接列表',
requiresAuth: false, requiresAuth: false,
requireLogin: false, requireLogin: false,
hideFooter: true,
hideSidebar: true,
roles: ['*'], roles: ['*'],
}, },
component: () => import('@/views/creative-generation-workshop/explore/list/index.vue'), component: () => import('@/views/creative-generation-workshop/explore/list/index.vue'),
@ -129,6 +131,8 @@ const COMPONENTS: AppRouteRecordRaw[] = [
locale: '分享链接详情', locale: '分享链接详情',
requiresAuth: false, requiresAuth: false,
requireLogin: false, requireLogin: false,
hideFooter: true,
hideSidebar: true,
roles: ['*'], roles: ['*'],
}, },
component: () => import('@/views/creative-generation-workshop/explore/detail/index.vue'), component: () => import('@/views/creative-generation-workshop/explore/detail/index.vue'),

View File

@ -3,6 +3,7 @@
.arco-pagination-item { .arco-pagination-item {
border-radius: 4px; border-radius: 4px;
border: 1px solid var(--BG-300, #e6e6e8); border: 1px solid var(--BG-300, #e6e6e8);
font-family: $font-family-manrope-regular;
&-ellipsis { &-ellipsis {
border: none; border: none;
} }
@ -26,9 +27,9 @@
border: 1px solid var(--BG-300, #e6e6e8); border: 1px solid var(--BG-300, #e6e6e8);
} }
&-prepend { &-prepend {
color: var(--Text-2, #3c4043); color: var(--Text-2, #55585f);
text-align: right; text-align: right;
font-family: $font-family-medium; font-family: $font-family-regular;
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
@ -38,4 +39,12 @@
background-color: transparent; background-color: transparent;
} }
} }
.arco-pagination-total {
color: var(--Text-2, #55585f);
font-family: $font-family-regular;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
}
} }

View File

@ -1,6 +1,6 @@
.arco-table { .arco-table {
@mixin table-cell-text { @mixin table-cell-text {
color: var(--Text-1, #3C4043); color: var(--Text-1, #211F24);
font-family: $font-family-regular; font-family: $font-family-regular;
font-size: 14px; font-size: 14px;
font-style: normal; font-style: normal;
@ -22,6 +22,18 @@
@include table-cell-text; @include table-cell-text;
font-family: 'PingFangSC-Medium'; font-family: 'PingFangSC-Medium';
} }
.arco-table-sorter {
.arco-table-sorter-icon {
.arco-icon {
color: #939499;
}
&-active {
.arco-icon {
color: $color-primary;
}
}
}
}
} }
} }
} }
@ -40,5 +52,15 @@
} }
} }
} }
.arco-scrollbar {
display: flex;
flex-direction: column;
.arco-table-element {
height: 100%;
}
.arco-scrollbar-container{
flex: 1;
}
}
} }
} }

View File

@ -9,6 +9,7 @@
html, html,
body { body {
height: 100%;
background: $color-background; background: $color-background;
font-family: $font-family-regular; font-family: $font-family-regular;
font-size: 14px; font-size: 14px;

View File

@ -1,8 +1,8 @@
import icon1 from '@/assets/img/media-account/icon-jl.png'; import icon1 from '@/assets/img/media-account/icon-jl.png';
import icon2 from '@/assets/img/media-account/icon-jg.png'; import icon2 from '@/assets/img/media-account/icon-jg.png';
import icon3 from '@/assets/img/media-account/icon-bili.png'; import icon3 from '@/assets/img/media-account/icon-bili.png';
import icon4 from '@/assets/img/media-account/icon-dy.png'; import icon4 from '@/assets/img/platform/icon-dy.png';
import icon5 from '@/assets/img/media-account/icon-xhs.png'; import icon5 from '@/assets/img/platform/icon-xhs.png';
// 投放账户 // 投放账户
export enum ENUM_PUT_ACCOUNT_PLATFORM { export enum ENUM_PUT_ACCOUNT_PLATFORM {

View File

@ -1,5 +1,5 @@
<script lang="jsx"> <script lang="jsx">
import { Image, Spin, Button, Input, Textarea } from '@arco-design/web-vue'; import { Image, Spin, Button, Input, Textarea, Affix } from '@arco-design/web-vue';
import TextOverTips from '@/components/text-over-tips'; import TextOverTips from '@/components/text-over-tips';
import SvgIcon from '@/components/svg-icon/index.vue'; import SvgIcon from '@/components/svg-icon/index.vue';
import DeleteCommentModal from './delete-comment-modal.vue'; import DeleteCommentModal from './delete-comment-modal.vue';
@ -13,6 +13,7 @@ import { useUserStore } from '@/stores';
import icon1 from '@/assets/img/creative-generation-workshop/icon-line.png'; import icon1 from '@/assets/img/creative-generation-workshop/icon-line.png';
import icon2 from '@/assets/img/creative-generation-workshop/icon-avatar-default.png'; import icon2 from '@/assets/img/creative-generation-workshop/icon-avatar-default.png';
import icon3 from '@/assets/img/error-img.png'; import icon3 from '@/assets/img/error-img.png';
import icon4 from '@/assets/img/creative-generation-workshop/icon-avatar-default-v2.png';
const _iconMap = new Map([ const _iconMap = new Map([
// [3, { icon: <icon-check-circle-fill size={16} class="color-#25C883 flex-shrink-0" /> }], // [3, { icon: <icon-check-circle-fill size={16} class="color-#25C883 flex-shrink-0" /> }],
@ -29,7 +30,7 @@ export default {
}, },
dataSource: { dataSource: {
type: Object, type: Object,
default: () => { }, default: () => {},
}, },
}, },
emits: ['toggle', 'updateComment', 'deleteComment'], emits: ['toggle', 'updateComment', 'deleteComment'],
@ -45,7 +46,7 @@ export default {
const textAreaRef = ref(null); const textAreaRef = ref(null);
const aiReview = computed(() => props.dataSource.ai_review); const aiReview = computed(() => props.dataSource.ai_review);
const violationItems = computed(() => props.dataSource?.ai_review?.violation_items ?? []); const inspectionItems = computed(() => props.dataSource?.ai_review?.inspection_items ?? []);
const closeReplay = () => { const closeReplay = () => {
isReplay.value = false; isReplay.value = false;
@ -55,17 +56,17 @@ export default {
const onReplay = (item) => { const onReplay = (item) => {
isReplay.value = true; isReplay.value = true;
replayTarget.value = item; replayTarget.value = item;
textAreaRef.value.focus();
}; };
const onComment = async () => { const onComment = async () => {
console.log(textAreaRef.value.focus());
const { code, data } = await postShareWorksComments(props.dataSource.id, route.params.shareCode, { const { code, data } = await postShareWorksComments(props.dataSource.id, route.params.shareCode, {
content: comment.value, content: comment.value,
comment_id: replayTarget.value.id, comment_id: replayTarget.value.id,
}); });
if (code === 200) { if (code === 200) {
emit('updateComment'); emit('updateComment');
comment.value = ''; onClearComment();
textAreaRef.value.focus(); textAreaRef.value.focus();
} }
}; };
@ -110,7 +111,7 @@ export default {
<div class="sticky bottom-0 left-0 w-full z-22 px-24px"> <div class="sticky bottom-0 left-0 w-full z-22 px-24px">
<div class="relative"> <div class="relative">
{isReplay.value && ( {isReplay.value && (
<div class="px-12px pt-8px absolute top-0 left-0 z-2 mb-8px w-full"> <div class="px-8px pt-8px absolute top-0 left-0 z-2 mb-8px w-full">
<div class="rounded-4px bg-#F2F3F5 h-30px px-8px flex justify-between items-center "> <div class="rounded-4px bg-#F2F3F5 h-30px px-8px flex justify-between items-center ">
<div class="flex items-center mr-12px flex-1 overflow-hidden"> <div class="flex items-center mr-12px flex-1 overflow-hidden">
<span class="mr-4px cts !color-#737478 flex-shrink-0">回复</span> <span class="mr-4px cts !color-#737478 flex-shrink-0">回复</span>
@ -163,7 +164,7 @@ export default {
{props.dataSource.comments?.map((item) => ( {props.dataSource.comments?.map((item) => (
<div class="comment-item flex px-12px py-8px group" key={item.id}> <div class="comment-item flex px-12px py-8px group" key={item.id}>
<Image <Image
src={item.commenter_id === 0 ? icon2 : item.commenter?.head_image} src={item.commenter_id === 0 ? icon2 : item.commenter?.head_image || icon4}
width={40} width={40}
height={40} height={40}
preview={false} preview={false}
@ -174,7 +175,7 @@ export default {
}} }}
/> />
<div class="flex flex-col flex-1 overflow-hidden"> <div class="flex flex-col flex-1 ">
<div class="flex justify-between"> <div class="flex justify-between">
<p class="mb-4px"> <p class="mb-4px">
<span class="cts !color-#211F24 mr-8px">{getCommentName(item)}</span> <span class="cts !color-#211F24 mr-8px">{getCommentName(item)}</span>
@ -200,7 +201,7 @@ export default {
/> />
</div> </div>
)} )}
<p class="cts !color-#211F24">{item.content}</p> <p class="cts !color-#211F24 break-all">{item.content}</p>
</div> </div>
</div> </div>
))} ))}
@ -212,15 +213,14 @@ export default {
const renderAiSuggest = () => { const renderAiSuggest = () => {
if (isEmpty(aiReview.value)) return null; if (isEmpty(aiReview.value)) return null;
const hasViolationItems = violationItems.value.length > 0 const hasInspectionItems = inspectionItems.value.length > 0;
return ( return (
<> <>
<div class="result-box p-16px rounded-8px"> <div class="result-box p-16px rounded-8px">
<div class="flex items-center justify-between mb-16px"> <div class="flex items-center justify-between mb-16px">
<p class="cts bold !color-#000 !text-16px">审核结果</p> <p class="cts bold !color-#000 !text-16px">审核结果</p>
{ {hasInspectionItems && (
hasViolationItems && (
<Button <Button
type="text" type="text"
class="!color-#6D4CFE hover:!color-#8A70FE" class="!color-#6D4CFE hover:!color-#8A70FE"
@ -228,14 +228,13 @@ export default {
> >
{isCollapse.value ? '展开详情' : '收起详情'} {isCollapse.value ? '展开详情' : '收起详情'}
</Button> </Button>
) )}
}
</div> </div>
<div class="flex items-center"> <div class="flex items-center">
{RESULT_LIST.map((item, index) => ( {RESULT_LIST.map((item, index) => (
<div class="flex flex-col justify-center items-center flex-1 result-item" key={index}> <div class="flex flex-col justify-center items-center flex-1 result-item" key={index}>
<span class="s1" style={{ color: item.color }}>{`${aiReview.value?.[item.value]}${item.suffix || '' <span class="s1" style={{ color: item.color }}>{`${aiReview.value?.[item.value]}${
item.suffix || ''
}`}</span>{' '} }`}</span>{' '}
<span class="cts mt-4px !lh-20px !text-12px !color-#737478">{item.label}</span> <span class="cts mt-4px !lh-20px !text-12px !color-#737478">{item.label}</span>
</div> </div>
@ -243,21 +242,22 @@ export default {
</div> </div>
</div> </div>
<div class={`collapse-box mb-16px overflow-hidden ${isCollapse.value ? 'h-0 ' : 'h-auto'}`}> <div class={`collapse-box mb-16px overflow-hidden ${isCollapse.value ? 'h-0 ' : 'h-auto'}`}>
{hasViolationItems && ( {hasInspectionItems &&
<div class="result-box p-16px rounded-8px mt-16px"> inspectionItems.value.map((parentItem, parentIndex) => (
<p class="cts bold !color-#000 !text-16px mb-16px">敏感词检测</p> <div class="result-box p-16px rounded-8px mt-16px" key={parentIndex}>
<p class="cts bold !color-#000 !text-16px mb-16px">{parentItem.name}</p>
<div class="grid grid-cols-3 gap-x-24px gap-y-8px"> <div class="grid grid-cols-3 gap-x-24px gap-y-8px">
{violationItems.value.map((item, index) => ( {parentItem.items.map((item, index) => (
<div class="audit-item" key={index}> <div class="audit-item" key={index}>
<div class="flex items-center h-20px"> <div class="flex items-center h-20px">
{_iconMap.get(item.risk_level)?.icon} {_iconMap.get(item.level)?.icon}
<TextOverTips context={item.word} class="cts ml-4px !color-#000" /> <TextOverTips context={item.name} class="cts ml-4px !color-#000" />
</div> </div>
</div> </div>
))} ))}
</div> </div>
</div> </div>
)} ))}
</div> </div>
</> </>
); );
@ -281,11 +281,11 @@ export default {
}; };
return () => ( return () => (
<section class="py-16px absolute right-16px w-440px h-full overflow-hidden"> <section class="ai-suggest-wrap py-16px fixed z-3 right-16px w-440px h-full overflow-hidden">
<div class="ai-suggest-box relative py-24px flex flex-col"> <div class="ai-suggest-box relative py-24px flex flex-col">
{!isEmpty(aiReview.value) && ( {!isEmpty(aiReview.value) && (
<div class="relative w-fit ml-24px mb-16px"> <div class="relative w-fit ml-24px mb-16px">
<span class="ai-text">AI 智能审核</span> <span class="ai-text relative z-2">AI 智能审核</span>
<img src={icon1} class="w-80px h-10.8px absolute bottom-1px left--9px" /> <img src={icon1} class="w-80px h-10.8px absolute bottom-1px left--9px" />
</div> </div>
)} )}
@ -297,7 +297,7 @@ export default {
/> />
{/**主体 */} {/**主体 */}
<div class="flex-1 overflow-y-auto px-24px"> <div class="flex-1 overflow-y-auto px-24px main-box">
{/* AI审核结果 */} {/* AI审核结果 */}
{renderAiSuggest()} {renderAiSuggest()}
{/* 评论与回复 */} {/* 评论与回复 */}

View File

@ -1,4 +1,7 @@
.ai-suggest-box { .ai-suggest-wrap {
top: $navbar-height;
height: calc(100% - ($navbar-height + 12px));
.ai-suggest-box {
width: 440px; width: 440px;
height: fit-content; height: fit-content;
max-height: 100%; max-height: 100%;
@ -36,6 +39,10 @@
background-color: #fff; background-color: #fff;
color: #211f24 !important; color: #211f24 !important;
transition: all 0.3s; transition: all 0.3s;
.arco-textarea-mirror,
.arco-textarea {
padding: 8px 16px !important;
}
&:hover { &:hover {
border-color: #6d4cfe !important; border-color: #6d4cfe !important;
} }
@ -49,7 +56,7 @@
.result-item { .result-item {
.s1 { .s1 {
color: var(--Brand-6, #6d4cfe); color: var(--Brand-6, #6d4cfe);
font-family: $font-family-manrope-regular; font-family: $font-family-manrope-medium;
font-size: 24px; font-size: 24px;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
@ -87,6 +94,27 @@
&:not(:last-child) { &:not(:last-child) {
margin-bottom: 8px; margin-bottom: 8px;
} }
&:hover {
border-radius: 8px;
background: rgba(255, 255, 255, 0.8);
}
}
}
}
.main-box {
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
width: 0;
height: 0;
background: transparent;
}
&::-webkit-scrollbar-thumb {
background-color: transparent;
border: none;
}
&::-webkit-scrollbar-track {
background: transparent;
} }
} }
} }

View File

@ -102,7 +102,7 @@ export default {
} else { } else {
return ( return (
<div class="main-img-box mb-16px relative overflow-hidden cursor-pointer"> <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" />
</div> </div>
); );
} }
@ -213,7 +213,7 @@ export default {
<div class="explore-page"> <div class="explore-page">
<header class="page-header"> <header class="page-header">
<div class="content w-full px-24px flex items-center bg-#fff justify-between"> <div class="content w-full px-24px flex items-center bg-#fff justify-between">
<div class="h-full flex items-center cursor-pointer" onClick={handleUserHome}> <div class="h-full flex items-center">
<img src={icon1} alt="" width={130} /> <img src={icon1} alt="" width={130} />
</div> </div>
<div class="flex items-center">{renderActionRow()}</div> <div class="flex items-center">{renderActionRow()}</div>

View File

@ -1,13 +1,36 @@
.explore-page { .explore-page {
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
z-index: -1;
}
position: relative; position: relative;
padding-top: $navbar-height;
min-width: 1200px; min-width: 1200px;
height: 100vh; min-height: 100vh;
background: #fff; background: #fff;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.page-header { .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: fixed; position: fixed;
right: 16px;
top: calc($navbar-height + 32px);
display: flex;
justify-content: center;
align-items: center;
}
.page-header {
position: sticky;
left: 0; left: 0;
right: 0; right: 0;
top: 0; top: 0;
@ -31,6 +54,7 @@
} }
.page-wrap { .page-wrap {
width: calc(100% - 456px);
flex: 1; flex: 1;
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -47,20 +71,7 @@
line-height: 40px; /* 142.857% */ 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 { .main-video-box {
width: 320px; width: 320px;
height: 472px; height: 472px;
@ -68,10 +79,10 @@
aspect-ratio: 3 / 4; aspect-ratio: 3 / 4;
} }
.main-img-box { .main-img-box {
width: 347px; width: 320px;
height: auto; height: auto;
max-height: 472px;
background: #fff; background: #fff;
aspect-ratio: 3/4;
} }
.desc-img-wrap { .desc-img-wrap {
display: grid; display: grid;

View File

@ -45,7 +45,7 @@ export default {
<div class="explore-page"> <div class="explore-page">
<header class="page-header"> <header class="page-header">
<div class="content w-full px-24px flex items-center bg-#fff"> <div class="content w-full px-24px flex items-center bg-#fff">
<div class="h-full flex items-center cursor-pointer" onClick={handleUserHome}> <div class="h-full flex items-center">
<img src={icon2} alt="" /> <img src={icon2} alt="" />
</div> </div>
</div> </div>
@ -56,7 +56,11 @@ export default {
) : ( ) : (
<div class="explore-container"> <div class="explore-container">
<div class="explore-list-wrap pt-24px pb-28px"> <div class="explore-list-wrap pt-24px pb-28px">
<TextOverTips context={`${works.value[0]?.title}${works.value.length}个文件`} class="mb-8px" /> <div class="mb-8px flex items-center w-fit">
<TextOverTips context={`${works.value[0]?.title?.slice(0,10)}...`} class="!w-fit mr-4px" />
<span class="cts color-#211F24">{`${works.value.length}个文件`}</span>
</div>
{/* <TextOverTips context={`${works.value[0]?.title}等${works.value.length}个文件`} /> */}
<p class="cts !color-#939499 mb-24px"> <p class="cts !color-#939499 mb-24px">
{`分享时间:${exactFormatTime(dataSource.value.created_at, 'YYYY-MM-DD HH:mm:ss')} 有效期${ {`分享时间:${exactFormatTime(dataSource.value.created_at, 'YYYY-MM-DD HH:mm:ss')} 有效期${
dataSource.value.days dataSource.value.days

View File

@ -100,7 +100,7 @@
<script setup> <script setup>
import { defineEmits, defineProps } from 'vue'; import { defineEmits, defineProps } from 'vue';
import { PLATFORMS, AuditStatus } from '@/views/creative-generation-workshop/manuscript/check-list/constants'; import { PLATFORMS, AuditStatus } from '@/views/creative-generation-workshop/manuscript-writer/check-list/constants';
const props = defineProps({ const props = defineProps({
query: { query: {

View File

@ -6,7 +6,7 @@
column-resizable column-resizable
:pagination="false" :pagination="false"
:scroll="{ x: '100%' }" :scroll="{ x: '100%' }"
class="manuscript-table w-100%" class="flex-1 manuscript-table w-100%"
bordered bordered
:row-selection="rowSelection" :row-selection="rowSelection"
:selected-row-keys="selectedRowKeys" :selected-row-keys="selectedRowKeys"
@ -118,13 +118,13 @@
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue';
import { formatTableField, exactFormatTime } from '@/utils/tools'; import { formatTableField, exactFormatTime } from '@/utils/tools';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants'; import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript-writer/list/constants';
import { patchWorkAuditsAuditWriter } from '@/api/all/generationWorkshop-writer.ts'; import { patchWorkAuditsAuditWriter } from '@/api/all/generationWorkshop-writer.ts';
import { import {
AuditStatus, AuditStatus,
CUSTOMER_OPINION, CUSTOMER_OPINION,
PLATFORMS, PLATFORMS,
} from '@/views/creative-generation-workshop/manuscript/check-list/constants'; } from '@/views/creative-generation-workshop/manuscript-writer/check-list/constants';
import { slsWithCatch } from '@/utils/stroage.ts'; import { slsWithCatch } from '@/utils/stroage.ts';
import TextOverTips from '@/components/text-over-tips'; import TextOverTips from '@/components/text-over-tips';

View File

@ -18,15 +18,15 @@ export const TABLE_COLUMNS1 = [
dataIndex: 'title', dataIndex: 'title',
width: 300, width: 300,
}, },
{ // {
title: '客户意见', // title: '客户意见',
dataIndex: 'customer_opinion', // dataIndex: 'customer_opinion',
width: 220, // width: 120,
}, // },
{ {
title: '稿件类型', title: '稿件类型',
dataIndex: 'type', dataIndex: 'type',
width: 180, width: 120,
}, },
{ {
title: '上传时间', title: '上传时间',
@ -71,11 +71,11 @@ export const TABLE_COLUMNS2 = [
dataIndex: 'title', dataIndex: 'title',
width: 300, width: 300,
}, },
{ // {
title: '客户意见', // title: '客户意见',
dataIndex: 'customer_opinion', // dataIndex: 'customer_opinion',
width: 220, // width: 120,
}, // },
{ {
title: '审核平台', title: '审核平台',
dataIndex: 'platform', dataIndex: 'platform',
@ -90,7 +90,7 @@ export const TABLE_COLUMNS2 = [
{ {
title: '稿件类型', title: '稿件类型',
dataIndex: 'type', dataIndex: 'type',
width: 180, width: 120,
}, },
{ {
title: '审核时间', title: '审核时间',
@ -140,11 +140,11 @@ export const TABLE_COLUMNS3 = [
dataIndex: 'title', dataIndex: 'title',
width: 300, width: 300,
}, },
{ // {
title: '客户意见', // title: '客户意见',
dataIndex: 'customer_opinion', // dataIndex: 'customer_opinion',
width: 200, // width: 120,
}, // },
{ {
title: '审核平台', title: '审核平台',
dataIndex: 'platform', dataIndex: 'platform',
@ -153,7 +153,7 @@ export const TABLE_COLUMNS3 = [
{ {
title: '稿件类型', title: '稿件类型',
dataIndex: 'type', dataIndex: 'type',
width: 180, width: 120,
}, },
{ {
title: '通过时间', title: '通过时间',
@ -217,8 +217,8 @@ export const INITIAL_QUERY = {
sort_order: undefined, sort_order: undefined,
}; };
import icon1 from '@/assets/img/media-account/icon-dy.png'; import icon1 from '@/assets/img/platform/icon-dy.png';
import icon2 from '@/assets/img/media-account/icon-xhs.png'; import icon2 from '@/assets/img/platform/icon-xhs.png';
export const PLATFORMS = [ export const PLATFORMS = [
{ {

View File

@ -49,7 +49,7 @@ import {
INITIAL_QUERY, INITIAL_QUERY,
AUDIT_STATUS_LIST, AUDIT_STATUS_LIST,
TABLE_COLUMNS1, TABLE_COLUMNS1,
} from '@/views/creative-generation-workshop/manuscript/check-list/constants'; } from '@/views/creative-generation-workshop/manuscript-writer/check-list/constants';
const { const {
dataSource, dataSource,

View File

@ -34,7 +34,7 @@
.pagination-box { .pagination-box {
display: flex; display: flex;
width: 100%; width: 100%;
padding: 16px 24px; padding: 16px 24px 0;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
} }

View File

@ -10,8 +10,8 @@
<div class="flex items-center flex-col justify-center"> <div class="flex items-center flex-col justify-center">
<img :src="icon1" width="80" height="80" class="mb-16px" /> <img :src="icon1" width="80" height="80" class="mb-16px" />
<span class="text-18px lh-26px font-400 color-#211F24 md mb-8px">内容稿件已通过审核</span> <span class="text-18px lh-26px font-400 color-#211F24 md mb-8px">内容稿件已通过审核</span>
<p class="text-14px lh-22px font-400 color-#737478 ld">想让内容更抓眼球更吸流量吗</p> <!-- <p class="text-14px lh-22px font-400 color-#737478 ld">想让内容更抓眼球更吸流量吗</p>
<p class="text-14px lh-22px font-400 color-#737478 ld">试试内容稿件分析功能吧</p> <p class="text-14px lh-22px font-400 color-#737478 ld">试试内容稿件分析功能吧</p> -->
</div> </div>
<!-- <template #footer> <!-- <template #footer>
<a-button type="primary" class="ml-8px" size="medium" @click="onConfirm">内容稿件分析</a-button> <a-button type="primary" class="ml-8px" size="medium" @click="onConfirm">内容稿件分析</a-button>
@ -20,15 +20,20 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'; import { ref, onUnmounted } from 'vue';
import icon1 from '@/assets/img/media-account/icon-feedback-success.png'; import icon1 from '@/assets/img/media-account/icon-feedback-success.png';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const visible = ref(false); const visible = ref(false);
const workIds = ref([]); const workIds = ref([]);
let autoCloseTimer = null;
const onClose = () => { const onClose = () => {
if (autoCloseTimer) {
clearTimeout(autoCloseTimer);
autoCloseTimer = null;
}
if (workIds.value.length === 1) { if (workIds.value.length === 1) {
router.push({ path: `/writer/manuscript/check-list/${route.params.writerCode}` }); router.push({ path: `/writer/manuscript/check-list/${route.params.writerCode}` });
} }
@ -39,8 +44,22 @@ const onClose = () => {
const open = (ids) => { const open = (ids) => {
workIds.value = cloneDeep(ids); workIds.value = cloneDeep(ids);
visible.value = true; visible.value = true;
if (autoCloseTimer) {
clearTimeout(autoCloseTimer);
autoCloseTimer = null;
}
autoCloseTimer = setTimeout(() => {
onClose();
}, 3000);
}; };
onUnmounted(() => {
if (autoCloseTimer) {
clearTimeout(autoCloseTimer);
autoCloseTimer = null;
}
});
defineExpose({ open }); defineExpose({ open });
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -5,11 +5,16 @@ import TextOverTips from '@/components/text-over-tips';
import icon1 from '@/assets/img/error-img.png'; import icon1 from '@/assets/img/error-img.png';
export default { export default {
emits: ['cardClick'],
setup(props, { emit, expose }) { setup(props, { emit, expose }) {
const visible = ref(false); const visible = ref(false);
const dataSource = ref([]); const dataSource = ref([]);
const selectCardInfo = ref({}); const selectCardInfo = ref({});
const handleCardClick = (item) => {
emit('cardClick', item);
onClose();
};
const open = (data, _selectCardInfo) => { const open = (data, _selectCardInfo) => {
dataSource.value = data; dataSource.value = data;
selectCardInfo.value = _selectCardInfo; selectCardInfo.value = _selectCardInfo;
@ -32,22 +37,24 @@ export default {
class="check-list-drawer-xt" class="check-list-drawer-xt"
footer={false} footer={false}
header={false} header={false}
onCancel={onClose}
> >
<div class="flex justify-between items-center h-56px px-24px"> <div class="flex justify-between items-center h-56px px-24px">
<div class="flex items-center"> <div class="flex items-center">
<div class="w-3px h-16px rounded-2px bg-#6D4CFE mr-8px"></div> <div class="w-3px h-16px rounded-2px bg-#6D4CFE mr-8px"></div>
<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 !text-14px">{`${dataSource.value.length}`}</span>
</div> </div>
<icon-menu-unfold size={16} class="color-##55585F cursor-pointer hover:color-#6D4CFE" 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) => (
<div <div
key={item.id}
onClick={() => handleCardClick(item)}
class={`card-item flex rounded-8px bg-#F7F8FA p-8px ${ class={`card-item flex rounded-8px bg-#F7F8FA p-8px ${
selectCardInfo.value.id === item.id ? 'active' : '' selectCardInfo.value.id === item.id ? 'active' : ''
}`} }`}
key={item.id}
> >
<Image <Image
width={48} width={48}
@ -61,8 +68,10 @@ export default {
}} }}
/> />
<div class="flex-1 overflow-hidden flex flex-col items-start"> <div class="flex-1 overflow-hidden flex flex-col items-start">
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} /> <TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px !text-14px`} />
<p class="cts">{`合规程度:${90}%`}</p> <p class="cts !text-14px">{`合规程度:${
item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'
}`}</p>
</div> </div>
</div> </div>
))} ))}

View File

@ -1,4 +1,9 @@
.check-list-drawer-xt { .check-list-drawer-xt {
.arco-drawer-mask {
background-color: transparent;
}
.arco-drawer {
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
.arco-drawer-body { .arco-drawer-body {
overflow: hidden; overflow: hidden;
display: flex; display: flex;
@ -18,13 +23,22 @@
} }
} }
.card-item { .card-item {
cursor: pointer;
border: 1px solid transparent; border: 1px solid transparent;
transition: all;
&:hover {
background-color: #e6e6e8;
}
&:not(:last-child) { &:not(:last-child) {
margin-bottom: 12px; margin-bottom: 12px;
} }
&.active { &.active {
border-color: #6d4cfe; border-color: #6d4cfe;
background-color: #f0edff; background-color: #f0edff;
:deep(.overflow-text) {
font-family: $font-family-medium !important;
}
}
} }
} }
} }

View File

@ -41,7 +41,7 @@ export const RESULT_LIST = [
}, },
{ {
label: '检验项', label: '检验项',
value: 'inspection_items', value: 'inspection_count',
color: '#211F24', color: '#211F24',
}, },
{ {

View File

@ -1,11 +1,25 @@
<template> <template>
<div class="highlight-textarea-container"> <div class="highlight-textarea-container">
<a-textarea ref="textareaWrapRef" v-model="inputValue" placeholder="请输入作品描述" :disabled="disabled" show-word-limit <a-textarea
:max-length="1000" size="large" class="textarea-input h-full w-full" @input="handleInput" ref="textareaWrapRef"
@focus="() => (focus = true)" @blur="() => (focus = false)" /> v-model="inputValue"
placeholder="请输入作品描述"
:disabled="disabled"
show-word-limit
:max-length="1000"
size="large"
class="textarea-input h-full w-full"
@input="handleInput"
@focus="() => (focus = true)"
@blur="() => (focus = false)"
/>
<div class="textarea-highlight" :class="{ focus: focus }" :style="{ visibility: inputValue ? 'visible' : 'hidden' }" <div
v-html="highlightedHtml" /> class="textarea-highlight"
:class="{ focus: focus }"
:style="{ visibility: inputValue ? 'visible' : 'hidden' }"
v-html="highlightedHtml"
/>
</div> </div>
</template> </template>
@ -97,7 +111,8 @@ const generateHighlightedHtml = (): string => {
}; };
onMounted(() => { onMounted(() => {
nativeTextarea = (textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') || nativeTextarea =
(textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') ||
document.querySelector('.textarea-input .arco-textarea'); document.querySelector('.textarea-input .arco-textarea');
if (nativeTextarea) { if (nativeTextarea) {
@ -158,7 +173,7 @@ const handleCompositionUpdate = () => {
font-weight: 400px; font-weight: 400px;
border: 1px solid #d7d7d9; border: 1px solid #d7d7d9;
border-radius: 4px; border-radius: 4px;
resize: vertical; resize: none;
white-space: pre-wrap; white-space: pre-wrap;
word-wrap: break-word; word-wrap: break-word;
z-index: inherit; z-index: inherit;
@ -193,9 +208,8 @@ const handleCompositionUpdate = () => {
background: transparent; background: transparent;
color: transparent; color: transparent;
caret-color: #211f24 !important; caret-color: #211f24 !important;
resize: none;
@include textarea-padding; @include textarea-padding;
// -webkit-text-fill-color: transparent !important;
overflow-y: auto; overflow-y: auto;
} }

View File

@ -22,7 +22,7 @@ import 'swiper/css/navigation';
import { Navigation } from 'swiper/modules'; import { Navigation } from 'swiper/modules';
import { FORM_RULES, enumTab, TAB_LIST, RESULT_LIST, LEVEL_MAP, escapeRegExp } from './constants'; import { FORM_RULES, enumTab, TAB_LIST, RESULT_LIST, LEVEL_MAP, escapeRegExp } 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 { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript-writer/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';
@ -193,7 +193,7 @@ export default {
再次审核 再次审核
</Button> </Button>
{isTextTab.value ? ( {isTextTab.value ? (
<Button size="medium" type="outline" class="w-123px" onClick={onAiReplace} disabled={isDisabled.value}> <Button size="medium" type="outline" class="w-123px check-btn" onClick={onAiReplace} disabled={isDisabled.value}>
{aiReplaceLoading.value ? ( {aiReplaceLoading.value ? (
<> <>
<IconLoading size={14} /> <IconLoading size={14} />
@ -344,7 +344,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 relative z-2">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>
<div class="flex flex-col items-center h-138px justify-center"> <div class="flex flex-col items-center h-138px justify-center">
@ -371,7 +371,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-8px relative w-fit"> <div class=" mb-8px relative w-fit">
<span class="ai-text">AI 审核建议</span> <span class="ai-text relative z-2">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>
{aiReview.value?.suggestion?.map((item, index) => ( {aiReview.value?.suggestion?.map((item, index) => (

View File

@ -10,12 +10,17 @@
font-family: $font-family-medium; font-family: $font-family-medium;
} }
} }
.check-btn {
.check-text { .check-text {
background: linear-gradient(84deg, #266cff 4.57%, #a15af0 84.93%); background: linear-gradient(84deg, #266cff 4.57%, #a15af0 84.93%);
background-clip: text; background-clip: text;
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
} }
&:hover {
opacity: 0.8;
}
}
.left-box { .left-box {
:deep(.arco-tabs) { :deep(.arco-tabs) {
.arco-tabs-nav { .arco-tabs-nav {
@ -138,7 +143,7 @@
height: fit-content; height: fit-content;
max-height: 100%; max-height: 100%;
.s1 { .s1 {
font-family: $font-family-manrope-regular; font-family: $font-family-manrope-medium;
font-size: 24px; font-size: 24px;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;

View File

@ -6,7 +6,7 @@ import TextOverTips from '@/components/text-over-tips';
import 'swiper/css'; import 'swiper/css';
import 'swiper/css/navigation'; import 'swiper/css/navigation';
import { Navigation } from 'swiper/modules'; import { Navigation } from 'swiper/modules';
import { PLATFORMS } from '@/views/creative-generation-workshop/manuscript/check-list/constants'; import { PLATFORMS } from '@/views/creative-generation-workshop/manuscript-writer/check-list/constants';
import icon1 from '@/assets/img/error-img.png'; import icon1 from '@/assets/img/error-img.png';
import icon2 from '@/assets/img/creative-generation-workshop/icon-lf.png'; import icon2 from '@/assets/img/creative-generation-workshop/icon-lf.png';
@ -64,7 +64,7 @@ export default {
/> />
<div class="flex-1 overflow-hidden flex flex-col items-start"> <div class="flex-1 overflow-hidden flex flex-col items-start">
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} /> <TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} />
<p class="cts">{`合规程度:${90}%`}</p> <p class="cts">{`合规程度:${item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'}`}</p>
</div> </div>
</SwiperSlide> </SwiperSlide>
))} ))}

View File

@ -37,7 +37,7 @@ export default {
const writerCode = computed(() => route.params.writerCode); const writerCode = computed(() => route.params.writerCode);
const { handleStartCheck, handleAgainCheck, ticket, checkLoading } = useGetAiReviewResult({ const { handleStartCheck, handleAgainCheck, ticket, checkLoading, resetAiReviewInfo } = useGetAiReviewResult({
cardInfo: selectCardInfo, cardInfo: selectCardInfo,
startAiReviewFn: postWorkAuditsAiReviewWriter, startAiReviewFn: postWorkAuditsAiReviewWriter,
getAiReviewResultFn: getWorkAuditsAiReviewResultWriter, getAiReviewResultFn: getWorkAuditsAiReviewResultWriter,
@ -56,13 +56,12 @@ export default {
submitLoading.value = false; submitLoading.value = false;
getDataLoading.value = false; getDataLoading.value = false;
checkLoading.value = false; checkLoading.value = false;
ticket.value = ''; resetAiReviewInfo();
const { files = [], ai_review } = item; const { files = [], ai_review } = item;
selectCardInfo.value = cloneDeep(item); selectCardInfo.value = cloneDeep(item);
selectedImageInfo.value = cloneDeep(files?.[0] ?? {}); selectedImageInfo.value = cloneDeep(files?.[0] ?? {});
console.log({ ai_review });
if (isEmpty(ai_review)) { if (isEmpty(ai_review)) {
handleStartCheck(); handleStartCheck();
} }
@ -210,7 +209,7 @@ 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 hover:color-#6D4CFE" /> <icon-menu-fold size={16} class="color-#55585F mr-4px icon" />
<span class="cts !color-#211F24">审核列表</span> <span class="cts !color-#211F24">审核列表</span>
</div> </div>
)} )}
@ -244,7 +243,7 @@ export default {
<CancelCheckModal ref={cancelCheckModalRef} onSelectCard={onChangeCard} /> <CancelCheckModal ref={cancelCheckModalRef} onSelectCard={onChangeCard} />
<CheckSuccessModal ref={checkSuccessModalRef} /> <CheckSuccessModal ref={checkSuccessModalRef} />
<CheckListDrawer ref={checkListDrawerRef} /> <CheckListDrawer ref={checkListDrawerRef} onCardClick={onCardClick} />
</> </>
); );
}, },

View File

@ -27,6 +27,12 @@ $footer-height: 68px;
position: absolute; position: absolute;
right: 0; right: 0;
top: calc($navbar-height + 8px); top: calc($navbar-height + 8px);
&:hover {
.icon,
.cts {
color: #6d4cfe !important;
}
}
} }
} }
.footer-row { .footer-row {

View File

@ -7,7 +7,7 @@ import TextOverTips from '@/components/text-over-tips';
import ImgBox from './img-box'; import ImgBox from './img-box';
import { formatFileSize, getVideoInfo, formatDuration, formatUploadSpeed } from '@/utils/tools'; import { formatFileSize, getVideoInfo, formatDuration, formatUploadSpeed } from '@/utils/tools';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts'; import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript-writer/list/constants.ts';
import { getVideoPreSignedUrlWriter, getImagePreSignedUrlWriter } from '@/api/all/generationWorkshop-writer'; import { getVideoPreSignedUrlWriter, getImagePreSignedUrlWriter } from '@/api/all/generationWorkshop-writer';
// import icon1 from '@/assets/img/creative-generation-workshop/icon-close.png'; // import icon1 from '@/assets/img/creative-generation-workshop/icon-close.png';

View File

@ -2,9 +2,9 @@
import { Button, Message as AMessage, Spin } from '@arco-design/web-vue'; import { Button, Message as AMessage, Spin } from '@arco-design/web-vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { AuditStatus } from '@/views/creative-generation-workshop/manuscript/check-list/constants'; import { AuditStatus } from '@/views/creative-generation-workshop/manuscript-writer/check-list/constants';
import { getWorksDetailWriter } from '@/api/all/generationWorkshop-writer.ts'; import { getWorksDetailWriter } from '@/api/all/generationWorkshop-writer.ts';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts'; import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript-writer/list/constants.ts';
import { convertVideoUrlToCoverUrl, exactFormatTime } from '@/utils/tools.ts'; import { convertVideoUrlToCoverUrl, exactFormatTime } from '@/utils/tools.ts';
import { slsWithCatch } from '@/utils/stroage.ts'; import { slsWithCatch } from '@/utils/stroage.ts';
@ -81,7 +81,7 @@ export default {
} else { } else {
return ( return (
<div class="main-img-box mb-16px relative overflow-hidden cursor-pointer"> <div class="main-img-box mb-16px relative overflow-hidden cursor-pointer">
<img src={coverImageUrl.value} class="w-100% h-100% object-contain absolute z-0 top-0 left-0" /> <img src={coverImageUrl.value} class="w-100% h-100% object-contain" />
</div> </div>
); );
} }
@ -154,7 +154,7 @@ export default {
<icon-oblique-line size="12" class="color-#C9CDD4 mx-4px" /> <icon-oblique-line size="12" class="color-#C9CDD4 mx-4px" />
<span class="cts bold !color-#1D2129">内容稿件详情</span> <span class="cts bold !color-#1D2129">内容稿件详情</span>
</div> </div>
<div class="flex-1 overflow-y-auto bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid py-32px"> <div class="flex-1 bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid py-32px">
<div class="w-684px mx-auto flex flex-col items-center"> <div class="w-684px mx-auto flex flex-col items-center">
<div class="flex justify-start flex-col w-full"> <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="mb-8px cts bold !text-28px !lh-40px !color-#211F24">{dataSource.value.title}</p>

View File

@ -2,6 +2,7 @@ $footer-height: 68px;
.manuscript-detail-wrap { .manuscript-detail-wrap {
width: 100%; width: 100%;
height: calc(100% - 72px); height: calc(100% - 72px);
margin-bottom: 72px;
.cts { .cts {
color: #939499; color: #939499;
font-family: $font-family-regular; font-family: $font-family-regular;
@ -22,8 +23,8 @@ $footer-height: 68px;
.main-img-box { .main-img-box {
width: 320px; width: 320px;
height: auto; height: auto;
max-height: 472px;
background: #fff; background: #fff;
aspect-ratio: 3/4;
} }
.desc-img-wrap { .desc-img-wrap {
display: grid; display: grid;

View File

@ -4,7 +4,7 @@ import EditForm, { ENUM_UPLOAD_STATUS, INITIAL_VIDEO_INFO } from '../components/
import CancelEditModal from './cancel-edit-modal.vue'; import CancelEditModal from './cancel-edit-modal.vue';
import { getWorksDetailWriter, putWorksUpdateWriter } from '@/api/all/generationWorkshop-writer.ts'; import { getWorksDetailWriter, putWorksUpdateWriter } from '@/api/all/generationWorkshop-writer.ts';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts'; import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript-writer/list/constants.ts';
import { formatDuration, formatFileSize, convertVideoUrlToCoverUrl } from '@/utils/tools'; import { formatDuration, formatFileSize, convertVideoUrlToCoverUrl } from '@/utils/tools';
import { slsWithCatch } from '@/utils/stroage.ts'; import { slsWithCatch } from '@/utils/stroage.ts';
@ -93,7 +93,7 @@ export default {
<> <>
<div class="manuscript-edit-wrap"> <div class="manuscript-edit-wrap">
<div class="flex items-center mb-8px"> <div class="flex items-center mb-8px">
<span class="cts color-#4E5969 cursor-pointer" onClick={onBack}> <span class="cts color-#4E5969 cursor-pointer" onClick={onCancel}>
内容稿件列表 内容稿件列表
</span> </span>
<icon-oblique-line size="12" class="color-#C9CDD4 mx-4px" /> <icon-oblique-line size="12" class="color-#C9CDD4 mx-4px" />

View File

@ -98,7 +98,7 @@
import { ref } from 'vue'; import { ref } from 'vue';
import { formatTableField, exactFormatTime } from '@/utils/tools'; import { formatTableField, exactFormatTime } from '@/utils/tools';
import { TABLE_COLUMNS } from './constants'; import { TABLE_COLUMNS } from './constants';
import { CHECK_STATUS, EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants'; import { CHECK_STATUS, EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript-writer/list/constants';
import TextOverTips from '@/components/text-over-tips'; import TextOverTips from '@/components/text-over-tips';
import HoverImagePreview from '@/components/hover-image-preview'; import HoverImagePreview from '@/components/hover-image-preview';

View File

@ -51,11 +51,20 @@ export default {
// 响应式状态 // 响应式状态
const visible = ref(false); const visible = ref(false);
const formRef = ref(null); const formRef = ref(null);
const uploadType = ref(UPLOAD_TYPE.LINK); const uploadType = ref(UPLOAD_TYPE.LOCAL);
const taskStatus = ref(TASK_STATUS.DEFAULT); const taskStatus = ref(TASK_STATUS.DEFAULT);
const form = ref(cloneDeep(INITIAL_FORM)); const form = ref(cloneDeep(INITIAL_FORM));
const works = ref([]); const works = ref([]);
// 生成自增 id基于当前列表中最大的 id
const getNextWorkId = () => {
const currentMax = works.value.reduce((max, item) => {
const numericId = Number(item?.id);
return Number.isFinite(numericId) ? Math.max(max, numericId) : max;
}, 0);
return currentMax + 1;
};
// 剪贴板功能 // 剪贴板功能
const isLink = computed(() => uploadType.value === UPLOAD_TYPE.LINK); const isLink = computed(() => uploadType.value === UPLOAD_TYPE.LINK);
@ -129,6 +138,7 @@ export default {
const formData = new FormData(); const formData = new FormData();
formData.append('file', file); formData.append('file', file);
const { code, data } = await postWorksByFileWriter(formData, { const { code, data } = await postWorksByFileWriter(formData, {
timeout: 0,
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
'writer-code': writerCode.value, 'writer-code': writerCode.value,
@ -136,7 +146,10 @@ export default {
}); });
if (code === 200) { if (code === 200) {
taskStatus.value = TASK_STATUS.SUCCESS; taskStatus.value = TASK_STATUS.SUCCESS;
works.value = data ? [data] : []; if (data) {
const id = data.id ?? getNextWorkId();
works.value.push({ ...data, id });
}
} }
}; };
@ -150,7 +163,7 @@ export default {
// 删除项目 // 删除项目
const onDelete = (index) => { const onDelete = (index) => {
works.value.splice(index, 1); works.value.splice(index, 1);
if(!works.value.length) { if (!works.value.length) {
taskStatus.value = TASK_STATUS.DEFAULT; taskStatus.value = TASK_STATUS.DEFAULT;
} }
// AMessage.success('删除成功'); // AMessage.success('删除成功');
@ -189,8 +202,9 @@ export default {
<Upload <Upload
action="/" action="/"
draggable draggable
multiple
customRequest={handleUpload} customRequest={handleUpload}
accept=".xlsx,.xls,.docx,.doc,.mp4,.mov,.avi,.flv,.wmv" accept=".xlsx,.xls,.docx,.doc,.mp4,.mov,.avi,.flv,.wmv,.m4v"
show-file-list={false} show-file-list={false}
> >
{{ {{
@ -328,23 +342,15 @@ export default {
footer: () => renderFooterButtons(), footer: () => renderFooterButtons(),
}} }}
> >
<Form <Form ref={formRef} model={form.value} layout="horizontal" auto-label-width>
ref={formRef} {/* {isDefault.value && (
rules={{
link: [{ required: true, message: '请输入飞书链接地址' }],
}}
model={form.value}
layout="horizontal"
auto-label-width
>
{isDefault.value && (
<FormItem label="上传方式"> <FormItem label="上传方式">
<RadioGroup v-model={uploadType.value} onChange={onUploadTypeChange}> <RadioGroup v-model={uploadType.value} onChange={onUploadTypeChange}>
<Radio value={UPLOAD_TYPE.LINK}>外部链接上传</Radio> <Radio value={UPLOAD_TYPE.LINK}>外部链接上传</Radio>
<Radio value={UPLOAD_TYPE.LOCAL}>本地上传</Radio> <Radio value={UPLOAD_TYPE.LOCAL}>本地上传</Radio>
</RadioGroup> </RadioGroup>
</FormItem> </FormItem>
)} )} */}
{renderFormContent()} {renderFormContent()}
</Form> </Form>

View File

@ -47,7 +47,7 @@ import UploadManuscriptModal from './components/upload-manuscript-modal';
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination'; import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
import { getWorksPageWriter } from '@/api/all/generationWorkshop-writer.ts'; import { getWorksPageWriter } from '@/api/all/generationWorkshop-writer.ts';
import { INITIAL_QUERY, EnumCheckStatus } from '@/views/creative-generation-workshop/manuscript/list/constants.ts'; import { INITIAL_QUERY, EnumCheckStatus } from '@/views/creative-generation-workshop/manuscript-writer/list/constants.ts';
const { dataSource, pageInfo, onPageChange, onPageSizeChange, resetPageInfo } = useTableSelectionWithPagination({ const { dataSource, pageInfo, onPageChange, onPageSizeChange, resetPageInfo } = useTableSelectionWithPagination({
onPageChange: () => { onPageChange: () => {

View File

@ -1,5 +1,5 @@
.manuscript-list-wrap { .manuscript-list-wrap {
height: 100%; // height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.filter-wrap { .filter-wrap {
@ -21,7 +21,7 @@
.pagination-box { .pagination-box {
display: flex; display: flex;
width: 100%; width: 100%;
padding: 16px 24px; padding: 16px 24px 0;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
} }

View File

@ -5,7 +5,7 @@ import EditForm, { ENUM_UPLOAD_STATUS, INITIAL_VIDEO_INFO } from '../components/
import CancelUploadModal from './cancel-upload-modal.vue'; import CancelUploadModal from './cancel-upload-modal.vue';
import UploadSuccessModal from './upload-success-modal.vue'; import UploadSuccessModal from './upload-success-modal.vue';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants'; import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript-writer/list/constants';
import { postWorksBatchWriter } from '@/api/all/generationWorkshop-writer.ts'; import { postWorksBatchWriter } from '@/api/all/generationWorkshop-writer.ts';
import { glsWithCatch, rlsWithCatch, slsWithCatch } from '@/utils/stroage.ts'; import { glsWithCatch, rlsWithCatch, slsWithCatch } from '@/utils/stroage.ts';
import { formatDuration, formatFileSize, convertVideoUrlToCoverUrl } from '@/utils/tools'; import { formatDuration, formatFileSize, convertVideoUrlToCoverUrl } from '@/utils/tools';
@ -199,8 +199,7 @@ export default {
_data.videoInfo.poster = convertVideoUrlToCoverUrl(url); _data.videoInfo.poster = convertVideoUrlToCoverUrl(url);
} }
return _data return _data;
}); });
works.value = _works; works.value = _works;
@ -266,7 +265,7 @@ export default {
<div <div
key={item.id} key={item.id}
id={`card-${item.id}`} id={`card-${item.id}`}
class={`group relative mb-12px px-8px py-12px flex flex-col rounded-8px bg-#F7F8FA border-1px border-solid border-transparent transition-all duration-300 cursor-pointer hover:bg-#E6E6E8 ${getCardClass( class={`group h-66px relative mb-12px px-12px py-8px flex flex-col rounded-8px bg-#F7F8FA border-1px border-solid border-transparent transition-all duration-300 cursor-pointer hover:bg-#E6E6E8 ${getCardClass(
item, item,
)}`} )}`}
onClick={() => onSelect(item)} onClick={() => onSelect(item)}
@ -277,7 +276,7 @@ export default {
onClick={(e) => onDelete(e, item, index)} onClick={(e) => onDelete(e, item, index)}
/> />
<TextOverTips <TextOverTips
context={item.content} context={item.title || '-'}
line={1} line={1}
class={`cts !color-#211F24 mb-8px ${selectCardInfo.value.id === item.id ? 'bold' : ''}`} class={`cts !color-#211F24 mb-8px ${selectCardInfo.value.id === item.id ? 'bold' : ''}`}
/> />
@ -285,18 +284,20 @@ export default {
<div class="flex items-center "> <div class="flex items-center ">
<img <img
src={item.type === EnumManuscriptType.Image ? icon1 : icon2} src={item.type === EnumManuscriptType.Image ? icon1 : icon2}
width="16" width="14"
height="16" height="14"
class="mr-4px" class="mr-4px"
/> />
<span <span
class={`cts ${item.type === EnumManuscriptType.Image ? '!color-#25C883' : '!color-#6D4CFE'}`} class={`cts !text-12px ${
item.type === EnumManuscriptType.Image ? '!color-#25C883' : '!color-#6D4CFE'
}`}
> >
{item.type === EnumManuscriptType.Image ? '图文' : '视频'} {item.type === EnumManuscriptType.Image ? '图文' : '视频'}
</span> </span>
</div> </div>
{errorDataCards.value.find((v) => v.id === item.id) && ( {errorDataCards.value.find((v) => v.id === item.id) && (
<p class="cts !color-#F64B31">必填项未填</p> <p class="cts !text-12px !color-#F64B31">必填项未填</p>
)} )}
</div> </div>
</div> </div>

View File

@ -1,7 +1,8 @@
$footer-height: 68px; $footer-height: 68px;
.manuscript-upload-wrap { .manuscript-upload-wrap {
height: calc(100% - 72px); height: calc(100% - 72px);
.cts { .cts,
:deep(.overflow-text) {
color: #939499; color: #939499;
font-family: $font-family-regular; font-family: $font-family-regular;
font-size: 14px; font-size: 14px;

View File

@ -6,7 +6,7 @@
column-resizable column-resizable
:pagination="false" :pagination="false"
:scroll="{ x: '100%' }" :scroll="{ x: '100%' }"
class="manuscript-table w-100%" class="flex-1 manuscript-table w-100%"
bordered bordered
:row-selection="rowSelection" :row-selection="rowSelection"
:selected-row-keys="selectedRowKeys" :selected-row-keys="selectedRowKeys"

View File

@ -21,12 +21,12 @@ export const TABLE_COLUMNS1 = [
{ {
title: '客户意见', title: '客户意见',
dataIndex: 'customer_opinion', dataIndex: 'customer_opinion',
width: 220, width: 120,
}, },
{ {
title: '稿件类型', title: '稿件类型',
dataIndex: 'type', dataIndex: 'type',
width: 180, width: 120,
}, },
{ {
title: '上传时间', title: '上传时间',
@ -84,7 +84,7 @@ export const TABLE_COLUMNS2 = [
{ {
title: '客户意见', title: '客户意见',
dataIndex: 'customer_opinion', dataIndex: 'customer_opinion',
width: 220, width: 120,
}, },
{ {
title: '审核平台', title: '审核平台',
@ -100,7 +100,7 @@ export const TABLE_COLUMNS2 = [
{ {
title: '稿件类型', title: '稿件类型',
dataIndex: 'type', dataIndex: 'type',
width: 180, width: 120,
}, },
{ {
title: '审核时间', title: '审核时间',
@ -153,7 +153,7 @@ export const TABLE_COLUMNS3 = [
{ {
title: '客户意见', title: '客户意见',
dataIndex: 'customer_opinion', dataIndex: 'customer_opinion',
width: 200, width: 120,
}, },
{ {
title: '审核平台', title: '审核平台',
@ -163,7 +163,7 @@ export const TABLE_COLUMNS3 = [
{ {
title: '稿件类型', title: '稿件类型',
dataIndex: 'type', dataIndex: 'type',
width: 180, width: 120,
}, },
{ {
title: '通过时间', title: '通过时间',
@ -227,8 +227,8 @@ export const INITIAL_QUERY = {
sort_order: undefined, sort_order: undefined,
}; };
import icon1 from '@/assets/img/media-account/icon-dy.png'; import icon1 from '@/assets/img/platform/icon-dy.png';
import icon2 from '@/assets/img/media-account/icon-xhs.png'; import icon2 from '@/assets/img/platform/icon-xhs.png';
export const PLATFORMS = [ export const PLATFORMS = [
{ {

View File

@ -34,7 +34,7 @@
.pagination-box { .pagination-box {
display: flex; display: flex;
width: 100%; width: 100%;
padding: 16px 24px; padding: 16px 24px 0;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
} }

View File

@ -5,11 +5,16 @@ import TextOverTips from '@/components/text-over-tips';
import icon1 from '@/assets/img/error-img.png'; import icon1 from '@/assets/img/error-img.png';
export default { export default {
emits: ['cardClick'],
setup(props, { emit, expose }) { setup(props, { emit, expose }) {
const visible = ref(false); const visible = ref(false);
const dataSource = ref([]); const dataSource = ref([]);
const selectCardInfo = ref({}); const selectCardInfo = ref({});
const handleCardClick = (item) => {
emit('cardClick', item);
onClose();
};
const open = (data, _selectCardInfo) => { const open = (data, _selectCardInfo) => {
dataSource.value = data; dataSource.value = data;
selectCardInfo.value = _selectCardInfo; selectCardInfo.value = _selectCardInfo;
@ -32,22 +37,24 @@ export default {
class="check-list-drawer-xt" class="check-list-drawer-xt"
footer={false} footer={false}
header={false} header={false}
onCancel={onClose}
> >
<div class="flex justify-between items-center h-56px px-24px"> <div class="flex justify-between items-center h-56px px-24px">
<div class="flex items-center"> <div class="flex items-center">
<div class="w-3px h-16px rounded-2px bg-#6D4CFE mr-8px"></div> <div class="w-3px h-16px rounded-2px bg-#6D4CFE mr-8px"></div>
<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 !text-14px">{`${dataSource.value.length}`}</span>
</div> </div>
<icon-menu-unfold size={16} class="color-##55585F cursor-pointer hover:color-#6D4CFE" 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) => (
<div <div
onClick={() => handleCardClick(item)}
key={item.id}
class={`card-item flex rounded-8px bg-#F7F8FA p-8px ${ class={`card-item flex rounded-8px bg-#F7F8FA p-8px ${
selectCardInfo.value.id === item.id ? 'active' : '' selectCardInfo.value.id === item.id ? 'active' : ''
}`} }`}
key={item.id}
> >
<Image <Image
width={48} width={48}
@ -61,8 +68,10 @@ export default {
}} }}
/> />
<div class="flex-1 overflow-hidden flex flex-col items-start"> <div class="flex-1 overflow-hidden flex flex-col items-start">
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} /> <TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px !text-14px`} />
<p class="cts">{`合规程度:${90}%`}</p> <p class="cts !text-14px">{`合规程度:${
item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'
}`}</p>
</div> </div>
</div> </div>
))} ))}

View File

@ -1,4 +1,9 @@
.check-list-drawer-xt { .check-list-drawer-xt {
.arco-drawer-mask {
background-color: transparent;
}
.arco-drawer {
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.15);
.arco-drawer-body { .arco-drawer-body {
overflow: hidden; overflow: hidden;
display: flex; display: flex;
@ -18,13 +23,22 @@
} }
} }
.card-item { .card-item {
cursor: pointer;
border: 1px solid transparent; border: 1px solid transparent;
transition: all;
&:hover {
background-color: #e6e6e8;
}
&:not(:last-child) { &:not(:last-child) {
margin-bottom: 12px; margin-bottom: 12px;
} }
&.active { &.active {
border-color: #6d4cfe; border-color: #6d4cfe;
background-color: #f0edff; background-color: #f0edff;
:deep(.overflow-text) {
font-family: $font-family-medium !important;
}
}
} }
} }
} }

View File

@ -41,7 +41,7 @@ export const RESULT_LIST = [
}, },
{ {
label: '检验项', label: '检验项',
value: 'inspection_items', value: 'inspection_count',
color: '#211F24', color: '#211F24',
}, },
{ {

View File

@ -1,11 +1,25 @@
<template> <template>
<div class="highlight-textarea-container"> <div class="highlight-textarea-container">
<a-textarea ref="textareaWrapRef" v-model="inputValue" placeholder="请输入作品描述" :disabled="disabled" show-word-limit <a-textarea
:max-length="1000" size="large" class="textarea-input h-full w-full" @input="handleInput" ref="textareaWrapRef"
@focus="() => (focus = true)" @blur="() => (focus = false)" /> v-model="inputValue"
placeholder="请输入作品描述"
:disabled="disabled"
show-word-limit
:max-length="1000"
size="large"
class="textarea-input h-full w-full"
@input="handleInput"
@focus="() => (focus = true)"
@blur="() => (focus = false)"
/>
<div class="textarea-highlight" :class="{ focus: focus }" :style="{ visibility: inputValue ? 'visible' : 'hidden' }" <div
v-html="highlightedHtml" /> class="textarea-highlight"
:class="{ focus: focus }"
:style="{ visibility: inputValue ? 'visible' : 'hidden' }"
v-html="highlightedHtml"
/>
</div> </div>
</template> </template>
@ -98,7 +112,8 @@ const generateHighlightedHtml = (): string => {
}; };
onMounted(() => { onMounted(() => {
nativeTextarea = (textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') || nativeTextarea =
(textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') ||
document.querySelector('.textarea-input .arco-textarea'); document.querySelector('.textarea-input .arco-textarea');
if (nativeTextarea) { if (nativeTextarea) {
@ -159,7 +174,7 @@ const handleCompositionUpdate = () => {
font-weight: 400px; font-weight: 400px;
border: 1px solid #d7d7d9; border: 1px solid #d7d7d9;
border-radius: 4px; border-radius: 4px;
resize: vertical; resize: none;
white-space: pre-wrap; white-space: pre-wrap;
word-wrap: break-word; word-wrap: break-word;
z-index: inherit; z-index: inherit;
@ -194,9 +209,8 @@ const handleCompositionUpdate = () => {
background: transparent; background: transparent;
color: transparent; color: transparent;
caret-color: #211f24 !important; caret-color: #211f24 !important;
resize: none;
@include textarea-padding; @include textarea-padding;
// -webkit-text-fill-color: transparent !important;
overflow-y: auto; overflow-y: auto;
} }

View File

@ -194,7 +194,7 @@ export default {
再次审核 再次审核
</Button> </Button>
{isTextTab.value ? ( {isTextTab.value ? (
<Button size="medium" type="outline" class="w-123px" onClick={onAiReplace} disabled={isDisabled.value}> <Button size="medium" type="outline" class="w-123px check-btn" onClick={onAiReplace} disabled={isDisabled.value}>
{aiReplaceLoading.value ? ( {aiReplaceLoading.value ? (
<> <>
<IconLoading size={14} /> <IconLoading size={14} />
@ -345,7 +345,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 relative z-2">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>
<div class="flex flex-col items-center h-138px justify-center"> <div class="flex flex-col items-center h-138px justify-center">
@ -372,7 +372,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-8px relative w-fit"> <div class=" mb-8px relative w-fit">
<span class="ai-text">AI 审核建议</span> <span class="ai-text relative z-2">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>
{aiReview.value?.suggestion?.map((item, index) => ( {aiReview.value?.suggestion?.map((item, index) => (

View File

@ -10,12 +10,18 @@
font-family: $font-family-medium; font-family: $font-family-medium;
} }
} }
.check-btn {
.check-text { .check-text {
background: linear-gradient(84deg, #266cff 4.57%, #a15af0 84.93%); background: linear-gradient(84deg, #266cff 4.57%, #a15af0 84.93%);
background-clip: text; background-clip: text;
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
} }
&:hover {
opacity: 0.8;
}
}
.left-box { .left-box {
:deep(.arco-tabs) { :deep(.arco-tabs) {
.arco-tabs-nav { .arco-tabs-nav {
@ -130,15 +136,17 @@
} }
} }
.right-box { .right-box {
border: 1px solid #E6E6E8; border: 1px solid #e6e6e8;
flex: 1; flex: 1;
border-radius: 8px; padding: 16px; display: flex; border-radius: 8px;
padding: 16px;
display: flex;
flex-direction: column; flex-direction: column;
overflow-y: auto; overflow-y: auto;
height: fit-content; height: fit-content;
max-height: 100%; max-height: 100%;
.s1 { .s1 {
font-family: $font-family-manrope-regular; font-family: $font-family-manrope-medium;
font-size: 24px; font-size: 24px;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;

View File

@ -64,7 +64,7 @@ export default {
/> />
<div class="flex-1 overflow-hidden flex flex-col items-start"> <div class="flex-1 overflow-hidden flex flex-col items-start">
<TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} /> <TextOverTips context={item.title} class={`cts !color-#211F24 title mb-4px`} />
<p class="cts">{`合规程度:${90}%`}</p> <p class="cts">{`合规程度:${item.ai_review?.compliance_level ? `${item.ai_review?.compliance_level}%` : '-'}`}</p>
</div> </div>
</SwiperSlide> </SwiperSlide>
))} ))}

View File

@ -38,7 +38,7 @@ export default {
const selectCardInfo = ref({}); const selectCardInfo = ref({});
const selectedImageInfo = ref(null); const selectedImageInfo = ref(null);
const { handleStartCheck, handleAgainCheck, ticket, checkLoading } = useGetAiReviewResult({ const { handleStartCheck, handleAgainCheck, ticket, checkLoading, resetAiReviewInfo } = useGetAiReviewResult({
cardInfo: selectCardInfo, cardInfo: selectCardInfo,
startAiReviewFn: postWorkAuditsAiReview, startAiReviewFn: postWorkAuditsAiReview,
getAiReviewResultFn: getWorkAuditsAiReviewResult, getAiReviewResultFn: getWorkAuditsAiReviewResult,
@ -57,7 +57,7 @@ export default {
submitLoading.value = false; submitLoading.value = false;
getDataLoading.value = false; getDataLoading.value = false;
checkLoading.value = false; checkLoading.value = false;
ticket.value = ''; resetAiReviewInfo();
const { files = [], ai_review } = item; const { files = [], ai_review } = item;
selectCardInfo.value = cloneDeep(item); selectCardInfo.value = cloneDeep(item);
@ -210,7 +210,7 @@ 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 hover:color-#6D4CFE" /> <icon-menu-fold size={16} class="color-#55585F icon mr-4px" />
<span class="cts !color-#211F24">审核列表</span> <span class="cts !color-#211F24">审核列表</span>
</div> </div>
)} )}
@ -244,7 +244,7 @@ export default {
<CancelCheckModal ref={cancelCheckModalRef} onSelectCard={onChangeCard} /> <CancelCheckModal ref={cancelCheckModalRef} onSelectCard={onChangeCard} />
<CheckSuccessModal ref={checkSuccessModalRef} /> <CheckSuccessModal ref={checkSuccessModalRef} />
<CheckListDrawer ref={checkListDrawerRef} /> <CheckListDrawer ref={checkListDrawerRef} onCardClick={onCardClick} />
</> </>
); );
}, },

View File

@ -27,6 +27,12 @@ $footer-height: 68px;
position: absolute; position: absolute;
right: 0; right: 0;
top: calc($navbar-height + 8px); top: calc($navbar-height + 8px);
&:hover {
.icon,
.cts {
color: #6d4cfe !important;
}
}
} }
} }
.footer-row { .footer-row {

View File

@ -336,10 +336,9 @@ export default {
onInput={onChange} onInput={onChange}
placeholder="请输入作品描述" placeholder="请输入作品描述"
size="large" size="large"
class="h-300px !w-784px" class="textarea-box !w-784px"
show-word-limit show-word-limit
max-length={1000} max-length={1000}
auto-size={{ minRows: 7, maxRows: 12 }}
/> />
</FormItem> </FormItem>
{isVideo.value ? ( {isVideo.value ? (

View File

@ -30,3 +30,9 @@
} }
} }
} }
.textarea-box {
:deep(.arco-textarea) {
height: 140px;
max-height: 298px;
}
}

View File

@ -206,7 +206,7 @@ export default {
v-slots={{ v-slots={{
title: () => ( title: () => (
<div class="flex items-center"> <div class="flex items-center">
<span class="cts mr-4px">{column.title}</span> <span class="cts mr-4px bold color-#211F24">{column.title}</span>
{column.tooltip && ( {column.tooltip && (
<Tooltip content={column.tooltip} position="top"> <Tooltip content={column.tooltip} position="top">
<IconQuestionCircle class="tooltip-icon color-#737478" size={16} /> <IconQuestionCircle class="tooltip-icon color-#737478" size={16} />
@ -221,7 +221,7 @@ export default {
class="flex items-center w-fit h-24px px-8px rounded-2px" class="flex items-center w-fit h-24px px-8px rounded-2px"
style={{ backgroundColor: getStatusInfo(record.audit_status).backgroundColor }} style={{ backgroundColor: getStatusInfo(record.audit_status).backgroundColor }}
> >
<span class="cts s1" style={{ color: getStatusInfo(record.audit_status).color }}> <span class="cts s1 bold" style={{ color: getStatusInfo(record.audit_status).color }}>
{getStatusInfo(record.audit_status).name} {getStatusInfo(record.audit_status).name}
</span> </span>
</div> </div>
@ -238,20 +238,23 @@ export default {
class="mr-4px" class="mr-4px"
/> />
<span <span
class="cts" class={`cts !text-14px !lh-22px ${
class={
record.type === EnumManuscriptType.Image ? '!color-#25C883' : '!color-#6D4CFE' record.type === EnumManuscriptType.Image ? '!color-#25C883' : '!color-#6D4CFE'
} }`}
> >
{record.type === EnumManuscriptType.Image ? '图文' : '视频'} {record.type === EnumManuscriptType.Image ? '图文' : '视频'}
</span> </span>
</div> </div>
); );
} else if (column.dataIndex === 'last_modified_at') { } else if (column.dataIndex === 'last_modified_at') {
return exactFormatTime( return (
<span class="cts num">
{exactFormatTime(
record.last_modified_at, record.last_modified_at,
'YYYY-MM-DD HH:mm:ss', 'YYYY-MM-DD HH:mm:ss',
'YYYY-MM-DD HH:mm:ss', 'YYYY-MM-DD HH:mm:ss',
)}
</span>
); );
} else { } else {
return formatTableField(column, record, true); return formatTableField(column, record, true);

View File

@ -116,7 +116,7 @@ export default {
}} }}
> >
<Form ref={formRef} rules={rules} model={formData.value} auto-label-width> <Form ref={formRef} rules={rules} model={formData.value} auto-label-width>
<FormItem label="有效期" prop="days"> <FormItem label="有效期" prop="days" row-class="!items-center">
<CommonSelect <CommonSelect
v-model={formData.value.days} v-model={formData.value.days}
options={OPTIONS} options={OPTIONS}
@ -130,6 +130,7 @@ export default {
<FormItem <FormItem
label="分享对象" label="分享对象"
prop="receiver" prop="receiver"
row-class="!items-center"
v-slots={{ v-slots={{
label: () => ( label: () => (
<div class="flex items-center"> <div class="flex items-center">

View File

@ -8,6 +8,9 @@
&.bold { &.bold {
font-family: $font-family-medium; font-family: $font-family-medium;
} }
&.num {
font-family: $font-family-manrope-regular;
}
} }
.filter-row-item { .filter-row-item {
.label { .label {
@ -23,5 +26,43 @@
.arco-scrollbar-track { .arco-scrollbar-track {
display: none !important; display: none !important;
} }
.arco-table {
.arco-table-container {
.arco-table-element {
thead {
.arco-table-tr {
.arco-table-th {
.arco-table-cell {
padding: 10px 16px !important;
}
}
}
}
tbody {
.arco-table-tr {
.arco-table-td {
.arco-table-cell {
padding: 6px 16px;
.arco-table-cell-content,
.arco-table-td-content {
font-size: 12px;
line-height: 20px;
}
}
}
}
}
}
}
}
.arco-pagination {
.arco-pagination-total,
.arco-pagination-jumper-prepend {
font-size: 14px;
}
.arco-pagination-jumper-prepend {
font-family: $font-family-regular;
}
}
} }
} }

View File

@ -79,8 +79,8 @@ export default {
); );
} else { } else {
return ( return (
<div class="main-img-box mb-16px relative overflow-hidden cursor-pointer"> <div class="main-img-box mb-16px overflow-hidden cursor-pointer">
<img src={coverImageUrl.value} class="w-100% h-100% object-contain absolute z-0 top-0 left-0" /> <img src={coverImageUrl.value} class="w-100% h-100% object-contain" />
</div> </div>
); );
} }
@ -153,7 +153,7 @@ export default {
<icon-oblique-line size="12" class="color-#C9CDD4 mx-4px" /> <icon-oblique-line size="12" class="color-#C9CDD4 mx-4px" />
<span class="cts bold !color-#1D2129">内容稿件详情</span> <span class="cts bold !color-#1D2129">内容稿件详情</span>
</div> </div>
<div class="flex-1 overflow-y-auto bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid py-32px"> <div class="flex-1 bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid py-32px">
<div class="w-684px mx-auto flex flex-col items-center"> <div class="w-684px mx-auto flex flex-col items-center">
<div class="flex justify-start flex-col w-full"> <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="mb-8px cts bold !text-28px !lh-40px !color-#211F24">{dataSource.value.title}</p>

View File

@ -2,6 +2,7 @@ $footer-height: 68px;
.manuscript-detail-wrap { .manuscript-detail-wrap {
width: 100%; width: 100%;
height: calc(100% - 72px); height: calc(100% - 72px);
margin-bottom: 72px;
.cts { .cts {
color: #939499; color: #939499;
font-family: $font-family-regular; font-family: $font-family-regular;
@ -22,8 +23,9 @@ $footer-height: 68px;
.main-img-box { .main-img-box {
width: 320px; width: 320px;
height: auto; height: auto;
max-height: 472px;
background: #fff; background: #fff;
aspect-ratio: 3/4; // aspect-ratio: 3/4;
} }
.desc-img-wrap { .desc-img-wrap {
display: grid; display: grid;

View File

@ -91,7 +91,7 @@ export default {
<> <>
<div class="manuscript-edit-wrap"> <div class="manuscript-edit-wrap">
<div class="flex items-center mb-8px"> <div class="flex items-center mb-8px">
<span class="cts color-#4E5969 cursor-pointer" onClick={onBack}> <span class="cts color-#4E5969 cursor-pointer" onClick={onCancel}>
内容稿件列表 内容稿件列表
</span> </span>
<icon-oblique-line size="12" class="color-#C9CDD4 mx-4px" /> <icon-oblique-line size="12" class="color-#C9CDD4 mx-4px" />

View File

@ -21,7 +21,7 @@ export const TABLE_COLUMNS = [
{ {
title: '客户意见', title: '客户意见',
dataIndex: 'customer_opinion', dataIndex: 'customer_opinion',
width: 220, width: 120,
}, },
// { // {
// title: '所属项目', // title: '所属项目',
@ -31,12 +31,12 @@ export const TABLE_COLUMNS = [
{ {
title: '稿件类型', title: '稿件类型',
dataIndex: 'type', dataIndex: 'type',
width: 180, width: 120,
}, },
{ {
title: '审核状态', title: '审核状态',
dataIndex: 'audit_status', dataIndex: 'audit_status',
width: 180, width: 120,
}, },
{ {
title: '上传时间', title: '上传时间',

View File

@ -1,6 +1,6 @@
<template> <template>
<a-table ref="tableRef" :data="dataSource" row-key="id" column-resizable :pagination="false" :scroll="{ x: '100%' }" <a-table ref="tableRef" :data="dataSource" row-key="id" column-resizable :pagination="false" :scroll="{ x: '100%' }"
class="manuscript-table w-100%" bordered @sorter-change="handleSorterChange"> class="manuscript-table w-100% flex-1" bordered @sorter-change="handleSorterChange">
<template #empty> <template #empty>
<NoData text="暂无稿件" /> <NoData text="暂无稿件" />
</template> </template>

View File

@ -52,6 +52,15 @@ export default {
const form = ref(cloneDeep(INITIAL_FORM)); const form = ref(cloneDeep(INITIAL_FORM));
const works = ref([]); const works = ref([]);
// 生成自增 id基于当前列表中最大的 id
const getNextWorkId = () => {
const currentMax = works.value.reduce((max, item) => {
const numericId = Number(item?.id);
return Number.isFinite(numericId) ? Math.max(max, numericId) : max;
}, 0);
return currentMax + 1;
};
// 剪贴板功能 // 剪贴板功能
const { copy } = useClipboard({ source: form.value.writerLink }); const { copy } = useClipboard({ source: form.value.writerLink });
@ -152,13 +161,17 @@ export default {
const formData = new FormData(); const formData = new FormData();
formData.append('file', file); formData.append('file', file);
const { code, data } = await postWorksByFile(formData, { const { code, data } = await postWorksByFile(formData, {
timeout: 0,
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
}, },
}); });
if (code === 200) { if (code === 200) {
taskStatus.value = TASK_STATUS.SUCCESS; taskStatus.value = TASK_STATUS.SUCCESS;
works.value = data ? [data] : []; if (data) {
const id = data.id ?? getNextWorkId();
works.value.push({ ...data, id });
}
} }
}; };
@ -220,8 +233,9 @@ export default {
<Upload <Upload
action="/" action="/"
draggable draggable
multiple
customRequest={handleUpload} customRequest={handleUpload}
accept=".xlsx,.xls,.docx,.doc,.mp4,.mov,.avi,.flv,.wmv" accept=".xlsx,.xls,.docx,.doc,.mp4,.mov,.avi,.flv,.wmv,.m4v"
show-file-list={false} show-file-list={false}
> >
{{ {{

View File

@ -21,7 +21,7 @@
.pagination-box { .pagination-box {
display: flex; display: flex;
width: 100%; width: 100%;
padding: 16px 24px; padding: 16px 24px 0;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
} }

View File

@ -199,8 +199,7 @@ export default {
_data.videoInfo.poster = convertVideoUrlToCoverUrl(url); _data.videoInfo.poster = convertVideoUrlToCoverUrl(url);
} }
return _data return _data;
}); });
works.value = _works; works.value = _works;
@ -267,7 +266,7 @@ export default {
<div <div
key={item.id} key={item.id}
id={`card-${item.id}`} id={`card-${item.id}`}
class={`group relative mb-12px px-8px py-12px flex flex-col rounded-8px bg-#F7F8FA border-1px border-solid border-transparent transition-all duration-300 cursor-pointer hover:bg-#E6E6E8 ${getCardClass( class={`group h-66px relative mb-12px px-12px py-8px flex flex-col rounded-8px bg-#F7F8FA border-1px border-solid border-transparent transition-all duration-300 cursor-pointer hover:bg-#E6E6E8 ${getCardClass(
item, item,
)}`} )}`}
onClick={() => onSelect(item)} onClick={() => onSelect(item)}
@ -278,7 +277,7 @@ export default {
onClick={(e) => onDelete(e, item, index)} onClick={(e) => onDelete(e, item, index)}
/> />
<TextOverTips <TextOverTips
context={item.content} context={item.title || '-'}
line={1} line={1}
class={`cts !color-#211F24 mb-8px ${selectCardInfo.value.id === item.id ? 'bold' : ''}`} class={`cts !color-#211F24 mb-8px ${selectCardInfo.value.id === item.id ? 'bold' : ''}`}
/> />
@ -286,18 +285,20 @@ export default {
<div class="flex items-center "> <div class="flex items-center ">
<img <img
src={item.type === EnumManuscriptType.Image ? icon1 : icon2} src={item.type === EnumManuscriptType.Image ? icon1 : icon2}
width="16" width="14"
height="16" height="14"
class="mr-4px" class="mr-4px"
/> />
<span <span
class={`cts ${item.type === EnumManuscriptType.Image ? '!color-#25C883' : '!color-#6D4CFE'}`} class={`cts !text-12px ${
item.type === EnumManuscriptType.Image ? '!color-#25C883' : '!color-#6D4CFE'
}`}
> >
{item.type === EnumManuscriptType.Image ? '图文' : '视频'} {item.type === EnumManuscriptType.Image ? '图文' : '视频'}
</span> </span>
</div> </div>
{errorDataCards.value.find((v) => v.id === item.id) && ( {errorDataCards.value.find((v) => v.id === item.id) && (
<p class="cts !color-#F64B31">必填项未填</p> <p class="cts !text-12px !color-#F64B31">必填项未填</p>
)} )}
</div> </div>
</div> </div>

View File

@ -1,7 +1,8 @@
$footer-height: 68px; $footer-height: 68px;
.manuscript-upload-wrap { .manuscript-upload-wrap {
height: calc(100% - 72px); height: calc(100% - 72px);
.cts { .cts,
:deep(.overflow-text) {
color: #939499; color: #939499;
font-family: $font-family-regular; font-family: $font-family-regular;
font-size: 14px; font-size: 14px;

View File

@ -143,8 +143,8 @@ import icon1 from '@/assets/img/media-account/icon5.png';
import icon2 from '@/assets/img/media-account/icon-warn.png'; import icon2 from '@/assets/img/media-account/icon-warn.png';
import icon3 from '@/assets/img/media-account/icon-warn-1.png'; import icon3 from '@/assets/img/media-account/icon-warn-1.png';
import icon4 from '@/assets/img/media-account/icon-success.png'; import icon4 from '@/assets/img/media-account/icon-success.png';
import icon5 from '@/assets/img/media-account/icon-dy.png'; import icon5 from '@/assets/img/platform/icon-dy.png';
import icon6 from '@/assets/img/media-account/icon-xhs.png'; import icon6 from '@/assets/img/platform/icon-xhs.png';
const route = useRoute(); const route = useRoute();
const id = route.params.id; const id = route.params.id;

View File

@ -145,8 +145,8 @@ import ReauthorizeAccountModal from '../reauthorize-account-modal';
import AuthorizedAccountModal from '../authorized-account-modal'; import AuthorizedAccountModal from '../authorized-account-modal';
import FooterBtn from './footer-btn'; import FooterBtn from './footer-btn';
import icon1 from '@/assets/img/media-account/icon-dy.png'; import icon1 from '@/assets/img/platform/icon-dy.png';
import icon2 from '@/assets/img/media-account/icon-xhs.png'; import icon2 from '@/assets/img/platform/icon-xhs.png';
import icon3 from '@/assets/img/media-account/icon-warn.png'; import icon3 from '@/assets/img/media-account/icon-warn.png';
const props = defineProps({ const props = defineProps({

View File

@ -41,8 +41,8 @@ import {
import icon1 from '@/assets/img/media-account/icon-download.png'; import icon1 from '@/assets/img/media-account/icon-download.png';
import icon2 from '@/assets/img/media-account/icon-delete.png'; import icon2 from '@/assets/img/media-account/icon-delete.png';
import icon3 from '@/assets/img/media-account/icon-dy.png'; import icon3 from '@/assets/img/platform/icon-dy.png';
import icon4 from '@/assets/img/media-account/icon-xhs.png'; import icon4 from '@/assets/img/platform/icon-xhs.png';
// import icon5 from '@/assets/img/media-account/icon-warn-1.png'; // import icon5 from '@/assets/img/media-account/icon-warn-1.png';
// import icon6 from '@/assets/img/media-account/icon-success.png'; // import icon6 from '@/assets/img/media-account/icon-success.png';