import { useStyle } from './style.ts' import { Badge, Button, Divider, Form, Popconfirm, Space, Tooltip } from 'antd' import { useAtom, useAtomValue, useSetAtom } from 'jotai' import { ModelContext, useSpanModel } from '@/store/r-form/model.ts' import { ReactNode, useEffect, useState } from 'react' import { transformAntdTableProColumns } from './utils' import Action from '@/components/action/Action.tsx' import { FilterOutlined } from '@ant-design/icons' import ListPageLayout from '@/layout/ListPageLayout.tsx' import { Table as ProTable } from '@/components/table' import { getValueCount, unSetColumnRules } from '@/utils' import { BetaSchemaForm, ProColumns, ProFormColumnsType } from '@ant-design/pro-components' import { useApiContext } from '@/context.ts' import { useDeepCompareEffect } from 'react-use' import { RFormTypes } from '@/types/r-form/model' import { ProCoreActionType } from '@ant-design/pro-utils/es/typing' import { getI18nTitle } from '@/i18n.ts' export interface RFormProps { title?: ReactNode namespace?: string columns?: ProColumns[] //重写columns actions?: ReactNode[] | JSX.Element[] //左上角的操作按钮 toolbar?: ReactNode //工具栏 renderActions?: (addAction: ReactNode) => ReactNode //渲染操作按钮 resolveColumns?: (columns: ProColumns[]) => ProColumns[] //处理columns renderColumnOptions?: (record: any, defaultOptions: ReactNode[], index: number, action: ProCoreActionType | undefined) => ReactNode //渲染列的操作 } const RForm = ( { namespace, actions = [], toolbar, resolveColumns, renderActions, renderColumnOptions, columns: propColumns = [], title }: RFormProps) => { const { styles, cx } = useStyle() const apiCtx = useApiContext() const { apiAtom, deleteModelAtom, modelAtom, modelCURDAtom, modelsAtom, modelSearchAtom, saveOrUpdateModelAtom } = useSpanModel(namespace || apiCtx?.menu?.meta?.name || 'default') as ModelContext const [ form ] = Form.useForm() const [ filterForm ] = Form.useForm() const setApi = useSetAtom(apiAtom) const [ model, setModel ] = useAtom(modelAtom) const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateModelAtom) const [ search, setSearch ] = useAtom(modelSearchAtom) const { data, isFetching, isLoading, refetch } = useAtomValue(modelsAtom) const { mutate: deleteModel, isPending: isDeleting } = useAtomValue(deleteModelAtom) const { data: curdModal, isLoading: curdLoading, refetch: reloadCURDModal } = useAtomValue(modelCURDAtom) const [ open, setOpen ] = useState(false) const [ openFilter, setFilterOpen ] = useState(false) const [ searchKey, setSearchKey ] = useState(search?.key) const [ columns, setColumns ] = useState([]) useDeepCompareEffect(() => { let res = transformAntdTableProColumns(curdModal?.columns || [], propColumns, curdModal?.config?.i18n) if (resolveColumns) { res = resolveColumns(res) } const options = (record: any) => { return [ { form.setFieldsValue(record) setOpen(true) }}>{'编辑'}, { deleteModel([ record.id ]) }} title={'确定要删除吗?'}> 删除 ] } const _columns = [ { title: 'ID', dataIndex: 'id', hideInTable: true, hideInSearch: true, formItemProps: { hidden: true } } ].concat(res as any).concat([ { title: getI18nTitle(curdModal?.config?.i18n, { dataIndex: 'option', title: '操作' },), dataIndex: 'option', valueType: 'option', fixed: 'right', render: (_, record, index, action) => { if (renderColumnOptions) { return renderColumnOptions(record, options(record), index, action) } return options(record) } } as any ]) setColumns(_columns) }, [ curdModal?.columns, curdModal?.config?.i18n, propColumns, renderColumnOptions, resolveColumns, deleteModel, form, isDeleting, setOpen, ]) useEffect(() => { if (apiCtx.isApi && apiCtx.api) { setApi(apiCtx.api) reloadCURDModal() } }, [ apiCtx.isApi, apiCtx.api ]) useDeepCompareEffect(() => { setSearchKey(search?.key) filterForm.setFieldsValue(search) }, [ search ]) useEffect(() => { if (isSuccess) { setOpen(false) } }, [ isSuccess ]) const formProps = curdModal?.form.layoutType === 'DrawerForm' ? { layoutType: 'DrawerForm', drawerProps: { maskClosable: false, } } : { layoutType: 'ModalForm', modalProps: { maskClosable: false, } } const renderTitle = () => { if (title) { return title } if (apiCtx.menu) { const { menu } = apiCtx return menu.title } return null } const tableTitle = <> const _renderActions = () => { if (renderActions) { return renderActions(tableTitle) } return {[ tableTitle, ...actions ]} } return ( <> { setSearch(prev => ({ ...prev, title: value })) }, allowClear: true, onChange: (e) => { setSearchKey(e.target?.value) }, value: searchKey, placeholder: '输入关键字搜索', },*/ actions: [ ) }, }} onFinish={async (values: any) => { //处理,变成数组 Object.keys(values).forEach(key => { if (typeof values[key] === 'string' && values[key].includes(',')) { values[key] = values[key].split(',') } }) setSearch(values) }} columns={unSetColumnRules(columns.filter(item => !item.hideInSearch) as ProFormColumnsType[])}/> ) } export default RForm