From ed9352f135e773076f1e08b694c2f043a430ce29 Mon Sep 17 00:00:00 2001 From: dark Date: Sat, 1 Jun 2024 17:10:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84CMS=E7=9A=84=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/tag-value/TagValue.tsx | 37 +- src/locales/lang/pages/cms/video/zh-CN.ts | 2 +- src/locales/lang/pages/cms/videoCloud/zh-CN.ts | 2 +- src/locales/lang/pages/cms/videoMagnet/zh-CN.ts | 2 +- src/pages/cms/video/index.tsx | 451 +++++++++++++++--- src/pages/cms/video/style.ts | 26 ++ src/pages/cms/video_cloud/index.tsx | 588 ++++++++++++++++++++---- src/pages/cms/video_cloud/style.ts | 26 ++ src/pages/cms/video_magnet/index.tsx | 588 ++++++++++++++++++++---- src/pages/cms/video_magnet/style.ts | 26 ++ src/pages/videos/list/index.tsx | 3 +- src/store/cms/video.ts | 14 +- src/store/cms/video_cloud.ts | 2 +- src/store/cms/video_magnet.ts | 2 +- 14 files changed, 1536 insertions(+), 233 deletions(-) create mode 100644 src/pages/cms/video/style.ts create mode 100644 src/pages/cms/video_cloud/style.ts create mode 100644 src/pages/cms/video_magnet/style.ts diff --git a/src/components/tag-value/TagValue.tsx b/src/components/tag-value/TagValue.tsx index 2fd5dd8..da2908d 100644 --- a/src/components/tag-value/TagValue.tsx +++ b/src/components/tag-value/TagValue.tsx @@ -18,11 +18,38 @@ const parserValue = (value?: ValueType | ValueType[]) => { return [] } if (Array.isArray(value)) { - return value + return value.map(i=>{ + if (typeof i === 'string' ) { + return i.trim() + } + if (typeof i === 'number') { + return i + } + return ((i as any).value ?? i) + }) + } + if (typeof value === 'string' && value.includes(',')) { + return value.split(',').map(item => item.trim()) + } + if (typeof value === 'number') { + return [ value ] } return [ value ] } +const parserTag = (tag: ValueType) => { + if (typeof tag === 'string') { + return tag.trim() + } + if (typeof tag === 'number') { + return tag + } + if (typeof tag === 'object') { + return ((tag as any).value ?? tag) + } + return tag +} + const TagValue = ( { value, onChange, checked = true, tags = [], wrap, single, @@ -32,7 +59,7 @@ const TagValue = ( const [ innerValue, setValue ] = useState(() => { return parserValue(value).filter(item => { return tags?.some(t => { - return ((t as any).value ?? t) === item + return parserTag(t) === item }) }) }) @@ -40,7 +67,7 @@ const TagValue = ( useEffect(() => { const val = parserValue(value).filter(item => { return tags?.some(t => { - return ((t as any).value ?? t) === item + return parserTag(t) === item }) }) setValue(val) @@ -50,10 +77,10 @@ const TagValue = ( {tags?.map(item => { if (item == null || item === '' || item === undefined) return null - const val = (item as any).value ?? item + const val = parserTag(item) const selected = innerValue.includes(val) return ( - { const prevValue = parserValue(value) const index = prevValue?.indexOf(val) diff --git a/src/locales/lang/pages/cms/video/zh-CN.ts b/src/locales/lang/pages/cms/video/zh-CN.ts index aeacfe2..a975535 100644 --- a/src/locales/lang/pages/cms/video/zh-CN.ts +++ b/src/locales/lang/pages/cms/video/zh-CN.ts @@ -6,7 +6,7 @@ export default { edit: '编辑', delete: '删除', type_id: [ - '在线观看', '下载', '网盘' + '在线观看', '磁链', '网盘' ], lock: [ '未锁', '锁定' diff --git a/src/locales/lang/pages/cms/videoCloud/zh-CN.ts b/src/locales/lang/pages/cms/videoCloud/zh-CN.ts index 995e40f..0ec0230 100644 --- a/src/locales/lang/pages/cms/videoCloud/zh-CN.ts +++ b/src/locales/lang/pages/cms/videoCloud/zh-CN.ts @@ -6,7 +6,7 @@ export default { edit: '编辑', delete: '删除', type_id: [ - '在线观看', '下载', '网盘' + '在线观看', '磁链', '网盘' ], lock: [ '未锁', '锁定' diff --git a/src/locales/lang/pages/cms/videoMagnet/zh-CN.ts b/src/locales/lang/pages/cms/videoMagnet/zh-CN.ts index 6eb4f0c..e394a03 100644 --- a/src/locales/lang/pages/cms/videoMagnet/zh-CN.ts +++ b/src/locales/lang/pages/cms/videoMagnet/zh-CN.ts @@ -6,7 +6,7 @@ export default { edit: '编辑', delete: '删除', type_id: [ - '在线观看', '下载', '网盘' + '在线观看', '磁链', '网盘' ], lock: [ '未锁', '锁定' diff --git a/src/pages/cms/video/index.tsx b/src/pages/cms/video/index.tsx index 2f4dec0..7e022ee 100644 --- a/src/pages/cms/video/index.tsx +++ b/src/pages/cms/video/index.tsx @@ -1,9 +1,9 @@ import { useTranslation } from '@/i18n.ts' -import { Button, Form, Image, Popconfirm } from 'antd' -import { useAtom, useAtomValue } from 'jotai' +import { Badge, Button, DatePicker, Divider, Form, Image, Popconfirm, Space, Tooltip } from 'antd' +import { useAtom, useAtomValue,useSetAtom } from 'jotai' import { deleteVideoAtom, - saveOrUpdateVideoAtom, videosAtom, videoSearchAtom, videoTypes + saveOrUpdateVideoAtom, videoAtom, videosAtom, videoSearchAtom, videoTypes } from '@/store/cms/video.ts' import { useEffect, useMemo, useState } from 'react' import Switch from '@/components/switch' @@ -11,26 +11,35 @@ import Action from '@/components/action/Action.tsx' import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components' import ListPageLayout from '@/layout/ListPageLayout.tsx' import TagPro from '@/components/tag-pro/TagPro.tsx' -import { useSetAtom } from 'jotai/index' import { categoriesAtom, categoryByIdAtom, categoryIdAtom } from '@/store/cms/category.ts' +import { getValueCount } from '@/utils' +import { FilterOutlined } from '@ant-design/icons' +import TagValue from '@/components/tag-value/TagValue.tsx' +import dayjs from 'dayjs' +import { useStyle } from './style.ts' const i18nPrefix = 'cms.video' const Video = () => { - // const { styles } = useStyle() + const { styles, cx } = useStyle() const { t } = useTranslation() const [ form ] = Form.useForm() + const [ filterForm ] = Form.useForm() const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateVideoAtom) const [ search, setSearch ] = useAtom(videoSearchAtom) + const [ currentVideo, setVideo ] = useAtom(videoAtom) const { data, isFetching, isLoading, refetch } = useAtomValue(videosAtom) const { mutate: deleteVideo, isPending: isDeleting } = useAtomValue(deleteVideoAtom) const setCategoryId = useSetAtom(categoryIdAtom) const { data: categories, isLoading: isCateLoading } = useAtomValue(categoriesAtom) const { data: category, isLoading: isCategoryFetching } = useAtomValue(categoryByIdAtom) const [ open, setOpen ] = useState(false) + const [ openFilter, setFilterOpen ] = useState(false) + const [ searchKey, setSearchKey ] = useState(search?.title) const columns = useMemo(() => { + return [ { title: 'ID', @@ -57,7 +66,13 @@ const Video = () => { } }, colProps: { - span: 8 + span: 12 + }, + render: (_text, record) => { + //高亮搜索关键字, 从search.title中获取 + const title = record.title?.replace?.(new RegExp(`(${search?.title})`, 'ig'), '$1') + + return } }, { @@ -69,7 +84,7 @@ const Video = () => { } }, colProps: { - span: 8 + span: 12 } }, { @@ -79,13 +94,10 @@ const Video = () => { fieldProps: { options: videoTypes, }, + hideInForm: true, render: (_dom, record) => { return t(`${i18nPrefix}.type_id.${record.type_id}`) }, - colProps: { - span: 8 - } - }, { 'title': t(`${i18nPrefix}.columns.source_url`, 'SourceUrl'), @@ -97,13 +109,15 @@ const Video = () => { width: 200, } }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.letter`, 'Letter'), 'dataIndex': 'letter', colProps: { span: 4 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.lock`, 'Lock'), @@ -114,7 +128,8 @@ const Video = () => { }, colProps: { span: 4 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.copyright`, 'Copyright'), @@ -125,7 +140,8 @@ const Video = () => { }, colProps: { span: 4 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.is_end`, 'IsEnd'), @@ -136,7 +152,8 @@ const Video = () => { }, colProps: { span: 4 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.status`, 'Status'), @@ -167,7 +184,8 @@ const Video = () => { }, colProps: { span: 4 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.pic`, 'Pic'), @@ -177,7 +195,8 @@ const Video = () => { }, colProps: { span: 20 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.category_id`, 'CategoryId'), @@ -186,126 +205,345 @@ const Video = () => { fieldProps: { loading: isCategoryFetching, options: categories?.rows ?? [], - fieldNames:{ + fieldNames: { label: 'name', value: 'id' } }, + render: (_dom, record) => { + return item.id === record.category_id).map(item=>{ + return { + label: item.name, + value: item.id + } + }) ?? []} + wrap={currentVideo?.id === record.id} + value={search?.category_id ?? []} + onChange={(values) => { + setSearch((prev: any) => { + return { + ...prev, + category_id: values, + } + }) + setCategoryId(values[0]) + setFilterOpen(true) + }} + /> + }, }, { 'title': t(`${i18nPrefix}.columns.actor`, 'Actor'), 'dataIndex': 'actor', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + actor: values, + } + }) + setFilterOpen(true) + }} + /> }, - }, { 'title': t(`${i18nPrefix}.columns.director`, 'Director'), - 'dataIndex': 'director' + 'dataIndex': 'director', + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + director: values, + } + }) + setFilterOpen(true) + }} + /> + }, + }, { 'title': t(`${i18nPrefix}.columns.writer`, 'Writer'), - 'dataIndex': 'writer' + 'dataIndex': 'writer', + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + writer: values, + } + }) + setFilterOpen(true) + }} + /> + }, + }, { 'title': t(`${i18nPrefix}.columns.remarks`, 'Remarks'), - 'dataIndex': 'remarks' + 'dataIndex': 'remarks', + hideInSearch: true, }, - { +/* { 'title': t(`${i18nPrefix}.columns.pubdate`, 'Pubdate'), 'dataIndex': 'pubdate', valueType: 'dateTime', colProps: { span: 4 } - }, + },*/ { 'title': t(`${i18nPrefix}.columns.total`, 'Total'), 'dataIndex': 'total', valueType: 'digit', colProps: { span: 4 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.serial`, 'Serial'), 'dataIndex': 'serial', colProps: { span: 4 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.duration`, 'Duration'), 'dataIndex': 'duration', colProps: { span: 4 - } + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.year`, 'Year'), 'dataIndex': 'year', valueType: 'dateYear', + fieldProps:{ + style:{ + width: '100%' + } + }, colProps: { - span: 4 + span: openFilter? 12: 4, + }, + render: (_dom, record) => { + if (record.year === undefined || record.year === null || record.year === 0) { + return null + } + + return { + setSearch((prev: any) => { + return { + ...prev, + year: values[0], + } + }) + setFilterOpen(true) + }} + /> + }, + renderFormItem: (_schema, config) => { + const props = { ...config } as any + delete props.mode + const isForm = config.type === 'form' + let value = isForm && config.value && config.value > 0 ? dayjs().set('year', config.value) : undefined + if (config.value?.$isDayjsObject) { + value = config.value as dayjs.Dayjs + } + return } + }, { 'title': t(`${i18nPrefix}.columns.tag`, 'Tag'), 'dataIndex': 'tag', valueType: 'textarea', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } - }, renderFormItem: (schema, config) => { - return - } + return + }, + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + tag: values, + } + }) + setFilterOpen(true) + }} + /> + }, + }, { 'title': t(`${i18nPrefix}.columns.area`, 'Area'), 'dataIndex': 'area', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + area: values, + } + }) + setFilterOpen(true) + }} + /> + }, + renderFormItem: (schema, config) => { - return + return } }, { 'title': t(`${i18nPrefix}.columns.lang`, 'Lang'), 'dataIndex': 'lang', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + lang: values, + } + }) + setFilterOpen(true) + }} + /> + }, + renderFormItem: (schema, config) => { - return + return } }, { 'title': t(`${i18nPrefix}.columns.version`, 'Version'), 'dataIndex': 'version', + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + version: values, + } + }) + setFilterOpen(true) + }} + /> + }, + renderFormItem: (schema, config) => { - return + return } }, { 'title': t(`${i18nPrefix}.columns.state`, 'State'), 'dataIndex': 'state', + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + state: values, + } + }) + setFilterOpen(true) + }} + /> + }, + renderFormItem: (schema, config) => { - return + return } }, { @@ -348,6 +586,7 @@ const Video = () => { onHeaderCell: () => ({ width: 200, }), + hideInSearch: true, }, { @@ -377,7 +616,14 @@ const Video = () => { ] } ] as ProColumns[] - }, [ isDeleting, category, isCategoryFetching, categories, isCateLoading ]) + }, [ isDeleting, category, isCategoryFetching, categories, isCateLoading, category, currentVideo, search, openFilter ]) + + useEffect(() => { + + setSearchKey(search?.title) + filterForm.setFieldsValue(search) + + }, [ search ]) useEffect(() => { if (isSuccess) { @@ -386,7 +632,7 @@ const Video = () => { }, [ isSuccess ]) return ( - + { key: value })) }, + onChange: (e) => { + setSearchKey(e.target?.value) + }, + value: searchKey, allowClear: true, placeholder: t(`${i18nPrefix}.placeholder`, '输入视频名称') }, actions: [ + + + + + + + ) + }, + + }} + onValuesChange={(values) => { + if (values.category_id) { + setCategoryId(values.category_id) + } + }} + + onFinish={async (values) => { + // console.log('values', values) + //处理,变成数组 + Object.keys(values).forEach(key => { + if (typeof values[key] === 'string' && values[key].includes(',')) { + values[key] = values[key].split(',') + } + }) + + setSearch(values) + + + }} + columns={columns.filter(item => !item.hideInSearch) as ProFormColumnsType[]}/> + ) } diff --git a/src/pages/cms/video/style.ts b/src/pages/cms/video/style.ts new file mode 100644 index 0000000..ba06f7f --- /dev/null +++ b/src/pages/cms/video/style.ts @@ -0,0 +1,26 @@ +import { createStyles } from '@/theme' + +export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any) => { + const prefix = `${prefixCls}-${token?.proPrefix}-video-local-list-page` + + const container = css` + .ant-table-cell{ + .ant-tag{ + padding-inline: 3px; + margin-inline-end: 3px; + } + } + .ant-table-empty { + .ant-table-body{ + height: calc(100vh - 350px) + } + } + .ant-pro-table-highlight{ + color: red; + } + ` + + return { + container: cx(prefix, props?.className, container), + } +}) \ No newline at end of file diff --git a/src/pages/cms/video_cloud/index.tsx b/src/pages/cms/video_cloud/index.tsx index c8605b6..604fd25 100644 --- a/src/pages/cms/video_cloud/index.tsx +++ b/src/pages/cms/video_cloud/index.tsx @@ -1,5 +1,5 @@ import { useTranslation } from '@/i18n.ts' -import { Button, Form, Image, Popconfirm } from 'antd' +import { Badge, Button, DatePicker, Divider, Form, Image, Popconfirm, Space, Tooltip } from 'antd' import { useAtom, useAtomValue } from 'jotai' import { useEffect, useMemo, useState } from 'react' import Switch from '@/components/switch' @@ -10,25 +10,41 @@ import { deleteVideoCloudAtom, saveOrUpdateVideoCloudAtom, videoCloudsAtom, - videoCloudSearchAtom + videoCloudSearchAtom, + videoCloudAtom, } from '@/store/cms/video_cloud.ts' +import TagValue from '@/components/tag-value/TagValue.tsx' +import dayjs from 'dayjs' +import TagPro from '@/components/tag-pro/TagPro.tsx' +import { useSetAtom } from 'jotai/index' +import { categoriesAtom, categoryByIdAtom, categoryIdAtom } from '@/store/cms/category.ts' import { videoTypes } from '@/store/cms/video.ts' - +import { useStyle} from './style' +import { getValueCount } from '@/utils' +import { FilterOutlined } from '@ant-design/icons' const i18nPrefix = 'cms.videoCloud' const VideoCloud = () => { - // const { styles } = useStyle() + const { styles, cx } = useStyle() const { t } = useTranslation() const [ form ] = Form.useForm() + const [ filterForm ] = Form.useForm() const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateVideoCloudAtom) const [ search, setSearch ] = useAtom(videoCloudSearchAtom) + const [ currentVideo, setVideo ] = useAtom(videoCloudAtom) const { data, isFetching, isLoading, refetch } = useAtomValue(videoCloudsAtom) const { mutate: deleteVideo, isPending: isDeleting } = useAtomValue(deleteVideoCloudAtom) + const setCategoryId = useSetAtom(categoryIdAtom) + const { data: categories, isLoading: isCateLoading } = useAtomValue(categoriesAtom) + const { data: category, isLoading: isCategoryFetching } = useAtomValue(categoryByIdAtom) const [ open, setOpen ] = useState(false) + const [ openFilter, setFilterOpen ] = useState(false) + const [ searchKey, setSearchKey ] = useState(search?.title) const columns = useMemo(() => { + return [ { title: 'ID', @@ -38,6 +54,15 @@ const VideoCloud = () => { formItemProps: { hidden: true } }, { + 'title': t(`${i18nPrefix}.columns.collect_id`, 'CollectId'), + 'dataIndex': 'collect_id', + hideInTable: true, + hideInSearch: true, + hideInSetting: true, + formItemProps: { hidden: true }, + }, + + { 'title': t(`${i18nPrefix}.columns.title`, 'Title'), 'dataIndex': 'title', onHeaderCell: () => { @@ -45,6 +70,15 @@ const VideoCloud = () => { width: 200, } }, + colProps: { + span: 12 + }, + render: (_text, record) => { + //高亮搜索关键字, 从search.title中获取 + const title = record.title?.replace?.(new RegExp(`(${search?.title})`, 'ig'), '$1') + + return + } }, { 'title': t(`${i18nPrefix}.columns.title_sub`, 'TitleSub'), @@ -54,25 +88,9 @@ const VideoCloud = () => { 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 }, + colProps: { + span: 12 + } }, { 'title': t(`${i18nPrefix}.columns.type_id`, 'TypeId'), @@ -81,24 +99,30 @@ const VideoCloud = () => { fieldProps: { options: videoTypes, }, + hideInForm: true, 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', + 'title': t(`${i18nPrefix}.columns.source_url`, 'SourceUrl'), + 'dataIndex': 'source_url', ellipsis: true, + copyable: true, onHeaderCell: () => { return { width: 200, } }, + hideInSearch: true, + }, + { + 'title': t(`${i18nPrefix}.columns.letter`, 'Letter'), + 'dataIndex': 'letter', + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.lock`, 'Lock'), @@ -107,6 +131,10 @@ const VideoCloud = () => { render: (_dom, record) => { return }, + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.copyright`, 'Copyright'), @@ -115,6 +143,10 @@ const VideoCloud = () => { render: (_dom, record) => { return }, + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.is_end`, 'IsEnd'), @@ -123,6 +155,10 @@ const VideoCloud = () => { render: (_dom, record) => { return }, + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.status`, 'Status'), @@ -131,116 +167,397 @@ const VideoCloud = () => { render: (_dom, record) => { return }, + colProps: { + span: 4 + } }, { - 'title': t(`${i18nPrefix}.columns.category_id`, 'CategoryId'), - 'dataIndex': 'category_id', - + '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 + }, + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.pic`, 'Pic'), 'dataIndex': 'pic', render: (_dom, record) => { - return + return }, + colProps: { + span: 20 + }, + hideInSearch: true, }, { - 'title': t(`${i18nPrefix}.columns.pic_local`, 'PicLocal'), - 'dataIndex': 'pic_local', - hideInSearch: true, - hideInSetting: true, - formItemProps: { hidden: true }, - hideInTable: true, + 'title': t(`${i18nPrefix}.columns.category_id`, 'CategoryId'), + 'dataIndex': 'category_id', + valueType: 'select', + fieldProps: { + loading: isCategoryFetching, + options: categories?.rows ?? [], + fieldNames: { + label: 'name', + value: 'id' + } + }, + render: (_dom, record) => { + return item.id === record.category_id).map(item=>{ + return { + label: item.name, + value: item.id + } + }) ?? []} + wrap={currentVideo?.id === record.id} + value={search?.category_id ?? []} + onChange={(values) => { + setSearch((prev: any) => { + return { + ...prev, + category_id: values, + } + }) + setCategoryId(values[0]) + setFilterOpen(true) + }} + /> + }, }, { 'title': t(`${i18nPrefix}.columns.actor`, 'Actor'), 'dataIndex': 'actor', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + actor: values, + } + }) + setFilterOpen(true) + }} + /> }, }, { 'title': t(`${i18nPrefix}.columns.director`, 'Director'), 'dataIndex': 'director', - ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + director: values, + } + }) + setFilterOpen(true) + }} + /> + }, + }, { 'title': t(`${i18nPrefix}.columns.writer`, 'Writer'), 'dataIndex': 'writer', - ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + writer: values, + } + }) + setFilterOpen(true) + }} + /> + }, + }, { - 'title': t(`${i18nPrefix}.columns.pubdate`, 'Pubdate'), - 'dataIndex': 'pubdate', - valueType: 'dateTime' + 'title': t(`${i18nPrefix}.columns.remarks`, 'Remarks'), + 'dataIndex': 'remarks', + hideInSearch: true, }, + /* { + 'title': t(`${i18nPrefix}.columns.pubdate`, 'Pubdate'), + 'dataIndex': 'pubdate', + valueType: 'dateTime', + colProps: { + span: 4 + } + },*/ { 'title': t(`${i18nPrefix}.columns.total`, 'Total'), 'dataIndex': 'total', - valueType: 'digit' + valueType: 'digit', + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.serial`, 'Serial'), 'dataIndex': 'serial', + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.duration`, 'Duration'), 'dataIndex': 'duration', + colProps: { + span: 4 + }, + hideInSearch: true, + }, + { + 'title': t(`${i18nPrefix}.columns.year`, 'Year'), + 'dataIndex': 'year', + valueType: 'dateYear', + fieldProps:{ + style:{ + width: '100%' + } + }, + colProps: { + span: openFilter? 12: 4, + }, + render: (_dom, record) => { + if (record.year === undefined || record.year === null || record.year === 0) { + return null + } + + return { + setSearch((prev: any) => { + return { + ...prev, + year: values[0], + } + }) + setFilterOpen(true) + }} + /> + }, + renderFormItem: (_schema, config) => { + const props = { ...config } as any + delete props.mode + const isForm = config.type === 'form' + let value = isForm && config.value && config.value > 0 ? dayjs().set('year', config.value) : undefined + if (config.value?.$isDayjsObject) { + value = config.value as dayjs.Dayjs + } + return + } + }, { - 'title': t(`${i18nPrefix}.columns.class`, 'Class'), - 'dataIndex': 'class', + 'title': t(`${i18nPrefix}.columns.tag`, 'Tag'), + 'dataIndex': 'tag', + valueType: 'textarea', + ellipsis: true, + renderFormItem: (schema, config) => { + return + }, + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + tag: values, + } + }) + setFilterOpen(true) + }} + /> + }, + }, { 'title': t(`${i18nPrefix}.columns.area`, 'Area'), 'dataIndex': 'area', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + area: values, + } + }) + setFilterOpen(true) + }} + /> }, + + renderFormItem: (schema, config) => { + return + } }, { 'title': t(`${i18nPrefix}.columns.lang`, 'Lang'), 'dataIndex': 'lang', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + lang: values, + } + }) + setFilterOpen(true) + }} + /> }, + + renderFormItem: (schema, config) => { + return + } }, { 'title': t(`${i18nPrefix}.columns.version`, 'Version'), - 'dataIndex': 'version' - }, - { - 'title': t(`${i18nPrefix}.columns.year`, 'Year'), - 'dataIndex': 'year', - valueType: 'dateYear' + 'dataIndex': 'version', + + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + version: values, + } + }) + setFilterOpen(true) + }} + /> + }, + + renderFormItem: (schema, config) => { + return + } }, { 'title': t(`${i18nPrefix}.columns.state`, 'State'), - 'dataIndex': 'state' + 'dataIndex': 'state', + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + state: values, + } + }) + setFilterOpen(true) + }} + /> + }, + + renderFormItem: (schema, config) => { + return + } }, { 'title': t(`${i18nPrefix}.columns.douban_score`, 'DoubanScore'), - 'dataIndex': 'douban_score' + 'dataIndex': 'douban_score', + hideInSearch: true, + hideInSetting: true, + formItemProps: { hidden: true }, + hideInTable: true, }, { 'title': t(`${i18nPrefix}.columns.douban_id`, 'DoubanId'), @@ -252,7 +569,11 @@ const VideoCloud = () => { }, { 'title': t(`${i18nPrefix}.columns.imdb_score`, 'ImdbScore'), - 'dataIndex': 'imdb_score' + 'dataIndex': 'imdb_score', + hideInSearch: true, + hideInSetting: true, + formItemProps: { hidden: true }, + hideInTable: true, }, { 'title': t(`${i18nPrefix}.columns.imdb_id`, 'ImdbId'), @@ -270,6 +591,7 @@ const VideoCloud = () => { onHeaderCell: () => ({ width: 200, }), + hideInSearch: true, }, { @@ -281,6 +603,7 @@ const VideoCloud = () => { { + setCategoryId(record.category_id) form.setFieldsValue(record) setOpen(true) }}>{t('actions.edit')}, @@ -298,7 +621,14 @@ const VideoCloud = () => { ] } ] as ProColumns[] - }, [ isDeleting ]) + }, [ isDeleting, category, isCategoryFetching, categories, isCateLoading, category, currentVideo, search, openFilter ]) + + useEffect(() => { + + setSearchKey(search?.title) + filterForm.setFieldsValue(search) + + }, [ search ]) useEffect(() => { if (isSuccess) { @@ -307,7 +637,7 @@ const VideoCloud = () => { }, [ isSuccess ]) return ( - + { key: value })) }, + onChange: (e) => { + setSearchKey(e.target?.value) + }, + value: searchKey, allowClear: true, placeholder: t(`${i18nPrefix}.placeholder`, '输入云盘视频名称') }, actions: [ + + + ] }} + scroll={{ - x: 3500, + x: 3500, y: 'calc(100vh - 290px)' }} + onRow={(record) => { + return { + className: cx({ + 'ant-table-row-selected': currentVideo?.id === record.id + }), + onClick: () => { + setVideo(record) + } + } + }} + dateFormatter="string" loading={isLoading || isFetching} dataSource={data?.rows ?? []} columns={columns} @@ -364,14 +721,15 @@ const VideoCloud = () => { }} /> { }} columns={columns as ProFormColumnsType[]}/> + + { + setFilterOpen(open) + }} + layout={'vertical'} + scrollToFirstError={true} + layoutType={'DrawerForm'} + drawerProps={{ + maskClosable: false, + mask: false, + }} + submitter={{ + searchConfig: { + resetText: t(`${i18nPrefix}.filter.reset`, '清空'), + submitText: t(`${i18nPrefix}.filter.submit`, '查询'), + }, + onReset: () => { + filterForm.resetFields() + }, + render: (props,) => { + return ( +
+ + + + +
+ ) + }, + + }} + onValuesChange={(values) => { + if (values.category_id) { + setCategoryId(values.category_id) + } + }} + + onFinish={async (values) => { + // console.log('values', values) + //处理,变成数组 + Object.keys(values).forEach(key => { + if (typeof values[key] === 'string' && values[key].includes(',')) { + values[key] = values[key].split(',') + } + }) + + setSearch(values) + + + }} + columns={columns.filter(item => !item.hideInSearch) as ProFormColumnsType[]}/>
) } diff --git a/src/pages/cms/video_cloud/style.ts b/src/pages/cms/video_cloud/style.ts new file mode 100644 index 0000000..4d58985 --- /dev/null +++ b/src/pages/cms/video_cloud/style.ts @@ -0,0 +1,26 @@ +import { createStyles } from '@/theme' + +export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any) => { + const prefix = `${prefixCls}-${token?.proPrefix}-video-cloud-list-page` + + const container = css` + .ant-table-cell{ + .ant-tag{ + padding-inline: 3px; + margin-inline-end: 3px; + } + } + .ant-table-empty { + .ant-table-body{ + height: calc(100vh - 350px) + } + } + .ant-pro-table-highlight{ + color: red; + } + ` + + return { + container: cx(prefix, props?.className, container), + } +}) \ No newline at end of file diff --git a/src/pages/cms/video_magnet/index.tsx b/src/pages/cms/video_magnet/index.tsx index 342abce..42ed674 100644 --- a/src/pages/cms/video_magnet/index.tsx +++ b/src/pages/cms/video_magnet/index.tsx @@ -1,5 +1,5 @@ import { useTranslation } from '@/i18n.ts' -import { Button, Form, Popconfirm, Image } from 'antd' +import { Button, Form, Popconfirm, Image, Tooltip, Badge, Divider, DatePicker, Space } from 'antd' import { useAtom, useAtomValue } from 'jotai' import { useEffect, useMemo, useState } from 'react' import Switch from '@/components/switch' @@ -9,25 +9,42 @@ import ListPageLayout from '@/layout/ListPageLayout.tsx' import { videoTypes } from '@/store/cms/video.ts' import { deleteVideoMagnetAtom, - saveOrUpdateVideoMagnetAtom, + saveOrUpdateVideoMagnetAtom, videoMagnetAtom, videoMagnetsAtom, videoMagnetSearchAtom } from '@/store/cms/video_magnet.ts' +import { getValueCount } from '@/utils' +import { FilterOutlined } from '@ant-design/icons' +import { useSetAtom } from 'jotai/index' +import { categoriesAtom, categoryByIdAtom, categoryIdAtom } from '@/store/cms/category.ts' +import TagValue from '@/components/tag-value/TagValue.tsx' +import dayjs from 'dayjs' +import TagPro from '@/components/tag-pro/TagPro.tsx' +import { useStyle } from './style' const i18nPrefix = 'cms.videoMagnet' const VideoMagnet = () => { - // const { styles } = useStyle() + const { styles, cx } = useStyle() const { t } = useTranslation() const [ form ] = Form.useForm() + const [ filterForm ] = Form.useForm() const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateVideoMagnetAtom) const [ search, setSearch ] = useAtom(videoMagnetSearchAtom) + const [ currentVideo, setVideo ] = useAtom(videoMagnetAtom) + const { data, isFetching, isLoading, refetch } = useAtomValue(videoMagnetsAtom) const { mutate: deleteVideo, isPending: isDeleting } = useAtomValue(deleteVideoMagnetAtom) + const setCategoryId = useSetAtom(categoryIdAtom) + const { data: categories, isLoading: isCateLoading } = useAtomValue(categoriesAtom) + const { data: category, isLoading: isCategoryFetching } = useAtomValue(categoryByIdAtom) const [ open, setOpen ] = useState(false) + const [ openFilter, setFilterOpen ] = useState(false) + const [ searchKey, setSearchKey ] = useState(search?.title) const columns = useMemo(() => { + return [ { title: 'ID', @@ -37,6 +54,15 @@ const VideoMagnet = () => { formItemProps: { hidden: true } }, { + 'title': t(`${i18nPrefix}.columns.collect_id`, 'CollectId'), + 'dataIndex': 'collect_id', + hideInTable: true, + hideInSearch: true, + hideInSetting: true, + formItemProps: { hidden: true }, + }, + + { 'title': t(`${i18nPrefix}.columns.title`, 'Title'), 'dataIndex': 'title', onHeaderCell: () => { @@ -44,6 +70,15 @@ const VideoMagnet = () => { width: 200, } }, + colProps: { + span: 12 + }, + render: (_text, record) => { + //高亮搜索关键字, 从search.title中获取 + const title = record.title?.replace?.(new RegExp(`(${search?.title})`, 'ig'), '$1') + + return + } }, { 'title': t(`${i18nPrefix}.columns.title_sub`, 'TitleSub'), @@ -53,25 +88,9 @@ const VideoMagnet = () => { 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 }, + colProps: { + span: 12 + } }, { 'title': t(`${i18nPrefix}.columns.type_id`, 'TypeId'), @@ -80,24 +99,30 @@ const VideoMagnet = () => { fieldProps: { options: videoTypes, }, + hideInForm: true, 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', + 'title': t(`${i18nPrefix}.columns.source_url`, 'SourceUrl'), + 'dataIndex': 'source_url', ellipsis: true, + copyable: true, onHeaderCell: () => { return { width: 200, } }, + hideInSearch: true, + }, + { + 'title': t(`${i18nPrefix}.columns.letter`, 'Letter'), + 'dataIndex': 'letter', + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.lock`, 'Lock'), @@ -106,6 +131,10 @@ const VideoMagnet = () => { render: (_dom, record) => { return }, + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.copyright`, 'Copyright'), @@ -114,6 +143,10 @@ const VideoMagnet = () => { render: (_dom, record) => { return }, + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.is_end`, 'IsEnd'), @@ -122,6 +155,10 @@ const VideoMagnet = () => { render: (_dom, record) => { return }, + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.status`, 'Status'), @@ -130,12 +167,30 @@ const VideoMagnet = () => { render: (_dom, record) => { return }, + colProps: { + span: 4 + } }, { - 'title': t(`${i18nPrefix}.columns.category_id`, 'CategoryId'), - 'dataIndex': 'category_id', - + '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 + }, + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.pic`, 'Pic'), @@ -143,104 +198,366 @@ const VideoMagnet = () => { render: (_dom, record) => { return }, + colProps: { + span: 20 + }, + hideInSearch: true, }, { - 'title': t(`${i18nPrefix}.columns.pic_local`, 'PicLocal'), - 'dataIndex': 'pic_local', - hideInSearch: true, - hideInSetting: true, - formItemProps: { hidden: true }, - hideInTable: true, + 'title': t(`${i18nPrefix}.columns.category_id`, 'CategoryId'), + 'dataIndex': 'category_id', + valueType: 'select', + fieldProps: { + loading: isCategoryFetching, + options: categories?.rows ?? [], + fieldNames: { + label: 'name', + value: 'id' + } + }, + render: (_dom, record) => { + return item.id === record.category_id).map(item => { + return { + label: item.name, + value: item.id + } + }) ?? []} + wrap={currentVideo?.id === record.id} + value={search?.category_id ?? []} + onChange={(values) => { + setSearch((prev: any) => { + return { + ...prev, + category_id: values, + } + }) + setCategoryId(values[0]) + setFilterOpen(true) + }} + /> + }, }, { 'title': t(`${i18nPrefix}.columns.actor`, 'Actor'), 'dataIndex': 'actor', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + actor: values, + } + }) + setFilterOpen(true) + }} + /> }, - }, { 'title': t(`${i18nPrefix}.columns.director`, 'Director'), 'dataIndex': 'director', - ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + director: values, + } + }) + setFilterOpen(true) + }} + /> + }, + }, { 'title': t(`${i18nPrefix}.columns.writer`, 'Writer'), 'dataIndex': 'writer', - ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + writer: values, + } + }) + setFilterOpen(true) + }} + /> }, + }, { - 'title': t(`${i18nPrefix}.columns.pubdate`, 'Pubdate'), - 'dataIndex': 'pubdate', - valueType: 'dateTime' + 'title': t(`${i18nPrefix}.columns.remarks`, 'Remarks'), + 'dataIndex': 'remarks', + hideInSearch: true, }, + /* { + 'title': t(`${i18nPrefix}.columns.pubdate`, 'Pubdate'), + 'dataIndex': 'pubdate', + valueType: 'dateTime', + colProps: { + span: 4 + } + },*/ { 'title': t(`${i18nPrefix}.columns.total`, 'Total'), 'dataIndex': 'total', - valueType: 'digit' + valueType: 'digit', + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.serial`, 'Serial'), 'dataIndex': 'serial', + colProps: { + span: 4 + }, + hideInSearch: true, }, { 'title': t(`${i18nPrefix}.columns.duration`, 'Duration'), 'dataIndex': 'duration', + colProps: { + span: 4 + }, + hideInSearch: true, }, { - 'title': t(`${i18nPrefix}.columns.class`, 'Class'), - 'dataIndex': 'class', + 'title': t(`${i18nPrefix}.columns.year`, 'Year'), + 'dataIndex': 'year', + valueType: 'dateYear', + fieldProps: { + style: { + width: '100%' + } + }, + colProps: { + span: openFilter ? 12 : 4, + }, + render: (_dom, record) => { + if (record.year === undefined || record.year === null || record.year === 0) { + return null + } + + return { + setSearch((prev: any) => { + return { + ...prev, + year: values[0], + } + }) + setFilterOpen(true) + }} + /> + }, + renderFormItem: (_schema, config) => { + const props = { ...config } as any + delete props.mode + const isForm = config.type === 'form' + let value = isForm && config.value && config.value > 0 ? dayjs().set('year', config.value) : undefined + if (config.value?.$isDayjsObject) { + value = config.value as dayjs.Dayjs + } + return + } + + }, + { + 'title': t(`${i18nPrefix}.columns.tag`, 'Tag'), + 'dataIndex': 'tag', + valueType: 'textarea', + ellipsis: true, + renderFormItem: (schema, config) => { + return + }, + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + tag: values, + } + }) + setFilterOpen(true) + }} + /> + }, + }, { 'title': t(`${i18nPrefix}.columns.area`, 'Area'), 'dataIndex': 'area', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + area: values, + } + }) + setFilterOpen(true) + }} + /> }, + + renderFormItem: (schema, config) => { + return + } }, { 'title': t(`${i18nPrefix}.columns.lang`, 'Lang'), 'dataIndex': 'lang', ellipsis: true, - onHeaderCell: () => { - return { - width: 200, - } + width: 200, + fieldProps: { + style: { width: '100%' } }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + lang: values, + } + }) + setFilterOpen(true) + }} + /> + }, + + renderFormItem: (schema, config) => { + return + } }, { 'title': t(`${i18nPrefix}.columns.version`, 'Version'), - 'dataIndex': 'version' - }, - { - 'title': t(`${i18nPrefix}.columns.year`, 'Year'), - 'dataIndex': 'year', - valueType: 'dateYear' + 'dataIndex': 'version', + + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + version: values, + } + }) + setFilterOpen(true) + }} + /> + }, + + renderFormItem: (schema, config) => { + return + } }, { 'title': t(`${i18nPrefix}.columns.state`, 'State'), - 'dataIndex': 'state' + 'dataIndex': 'state', + width: 200, + fieldProps: { + style: { width: '100%' } + }, + render: (_dom, record) => { + return { + setSearch((prev: any) => { + return { + ...prev, + state: values, + } + }) + setFilterOpen(true) + }} + /> + }, + + renderFormItem: (schema, config) => { + return + } }, { 'title': t(`${i18nPrefix}.columns.douban_score`, 'DoubanScore'), - 'dataIndex': 'douban_score' + 'dataIndex': 'douban_score', + hideInSearch: true, + hideInSetting: true, + formItemProps: { hidden: true }, + hideInTable: true, }, { 'title': t(`${i18nPrefix}.columns.douban_id`, 'DoubanId'), @@ -252,7 +569,11 @@ const VideoMagnet = () => { }, { 'title': t(`${i18nPrefix}.columns.imdb_score`, 'ImdbScore'), - 'dataIndex': 'imdb_score' + 'dataIndex': 'imdb_score', + hideInSearch: true, + hideInSetting: true, + formItemProps: { hidden: true }, + hideInTable: true, }, { 'title': t(`${i18nPrefix}.columns.imdb_id`, 'ImdbId'), @@ -270,9 +591,9 @@ const VideoMagnet = () => { onHeaderCell: () => ({ width: 200, }), + hideInSearch: true, }, - { title: t(`${i18nPrefix}.columns.option`, '操作'), key: 'option', @@ -282,6 +603,7 @@ const VideoMagnet = () => { { + setCategoryId(record.category_id) form.setFieldsValue(record) setOpen(true) }}>{t('actions.edit')}, @@ -299,7 +621,14 @@ const VideoMagnet = () => { ] } ] as ProColumns[] - }, [ isDeleting ]) + }, [ isDeleting, category, isCategoryFetching, categories, isCateLoading, category, currentVideo, search, openFilter ]) + + useEffect(() => { + + setSearchKey(search?.title) + filterForm.setFieldsValue(search) + + }, [ search ]) useEffect(() => { if (isSuccess) { @@ -308,7 +637,7 @@ const VideoMagnet = () => { }, [ isSuccess ]) return ( - + { key: value })) }, + onChange: (e) => { + setSearchKey(e.target?.value) + }, + value: searchKey, allowClear: true, placeholder: t(`${i18nPrefix}.placeholder`, '输入磁链视频名称') }, actions: [ + + + + + + + ) + }, + + }} + onValuesChange={(values) => { + if (values.category_id) { + setCategoryId(values.category_id) + } + }} + + onFinish={async (values) => { + // console.log('values', values) + //处理,变成数组 + Object.keys(values).forEach(key => { + if (typeof values[key] === 'string' && values[key].includes(',')) { + values[key] = values[key].split(',') + } + }) + + setSearch(values) + + + }} + columns={columns.filter(item => !item.hideInSearch) as ProFormColumnsType[]}/> + ) } diff --git a/src/pages/cms/video_magnet/style.ts b/src/pages/cms/video_magnet/style.ts new file mode 100644 index 0000000..52f459a --- /dev/null +++ b/src/pages/cms/video_magnet/style.ts @@ -0,0 +1,26 @@ +import { createStyles } from '@/theme' + +export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any) => { + const prefix = `${prefixCls}-${token?.proPrefix}-video-magnet-list-page` + + const container = css` + .ant-table-cell{ + .ant-tag{ + padding-inline: 3px; + margin-inline-end: 3px; + } + } + .ant-table-empty { + .ant-table-body{ + height: calc(100vh - 350px) + } + } + .ant-pro-table-highlight{ + color: red; + } + ` + + return { + container: cx(prefix, props?.className, container), + } +}) \ No newline at end of file diff --git a/src/pages/videos/list/index.tsx b/src/pages/videos/list/index.tsx index 2f94be5..69d695e 100644 --- a/src/pages/videos/list/index.tsx +++ b/src/pages/videos/list/index.tsx @@ -126,7 +126,7 @@ const Video = () => { }, colProps: { span: 8 - } + }, }, // { // 'title': t(`${i18nPrefix}.columns.source_url`, 'SourceUrl'), @@ -451,6 +451,7 @@ const Video = () => { fieldProps: { style: { width: '100%' } }, + hideInSearch: true, }, // { // 'title': t(`${i18nPrefix}.columns.remarks`, 'Remarks'), diff --git a/src/store/cms/video.ts b/src/store/cms/video.ts index 50e30d1..0a49554 100644 --- a/src/store/cms/video.ts +++ b/src/store/cms/video.ts @@ -10,7 +10,7 @@ const i18nPrefix = 'cms.video' type SearchParams = IPage & { key?: string -} +} & Partial export const videoTypes = [ { label: t(`${i18nPrefix}.type_id.0`), value: 0 }, @@ -37,7 +37,17 @@ export const videosAtom = atomWithQuery((get) => { return { queryKey: [ 'videos', get(videoSearchAtom) ], queryFn: async ({ queryKey: [ , params ] }) => { - return await cmsServ.video.list(params as SearchParams) + //处理数组,转成,分隔的字符串 + const p = {} as SearchParams + Object.keys(params as any).forEach(key=>{ + const value =(params as any)[key] + if (Array.isArray(value)) { + p[key] = value.join(',') + } else { + p[key] = value + } + }) + return await cmsServ.video.list(p) }, select: res => { const data = res.data diff --git a/src/store/cms/video_cloud.ts b/src/store/cms/video_cloud.ts index 6d323eb..b1210c9 100644 --- a/src/store/cms/video_cloud.ts +++ b/src/store/cms/video_cloud.ts @@ -9,7 +9,7 @@ import cmsServ from '@/service/cms.ts' type SearchParams = IPage & { key?: string -} +} & Partial export const videoCloudIdAtom = atom(0) diff --git a/src/store/cms/video_magnet.ts b/src/store/cms/video_magnet.ts index 6d7fed3..e55e623 100644 --- a/src/store/cms/video_magnet.ts +++ b/src/store/cms/video_magnet.ts @@ -9,7 +9,7 @@ import cmsServ from '@/service/cms.ts' type SearchParams = IPage & { key?: string -} +} & Partial export const videoMagnetIdAtom = atom(0)