| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | import { useState, useEffect } from 'react';
|
| | import { useTranslation } from 'react-i18next';
|
| | import { Modal } from '@douyinfe/semi-ui';
|
| | import {
|
| | API,
|
| | copy,
|
| | isAdmin,
|
| | showError,
|
| | showSuccess,
|
| | timestamp2string,
|
| | } from '../../helpers';
|
| | import { ITEMS_PER_PAGE } from '../../constants';
|
| | import { useTableCompactMode } from '../common/useTableCompactMode';
|
| |
|
| | export const useTaskLogsData = () => {
|
| | const { t } = useTranslation();
|
| |
|
| |
|
| | const COLUMN_KEYS = {
|
| | SUBMIT_TIME: 'submit_time',
|
| | FINISH_TIME: 'finish_time',
|
| | DURATION: 'duration',
|
| | CHANNEL: 'channel',
|
| | PLATFORM: 'platform',
|
| | TYPE: 'type',
|
| | TASK_ID: 'task_id',
|
| | TASK_STATUS: 'task_status',
|
| | PROGRESS: 'progress',
|
| | FAIL_REASON: 'fail_reason',
|
| | RESULT_URL: 'result_url',
|
| | };
|
| |
|
| |
|
| | const [logs, setLogs] = useState([]);
|
| | const [loading, setLoading] = useState(false);
|
| | const [activePage, setActivePage] = useState(1);
|
| | const [logCount, setLogCount] = useState(0);
|
| | const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
| |
|
| |
|
| | const isAdminUser = isAdmin();
|
| |
|
| | const STORAGE_KEY = isAdminUser
|
| | ? 'task-logs-table-columns-admin'
|
| | : 'task-logs-table-columns-user';
|
| |
|
| |
|
| | const [isModalOpen, setIsModalOpen] = useState(false);
|
| | const [modalContent, setModalContent] = useState('');
|
| |
|
| |
|
| | const [isVideoModalOpen, setIsVideoModalOpen] = useState(false);
|
| | const [videoUrl, setVideoUrl] = useState('');
|
| |
|
| |
|
| | const [formApi, setFormApi] = useState(null);
|
| | let now = new Date();
|
| | let zeroNow = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
| |
|
| | const formInitValues = {
|
| | channel_id: '',
|
| | task_id: '',
|
| | dateRange: [
|
| | timestamp2string(zeroNow.getTime() / 1000),
|
| | timestamp2string(now.getTime() / 1000 + 3600),
|
| | ],
|
| | };
|
| |
|
| |
|
| | const [visibleColumns, setVisibleColumns] = useState({});
|
| | const [showColumnSelector, setShowColumnSelector] = useState(false);
|
| |
|
| |
|
| | const [compactMode, setCompactMode] = useTableCompactMode('taskLogs');
|
| |
|
| |
|
| | useEffect(() => {
|
| | const savedColumns = localStorage.getItem(STORAGE_KEY);
|
| | if (savedColumns) {
|
| | try {
|
| | const parsed = JSON.parse(savedColumns);
|
| | const defaults = getDefaultColumnVisibility();
|
| | const merged = { ...defaults, ...parsed };
|
| |
|
| |
|
| | if (!isAdminUser) {
|
| | merged[COLUMN_KEYS.CHANNEL] = false;
|
| | }
|
| | setVisibleColumns(merged);
|
| | } catch (e) {
|
| | console.error('Failed to parse saved column preferences', e);
|
| | initDefaultColumns();
|
| | }
|
| | } else {
|
| | initDefaultColumns();
|
| | }
|
| | }, []);
|
| |
|
| |
|
| | const getDefaultColumnVisibility = () => {
|
| | return {
|
| | [COLUMN_KEYS.SUBMIT_TIME]: true,
|
| | [COLUMN_KEYS.FINISH_TIME]: true,
|
| | [COLUMN_KEYS.DURATION]: true,
|
| | [COLUMN_KEYS.CHANNEL]: isAdminUser,
|
| | [COLUMN_KEYS.PLATFORM]: true,
|
| | [COLUMN_KEYS.TYPE]: true,
|
| | [COLUMN_KEYS.TASK_ID]: true,
|
| | [COLUMN_KEYS.TASK_STATUS]: true,
|
| | [COLUMN_KEYS.PROGRESS]: true,
|
| | [COLUMN_KEYS.FAIL_REASON]: true,
|
| | [COLUMN_KEYS.RESULT_URL]: true,
|
| | };
|
| | };
|
| |
|
| |
|
| | const initDefaultColumns = () => {
|
| | const defaults = getDefaultColumnVisibility();
|
| | setVisibleColumns(defaults);
|
| | localStorage.setItem(STORAGE_KEY, JSON.stringify(defaults));
|
| | };
|
| |
|
| |
|
| | const handleColumnVisibilityChange = (columnKey, checked) => {
|
| | const updatedColumns = { ...visibleColumns, [columnKey]: checked };
|
| | setVisibleColumns(updatedColumns);
|
| | };
|
| |
|
| |
|
| | const handleSelectAll = (checked) => {
|
| | const allKeys = Object.keys(COLUMN_KEYS).map((key) => COLUMN_KEYS[key]);
|
| | const updatedColumns = {};
|
| |
|
| | allKeys.forEach((key) => {
|
| | if (key === COLUMN_KEYS.CHANNEL && !isAdminUser) {
|
| | updatedColumns[key] = false;
|
| | } else {
|
| | updatedColumns[key] = checked;
|
| | }
|
| | });
|
| |
|
| | setVisibleColumns(updatedColumns);
|
| | };
|
| |
|
| |
|
| | useEffect(() => {
|
| | if (Object.keys(visibleColumns).length > 0) {
|
| | localStorage.setItem(STORAGE_KEY, JSON.stringify(visibleColumns));
|
| | }
|
| | }, [visibleColumns]);
|
| |
|
| |
|
| | const getFormValues = () => {
|
| | const formValues = formApi ? formApi.getValues() : {};
|
| |
|
| |
|
| | let start_timestamp = timestamp2string(zeroNow.getTime() / 1000);
|
| | let end_timestamp = timestamp2string(now.getTime() / 1000 + 3600);
|
| |
|
| | if (
|
| | formValues.dateRange &&
|
| | Array.isArray(formValues.dateRange) &&
|
| | formValues.dateRange.length === 2
|
| | ) {
|
| | start_timestamp = formValues.dateRange[0];
|
| | end_timestamp = formValues.dateRange[1];
|
| | }
|
| |
|
| | return {
|
| | channel_id: formValues.channel_id || '',
|
| | task_id: formValues.task_id || '',
|
| | start_timestamp,
|
| | end_timestamp,
|
| | };
|
| | };
|
| |
|
| |
|
| | const enrichLogs = (items) => {
|
| | return items.map((log) => ({
|
| | ...log,
|
| | timestamp2string: timestamp2string(log.created_at),
|
| | key: '' + log.id,
|
| | }));
|
| | };
|
| |
|
| |
|
| | const syncPageData = (payload) => {
|
| | const items = enrichLogs(payload.items || []);
|
| | setLogs(items);
|
| | setLogCount(payload.total || 0);
|
| | setActivePage(payload.page || 1);
|
| | setPageSize(payload.page_size || pageSize);
|
| | };
|
| |
|
| |
|
| | const loadLogs = async (page = 1, size = pageSize) => {
|
| | setLoading(true);
|
| | const { channel_id, task_id, start_timestamp, end_timestamp } =
|
| | getFormValues();
|
| | let localStartTimestamp = parseInt(Date.parse(start_timestamp) / 1000);
|
| | let localEndTimestamp = parseInt(Date.parse(end_timestamp) / 1000);
|
| | let url = isAdminUser
|
| | ? `/api/task/?p=${page}&page_size=${size}&channel_id=${channel_id}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`
|
| | : `/api/task/self?p=${page}&page_size=${size}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
| | const res = await API.get(url);
|
| | const { success, message, data } = res.data;
|
| | if (success) {
|
| | syncPageData(data);
|
| | } else {
|
| | showError(message);
|
| | }
|
| | setLoading(false);
|
| | };
|
| |
|
| |
|
| | const handlePageChange = (page) => {
|
| | loadLogs(page, pageSize).then();
|
| | };
|
| |
|
| | const handlePageSizeChange = async (size) => {
|
| | localStorage.setItem('task-page-size', size + '');
|
| | await loadLogs(1, size);
|
| | };
|
| |
|
| |
|
| | const refresh = async () => {
|
| | await loadLogs(1, pageSize);
|
| | };
|
| |
|
| |
|
| | const copyText = async (text) => {
|
| | if (await copy(text)) {
|
| | showSuccess(t('已复制:') + text);
|
| | } else {
|
| | Modal.error({ title: t('无法复制到剪贴板,请手动复制'), content: text });
|
| | }
|
| | };
|
| |
|
| |
|
| | const openContentModal = (content) => {
|
| | setModalContent(content);
|
| | setIsModalOpen(true);
|
| | };
|
| |
|
| |
|
| | const openVideoModal = (url) => {
|
| | setVideoUrl(url);
|
| | setIsVideoModalOpen(true);
|
| | };
|
| |
|
| |
|
| | useEffect(() => {
|
| | const localPageSize =
|
| | parseInt(localStorage.getItem('task-page-size')) || ITEMS_PER_PAGE;
|
| | setPageSize(localPageSize);
|
| | loadLogs(1, localPageSize).then();
|
| | }, []);
|
| |
|
| | return {
|
| |
|
| | logs,
|
| | loading,
|
| | activePage,
|
| | logCount,
|
| | pageSize,
|
| | isAdminUser,
|
| |
|
| |
|
| | isModalOpen,
|
| | setIsModalOpen,
|
| | modalContent,
|
| |
|
| |
|
| | isVideoModalOpen,
|
| | setIsVideoModalOpen,
|
| | videoUrl,
|
| |
|
| |
|
| | formApi,
|
| | setFormApi,
|
| | formInitValues,
|
| | getFormValues,
|
| |
|
| |
|
| | visibleColumns,
|
| | showColumnSelector,
|
| | setShowColumnSelector,
|
| | handleColumnVisibilityChange,
|
| | handleSelectAll,
|
| | initDefaultColumns,
|
| | COLUMN_KEYS,
|
| |
|
| |
|
| | compactMode,
|
| | setCompactMode,
|
| |
|
| |
|
| | loadLogs,
|
| | handlePageChange,
|
| | handlePageSizeChange,
|
| | refresh,
|
| | copyText,
|
| | openContentModal,
|
| | openVideoModal,
|
| | enrichLogs,
|
| | syncPageData,
|
| |
|
| |
|
| | t,
|
| | };
|
| | };
|
| |
|