10 changed files with 1446 additions and 100 deletions
			
			
		- 
					53src/locales/lang/pages/cms/video/zh-CN.ts
 - 
					52src/locales/lang/pages/cms/videoCloud/zh-CN.ts
 - 
					52src/locales/lang/pages/cms/videoMagnet/zh-CN.ts
 - 
					5src/locales/lang/zh-CN.ts
 - 
					388src/pages/cms/video/index.tsx
 - 
					395src/pages/cms/video_cloud/index.tsx
 - 
					396src/pages/cms/video_magnet/index.tsx
 - 
					19src/store/cms/video.ts
 - 
					12src/store/cms/video_cloud.ts
 - 
					12src/store/cms/video_magnet.ts
 
@ -0,0 +1,53 @@ | 
			
		|||||
 | 
				export default { | 
			
		||||
 | 
				  title: '视频管理', | 
			
		||||
 | 
				  description: '视频管理', | 
			
		||||
 | 
				  search: '搜索', | 
			
		||||
 | 
				  add: '新增', | 
			
		||||
 | 
				  edit: '编辑', | 
			
		||||
 | 
				  delete: '删除', | 
			
		||||
 | 
				  type_id: [ | 
			
		||||
 | 
				    '在线观看', '下载', '网盘' | 
			
		||||
 | 
				  ], | 
			
		||||
 | 
				  lock: [ | 
			
		||||
 | 
				    '未锁', '锁定' | 
			
		||||
 | 
				  ], | 
			
		||||
 | 
				  columns: { | 
			
		||||
 | 
				    id: 'ID', | 
			
		||||
 | 
				    source_url: '源站点地址', | 
			
		||||
 | 
				    collect_id: '站点id', | 
			
		||||
 | 
				    type_id: '类型', | 
			
		||||
 | 
				    title: '标题', | 
			
		||||
 | 
				    title_sub: '副标', | 
			
		||||
 | 
				    letter: '首字母', | 
			
		||||
 | 
				    tag: 'TAG', | 
			
		||||
 | 
				    lock: '锁定后显示', | 
			
		||||
 | 
				    copyright: '版权', | 
			
		||||
 | 
				    is_end: '完结', | 
			
		||||
 | 
				    status: '状态', | 
			
		||||
 | 
				    category_id: '分类', | 
			
		||||
 | 
				    pic: '图片', | 
			
		||||
 | 
				    pic_local: '图片本地路径或MD5', | 
			
		||||
 | 
				    pic_status: '图片状态', | 
			
		||||
 | 
				    actor: '演员', | 
			
		||||
 | 
				    director: '导演', | 
			
		||||
 | 
				    writer: '编剧', | 
			
		||||
 | 
				    remarks: '备注', | 
			
		||||
 | 
				    pubdate: '发布时间', | 
			
		||||
 | 
				    total: '总集数', | 
			
		||||
 | 
				    serial: '连载数', | 
			
		||||
 | 
				    duration: '视频时长', | 
			
		||||
 | 
				    area: '地区', | 
			
		||||
 | 
				    lang: '语言', | 
			
		||||
 | 
				    version: '资源版本', | 
			
		||||
 | 
				    year: '年份', | 
			
		||||
 | 
				    state: '资源类别', | 
			
		||||
 | 
				    douban_score: '豆瓣评分', | 
			
		||||
 | 
				    douban_id: '豆瓣ID', | 
			
		||||
 | 
				    imdb_score: 'imdb评分', | 
			
		||||
 | 
				    imdb_id: 'imdb的id', | 
			
		||||
 | 
				    content: '内容', | 
			
		||||
 | 
				    created_at: '创建时间', | 
			
		||||
 | 
				    updated_at: '更新时间' | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  } | 
			
		||||
 | 
				} | 
			
		||||
@ -0,0 +1,52 @@ | 
			
		|||||
 | 
				export default { | 
			
		||||
 | 
				  title: '云盘视频管理', | 
			
		||||
 | 
				  description: '云盘视频管理', | 
			
		||||
 | 
				  search: '搜索', | 
			
		||||
 | 
				  add: '新增', | 
			
		||||
 | 
				  edit: '编辑', | 
			
		||||
 | 
				  delete: '删除', | 
			
		||||
 | 
				  type_id: [ | 
			
		||||
 | 
				    '在线观看', '下载', '网盘' | 
			
		||||
 | 
				  ], | 
			
		||||
 | 
				  lock: [ | 
			
		||||
 | 
				    '未锁', '锁定' | 
			
		||||
 | 
				  ], | 
			
		||||
 | 
				  columns: { | 
			
		||||
 | 
				    source_url: '源站点地址', | 
			
		||||
 | 
				    collect_id: '站点id', | 
			
		||||
 | 
				    type_id: '类型', | 
			
		||||
 | 
				    title: '标题', | 
			
		||||
 | 
				    title_sub: '副标', | 
			
		||||
 | 
				    letter: '首字母', | 
			
		||||
 | 
				    tag: 'TAG', | 
			
		||||
 | 
				    lock: '锁定后显示', | 
			
		||||
 | 
				    copyright: '版权', | 
			
		||||
 | 
				    is_end: '完结', | 
			
		||||
 | 
				    status: '状态', | 
			
		||||
 | 
				    category_id: '分类', | 
			
		||||
 | 
				    pic: '图片', | 
			
		||||
 | 
				    pic_local: '图片本地路径或MD5', | 
			
		||||
 | 
				    pic_status: '图片状态', | 
			
		||||
 | 
				    actor: '演员', | 
			
		||||
 | 
				    director: '导演', | 
			
		||||
 | 
				    writer: '编剧', | 
			
		||||
 | 
				    remarks: '备注', | 
			
		||||
 | 
				    pubdate: '发布时间', | 
			
		||||
 | 
				    total: '总集数', | 
			
		||||
 | 
				    serial: '连载数', | 
			
		||||
 | 
				    duration: '视频时长', | 
			
		||||
 | 
				    class: '分类', | 
			
		||||
 | 
				    area: '地区', | 
			
		||||
 | 
				    lang: '语言', | 
			
		||||
 | 
				    version: '资源版本', | 
			
		||||
 | 
				    year: '年份', | 
			
		||||
 | 
				    state: '资源类别', | 
			
		||||
 | 
				    douban_score: '豆瓣评分', | 
			
		||||
 | 
				    douban_id: '豆瓣ID', | 
			
		||||
 | 
				    imdb_score: 'imdb评分', | 
			
		||||
 | 
				    imdb_id: 'imdb的id', | 
			
		||||
 | 
				    content: '内容', | 
			
		||||
 | 
				    created_at: '创建时间', | 
			
		||||
 | 
				    updated_at: '更新时间' | 
			
		||||
 | 
				  } | 
			
		||||
 | 
				} | 
			
		||||
@ -0,0 +1,52 @@ | 
			
		|||||
 | 
				export default { | 
			
		||||
 | 
				  title: '磁链视频管理', | 
			
		||||
 | 
				  description: '磁链视频管理', | 
			
		||||
 | 
				  search: '搜索', | 
			
		||||
 | 
				  add: '新增', | 
			
		||||
 | 
				  edit: '编辑', | 
			
		||||
 | 
				  delete: '删除', | 
			
		||||
 | 
				  type_id: [ | 
			
		||||
 | 
				    '在线观看', '下载', '网盘' | 
			
		||||
 | 
				  ], | 
			
		||||
 | 
				  lock: [ | 
			
		||||
 | 
				    '未锁', '锁定' | 
			
		||||
 | 
				  ], | 
			
		||||
 | 
				  columns: { | 
			
		||||
 | 
				    source_url: '源站点地址', | 
			
		||||
 | 
				    collect_id: '站点id', | 
			
		||||
 | 
				    type_id: '类型', | 
			
		||||
 | 
				    title: '标题', | 
			
		||||
 | 
				    title_sub: '副标', | 
			
		||||
 | 
				    letter: '首字母', | 
			
		||||
 | 
				    tag: 'TAG', | 
			
		||||
 | 
				    lock: '锁定后显示', | 
			
		||||
 | 
				    copyright: '版权', | 
			
		||||
 | 
				    is_end: '完结', | 
			
		||||
 | 
				    status: '状态', | 
			
		||||
 | 
				    category_id: '分类', | 
			
		||||
 | 
				    pic: '图片', | 
			
		||||
 | 
				    pic_local: '图片本地路径或MD5', | 
			
		||||
 | 
				    pic_status: '图片状态', | 
			
		||||
 | 
				    actor: '演员', | 
			
		||||
 | 
				    director: '导演', | 
			
		||||
 | 
				    writer: '编剧', | 
			
		||||
 | 
				    remarks: '备注', | 
			
		||||
 | 
				    pubdate: '发布时间', | 
			
		||||
 | 
				    total: '总集数', | 
			
		||||
 | 
				    serial: '连载数', | 
			
		||||
 | 
				    duration: '视频时长', | 
			
		||||
 | 
				    class: '分类', | 
			
		||||
 | 
				    area: '地区', | 
			
		||||
 | 
				    lang: '语言', | 
			
		||||
 | 
				    version: '资源版本', | 
			
		||||
 | 
				    year: '年份', | 
			
		||||
 | 
				    state: '资源类别', | 
			
		||||
 | 
				    douban_score: '豆瓣评分', | 
			
		||||
 | 
				    douban_id: '豆瓣ID', | 
			
		||||
 | 
				    imdb_score: 'imdb评分', | 
			
		||||
 | 
				    imdb_id: 'imdb的id', | 
			
		||||
 | 
				    content: '内容', | 
			
		||||
 | 
				    created_at: '创建时间', | 
			
		||||
 | 
				    updated_at: '更新时间' | 
			
		||||
 | 
				  } | 
			
		||||
 | 
				} | 
			
		||||
@ -0,0 +1,388 @@ | 
			
		|||||
 | 
				import { useTranslation } from '@/i18n.ts' | 
			
		||||
 | 
				import { Button, Form, Popconfirm } from 'antd' | 
			
		||||
 | 
				import { useAtom, useAtomValue } from 'jotai' | 
			
		||||
 | 
				import { | 
			
		||||
 | 
				  deleteVideoAtom, | 
			
		||||
 | 
				  saveOrUpdateVideoAtom, videosAtom, videoSearchAtom, videoTypes | 
			
		||||
 | 
				} from '@/store/cms/video.ts' | 
			
		||||
 | 
				import { useEffect, useMemo, useState } from 'react' | 
			
		||||
 | 
				import Switch from '@/components/switch' | 
			
		||||
 | 
				import Action from '@/components/action/Action.tsx' | 
			
		||||
 | 
				import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components' | 
			
		||||
 | 
				import ListPageLayout from '@/layout/ListPageLayout.tsx' | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				const i18nPrefix = 'cms.video' | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				const Video = () => { | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  // const { styles } = useStyle()
 | 
			
		||||
 | 
				  const { t } = useTranslation() | 
			
		||||
 | 
				  const [ form ] = Form.useForm() | 
			
		||||
 | 
				  const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateVideoAtom) | 
			
		||||
 | 
				  const [ search, setSearch ] = useAtom(videoSearchAtom) | 
			
		||||
 | 
				  const { data, isFetching, isLoading, refetch } = useAtomValue(videosAtom) | 
			
		||||
 | 
				  const { mutate: deleteVideo, isPending: isDeleting } = useAtomValue(deleteVideoAtom) | 
			
		||||
 | 
				  const [ open, setOpen ] = useState(false) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  const columns = useMemo(() => { | 
			
		||||
 | 
				    return [ | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        title: 'ID', | 
			
		||||
 | 
				        dataIndex: 'id', | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true } | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.title`, 'Title'), | 
			
		||||
 | 
				        'dataIndex': 'title', | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.title_sub`, 'TitleSub'), | 
			
		||||
 | 
				        'dataIndex': 'title_sub', | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.source_url`, 'SourceUrl'), | 
			
		||||
 | 
				        'dataIndex': 'source_url', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        copyable: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.collect_id`, 'CollectId'), | 
			
		||||
 | 
				        'dataIndex': 'collect_id', | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.type_id`, 'TypeId'), | 
			
		||||
 | 
				        'dataIndex': 'type_id', | 
			
		||||
 | 
				        valueType: 'select', | 
			
		||||
 | 
				        fieldProps: { | 
			
		||||
 | 
				          options: videoTypes, | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return t(`${i18nPrefix}.type_id.${record.type_id}`) | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.letter`, 'Letter'), | 
			
		||||
 | 
				        'dataIndex': 'letter' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.tag`, 'Tag'), | 
			
		||||
 | 
				        'dataIndex': 'tag', | 
			
		||||
 | 
				        valueType: 'textarea', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.lock`, 'Lock'), | 
			
		||||
 | 
				        'dataIndex': 'lock', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.copyright`, 'Copyright'), | 
			
		||||
 | 
				        'dataIndex': 'copyright', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.is_end`, 'IsEnd'), | 
			
		||||
 | 
				        'dataIndex': 'is_end', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.status`, 'Status'), | 
			
		||||
 | 
				        'dataIndex': 'status', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.category_id`, 'CategoryId'), | 
			
		||||
 | 
				        'dataIndex': 'category_id', | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pic`, 'Pic'), | 
			
		||||
 | 
				        'dataIndex': 'pic', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <img src={record.pic} alt="" style={{ width: 100 }}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pic_local`, 'PicLocal'), | 
			
		||||
 | 
				        'dataIndex': 'pic_local', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pic_status`, 'PicStatus'), | 
			
		||||
 | 
				        'dataIndex': 'pic_status', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.actor`, 'Actor'), | 
			
		||||
 | 
				        'dataIndex': 'actor', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.director`, 'Director'), | 
			
		||||
 | 
				        'dataIndex': 'director' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.writer`, 'Writer'), | 
			
		||||
 | 
				        'dataIndex': 'writer' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.remarks`, 'Remarks'), | 
			
		||||
 | 
				        'dataIndex': 'remarks' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pubdate`, 'Pubdate'), | 
			
		||||
 | 
				        'dataIndex': 'pubdate', | 
			
		||||
 | 
				        valueType: 'dateTime' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.total`, 'Total'), | 
			
		||||
 | 
				        'dataIndex': 'total', | 
			
		||||
 | 
				        valueType: 'digit' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.serial`, 'Serial'), | 
			
		||||
 | 
				        'dataIndex': 'serial', | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.duration`, 'Duration'), | 
			
		||||
 | 
				        'dataIndex': 'duration', | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.area`, 'Area'), | 
			
		||||
 | 
				        'dataIndex': 'area', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.lang`, 'Lang'), | 
			
		||||
 | 
				        'dataIndex': 'lang', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.version`, 'Version'), | 
			
		||||
 | 
				        'dataIndex': 'version' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.year`, 'Year'), | 
			
		||||
 | 
				        'dataIndex': 'year', | 
			
		||||
 | 
				        valueType: 'dateYear' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.state`, 'State'), | 
			
		||||
 | 
				        'dataIndex': 'state' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.douban_score`, 'DoubanScore'), | 
			
		||||
 | 
				        'dataIndex': 'douban_score' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.douban_id`, 'DoubanId'), | 
			
		||||
 | 
				        'dataIndex': 'douban_id', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.imdb_score`, 'ImdbScore'), | 
			
		||||
 | 
				        'dataIndex': 'imdb_score' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.imdb_id`, 'ImdbId'), | 
			
		||||
 | 
				        'dataIndex': 'imdb_id', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.content`, 'Content'), | 
			
		||||
 | 
				        'dataIndex': 'content', | 
			
		||||
 | 
				        valueType: 'textarea', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => ({ | 
			
		||||
 | 
				          width: 200, | 
			
		||||
 | 
				        }), | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        title: t(`${i18nPrefix}.columns.option`, '操作'), | 
			
		||||
 | 
				        key: 'option', | 
			
		||||
 | 
				        valueType: 'option', | 
			
		||||
 | 
				        fixed: 'right', | 
			
		||||
 | 
				        render: (_, record) => [ | 
			
		||||
 | 
				          <Action key="edit" | 
			
		||||
 | 
				                  as={'a'} | 
			
		||||
 | 
				                  onClick={() => { | 
			
		||||
 | 
				                    form.setFieldsValue(record) | 
			
		||||
 | 
				                    setOpen(true) | 
			
		||||
 | 
				                  }}>{t('actions.edit')}</Action>, | 
			
		||||
 | 
				          <Popconfirm | 
			
		||||
 | 
				                  key={'del_confirm'} | 
			
		||||
 | 
				                  disabled={isDeleting} | 
			
		||||
 | 
				                  onConfirm={() => { | 
			
		||||
 | 
				                    deleteVideo([ record.id ]) | 
			
		||||
 | 
				                  }} | 
			
		||||
 | 
				                  title={t('message.deleteConfirm')}> | 
			
		||||
 | 
				            <a key="del"> | 
			
		||||
 | 
				              {t('actions.delete', '删除')} | 
			
		||||
 | 
				            </a> | 
			
		||||
 | 
				          </Popconfirm> | 
			
		||||
 | 
				        ] | 
			
		||||
 | 
				      } | 
			
		||||
 | 
				    ] as ProColumns[] | 
			
		||||
 | 
				  }, [ isDeleting ]) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  useEffect(() => { | 
			
		||||
 | 
				    if (isSuccess) { | 
			
		||||
 | 
				      setOpen(false) | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				  }, [ isSuccess ]) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  return ( | 
			
		||||
 | 
				          <ListPageLayout> | 
			
		||||
 | 
				            <ProTable | 
			
		||||
 | 
				                    rowKey="id" | 
			
		||||
 | 
				                    headerTitle={t(`${i18nPrefix}.title`, '视频管理')} | 
			
		||||
 | 
				                    toolbar={{ | 
			
		||||
 | 
				                      search: { | 
			
		||||
 | 
				                        loading: isFetching && !!search.key, | 
			
		||||
 | 
				                        onSearch: (value: string) => { | 
			
		||||
 | 
				                          setSearch(prev => ({ | 
			
		||||
 | 
				                            ...prev, | 
			
		||||
 | 
				                            key: value | 
			
		||||
 | 
				                          })) | 
			
		||||
 | 
				                        }, | 
			
		||||
 | 
				                        allowClear: true, | 
			
		||||
 | 
				                        placeholder: t(`${i18nPrefix}.placeholder`, '输入视频名称') | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				                      actions: [ | 
			
		||||
 | 
				                        <Button | 
			
		||||
 | 
				                                onClick={() => { | 
			
		||||
 | 
				                                  form.resetFields() | 
			
		||||
 | 
				                                  form.setFieldsValue({ | 
			
		||||
 | 
				                                    id: 0, | 
			
		||||
 | 
				                                  }) | 
			
		||||
 | 
				                                  setOpen(true) | 
			
		||||
 | 
				                                }} | 
			
		||||
 | 
				                                type={'primary'}>{t(`${i18nPrefix}.add`, '添加')}</Button> | 
			
		||||
 | 
				                      ] | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    scroll={{ | 
			
		||||
 | 
				                      x: 3500, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    loading={isLoading || isFetching} | 
			
		||||
 | 
				                    dataSource={data?.rows ?? []} | 
			
		||||
 | 
				                    columns={columns} | 
			
		||||
 | 
				                    search={false} | 
			
		||||
 | 
				                    options={{ | 
			
		||||
 | 
				                      reload: () => { | 
			
		||||
 | 
				                        refetch() | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    pagination={{ | 
			
		||||
 | 
				                      total: data?.total, | 
			
		||||
 | 
				                      pageSize: search.pageSize, | 
			
		||||
 | 
				                      current: search.page, | 
			
		||||
 | 
				                      onChange: (current, pageSize) => { | 
			
		||||
 | 
				                        setSearch(prev => { | 
			
		||||
 | 
				                          return { | 
			
		||||
 | 
				                            ...prev, | 
			
		||||
 | 
				                            page: current, | 
			
		||||
 | 
				                            pageSize: pageSize, | 
			
		||||
 | 
				                          } | 
			
		||||
 | 
				                        }) | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				            /> | 
			
		||||
 | 
				            <BetaSchemaForm | 
			
		||||
 | 
				                    shouldUpdate={false} | 
			
		||||
 | 
				                    width={600} | 
			
		||||
 | 
				                    form={form} | 
			
		||||
 | 
				                    layout={'vertical'} | 
			
		||||
 | 
				                    scrollToFirstError={true} | 
			
		||||
 | 
				                    title={t(`${i18nPrefix}.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '视频编辑' : '视频添加')} | 
			
		||||
 | 
				                    // colProps={{ span: 24 }}
 | 
			
		||||
 | 
				                    labelCol={{ span: 6 }} | 
			
		||||
 | 
				                    // wrapperCol={{ span: 14 }}
 | 
			
		||||
 | 
				                    layoutType={'DrawerForm'} | 
			
		||||
 | 
				                    open={open} | 
			
		||||
 | 
				                    drawerProps={{ | 
			
		||||
 | 
				                      maskClosable: false, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    onOpenChange={(open) => { | 
			
		||||
 | 
				                      setOpen(open) | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    loading={isSubmitting} | 
			
		||||
 | 
				                    onFinish={async (values) => { | 
			
		||||
 | 
				                      // console.log('values', values)
 | 
			
		||||
 | 
				                      saveOrUpdate(values) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    columns={columns as ProFormColumnsType[]}/> | 
			
		||||
 | 
				          </ListPageLayout> | 
			
		||||
 | 
				  ) | 
			
		||||
 | 
				} | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				export default Video | 
			
		||||
@ -0,0 +1,395 @@ | 
			
		|||||
 | 
				import { useTranslation } from '@/i18n.ts' | 
			
		||||
 | 
				import { Button, Form, Image, Popconfirm } from 'antd' | 
			
		||||
 | 
				import { useAtom, useAtomValue } from 'jotai'  | 
			
		||||
 | 
				import { useEffect, useMemo, useState } from 'react' | 
			
		||||
 | 
				import Switch from '@/components/switch' | 
			
		||||
 | 
				import Action from '@/components/action/Action.tsx' | 
			
		||||
 | 
				import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components' | 
			
		||||
 | 
				import ListPageLayout from '@/layout/ListPageLayout.tsx' | 
			
		||||
 | 
				import { | 
			
		||||
 | 
				  deleteVideoCloudAtom, | 
			
		||||
 | 
				  saveOrUpdateVideoCloudAtom, | 
			
		||||
 | 
				  videoCloudsAtom, | 
			
		||||
 | 
				  videoCloudSearchAtom | 
			
		||||
 | 
				} from '@/store/cms/video_cloud.ts' | 
			
		||||
 | 
				import { videoTypes } from '@/store/cms/video.ts' | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				const i18nPrefix = 'cms.videoCloud' | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				const VideoCloud = () => { | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  // const { styles } = useStyle()
 | 
			
		||||
 | 
				  const { t } = useTranslation() | 
			
		||||
 | 
				  const [ form ] = Form.useForm() | 
			
		||||
 | 
				  const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateVideoCloudAtom) | 
			
		||||
 | 
				  const [ search, setSearch ] = useAtom(videoCloudSearchAtom) | 
			
		||||
 | 
				  const { data, isFetching, isLoading, refetch } = useAtomValue(videoCloudsAtom) | 
			
		||||
 | 
				  const { mutate: deleteVideo, isPending: isDeleting } = useAtomValue(deleteVideoCloudAtom) | 
			
		||||
 | 
				  const [ open, setOpen ] = useState(false) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  const columns = useMemo(() => { | 
			
		||||
 | 
				    return [ | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        title: 'ID', | 
			
		||||
 | 
				        dataIndex: 'id', | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true } | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.title`, 'Title'), | 
			
		||||
 | 
				        'dataIndex': 'title', | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.title_sub`, 'TitleSub'), | 
			
		||||
 | 
				        'dataIndex': 'title_sub', | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.source_url`, 'SourceUrl'), | 
			
		||||
 | 
				        'dataIndex': 'source_url', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        copyable: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.collect_id`, 'CollectId'), | 
			
		||||
 | 
				        'dataIndex': 'collect_id', | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.type_id`, 'TypeId'), | 
			
		||||
 | 
				        'dataIndex': 'type_id', | 
			
		||||
 | 
				        valueType: 'select', | 
			
		||||
 | 
				        fieldProps: { | 
			
		||||
 | 
				          options: videoTypes, | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return t(`${i18nPrefix}.type_id.${record.type_id}`) | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.letter`, 'Letter'), | 
			
		||||
 | 
				        'dataIndex': 'letter' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.tag`, 'Tag'), | 
			
		||||
 | 
				        'dataIndex': 'tag', | 
			
		||||
 | 
				        valueType: 'textarea', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.lock`, 'Lock'), | 
			
		||||
 | 
				        'dataIndex': 'lock', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.copyright`, 'Copyright'), | 
			
		||||
 | 
				        'dataIndex': 'copyright', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.is_end`, 'IsEnd'), | 
			
		||||
 | 
				        'dataIndex': 'is_end', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.status`, 'Status'), | 
			
		||||
 | 
				        'dataIndex': 'status', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.category_id`, 'CategoryId'), | 
			
		||||
 | 
				        'dataIndex': 'category_id', | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pic`, 'Pic'), | 
			
		||||
 | 
				        'dataIndex': 'pic', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return  <Image src={record.pic} height={40}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pic_local`, 'PicLocal'), | 
			
		||||
 | 
				        'dataIndex': 'pic_local', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.actor`, 'Actor'), | 
			
		||||
 | 
				        'dataIndex': 'actor', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.director`, 'Director'), | 
			
		||||
 | 
				        'dataIndex': 'director', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.writer`, 'Writer'), | 
			
		||||
 | 
				        'dataIndex': 'writer', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pubdate`, 'Pubdate'), | 
			
		||||
 | 
				        'dataIndex': 'pubdate', | 
			
		||||
 | 
				        valueType: 'dateTime' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.total`, 'Total'), | 
			
		||||
 | 
				        'dataIndex': 'total', | 
			
		||||
 | 
				        valueType: 'digit' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.serial`, 'Serial'), | 
			
		||||
 | 
				        'dataIndex': 'serial', | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.duration`, 'Duration'), | 
			
		||||
 | 
				        'dataIndex': 'duration', | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.class`, 'Class'), | 
			
		||||
 | 
				        'dataIndex': 'class', | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.area`, 'Area'), | 
			
		||||
 | 
				        'dataIndex': 'area', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.lang`, 'Lang'), | 
			
		||||
 | 
				        'dataIndex': 'lang', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.version`, 'Version'), | 
			
		||||
 | 
				        'dataIndex': 'version' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.year`, 'Year'), | 
			
		||||
 | 
				        'dataIndex': 'year', | 
			
		||||
 | 
				        valueType: 'dateYear' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.state`, 'State'), | 
			
		||||
 | 
				        'dataIndex': 'state' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.douban_score`, 'DoubanScore'), | 
			
		||||
 | 
				        'dataIndex': 'douban_score' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.douban_id`, 'DoubanId'), | 
			
		||||
 | 
				        'dataIndex': 'douban_id', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.imdb_score`, 'ImdbScore'), | 
			
		||||
 | 
				        'dataIndex': 'imdb_score' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.imdb_id`, 'ImdbId'), | 
			
		||||
 | 
				        'dataIndex': 'imdb_id', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.content`, 'Content'), | 
			
		||||
 | 
				        'dataIndex': 'content', | 
			
		||||
 | 
				        valueType: 'textarea', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => ({ | 
			
		||||
 | 
				          width: 200, | 
			
		||||
 | 
				        }), | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        title: t(`${i18nPrefix}.columns.option`, '操作'), | 
			
		||||
 | 
				        key: 'option', | 
			
		||||
 | 
				        valueType: 'option', | 
			
		||||
 | 
				        fixed: 'right', | 
			
		||||
 | 
				        render: (_, record) => [ | 
			
		||||
 | 
				          <Action key="edit" | 
			
		||||
 | 
				                  as={'a'} | 
			
		||||
 | 
				                  onClick={() => { | 
			
		||||
 | 
				                    form.setFieldsValue(record) | 
			
		||||
 | 
				                    setOpen(true) | 
			
		||||
 | 
				                  }}>{t('actions.edit')}</Action>, | 
			
		||||
 | 
				          <Popconfirm | 
			
		||||
 | 
				                  key={'del_confirm'} | 
			
		||||
 | 
				                  disabled={isDeleting} | 
			
		||||
 | 
				                  onConfirm={() => { | 
			
		||||
 | 
				                    deleteVideo([ record.id ]) | 
			
		||||
 | 
				                  }} | 
			
		||||
 | 
				                  title={t('message.deleteConfirm')}> | 
			
		||||
 | 
				            <a key="del"> | 
			
		||||
 | 
				              {t('actions.delete', '删除')} | 
			
		||||
 | 
				            </a> | 
			
		||||
 | 
				          </Popconfirm> | 
			
		||||
 | 
				        ] | 
			
		||||
 | 
				      } | 
			
		||||
 | 
				    ] as ProColumns[] | 
			
		||||
 | 
				  }, [ isDeleting ]) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  useEffect(() => { | 
			
		||||
 | 
				    if (isSuccess) { | 
			
		||||
 | 
				      setOpen(false) | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				  }, [ isSuccess ]) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  return ( | 
			
		||||
 | 
				          <ListPageLayout> | 
			
		||||
 | 
				            <ProTable | 
			
		||||
 | 
				                    rowKey="id" | 
			
		||||
 | 
				                    headerTitle={t(`${i18nPrefix}.title`, '云盘视频管理')} | 
			
		||||
 | 
				                    toolbar={{ | 
			
		||||
 | 
				                      search: { | 
			
		||||
 | 
				                        loading: isFetching && !!search.key, | 
			
		||||
 | 
				                        onSearch: (value: string) => { | 
			
		||||
 | 
				                          setSearch(prev => ({ | 
			
		||||
 | 
				                            ...prev, | 
			
		||||
 | 
				                            key: value | 
			
		||||
 | 
				                          })) | 
			
		||||
 | 
				                        }, | 
			
		||||
 | 
				                        allowClear: true, | 
			
		||||
 | 
				                        placeholder: t(`${i18nPrefix}.placeholder`, '输入云盘视频名称') | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				                      actions: [ | 
			
		||||
 | 
				                        <Button | 
			
		||||
 | 
				                                onClick={() => { | 
			
		||||
 | 
				                                  form.resetFields() | 
			
		||||
 | 
				                                  form.setFieldsValue({ | 
			
		||||
 | 
				                                    id: 0, | 
			
		||||
 | 
				                                  }) | 
			
		||||
 | 
				                                  setOpen(true) | 
			
		||||
 | 
				                                }} | 
			
		||||
 | 
				                                type={'primary'}>{t(`${i18nPrefix}.add`, '添加')}</Button> | 
			
		||||
 | 
				                      ] | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    scroll={{ | 
			
		||||
 | 
				                      x: 3500, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    loading={isLoading || isFetching} | 
			
		||||
 | 
				                    dataSource={data?.rows ?? []} | 
			
		||||
 | 
				                    columns={columns} | 
			
		||||
 | 
				                    search={false} | 
			
		||||
 | 
				                    options={{ | 
			
		||||
 | 
				                      reload: () => { | 
			
		||||
 | 
				                        refetch() | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    pagination={{ | 
			
		||||
 | 
				                      total: data?.total, | 
			
		||||
 | 
				                      pageSize: search.pageSize, | 
			
		||||
 | 
				                      current: search.page, | 
			
		||||
 | 
				                      onChange: (current, pageSize) => { | 
			
		||||
 | 
				                        setSearch(prev => { | 
			
		||||
 | 
				                          return { | 
			
		||||
 | 
				                            ...prev, | 
			
		||||
 | 
				                            page: current, | 
			
		||||
 | 
				                            pageSize: pageSize, | 
			
		||||
 | 
				                          } | 
			
		||||
 | 
				                        }) | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				            /> | 
			
		||||
 | 
				            <BetaSchemaForm | 
			
		||||
 | 
				                    shouldUpdate={false} | 
			
		||||
 | 
				                    width={600} | 
			
		||||
 | 
				                    form={form} | 
			
		||||
 | 
				                    layout={'vertical'} | 
			
		||||
 | 
				                    scrollToFirstError={true} | 
			
		||||
 | 
				                    title={t(`${i18nPrefix}.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '云盘视频编辑' : '云盘视频添加')} | 
			
		||||
 | 
				                    // colProps={{ span: 24 }}
 | 
			
		||||
 | 
				                    labelCol={{ span: 6 }} | 
			
		||||
 | 
				                    // wrapperCol={{ span: 14 }}
 | 
			
		||||
 | 
				                    layoutType={'DrawerForm'} | 
			
		||||
 | 
				                    open={open} | 
			
		||||
 | 
				                    drawerProps={{ | 
			
		||||
 | 
				                      maskClosable: false, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    onOpenChange={(open) => { | 
			
		||||
 | 
				                      setOpen(open) | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    loading={isSubmitting} | 
			
		||||
 | 
				                    onFinish={async (values) => { | 
			
		||||
 | 
				                      // console.log('values', values)
 | 
			
		||||
 | 
				                      saveOrUpdate(values) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    columns={columns as ProFormColumnsType[]}/> | 
			
		||||
 | 
				          </ListPageLayout> | 
			
		||||
 | 
				  ) | 
			
		||||
 | 
				} | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				export default VideoCloud | 
			
		||||
@ -0,0 +1,396 @@ | 
			
		|||||
 | 
				import { useTranslation } from '@/i18n.ts' | 
			
		||||
 | 
				import { Button, Form, Popconfirm, Image } from 'antd' | 
			
		||||
 | 
				import { useAtom, useAtomValue } from 'jotai' | 
			
		||||
 | 
				import { useEffect, useMemo, useState } from 'react' | 
			
		||||
 | 
				import Switch from '@/components/switch' | 
			
		||||
 | 
				import Action from '@/components/action/Action.tsx' | 
			
		||||
 | 
				import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components' | 
			
		||||
 | 
				import ListPageLayout from '@/layout/ListPageLayout.tsx' | 
			
		||||
 | 
				import { videoTypes } from '@/store/cms/video.ts' | 
			
		||||
 | 
				import { | 
			
		||||
 | 
				  deleteVideoMagnetAtom, | 
			
		||||
 | 
				  saveOrUpdateVideoMagnetAtom, | 
			
		||||
 | 
				  videoMagnetsAtom, | 
			
		||||
 | 
				  videoMagnetSearchAtom | 
			
		||||
 | 
				} from '@/store/cms/video_magnet.ts' | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				const i18nPrefix = 'cms.videoMagnet' | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				const VideoMagnet = () => { | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  // const { styles } = useStyle()
 | 
			
		||||
 | 
				  const { t } = useTranslation() | 
			
		||||
 | 
				  const [ form ] = Form.useForm() | 
			
		||||
 | 
				  const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateVideoMagnetAtom) | 
			
		||||
 | 
				  const [ search, setSearch ] = useAtom(videoMagnetSearchAtom) | 
			
		||||
 | 
				  const { data, isFetching, isLoading, refetch } = useAtomValue(videoMagnetsAtom) | 
			
		||||
 | 
				  const { mutate: deleteVideo, isPending: isDeleting } = useAtomValue(deleteVideoMagnetAtom) | 
			
		||||
 | 
				  const [ open, setOpen ] = useState(false) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  const columns = useMemo(() => { | 
			
		||||
 | 
				    return [ | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        title: 'ID', | 
			
		||||
 | 
				        dataIndex: 'id', | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true } | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.title`, 'Title'), | 
			
		||||
 | 
				        'dataIndex': 'title', | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.title_sub`, 'TitleSub'), | 
			
		||||
 | 
				        'dataIndex': 'title_sub', | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.source_url`, 'SourceUrl'), | 
			
		||||
 | 
				        'dataIndex': 'source_url', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        copyable: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.collect_id`, 'CollectId'), | 
			
		||||
 | 
				        'dataIndex': 'collect_id', | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.type_id`, 'TypeId'), | 
			
		||||
 | 
				        'dataIndex': 'type_id', | 
			
		||||
 | 
				        valueType: 'select', | 
			
		||||
 | 
				        fieldProps: { | 
			
		||||
 | 
				          options: videoTypes, | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return t(`${i18nPrefix}.type_id.${record.type_id}`) | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.letter`, 'Letter'), | 
			
		||||
 | 
				        'dataIndex': 'letter' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.tag`, 'Tag'), | 
			
		||||
 | 
				        'dataIndex': 'tag', | 
			
		||||
 | 
				        valueType: 'textarea', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.lock`, 'Lock'), | 
			
		||||
 | 
				        'dataIndex': 'lock', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.copyright`, 'Copyright'), | 
			
		||||
 | 
				        'dataIndex': 'copyright', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.is_end`, 'IsEnd'), | 
			
		||||
 | 
				        'dataIndex': 'is_end', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.status`, 'Status'), | 
			
		||||
 | 
				        'dataIndex': 'status', | 
			
		||||
 | 
				        valueType: 'switch', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Switch value={record.lock} size={'small'}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.category_id`, 'CategoryId'), | 
			
		||||
 | 
				        'dataIndex': 'category_id', | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pic`, 'Pic'), | 
			
		||||
 | 
				        'dataIndex': 'pic', | 
			
		||||
 | 
				        render: (_dom, record) => { | 
			
		||||
 | 
				          return <Image src={record.pic} height={40}/> | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pic_local`, 'PicLocal'), | 
			
		||||
 | 
				        'dataIndex': 'pic_local', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.actor`, 'Actor'), | 
			
		||||
 | 
				        'dataIndex': 'actor', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.director`, 'Director'), | 
			
		||||
 | 
				        'dataIndex': 'director', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.writer`, 'Writer'), | 
			
		||||
 | 
				        'dataIndex': 'writer', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.pubdate`, 'Pubdate'), | 
			
		||||
 | 
				        'dataIndex': 'pubdate', | 
			
		||||
 | 
				        valueType: 'dateTime' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.total`, 'Total'), | 
			
		||||
 | 
				        'dataIndex': 'total', | 
			
		||||
 | 
				        valueType: 'digit' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.serial`, 'Serial'), | 
			
		||||
 | 
				        'dataIndex': 'serial', | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.duration`, 'Duration'), | 
			
		||||
 | 
				        'dataIndex': 'duration', | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.class`, 'Class'), | 
			
		||||
 | 
				        'dataIndex': 'class', | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.area`, 'Area'), | 
			
		||||
 | 
				        'dataIndex': 'area', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.lang`, 'Lang'), | 
			
		||||
 | 
				        'dataIndex': 'lang', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => { | 
			
		||||
 | 
				          return { | 
			
		||||
 | 
				            width: 200, | 
			
		||||
 | 
				          } | 
			
		||||
 | 
				        }, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.version`, 'Version'), | 
			
		||||
 | 
				        'dataIndex': 'version' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.year`, 'Year'), | 
			
		||||
 | 
				        'dataIndex': 'year', | 
			
		||||
 | 
				        valueType: 'dateYear' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.state`, 'State'), | 
			
		||||
 | 
				        'dataIndex': 'state' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.douban_score`, 'DoubanScore'), | 
			
		||||
 | 
				        'dataIndex': 'douban_score' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.douban_id`, 'DoubanId'), | 
			
		||||
 | 
				        'dataIndex': 'douban_id', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.imdb_score`, 'ImdbScore'), | 
			
		||||
 | 
				        'dataIndex': 'imdb_score' | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.imdb_id`, 'ImdbId'), | 
			
		||||
 | 
				        'dataIndex': 'imdb_id', | 
			
		||||
 | 
				        hideInSearch: true, | 
			
		||||
 | 
				        hideInSetting: true, | 
			
		||||
 | 
				        formItemProps: { hidden: true }, | 
			
		||||
 | 
				        hideInTable: true, | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        'title': t(`${i18nPrefix}.columns.content`, 'Content'), | 
			
		||||
 | 
				        'dataIndex': 'content', | 
			
		||||
 | 
				        valueType: 'textarea', | 
			
		||||
 | 
				        ellipsis: true, | 
			
		||||
 | 
				        onHeaderCell: () => ({ | 
			
		||||
 | 
				          width: 200, | 
			
		||||
 | 
				        }), | 
			
		||||
 | 
				      }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				      { | 
			
		||||
 | 
				        title: t(`${i18nPrefix}.columns.option`, '操作'), | 
			
		||||
 | 
				        key: 'option', | 
			
		||||
 | 
				        valueType: 'option', | 
			
		||||
 | 
				        fixed: 'right', | 
			
		||||
 | 
				        render: (_, record) => [ | 
			
		||||
 | 
				          <Action key="edit" | 
			
		||||
 | 
				                  as={'a'} | 
			
		||||
 | 
				                  onClick={() => { | 
			
		||||
 | 
				                    form.setFieldsValue(record) | 
			
		||||
 | 
				                    setOpen(true) | 
			
		||||
 | 
				                  }}>{t('actions.edit')}</Action>, | 
			
		||||
 | 
				          <Popconfirm | 
			
		||||
 | 
				                  key={'del_confirm'} | 
			
		||||
 | 
				                  disabled={isDeleting} | 
			
		||||
 | 
				                  onConfirm={() => { | 
			
		||||
 | 
				                    deleteVideo([ record.id ]) | 
			
		||||
 | 
				                  }} | 
			
		||||
 | 
				                  title={t('message.deleteConfirm')}> | 
			
		||||
 | 
				            <a key="del"> | 
			
		||||
 | 
				              {t('actions.delete', '删除')} | 
			
		||||
 | 
				            </a> | 
			
		||||
 | 
				          </Popconfirm> | 
			
		||||
 | 
				        ] | 
			
		||||
 | 
				      } | 
			
		||||
 | 
				    ] as ProColumns[] | 
			
		||||
 | 
				  }, [ isDeleting ]) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  useEffect(() => { | 
			
		||||
 | 
				    if (isSuccess) { | 
			
		||||
 | 
				      setOpen(false) | 
			
		||||
 | 
				    } | 
			
		||||
 | 
				  }, [ isSuccess ]) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  return ( | 
			
		||||
 | 
				          <ListPageLayout> | 
			
		||||
 | 
				            <ProTable | 
			
		||||
 | 
				                    rowKey="id" | 
			
		||||
 | 
				                    headerTitle={t(`${i18nPrefix}.title`, '磁链视频管理')} | 
			
		||||
 | 
				                    toolbar={{ | 
			
		||||
 | 
				                      search: { | 
			
		||||
 | 
				                        loading: isFetching && !!search.key, | 
			
		||||
 | 
				                        onSearch: (value: string) => { | 
			
		||||
 | 
				                          setSearch(prev => ({ | 
			
		||||
 | 
				                            ...prev, | 
			
		||||
 | 
				                            key: value | 
			
		||||
 | 
				                          })) | 
			
		||||
 | 
				                        }, | 
			
		||||
 | 
				                        allowClear: true, | 
			
		||||
 | 
				                        placeholder: t(`${i18nPrefix}.placeholder`, '输入磁链视频名称') | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				                      actions: [ | 
			
		||||
 | 
				                        <Button | 
			
		||||
 | 
				                                onClick={() => { | 
			
		||||
 | 
				                                  form.resetFields() | 
			
		||||
 | 
				                                  form.setFieldsValue({ | 
			
		||||
 | 
				                                    id: 0, | 
			
		||||
 | 
				                                  }) | 
			
		||||
 | 
				                                  setOpen(true) | 
			
		||||
 | 
				                                }} | 
			
		||||
 | 
				                                type={'primary'}>{t(`${i18nPrefix}.add`, '添加')}</Button> | 
			
		||||
 | 
				                      ] | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    scroll={{ | 
			
		||||
 | 
				                      x: 3500, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    loading={isLoading || isFetching} | 
			
		||||
 | 
				                    dataSource={data?.rows ?? []} | 
			
		||||
 | 
				                    columns={columns} | 
			
		||||
 | 
				                    search={false} | 
			
		||||
 | 
				                    options={{ | 
			
		||||
 | 
				                      reload: () => { | 
			
		||||
 | 
				                        refetch() | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    pagination={{ | 
			
		||||
 | 
				                      total: data?.total, | 
			
		||||
 | 
				                      pageSize: search.pageSize, | 
			
		||||
 | 
				                      current: search.page, | 
			
		||||
 | 
				                      onChange: (current, pageSize) => { | 
			
		||||
 | 
				                        setSearch(prev => { | 
			
		||||
 | 
				                          return { | 
			
		||||
 | 
				                            ...prev, | 
			
		||||
 | 
				                            page: current, | 
			
		||||
 | 
				                            pageSize: pageSize, | 
			
		||||
 | 
				                          } | 
			
		||||
 | 
				                        }) | 
			
		||||
 | 
				                      }, | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				            /> | 
			
		||||
 | 
				            <BetaSchemaForm | 
			
		||||
 | 
				                    shouldUpdate={false} | 
			
		||||
 | 
				                    width={600} | 
			
		||||
 | 
				                    form={form} | 
			
		||||
 | 
				                    layout={'vertical'} | 
			
		||||
 | 
				                    scrollToFirstError={true} | 
			
		||||
 | 
				                    title={t(`${i18nPrefix}.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '磁链视频编辑' : '磁链视频添加')} | 
			
		||||
 | 
				                    // colProps={{ span: 24 }}
 | 
			
		||||
 | 
				                    labelCol={{ span: 6 }} | 
			
		||||
 | 
				                    // wrapperCol={{ span: 14 }}
 | 
			
		||||
 | 
				                    layoutType={'DrawerForm'} | 
			
		||||
 | 
				                    open={open} | 
			
		||||
 | 
				                    drawerProps={{ | 
			
		||||
 | 
				                      maskClosable: false, | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    onOpenChange={(open) => { | 
			
		||||
 | 
				                      setOpen(open) | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    loading={isSubmitting} | 
			
		||||
 | 
				                    onFinish={async (values) => { | 
			
		||||
 | 
				                      // console.log('values', values)
 | 
			
		||||
 | 
				                      saveOrUpdate(values) | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				                    }} | 
			
		||||
 | 
				                    columns={columns as ProFormColumnsType[]}/> | 
			
		||||
 | 
				          </ListPageLayout> | 
			
		||||
 | 
				  ) | 
			
		||||
 | 
				} | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				export default VideoMagnet | 
			
		||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue