2025-09-15 20:26:31 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<a-drawer
|
|
|
|
|
|
title="创建任务"
|
|
|
|
|
|
cancel-text="取消"
|
|
|
|
|
|
ok-text="创建任务"
|
|
|
|
|
|
placement="right"
|
|
|
|
|
|
v-model:visible="showDriwer"
|
|
|
|
|
|
@after-visible-change="showDriwerChange"
|
|
|
|
|
|
width="480px"
|
2025-09-18 14:40:47 +08:00
|
|
|
|
class="task-drawer"
|
|
|
|
|
|
style="z-index: 999"
|
2025-09-15 20:26:31 +08:00
|
|
|
|
>
|
2025-09-18 14:40:47 +08:00
|
|
|
|
<div class="drawer-content" :style="isActive == 'ai' ? 'height: 376px;' : 'height:216px;'">
|
|
|
|
|
|
<div class="flex flex-col justify-center items-start">
|
|
|
|
|
|
<CommonSelect
|
|
|
|
|
|
v-model="localQuery.accounts"
|
|
|
|
|
|
:options="accountList || []"
|
|
|
|
|
|
:multiple="true"
|
|
|
|
|
|
@change="(val) => handleChange('accounts', val)"
|
|
|
|
|
|
class="!w-432px select-with-tags"
|
|
|
|
|
|
placeholder="请选择账号名称"
|
|
|
|
|
|
:allowSearch="true"
|
|
|
|
|
|
:maxTagCount="999"
|
|
|
|
|
|
popup-container=".filter-popup-content"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<div class="ai-content-generator">
|
|
|
|
|
|
<div class="flex mt-16px">
|
|
|
|
|
|
<Button
|
|
|
|
|
|
class="w-194px h-38px mr-8px"
|
|
|
|
|
|
:class="isActive == 'ai' ? 'active-chose' : ''"
|
|
|
|
|
|
@click="handleSelect('ai')"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #icon>
|
|
|
|
|
|
<img :src="aiIcon" class="w-16 h-16 mr-8px" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
AI生成
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
class="w-194px h-38px"
|
|
|
|
|
|
:class="isActive == 'chose' ? 'active-chose' : ''"
|
|
|
|
|
|
@click="handleSelect('chose')"
|
|
|
|
|
|
>
|
|
|
|
|
|
从成品库选择</Button
|
|
|
|
|
|
>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-show="isActive == 'ai'">
|
|
|
|
|
|
<!-- 任务描述区域 -->
|
|
|
|
|
|
<div class="form-section">
|
|
|
|
|
|
<div class="flex items-center w-400px mt-16px mb-8px">
|
|
|
|
|
|
<div class="section-title">任务描述</div>
|
|
|
|
|
|
<div class="font-size-12px text-[#999999]">(非必填)</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="w-400px h-126px border-rounded-8px mb-8px" style="background: #fff">
|
|
|
|
|
|
<a-textarea
|
|
|
|
|
|
placeholder="描述你想让AI帮你生成的内容。未填写时,AI 会参考账号历史内容的题材与行业方向,结合当下话题,自动生成文案和图片后发布"
|
|
|
|
|
|
class="task-description font-size-12px"
|
|
|
|
|
|
:rows="5"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- 素材添加区域 -->
|
|
|
|
|
|
<div class="form-section material-section">
|
2025-09-20 14:13:01 +08:00
|
|
|
|
<div v-if="hasChose" class="flex items-center"></div>
|
2025-09-20 11:25:34 +08:00
|
|
|
|
<div v-else class="flex flex-col items-center">
|
|
|
|
|
|
<Button class="add-material-btn" @click="handleAddMaterial">
|
|
|
|
|
|
<template #icon>
|
|
|
|
|
|
<icon-plus size="16" class="mr-8px" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
从原料库添加
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<p class="material-hint">AI会参考添加的文本、图片、视频等素材,完成符合需求的创作</p>
|
|
|
|
|
|
</div>
|
2025-09-18 14:40:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-show="isActive == 'chose'">
|
|
|
|
|
|
<!-- 任务描述区域 -->
|
|
|
|
|
|
<div class="form-section">
|
|
|
|
|
|
<div class="flex items-center w-400px mt-16px mb-8px">
|
|
|
|
|
|
<div class="section-title">发布内容</div>
|
|
|
|
|
|
<div class="font-size-12px text-[#999999]">(必填)</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="form-section material-section">
|
2025-09-20 16:29:05 +08:00
|
|
|
|
<Button @click="handleAddContent" class="add-material-btn">
|
2025-09-18 14:40:47 +08:00
|
|
|
|
<template #icon>
|
|
|
|
|
|
<icon-plus size="16" class="mr-8px" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
添加内容
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
|
|
<p class="material-hint">前往成品库,选择要发布的内容</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- 发布计划区域 -->
|
|
|
|
|
|
<div class="publish-section">
|
|
|
|
|
|
<div class="flex items-center justify-between w-384px">
|
|
|
|
|
|
<div class="section-title">发布计划</div>
|
|
|
|
|
|
<CommonSelect
|
2025-09-19 18:07:33 +08:00
|
|
|
|
v-model="publishType"
|
|
|
|
|
|
:options="publishOptions"
|
|
|
|
|
|
@change="handlePublishTypeChange"
|
|
|
|
|
|
class="w-180px background-#fff publish-type-select"
|
|
|
|
|
|
:allowSearch="false"
|
|
|
|
|
|
:multiple="false"
|
2025-09-18 14:40:47 +08:00
|
|
|
|
popup-container=".filter-popup-content"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-09-19 18:07:33 +08:00
|
|
|
|
<div v-if="publishType === 'timing'">
|
2025-09-18 14:40:47 +08:00
|
|
|
|
<div class="line"></div>
|
|
|
|
|
|
<div class="flex items-center justify-between mt-16px w-384px">
|
|
|
|
|
|
<div class="section-title">日期</div>
|
|
|
|
|
|
<a-date-picker
|
|
|
|
|
|
class="w-180px h-40px background-#fff"
|
|
|
|
|
|
@change="handleDateChange"
|
|
|
|
|
|
v-model="currentDate"
|
|
|
|
|
|
format="YYYY年MM月DD日周dd"
|
|
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="line"></div>
|
|
|
|
|
|
<div class="flex items-center justify-between mt-16px w-384px">
|
|
|
|
|
|
<div class="section-title">时间</div>
|
2025-09-19 18:07:33 +08:00
|
|
|
|
<a-time-picker v-model="strValue" format="HH:mm" class="w-180px h-40px background-#fff" />
|
2025-09-18 14:40:47 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<a-drawer
|
2025-09-20 14:13:01 +08:00
|
|
|
|
title="原料库"
|
2025-09-18 14:40:47 +08:00
|
|
|
|
cancel-text="取消"
|
|
|
|
|
|
ok-text="确定"
|
|
|
|
|
|
placement="right"
|
|
|
|
|
|
v-model:visible="showDrawer2"
|
|
|
|
|
|
@after-visible-change="showDriwerChange"
|
|
|
|
|
|
width="904px"
|
|
|
|
|
|
class="task-drawer"
|
|
|
|
|
|
style="right: 481px"
|
|
|
|
|
|
>
|
2025-09-20 14:49:49 +08:00
|
|
|
|
<Table
|
|
|
|
|
|
:data-source="materialData"
|
|
|
|
|
|
bordered
|
|
|
|
|
|
:columns="columns"
|
|
|
|
|
|
:pagination="false"
|
2025-09-20 14:53:27 +08:00
|
|
|
|
row-key="id"
|
|
|
|
|
|
:row-selection="rowSelection"
|
2025-09-20 14:49:49 +08:00
|
|
|
|
>
|
2025-09-20 14:13:01 +08:00
|
|
|
|
<template #name="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
2025-09-20 14:22:03 +08:00
|
|
|
|
<img :src="record.cover" class="w-64px h-64px border-rounded-8px bg-#F0EDFF" />
|
2025-09-20 14:13:01 +08:00
|
|
|
|
<div class="flex flex-col ml-8px">
|
|
|
|
|
|
<div>{{ record.name }}</div>
|
|
|
|
|
|
<div class="text-#999 text-12px">序号:{{ record.uid }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #type="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
{{ getType(record.type) }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #from="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
{{ getFrom(record.type) }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
2025-09-19 14:57:14 +08:00
|
|
|
|
<template #create_at="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
2025-09-20 14:13:01 +08:00
|
|
|
|
{{ record.created_at ? dayjs(record.created_at * 1000).format('YYYY-MM-DD HH:mm:ss') : '-' }}
|
2025-09-19 14:57:14 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
2025-09-20 14:13:01 +08:00
|
|
|
|
</Table>
|
2025-09-20 14:49:49 +08:00
|
|
|
|
<!-- 分页控件 -->
|
|
|
|
|
|
<div v-if="pageInfo.total > 0" class="pagination-box">
|
|
|
|
|
|
<a-pagination
|
|
|
|
|
|
:total="pageInfo.total"
|
|
|
|
|
|
size="mini"
|
|
|
|
|
|
show-total
|
|
|
|
|
|
show-jumper
|
|
|
|
|
|
show-page-size
|
|
|
|
|
|
:current="pageInfo.page"
|
|
|
|
|
|
:page-size="pageInfo.page_size"
|
|
|
|
|
|
@change="onPageChange"
|
|
|
|
|
|
@page-size-change="onPageSizeChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
2025-09-20 15:39:46 +08:00
|
|
|
|
<template #footer>
|
|
|
|
|
|
<div class="flex items-center justify-between">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
<div class="color-#737478 font-size-14px">已选择:</div>
|
|
|
|
|
|
<div class="color-#737478 font-size-14px">{{ choseText }}</div>
|
2025-09-20 16:29:05 +08:00
|
|
|
|
<div v-for="item in choseImgArray" :key="item.id" class="ml-16px">
|
|
|
|
|
|
<img :src="item.cover" alt="" class="w-44px h-44px border-rounded-8px bg-#F0EDFF" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="flex justify-end">
|
|
|
|
|
|
<Button @click="handleCancel">取消</Button>
|
|
|
|
|
|
<Button class="ml-16px" type="primary" @click="handleOk">确定</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</a-drawer>
|
|
|
|
|
|
<a-drawer
|
|
|
|
|
|
title="成品库"
|
|
|
|
|
|
cancel-text="取消"
|
|
|
|
|
|
ok-text="确定"
|
|
|
|
|
|
placement="right"
|
|
|
|
|
|
v-model:visible="showDrawer3"
|
|
|
|
|
|
@after-visible-change="showDriwerChange"
|
|
|
|
|
|
width="904px"
|
|
|
|
|
|
class="task-drawer"
|
|
|
|
|
|
style="right: 481px"
|
|
|
|
|
|
>
|
|
|
|
|
|
<Table
|
|
|
|
|
|
:data-source="materialData"
|
|
|
|
|
|
bordered
|
|
|
|
|
|
:columns="columns2"
|
|
|
|
|
|
:pagination="false"
|
|
|
|
|
|
row-key="id"
|
|
|
|
|
|
:row-selection="rowSelection"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #cover="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
<img
|
|
|
|
|
|
:src="record.cover ? record.cover : icon4"
|
|
|
|
|
|
alt=""
|
|
|
|
|
|
class="w-44px h-44px border-rounded-8px bg-#F0EDFF"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #name="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
<div>{{ record.title }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #type="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
<img
|
|
|
|
|
|
:src="record.type === EnumManuscriptType.Image ? icon2 : icon3"
|
|
|
|
|
|
width="16"
|
|
|
|
|
|
height="16"
|
|
|
|
|
|
class="mr-4px"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<span class="cts" :class="record.type === EnumManuscriptType.Image ? '!color-#25C883' : '!color-#6D4CFE'">{{
|
|
|
|
|
|
record.type === EnumManuscriptType.Image ? '图文' : '视频'
|
|
|
|
|
|
}}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #uploader="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
{{ record.last_modifier.mobile }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #audit_status="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
{{ getStatus(record.audit_status) }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #last_modified_at="{ record }">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
{{ record.created_at ? dayjs(record.last_modified_at * 1000).format('YYYY-MM-DD HH:mm:ss') : '-' }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</Table>
|
|
|
|
|
|
<!-- 分页控件 -->
|
|
|
|
|
|
<div v-if="pageInfo.total > 0" class="pagination-box">
|
|
|
|
|
|
<a-pagination
|
|
|
|
|
|
:total="pageInfo.total"
|
|
|
|
|
|
size="mini"
|
|
|
|
|
|
show-total
|
|
|
|
|
|
show-jumper
|
|
|
|
|
|
show-page-size
|
|
|
|
|
|
:current="pageInfo.page"
|
|
|
|
|
|
:page-size="pageInfo.page_size"
|
|
|
|
|
|
@change="onPageChange"
|
|
|
|
|
|
@page-size-change="onPageSizeChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
<div class="flex items-center justify-between">
|
|
|
|
|
|
<div class="flex items-center">
|
|
|
|
|
|
<div class="color-#737478 font-size-14px">已选择:</div>
|
|
|
|
|
|
<div class="color-#737478 font-size-14px">{{ choseText }}</div>
|
|
|
|
|
|
<div v-for="item in choseImgArray" :key="item.id" class="ml-16px">
|
|
|
|
|
|
<img :src="item.cover ? item.cover : icon4" class="w-44px h-44px border-rounded-8px bg-#F0EDFF" />
|
|
|
|
|
|
</div>
|
2025-09-20 15:39:46 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="flex justify-end">
|
|
|
|
|
|
<Button @click="handleCancel">取消</Button>
|
|
|
|
|
|
<Button class="ml-16px" type="primary" @click="handleOk">确定</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
2025-09-18 14:40:47 +08:00
|
|
|
|
</a-drawer>
|
2025-09-15 20:26:31 +08:00
|
|
|
|
</a-drawer>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
2025-09-20 16:29:05 +08:00
|
|
|
|
import { getWorksPage, getWriterLinksGenerate } from '@/api/all/generationWorkshop.ts';
|
2025-09-19 18:36:20 +08:00
|
|
|
|
import { ref, reactive, onMounted, nextTick } from 'vue';
|
2025-09-18 14:40:47 +08:00
|
|
|
|
import aiIcon from '@/assets/img/media-account/icon-AI.png';
|
2025-09-20 14:13:01 +08:00
|
|
|
|
import { Checkbox, Button, Space, Pagination, notification, DatePicker, TimePicker, Table } from 'ant-design-vue';
|
2025-09-19 14:57:14 +08:00
|
|
|
|
import { TABS_LIST, ORIGIN_LIST, RawMaterialType } from '@/views/material-center/components/raw-material/constants';
|
2025-09-18 14:40:47 +08:00
|
|
|
|
import dayjs from 'dayjs';
|
2025-09-19 14:57:14 +08:00
|
|
|
|
import { getRawMaterialsPage } from '@/api/all/generationWorkshop';
|
|
|
|
|
|
// 工具引入
|
|
|
|
|
|
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
|
2025-09-20 16:29:05 +08:00
|
|
|
|
import { EnumManuscriptType } from '@/views/material-center/components/finished-products/manuscript/list/constants';
|
|
|
|
|
|
import icon2 from '@/assets/img/creative-generation-workshop/icon-photo.png';
|
|
|
|
|
|
import icon3 from '@/assets/img/creative-generation-workshop/icon-video.png';
|
|
|
|
|
|
import icon4 from '@/assets/img/error-img.png';
|
2025-09-20 15:39:46 +08:00
|
|
|
|
const choseText = ref('');
|
2025-09-19 14:57:14 +08:00
|
|
|
|
const columns = ref([
|
|
|
|
|
|
{
|
2025-09-20 14:13:01 +08:00
|
|
|
|
title: '文件名称',
|
2025-09-19 14:57:14 +08:00
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
|
width: 200,
|
2025-09-20 14:13:01 +08:00
|
|
|
|
slots: { customRender: 'name' },
|
2025-09-19 14:57:14 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '类型',
|
|
|
|
|
|
dataIndex: 'type',
|
|
|
|
|
|
width: 100,
|
2025-09-20 14:13:01 +08:00
|
|
|
|
slots: { customRender: 'type' },
|
2025-09-19 14:57:14 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2025-09-20 14:13:01 +08:00
|
|
|
|
title: '来源',
|
|
|
|
|
|
dataIndex: 'from',
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
slots: { customRender: 'from' },
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '上传时间',
|
2025-09-19 14:57:14 +08:00
|
|
|
|
dataIndex: 'created_at',
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
slots: { customRender: 'create_at' },
|
|
|
|
|
|
},
|
|
|
|
|
|
]);
|
2025-09-20 14:22:03 +08:00
|
|
|
|
|
2025-09-20 16:29:05 +08:00
|
|
|
|
const columns2 = ref([
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '图片/视频',
|
|
|
|
|
|
dataIndex: 'cover',
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
slots: { customRender: 'cover' },
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '文件名称',
|
|
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
slots: { customRender: 'name' },
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '稿件类型',
|
|
|
|
|
|
dataIndex: 'type',
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
slots: { customRender: 'type' },
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '审核状态',
|
|
|
|
|
|
dataIndex: 'audit_status',
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
slots: { customRender: 'audit_status' },
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '最后修改时间',
|
|
|
|
|
|
dataIndex: 'last_modified_at',
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
slots: { customRender: 'last_modified_at' },
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '上传人员',
|
|
|
|
|
|
dataIndex: 'uploader',
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
slots: { customRender: 'uploader' },
|
|
|
|
|
|
},
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
const handleSelect = (value) => {
|
|
|
|
|
|
isActive.value = value;
|
|
|
|
|
|
if (value == 'ai') {
|
|
|
|
|
|
showDrawer3.value = false;
|
|
|
|
|
|
handleSearch();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showDrawer2.value = false;
|
|
|
|
|
|
handleSearchWork();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const choseImgArray = ref([]);
|
2025-09-19 14:57:14 +08:00
|
|
|
|
// 表格分页逻辑
|
2025-09-20 14:57:25 +08:00
|
|
|
|
const { pageInfo, onPageChange, onPageSizeChange, rowSelection, selectedRowKeys } = useTableSelectionWithPagination({
|
2025-09-20 14:53:27 +08:00
|
|
|
|
rowKey: 'id',
|
2025-09-19 14:57:14 +08:00
|
|
|
|
onPageChange: () => handleSearch(),
|
|
|
|
|
|
onPageSizeChange: () => handleSearch(),
|
|
|
|
|
|
});
|
2025-09-20 14:13:01 +08:00
|
|
|
|
|
2025-09-20 14:53:27 +08:00
|
|
|
|
// 监听选中项变化
|
|
|
|
|
|
watch(selectedRowKeys, (newVal) => {
|
|
|
|
|
|
console.log(newVal);
|
|
|
|
|
|
query.ids = newVal;
|
2025-09-20 15:39:46 +08:00
|
|
|
|
const filteredData = materialData.value.filter((item) => newVal.includes(item.id));
|
2025-09-20 16:29:05 +08:00
|
|
|
|
choseImgArray.value = materialData.value.filter(
|
|
|
|
|
|
(item) => newVal.includes(item.id) && (item.type == 0 || item.type == 1),
|
|
|
|
|
|
);
|
|
|
|
|
|
console.log('+++++', choseImgArray.value);
|
2025-09-20 15:39:46 +08:00
|
|
|
|
choseText.value = '';
|
|
|
|
|
|
const typeCount = filteredData.reduce((acc, item) => {
|
|
|
|
|
|
acc[item.type] = (acc[item.type] || 0) + 1;
|
|
|
|
|
|
return acc;
|
|
|
|
|
|
}, {});
|
|
|
|
|
|
console.log('+++++', typeCount);
|
|
|
|
|
|
Object.entries(typeCount).forEach(([type, count]) => {
|
|
|
|
|
|
console.log('++++tyype', type, getType(type));
|
|
|
|
|
|
console.log(`${getType(type)}: ${count}个`);
|
|
|
|
|
|
choseText.value += `${getType(type)}: ${count}个 `;
|
|
|
|
|
|
});
|
2025-09-20 14:53:27 +08:00
|
|
|
|
});
|
2025-09-20 14:49:49 +08:00
|
|
|
|
|
2025-09-18 14:40:47 +08:00
|
|
|
|
// 定义props和emit
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
|
operators: Array,
|
|
|
|
|
|
platformOptions: Array,
|
|
|
|
|
|
accountList: Array,
|
|
|
|
|
|
query: Object,
|
|
|
|
|
|
});
|
2025-09-19 14:57:14 +08:00
|
|
|
|
// 查询参数
|
|
|
|
|
|
const query = reactive({
|
|
|
|
|
|
page: pageInfo.value.page,
|
|
|
|
|
|
page_size: pageInfo.value.page_size,
|
|
|
|
|
|
platforms: undefined,
|
|
|
|
|
|
operator_ids: undefined,
|
|
|
|
|
|
ids: [],
|
|
|
|
|
|
top_execution_time: undefined,
|
|
|
|
|
|
});
|
|
|
|
|
|
const materialData = ref([]);
|
|
|
|
|
|
const handleSearch = async () => {
|
|
|
|
|
|
const res = await getRawMaterialsPage(query);
|
2025-09-20 14:49:49 +08:00
|
|
|
|
pageInfo.value.total = res.data.total;
|
2025-09-20 16:29:05 +08:00
|
|
|
|
if (pageInfo.value.page == 1) {
|
|
|
|
|
|
materialData.value = [];
|
|
|
|
|
|
}
|
2025-09-19 14:57:14 +08:00
|
|
|
|
materialData.value = [...materialData.value, ...res.data.data];
|
|
|
|
|
|
};
|
2025-09-20 14:53:27 +08:00
|
|
|
|
|
2025-09-20 16:29:05 +08:00
|
|
|
|
const handleSearchWork = async () => {
|
|
|
|
|
|
const res = await getWorksPage(query);
|
|
|
|
|
|
pageInfo.value.total = res.data.total;
|
|
|
|
|
|
if (pageInfo.value.page == 1) {
|
|
|
|
|
|
materialData.value = [];
|
|
|
|
|
|
}
|
|
|
|
|
|
materialData.value = [...materialData.value, ...res.data.data];
|
|
|
|
|
|
};
|
2025-09-19 18:07:33 +08:00
|
|
|
|
|
2025-09-20 16:29:05 +08:00
|
|
|
|
const isActive = ref('ai');
|
2025-09-19 18:07:33 +08:00
|
|
|
|
// 发布类型选项
|
|
|
|
|
|
const publishOptions = ref([
|
|
|
|
|
|
{ value: 'immediate', label: '立即发布' },
|
|
|
|
|
|
{ value: 'timing', label: '定时发布' },
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
// 发布类型,默认为立即发布
|
|
|
|
|
|
const publishType = ref('immediate');
|
|
|
|
|
|
|
2025-09-20 16:29:05 +08:00
|
|
|
|
const getStatus = (status) => {
|
|
|
|
|
|
// 处理字符串和数字类型的type值
|
|
|
|
|
|
switch (status) {
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
return '全部';
|
|
|
|
|
|
case RawMaterialType.Video:
|
|
|
|
|
|
case '1':
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
return '待审核';
|
|
|
|
|
|
case RawMaterialType.Text:
|
|
|
|
|
|
case '2':
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
return '审核中';
|
|
|
|
|
|
case RawMaterialType.Text:
|
|
|
|
|
|
case '3':
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
return '已通过';
|
|
|
|
|
|
default:
|
|
|
|
|
|
return '未知';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2025-09-20 14:13:01 +08:00
|
|
|
|
const getType = (type) => {
|
2025-09-20 15:39:46 +08:00
|
|
|
|
// 处理字符串和数字类型的type值
|
2025-09-20 14:13:01 +08:00
|
|
|
|
switch (type) {
|
|
|
|
|
|
case RawMaterialType.Image:
|
2025-09-20 15:39:46 +08:00
|
|
|
|
case '0':
|
|
|
|
|
|
case 0:
|
2025-09-20 14:13:01 +08:00
|
|
|
|
return '图片';
|
|
|
|
|
|
case RawMaterialType.Video:
|
2025-09-20 15:39:46 +08:00
|
|
|
|
case '1':
|
|
|
|
|
|
case 1:
|
2025-09-20 14:13:01 +08:00
|
|
|
|
return '视频';
|
|
|
|
|
|
case RawMaterialType.Text:
|
2025-09-20 15:39:46 +08:00
|
|
|
|
case '2':
|
|
|
|
|
|
case 2:
|
2025-09-20 14:13:01 +08:00
|
|
|
|
return '文本';
|
|
|
|
|
|
default:
|
|
|
|
|
|
return '未知';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const getFrom = (type) => {
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
return '本地上传';
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
return 'AI生成';
|
|
|
|
|
|
default:
|
|
|
|
|
|
return '未知';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2025-09-19 18:07:33 +08:00
|
|
|
|
// 处理发布类型变化
|
|
|
|
|
|
const handlePublishTypeChange = (value) => {
|
|
|
|
|
|
publishType.value = value;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-09-18 14:40:47 +08:00
|
|
|
|
// 本地筛选状态(保持上次选择)
|
|
|
|
|
|
const localQuery = ref({
|
|
|
|
|
|
accounts: props.query?.ids || [],
|
|
|
|
|
|
});
|
2025-09-15 20:26:31 +08:00
|
|
|
|
const showDriwer = ref(false);
|
2025-09-18 14:40:47 +08:00
|
|
|
|
const showDrawer2 = ref(false);
|
2025-09-20 16:29:05 +08:00
|
|
|
|
const showDrawer3 = ref(false);
|
2025-09-18 14:40:47 +08:00
|
|
|
|
const emit = defineEmits(['filter-change']);
|
|
|
|
|
|
const isTiming = ref(true);
|
|
|
|
|
|
const currentDate = ref(new Date());
|
2025-09-19 18:07:33 +08:00
|
|
|
|
// 将时间选择器默认值设置为当前时间
|
|
|
|
|
|
const strValue = ref(dayjs().format('HH:mm'));
|
|
|
|
|
|
|
|
|
|
|
|
// 监听抽屉显示状态,每次打开时更新时间为当前时间
|
|
|
|
|
|
watch(showDriwer, (newVal) => {
|
|
|
|
|
|
if (newVal) {
|
|
|
|
|
|
strValue.value = dayjs().format('HH:mm');
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2025-09-19 14:57:14 +08:00
|
|
|
|
|
2025-09-20 14:22:03 +08:00
|
|
|
|
const handleTabSelect = (value) => {
|
2025-09-18 14:40:47 +08:00
|
|
|
|
isActive.value = value;
|
|
|
|
|
|
};
|
|
|
|
|
|
const handleAddMaterial = () => {
|
|
|
|
|
|
showDrawer2.value = true;
|
|
|
|
|
|
};
|
2025-09-20 16:29:05 +08:00
|
|
|
|
const handleAddContent = () => {
|
|
|
|
|
|
showDrawer3.value = true;
|
|
|
|
|
|
};
|
2025-09-18 14:40:47 +08:00
|
|
|
|
const handleDateChange = (date) => {};
|
2025-09-15 20:26:31 +08:00
|
|
|
|
// 暴露方法给父组件
|
2025-09-19 18:36:20 +08:00
|
|
|
|
const showDrawer = (accountInfo = null) => {
|
2025-09-15 20:26:31 +08:00
|
|
|
|
showDriwer.value = true;
|
2025-09-19 18:36:20 +08:00
|
|
|
|
// 如果传入了账号信息,则设置为默认选中
|
|
|
|
|
|
if (accountInfo && accountInfo.id) {
|
|
|
|
|
|
// 使用 nextTick 确保在 DOM 更新后设置默认值
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
localQuery.value.accounts = [accountInfo.name];
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2025-09-15 20:26:31 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const showDriwerChange = (visible: boolean) => {
|
|
|
|
|
|
console.log('Drawer visible: ', visible);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-09-18 14:40:47 +08:00
|
|
|
|
// 处理筛选条件变化(不关闭弹窗,直接触发筛选)
|
|
|
|
|
|
const handleChange = (field, value) => {
|
|
|
|
|
|
localQuery.value[field] = value;
|
|
|
|
|
|
// 直接触发筛选变更,不需要确认按钮
|
|
|
|
|
|
emit('filter-change', {
|
|
|
|
|
|
accounts: localQuery.value.accounts,
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-09-15 20:26:31 +08:00
|
|
|
|
// 使用defineExpose暴露方法
|
|
|
|
|
|
defineExpose({
|
2025-09-18 14:40:47 +08:00
|
|
|
|
showDrawer,
|
2025-09-15 20:26:31 +08:00
|
|
|
|
});
|
2025-09-18 14:40:47 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.drawer-content {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 抽屉左侧圆角样式 */
|
|
|
|
|
|
.arco-drawer {
|
|
|
|
|
|
border-top-left-radius: 8px !important;
|
|
|
|
|
|
border-bottom-left-radius: 8px !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ai-content-generator {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: start;
|
|
|
|
|
|
margin-top: 24px;
|
|
|
|
|
|
width: 432px;
|
|
|
|
|
|
background: linear-gradient(to right, #f0f5ff, #fff6f5) !important;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.active-chose {
|
|
|
|
|
|
border: #722ed1 1px solid !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.main-container {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
max-width: 600px;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
border: 1px solid #e0e0e0;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
padding: 24px;
|
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tab-group {
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tab-button {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
height: 48px;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.ai-tab .ai-icon {
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
width: 16px;
|
|
|
|
|
|
height: 16px;
|
|
|
|
|
|
background-color: #722ed1;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
line-height: 16px;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-section {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
width: 400px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.publish-section {
|
|
|
|
|
|
width: 432px;
|
|
|
|
|
|
padding: 16px 24px;
|
|
|
|
|
|
background-color: #f7f8fa;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
align-items: start;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
margin-top: 24px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.task-description {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
height: 126px;
|
|
|
|
|
|
border: none !important;
|
|
|
|
|
|
box-shadow: none !important;
|
|
|
|
|
|
outline: none !important; /* 去除默认的聚焦轮廓 */
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.task-description::placeholder {
|
|
|
|
|
|
color: #999;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.material-section {
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.add-material-btn {
|
|
|
|
|
|
width: 240px;
|
|
|
|
|
|
height: 38px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
border: 1px dashed #e0e0e0 !important;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.drag-handle {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
width: 16px;
|
|
|
|
|
|
height: 16px;
|
|
|
|
|
|
background-color: #ff7d00;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
top: 50%;
|
|
|
|
|
|
left: 50%;
|
|
|
|
|
|
transform: translate(-50%, -50%);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.material-hint {
|
|
|
|
|
|
color: #939499;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
margin: 0 40px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.size-selector {
|
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.size-tag {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
padding: 6px 16px;
|
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-19 18:07:33 +08:00
|
|
|
|
.publish-type-select :deep(.ant-select-selection-item) {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-18 14:40:47 +08:00
|
|
|
|
.publish-select {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.line {
|
|
|
|
|
|
background-color: #e6e6e8;
|
|
|
|
|
|
width: 382px;
|
|
|
|
|
|
height: 1px;
|
|
|
|
|
|
margin-top: 16px;
|
|
|
|
|
|
}
|
2025-09-20 14:49:49 +08:00
|
|
|
|
/* 分页样式 */
|
|
|
|
|
|
.pagination-box {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
padding: 16px 0;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
2025-09-18 14:40:47 +08:00
|
|
|
|
</style>
|