From 70a41eb715420aefab8a4fa151bcec95e5af87b3 Mon Sep 17 00:00:00 2001 From: dark Date: Sun, 12 May 2024 22:41:01 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E9=9B=86=E7=AB=99=E7=82=B9collect?= =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layout/ListPageLayout.tsx | 35 ++-- src/locales/lang/pages/cms/collect/zh-CN.ts | 36 ++++ src/locales/lang/zh-CN.ts | 4 + src/pages/cms/collect/index.tsx | 315 ++++++++++++++++++++++++++++ src/pages/cms/collect/style.ts | 13 ++ src/store/cms/collect.ts | 26 ++- 6 files changed, 409 insertions(+), 20 deletions(-) create mode 100644 src/locales/lang/pages/cms/collect/zh-CN.ts create mode 100644 src/pages/cms/collect/index.tsx create mode 100644 src/pages/cms/collect/style.ts diff --git a/src/layout/ListPageLayout.tsx b/src/layout/ListPageLayout.tsx index 291f839..58afe25 100644 --- a/src/layout/ListPageLayout.tsx +++ b/src/layout/ListPageLayout.tsx @@ -3,23 +3,32 @@ import { useStyle } from '@/layout/style.ts' import { PageContainer, PageContainerProps } from '@ant-design/pro-components' interface IListPageLayoutProps extends PageContainerProps { - children: React.ReactNode + children: React.ReactNode + authHeight?: boolean } -const ListPageLayout: React.FC = ({ children, ...props }) => { - const { styles } = useStyle({ className: 'two-col' }) +const ListPageLayout: React.FC = ( + { + children, authHeight = true, ...props + }) => { + const { styles, cx } = useStyle({ className: 'two-col' }) - return ( - <> - - {children} - - - ) + return ( + <> + +
+ {children} +
+
+ + ) } export default ListPageLayout diff --git a/src/locales/lang/pages/cms/collect/zh-CN.ts b/src/locales/lang/pages/cms/collect/zh-CN.ts new file mode 100644 index 0000000..5687e1c --- /dev/null +++ b/src/locales/lang/pages/cms/collect/zh-CN.ts @@ -0,0 +1,36 @@ +export default { + title: '采集站点管理', + description: '采集站点管理', + list: '采集列表', + add: '新增采集', + edit: '编辑采集', + delete: '删除采集', + detail: '采集详情', + type_id: [ + '在线观看', '磁链', '网盘' + ], + sync_pic: [ + '关闭', '开启', '全局' + ], + columns: { + name: '站点名称', + url: '采集地址', + param: '参数', + type_id: '类型', + opt: '操作', + filter: '过滤器', + filter_form: '过滤表单', + sync_pic: '同步图片', + icon_cdn: '图标CDN', + class: '分类', + weights: '权重', + status: '状态', + open_replace: '开启替换', + replace_str: '替换字符串', + site_auth: '搜片认证站点', + site_cooperation: '搜片合作优质站点', + categories_rules: '采集规则', + create_time: '创建时间', + update_time: '更新时间' + } +} \ No newline at end of file diff --git a/src/locales/lang/zh-CN.ts b/src/locales/lang/zh-CN.ts index 8f72057..a6b66ef 100644 --- a/src/locales/lang/zh-CN.ts +++ b/src/locales/lang/zh-CN.ts @@ -2,6 +2,7 @@ import antdZh from 'antd/locale/zh_CN' import menus from './pages/system/menus/zh-CN.ts' import roles from './pages/system/roles/zh-CN.ts' import status from './status/zh-CN.ts' +import collect from './pages/cms/collect/zh-CN.ts' export default { ...antdZh, @@ -46,6 +47,9 @@ export default { menus, roles }, + cms: { + collect, + }, actions: { news: '新增', add: '添加', diff --git a/src/pages/cms/collect/index.tsx b/src/pages/cms/collect/index.tsx new file mode 100644 index 0000000..9f2fdb8 --- /dev/null +++ b/src/pages/cms/collect/index.tsx @@ -0,0 +1,315 @@ +import { useEffect, useMemo, useState } from 'react' +import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components' +import { useTranslation } from '@/i18n.ts' +import { useAtom, useAtomValue } from 'jotai' +import { + collectsAtom, + deleteCollectAtom, + saveOrUpdateCollectAtom, + collectSearchAtom, + syncPicTypes, + types +} from '@/store/cms/collect.ts' +import { Button, Form, Popconfirm } from 'antd' +import ListPageLayout from '@/layout/ListPageLayout.tsx' +import Switch from '@/components/switch' +import Action from '@/components/action/Action.tsx' + +const i18nPrefix = 'cms.collect' + +const Collect = () => { + + // const { styles } = useStyle() + const { t } = useTranslation() + const [ form ] = Form.useForm() + const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateCollectAtom) + const [ search, setSearch ] = useAtom(collectSearchAtom) + const { data, isFetching, isLoading, refetch } = useAtomValue(collectsAtom) + const { mutate: deleteCollect, isPending: isDeleting } = useAtomValue(deleteCollectAtom) + const [ open, setOpen ] = useState(false) + + const columns = useMemo(() => { + return [ + { + title: 'ID', + dataIndex: 'id', + hideInTable: true, + hideInSearch: true, + formItemProps: { hidden: true } + }, + { + 'title': t(`${i18nPrefix}.columns.name`, '站点名称'), + 'dataIndex': 'name', + onHeaderCell: () => ({ + width: 200, + }), + ellipsis: true, + formItemProps: { + width: undefined, + rules: [ + { required: true, message: t(`${i18nPrefix}.columns.name`, '站点名称') } + ] + }, + + }, + { + 'title': t(`${i18nPrefix}.columns.icon_cdn`, '站点图标'), + 'dataIndex': 'icon_cdn', + onHeaderCell: () => ({ + width: 80, + }), + render: (_text, record) => { + return + }, + }, + { + 'title': t(`${i18nPrefix}.columns.url`, '站点URL'), + 'dataIndex': 'url', + onHeaderCell: () => ({ + width: 150, + }), + ellipsis: true, + copyable: true, + }, + { + 'title': t(`${i18nPrefix}.columns.param`, '参数'), + 'dataIndex': 'param', + hideInTable: true, + }, + { + 'title': t(`${i18nPrefix}.columns.type_id`, '类型'), + 'dataIndex': 'type_id', + valueType: 'select', + onHeaderCell: () => ({ + width: 100, + }), + render: (_text, record) => { + return t(`${i18nPrefix}.type_id.${record.type_id}`, '') + }, + fieldProps: { + options: types + } + }, + { + 'title': t(`${i18nPrefix}.columns.opt`, '操作方式'), + 'dataIndex': 'opt', + hideInTable: true, + }, + { + 'title': t(`${i18nPrefix}.columns.filter`, '过滤模式'), + 'dataIndex': 'filter', + hideInTable: true, + }, + { + 'title': t(`${i18nPrefix}.columns.filter_form`, '过滤表单'), + 'dataIndex': 'filter_form', + hideInTable: true, + }, + { + 'title': t(`${i18nPrefix}.columns.sync_pic`, '同步图片'), + 'dataIndex': 'sync_pic', + valueType: 'select', + onHeaderCell: () => ({ + width: 100, + }), + render: (_text, record) => { + return t(`${i18nPrefix}.sync_pic.${record.sync_pic}`, '') + }, + fieldProps: { + options: syncPicTypes + } + + }, + { + 'title': t(`${i18nPrefix}.columns.class`, '扩展分类'), + 'dataIndex': 'class', + valueType: 'textarea', + }, + { + 'title': t(`${i18nPrefix}.columns.weights`, '权重'), + 'dataIndex': 'weights', + valueType: 'digit', + onHeaderCell: () => ({ + width: 80, + }), + }, + { + 'title': t(`${i18nPrefix}.columns.status`, '启用'), + 'dataIndex': 'status', + valueType: 'switch', + onHeaderCell: () => ({ + width: 80, + }), + render: (_dom, record) => { + return + } + }, + { + 'title': t(`${i18nPrefix}.columns.open_replace`, '开启替换'), + 'dataIndex': 'open_replace', + valueType: 'switch', + onHeaderCell: () => ({ + width: 80, + }), + render: (_dom, record) => { + return + } + }, + { + 'title': t(`${i18nPrefix}.columns.replace_str`, '替换内容'), + 'dataIndex': 'replace_str', + valueType: 'textarea', + ellipsis: true, + }, + { + 'title': t(`${i18nPrefix}.columns.site_auth`, '搜片认证站点'), + 'dataIndex': 'site_auth', + valueType: 'switch', + onHeaderCell: () => ({ + width: 100, + }), + render: (_dom, record) => { + return + } + }, + { + 'title': t(`${i18nPrefix}.columns.site_cooperation`, '搜片合作优质站点'), + 'dataIndex': 'site_cooperation', + valueType: 'switch', + onHeaderCell: () => ({ + width: 130, + }), + render: (_dom, record) => { + return + } + }, + { + 'title': t(`${i18nPrefix}.columns.categories_rules`, '站点采集规则'), + 'dataIndex': 'categories_rules', + valueType: 'textarea', + onHeaderCell: () => ({ + width: 200, + }), + ellipsis: true, + }, + { + title: t(`${i18nPrefix}.columns.option`, '操作'), + key: 'option', + valueType: 'option', + fixed: 'right', + render: (_, record) => [ + { + form.setFieldsValue(record) + setOpen(true) + }}>{t('actions.edit')}, + { + deleteCollect([ record.id ]) + }} + title={t('message.deleteConfirm')}> + + {t('actions.delete', '删除')} + + + ] + } + ] as ProColumns[] + }, [ isDeleting ]) + + useEffect(() => { + if (isSuccess) { + setOpen(false) + } + }, [ isSuccess ]) + + return ( + + { + setSearch(prev => ({ + ...prev, + key: value + })) + }, + allowClear: true, + placeholder: t(`${i18nPrefix}.placeholder`, '输入站点名称') + }, + actions: [ + + ] + }} + scroll={{ + x: 2000, + }} + 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, + } + }) + }, + + }} + /> + { + setOpen(open) + }} + loading={isSubmitting} + onFinish={async (values) => { + // console.log('values', values) + saveOrUpdate(values) + + }} + columns={columns as ProFormColumnsType[]}/> + + ) +} + +export default Collect \ No newline at end of file diff --git a/src/pages/cms/collect/style.ts b/src/pages/cms/collect/style.ts new file mode 100644 index 0000000..bc9bfe5 --- /dev/null +++ b/src/pages/cms/collect/style.ts @@ -0,0 +1,13 @@ +import { createStyles } from '@/theme' + +export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any) => { + const prefix = `${prefixCls}-${token?.proPrefix}-cms-collect-page` + + const container = css` + + ` + + return { + container: cx(prefix, props?.className, container), + } +}) \ No newline at end of file diff --git a/src/store/cms/collect.ts b/src/store/cms/collect.ts index 17f3c16..51a246a 100644 --- a/src/store/cms/collect.ts +++ b/src/store/cms/collect.ts @@ -6,29 +6,41 @@ import { message } from 'antd' import { t } from 'i18next' import cmsServ from '@/service/cms.ts' - +const i18nPrefix = 'cms.collect' type SearchParams = IPage & { key?: string } -export const idAtom = atom(0) +export const types = [ + { label: t(`${i18nPrefix}.type_id.0`), value: 0 }, + { label: t(`${i18nPrefix}.type_id.1`), value: 1 }, + { label: t(`${i18nPrefix}.type_id.2`), value: 2 }, +] + +export const syncPicTypes = [ + { label: t(`${i18nPrefix}.sync_pic.0`), value: 0 }, + { label: t(`${i18nPrefix}.sync_pic.1`), value: 1 }, + { label: t(`${i18nPrefix}.sync_pic.2`), value: 2 }, +] + +export const collectIdAtom = atom(0) export const collectIdsAtom = atom([]) export const collectAtom = atom(undefined as unknown as Cms.ICollect) -export const searchAtom = atom({ +export const collectSearchAtom = atom({ key: '' } as SearchParams) -export const pageAtom = atom({ +export const collectPageAtom = atom({ pageSize: 10, page: 1, }) export const collectsAtom = atomWithQuery((get) => { return { - queryKey: [ 'collects', get(searchAtom) ], + queryKey: [ 'collects', get(collectSearchAtom) ], queryFn: async ({ queryKey: [ , params ] }) => { return await cmsServ.collect.list(params as SearchParams) }, @@ -63,7 +75,7 @@ export const saveOrUpdateCollectAtom = atomWithMutation { onSuccess: (res) => { message.success('message.deleteSuccess') //更新列表 - get(queryClientAtom).invalidateQueries({ queryKey: [ 'collects', get(searchAtom) ] }) + get(queryClientAtom).invalidateQueries({ queryKey: [ 'collects', get(collectSearchAtom) ] }) return res } }