import { useState, useEffect } from 'react'
import { Tabs, Table, Button, Modal, Form, Input, InputNumber, DatePicker, message, Space, Upload, Popconfirm } from 'antd'
import { PlusOutlined, EditOutlined, DeleteOutlined, DownloadOutlined, UploadOutlined } from '@ant-design/icons'
import { listEpisodes, createEpisode, updateEpisode, deleteEpisode } from '../../services/episodeService'
import { listTargets, createTarget, updateTarget, deleteTarget } from '../../services/yearlyTargetService'
import http from '../../services/http'
const { TabPane } = Tabs
// ============================================================
// Tab1: 节目期次
// ============================================================
function EpisodesTab() {
const [episodes, setEpisodes] = useState([])
const [loading, setLoading] = useState(false)
const [modalVisible, setModalVisible] = useState(false)
const [editing, setEditing] = useState(null)
const [form] = Form.useForm()
useEffect(() => {
loadEpisodes()
}, [])
const loadEpisodes = () => {
setLoading(true)
listEpisodes().then(data => {
setEpisodes((data || []).sort((a, b) => new Date(b.air_date) - new Date(a.air_date)))
setLoading(false)
}).catch(() => {
message.error('加载节目列表失败')
setLoading(false)
})
}
const handleCreate = () => {
setEditing(null)
form.resetFields()
setModalVisible(true)
}
const handleEdit = (record) => {
setEditing(record)
form.setFieldsValue({
episode_number: record.episode_number,
program_name: record.program_name,
air_date: record.air_date ? record.air_date : null,
editor_name_snapshot: record.editor_name_snapshot || '',
audience_share: record.audience_share,
audience_rating: record.audience_rating,
is_rerun: record.is_rerun,
notes: record.notes,
})
setModalVisible(true)
}
const handleDelete = (id) => {
deleteEpisode(id).then(() => {
message.success('删除成功')
loadEpisodes()
}).catch(err => {
message.error(err.response?.data?.detail || '删除失败')
})
}
const handleSubmit = () => {
form.validateFields().then(values => {
const payload = {
...values,
air_date: values.air_date ? values.air_date.format('YYYY-MM-DD') : null,
}
const promise = editing
? updateEpisode(editing.id, payload)
: createEpisode(payload)
promise.then(() => {
message.success(editing ? '更新成功' : '创建成功')
setModalVisible(false)
loadEpisodes()
}).catch(err => {
message.error(err.response?.data?.detail || '操作失败')
})
})
}
const columns = [
{ title: '期次号', dataIndex: 'episode_number', key: 'episode_number', width: 80 },
{ title: '节目名', dataIndex: 'program_name', key: 'program_name' },
{ title: '播出日期', dataIndex: 'air_date', key: 'air_date', render: d => d || '-' },
{ title: '编导', dataIndex: 'editor_name_snapshot', key: 'editor_name_snapshot', render: v => v || '-' },
{ title: '收视份额', dataIndex: 'audience_share', key: 'audience_share', render: v => v != null ? v.toFixed(4) : '-' },
{ title: '收视率', dataIndex: 'audience_rating', key: 'audience_rating', render: v => v != null ? v.toFixed(2) : '-' },
{
title: '操作',
key: 'action',
render: (_, record) => (
导入结果
总计:{result.total} 条
成功:{result.imported} 条
{result.errors?.length > 0 && ( <>失败:{result.errors.length} 条
> )}支持批量导入节目期次,导入失败时可根据提示修正后重新上传。
注意:Phase 2 不支持重播行导入,有重播行请留空。