修改样式

This commit is contained in:
lq
2025-09-24 12:08:21 +08:00
parent dac4d7a20b
commit aed2681f4e
5 changed files with 175 additions and 27 deletions

View File

@ -26,3 +26,8 @@ export const getTaskSchedulesDetail = (id: string) => {
export const createTask = (params = {}) => {
return Http.post(`/v1/task-schedules/manual`, params);
};
//任务管理-手动添加
export const generateContent = (id: string) => {
return Http.post(`/v1/task-schedules/${id}/generate-content`);
};

View File

@ -12,11 +12,11 @@
style="z-index: 999"
>
<div class="drawer-content" :style="isActive == 'ai' ? 'height: 376px;' : 'height:216px;'">
<div class="flex flex-col justify-center items-start">
<div class="flex flex-col justify-center">
<CommonSelect
v-model="localQuery.accounts"
:options="accountList || []"
:multiple="true"
:multiple="false"
@change="(val) => handleChange('accounts', val)"
class="!w-432px select-with-tags"
placeholder="请选择账号名称"
@ -110,7 +110,15 @@
<p class="material-hint">前往成品库选择要发布的内容</p>
</div>
<div v-else class="flex flex-col items-start w-full">
<div v-else class="flex flex-col items-start w-full content-center">
<div class="opt-btn">
<SwapOutlined class="bg-#00000060 p-4px rounded-4px cursor-pointer" @click="handleAddContent" />
<DeleteOutlined
style="margin-left: 16px"
class="bg-#00000060 p-4px rounded-4px cursor-pointer"
@click="handleDelte"
/>
</div>
<div class="mb-12px">{{ selectedProducts.data[0].title }}</div>
<div v-for="item in selectedProducts.images" :key="item.id">
<img v-if="item.cover" :src="item.cover" class="w-88 h-88 mr-8px border-rounded-8px mb-12px" />
@ -182,6 +190,7 @@
import { getWorksPage } from '@/api/all/generationWorkshop.ts';
import { ref, reactive, watch, nextTick } from 'vue';
import aiIcon from '@/assets/img/media-account/icon-AI.png';
import { SwapOutlined, DeleteOutlined } from '@ant-design/icons-vue';
import { Button, DatePicker, TimePicker } from 'ant-design-vue';
import { TABS_LIST, ORIGIN_LIST, RawMaterialType } from '@/views/material-center/components/raw-material/constants';
import dayjs from 'dayjs';
@ -195,6 +204,7 @@ import icon4 from '@/assets/img/error-img.png';
import RawMaterialDrawer from './raw-material-drawer.vue';
import FinishedProductDrawer from './finished-product-drawer.vue';
import { message } from 'ant-design-vue';
import { fetchAccountOperators, getMediaAccountList } from '@/api/all/propertyMarketing';
// 状态管理
const choseText = ref('');
const taskDescription = ref('');
@ -204,7 +214,17 @@ const isActive = ref('ai');
const showDriwer = ref(false);
const showDrawer2 = ref(false);
const showDrawer3 = ref(false);
const accountList = ref([]);
onMounted(() => {
getData();
});
const getData = async () => {
const res = await fetchAccountOperators();
if (res.code === 200) {
accountList.value = res.data;
}
};
// 发布类型选项
const publishOptions = ref([
{ value: 'immediate', label: '立即发布' },
@ -290,7 +310,15 @@ const handleAddContent = () => {
productQuery.page_size = 10;
showDrawer3.value = true;
};
const handleDelte = () => {
hasChoseFinishedProducts.value = false;
selectedProducts.value = {
keys: [],
data: [],
text: '',
images: [],
};
};
// 处理原料库选择确认
const handleMaterialConfirm = (result) => {
console.log('handleMaterialConfirm', result);
@ -402,7 +430,7 @@ const handleCreateTask = () => {
const taskData = {
media_account_id: localQuery.value.ids[0],
is_ai_generate: isActive.value == 'chose' ? 0 : 1,
description: taskDescription.value,
ai_prompt: taskDescription.value,
raw_material_ids: selectedMaterials.value.keys,
products: selectedProducts.value.keys,
publish_type: publishType.value == 'immediate' ? 0 : 1,
@ -534,6 +562,16 @@ defineExpose({
font-size: 14px;
margin: 0 40px;
}
.content-center {
position: relative;
}
.opt-btn {
display: flex;
position: absolute; /* 设置为绝对定位 */
top: 0; /* 紧贴顶部 */
right: 0; /* 紧贴右侧 */
}
.publish-type-select :deep(.ant-select-selection-item) {
text-align: center;
@ -541,7 +579,12 @@ defineExpose({
align-items: center;
justify-content: center;
}
.select-with-tags :deep(.ant-select-selection-item) {
text-align: start;
display: flex;
align-items: center;
justify-content: start;
}
.line {
background-color: #e6e6e8;
width: 382px;

View File

@ -44,7 +44,12 @@
<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>
<div
class="flex items-center justify-center font-size-14px p-4px border-rounded-4px"
:style="getAuditStatusStyle(record.audit_status)"
>
{{ getStatus(record.audit_status) }}
</div>
</template>
<template #last_modified_at="{ record }">
<div class="flex items-center">
@ -189,7 +194,7 @@ watch(selectedRows, (newRows) => {
// 多选模式
choseText.value = newRows.length + '个稿件';
// 过滤掉文本类型,只保留非文本类型的项目
choseImgArray.value = newRows.filter(item => item.type !== 'text');
choseImgArray.value = newRows.filter((item) => item.type !== 'text');
}
});
@ -207,6 +212,19 @@ const getStatus = (status: number) => {
}
};
const getAuditStatusStyle = (status: number) => {
switch (status) {
case 1:
return { backgroundColor: '#f0f0f0', color: '#666' };
case 2:
return { backgroundColor: '#fff7ed', color: '#ff9c00' };
case 3:
return { backgroundColor: '#e6ffe6', color: '#008000' };
default:
return { backgroundColor: '#f0f0f0', color: '#666' };
}
};
// 抽屉显示状态变化处理
const onAfterVisibleChange = (visible: boolean) => {
emit('after-visible-change', visible);

View File

@ -1,7 +1,8 @@
<template>
<a-trigger trigger="click" position="br" @click.stop>
<a-trigger trigger="click" position="br" @click.stop @popup-visible-change="onPopupVisibleChange">
<div class="task-item">
<div class="color-indicator" :style="{ background: getTaskColor() }"></div>
<div>{{ timestampToTime(task.execution_time) }}</div>
<div class="task-name" :title="task?.name || '-'">{{ task?.name || 'AI生成内容' }}</div>
</div>
<template #content>
@ -34,11 +35,37 @@
<div class="font-size-14px color-#211F24 color-#211F24 task-description" :title="task.name || 'AI生成内容'">
{{ task.name || 'AI生成内容' }}
</div>
<div v-if="task.ai_generate_status == 0" class="AILoding">
<div v-if="task.ai_generate_status == 1" class="AILoding">
<ASpin />
<div style="color: #9a56ba">内容生成中...</div>
<div style="color: #9a56ba">完成后将自动展示您可先返回其他操作</div>
</div>
<div v-else-if="task.ai_generate_status == 0 && taskDetail" class="w-full pl-16px">
<div
v-for="item in choseTextArray"
:key="item.id"
class="flex items-center bg-#F7F8FA border-rounded-8px w-full justify-items-center pt-8px pb-8px pl-12px pr-12px mb-16px"
>
{{ item }}
</div>
<div class="flex items-center w-full">
<img
v-for="item in choseImgArray"
:key="item.id"
:src="item.cover || item.url"
class="w-88 h-88 mr-8px border-rounded-8px"
/>
</div>
<div class="flex items-center w-full">
<video
v-for="item in choseVideoArray"
:key="item.id"
:src="item.cover || item.url"
class="w-44 h-44 mr-8px border-rounded-8px object-fit-contain"
/>
</div>
</div>
<div class="flex items-center mt-12px w-full h-1px bg-#E6E6E8"></div>
<div class="flex items-center mt-12px mb-16px action-buttons">
<div class="flex items-center mr-12px" @click.stop="handleDelete">
@ -53,7 +80,7 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import { Spin as ASpin } from 'ant-design-vue';
import iconDy from '@/assets/img/platform/icon-dy.png';
import iconXhs from '@/assets/img/platform/icon-xhs.png';
@ -63,18 +90,47 @@ import iconSph from '@/assets/img/platform/icon-sph.png';
import iconWb from '@/assets/img/platform/icon-wb.png';
import iconGzh from '@/assets/img/platform/icon-gzh.png';
import iconWarn from '@/assets/img/media-account/icon-warn.png';
import { getTaskSchedulesDetail } from '@/api/all/assignment-management';
// 定义props和emit
const props = defineProps({
task: Object,
record: Object,
});
onMounted(() => {
console.log('props.task', props.task, props.record);
});
const taskDetail = ref(null);
const choseImgArray = ref([]);
const choseTextArray = ref([]);
const choseVideoArray = ref([]);
const getTaskDetail = async () => {
if (!props.task || !props.task.id) return;
const isPanelVisible = ref(false);
try {
const res = await getTaskSchedulesDetail(props.task.id);
if (res && res.data) {
if (res.data.type == 1) {
taskDetail.value = res.data.work;
choseImgArray.value = res.data.work.files.filter((item) => [0].includes(item.type));
choseTextArray.value = res.data.work.files.filter((item) => [2].includes(item.type));
choseVideoArray.value = res.data.work.files.filter((item) => [1].includes(item.type));
} else {
taskDetail.value = res.data.raw_materials;
console.log('任务详情:', res.data, taskDetail.value);
choseImgArray.value = taskDetail.value.filter((item) => [0].includes(item.type));
choseTextArray.value = taskDetail.value.filter((item) => [2].includes(item.type));
choseVideoArray.value = taskDetail.value.filter((item) => [1].includes(item.type));
console.log('任务详情:', choseImgArray.value, choseTextArray.value);
}
}
} catch (error) {
console.error('获取任务详情失败:', error);
}
};
const onPopupVisibleChange = (visible) => {
if (visible) {
getTaskDetail();
}
};
const handleDelete = () => {
emit('handle-task', 'delete', props.task, props.record);
@ -84,12 +140,26 @@ const gotoDetail = () => {
emit('handle-task', 'goto-detail', props.task, props.record);
};
const handleTimeChange = (time: string) => {
if (time) {
emit('handle-task', 'edit-time', props.task, timestampToTime1() + ' ' + time + ':00');
}
// if (time) {
// emit('handle-task', 'edit-time', props.task, timestampToTime1() + ' ' + time + ':00');
// }
};
const handleAICreate = (task, record) => {};
const handleAICreate = () => {
emit('handle-task', 'ai-create', props.task, props.record);
};
const timestampToTime = (timestamp: number): string => {
// 如果没有传入时间戳,则返回空字符串
if (!timestamp) return '';
// 将时间戳转换为毫秒(如果时间戳是秒单位的话)
const date = new Date(timestamp * 1000);
// 格式化为 HH:mm 格式
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
return `${hours}:${minutes}`;
};
const timestampToTime1 = (): string => {
const timestamp = Date.now();
const date = new Date(timestamp);

View File

@ -128,7 +128,13 @@ import FilterPopup from './components/filter-popup.vue';
import DrowPopup from './components/draw-popup.vue';
import TaskItem from './components/task-item.vue';
// API引入
import { getTaskSchedules, delTaskSchedules, editTaskSchedules, createTask } from '@/api/all/assignment-management';
import {
getTaskSchedules,
delTaskSchedules,
editTaskSchedules,
createTask,
generateContent,
} from '@/api/all/assignment-management';
import { fetchAccountOperators, getMediaAccountList } from '@/api/all/propertyMarketing';
// 工具引入
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
@ -224,7 +230,6 @@ const processTableData = (apiData: any[]) => {
dateHeaders.forEach((day) => {
rowData[day] = [];
});
// 分配任务到对应日期列
if (account.task_schedules?.length) {
account.task_schedules.forEach((task: any) => {
@ -472,12 +477,13 @@ const handleCellClick = (record: any, rowIndex: any, column: any) => {
};
// 任务操作处理
const handleTaskAction = (action: string, task: any, ...args: any[]) => {
const handleTaskAction = async (action: string, task: any, ...args: any[]) => {
console.log('handleTaskAction', action, task, args);
switch (action) {
case 'delete':
currentTask.value = task;
deleteTitle.value = task.type === 1 ? '删除内容稿件排期' : '删除选题排期';
deleteContent.value = `确认删除“${task.name}”吗?`;
deleteContent.value = `确认删除“${task.name || 'AI生成内容'}”吗?`;
showModal.value = true;
break;
case 'edit-time':
@ -486,6 +492,12 @@ const handleTaskAction = (action: string, task: any, ...args: any[]) => {
case 'goto-detail':
router.push(`/media-account/management-detail/${task.id}`);
break;
case 'ai-create':
const res = await generateContent(task.id);
if (res.code === 200) {
message.success(res.data.message);
}
break;
}
};