dark
7 months ago
6 changed files with 409 additions and 20 deletions
-
35src/layout/ListPageLayout.tsx
-
36src/locales/lang/pages/cms/collect/zh-CN.ts
-
4src/locales/lang/zh-CN.ts
-
315src/pages/cms/collect/index.tsx
-
13src/pages/cms/collect/style.ts
-
26src/store/cms/collect.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: '更新时间' |
||||
|
} |
||||
|
} |
@ -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 <img src={record.icon_cdn} style={{ width: 20, height: 20 }}/> |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
'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 <Switch value={record.status} size={'small'}/> |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
'title': t(`${i18nPrefix}.columns.open_replace`, '开启替换'), |
||||
|
'dataIndex': 'open_replace', |
||||
|
valueType: 'switch', |
||||
|
onHeaderCell: () => ({ |
||||
|
width: 80, |
||||
|
}), |
||||
|
render: (_dom, record) => { |
||||
|
return <Switch value={record.open_replace} size={'small'}/> |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
'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 <Switch value={record.site_auth} size={'small'}/> |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
'title': t(`${i18nPrefix}.columns.site_cooperation`, '搜片合作优质站点'), |
||||
|
'dataIndex': 'site_cooperation', |
||||
|
valueType: 'switch', |
||||
|
onHeaderCell: () => ({ |
||||
|
width: 130, |
||||
|
}), |
||||
|
render: (_dom, record) => { |
||||
|
return <Switch value={record.site_cooperation} size={'small'}/> |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
'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) => [ |
||||
|
<Action key="edit" |
||||
|
as={'a'} |
||||
|
onClick={() => { |
||||
|
form.setFieldsValue(record) |
||||
|
setOpen(true) |
||||
|
}}>{t('actions.edit')}</Action>, |
||||
|
<Popconfirm |
||||
|
key={'del_confirm'} |
||||
|
disabled={isDeleting} |
||||
|
onConfirm={() => { |
||||
|
deleteCollect([ 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: 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, |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
}} |
||||
|
/> |
||||
|
<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 Collect |
@ -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), |
||||
|
} |
||||
|
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue