| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- import { Button } from 'antd'
- import LeftMenu from './Components/LeftMenu'
- import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc'
- import { arrayMoveImmutable } from 'array-move'
- import type { ColumnsType } from 'antd/lib/table'
- import type { SortableContainerProps, SortEnd } from 'react-sortable-hoc'
- import { useRef, useState } from 'react'
- import { useRequest } from 'umi'
- import type { ProFormInstance } from '@ant-design/pro-form'
- import {
- addDataSource,
- addDataSourceItem,
- queryDataSource,
- updateDataSourceItem
- } from '@/services/api/schema'
- import { MenuOutlined, PlusOutlined } from '@ant-design/icons'
- import classNames from 'classnames'
- import { ModalForm, ProFormRadio, ProFormText } from '@ant-design/pro-form'
- import ProTable from '@ant-design/pro-table'
- import { ModalType } from '@/utils/enum'
- const DragHandle = SortableHandle(() => <MenuOutlined style={{ cursor: 'grab', color: '#999' }} />)
- const SortableItem = SortableElement((props: React.HTMLAttributes<HTMLTableRowElement>) => (
- <tr {...props} />
- ))
- const SortableBody = SortableContainer((props: React.HTMLAttributes<HTMLTableSectionElement>) => (
- <tbody {...props} />
- ))
- type iState = {
- menuData: API.DataSourceMenuItem[]
- activeID: Nullable<string>
- modalType: ModalType
- menuDataItems: API.DataSourceItem[]
- }
- const Option = () => {
- const formRef = useRef<ProFormInstance>(null)
- const [state, setState] = useState<iState>({
- menuData: [],
- activeID: null,
- modalType: ModalType.ADD,
- menuDataItems: []
- })
- const { run: tryFetchList } = useRequest(queryDataSource, {
- onSuccess: (result: API.DataSourceMenuItem) => {
- setState({ ...state, menuData: result })
- }
- })
- const { run: tryAddDataSourceItem } = useRequest(
- (params: API.LinkAccountParams) => addDataSourceItem(params),
- {
- manual: true,
- onSuccess: async () => {
- await tryFetchList()
- }
- }
- )
- const { run: tryUpdateItem } = useRequest(updateDataSourceItem, {
- manual: true,
- onSuccess: () => tryFetchList()
- })
- const columns: ColumnsType<API.DataSourceItem> = [
- {
- title: '排序',
- dataIndex: 'sort',
- width: 50,
- render: () => <DragHandle />
- },
- {
- title: '序号',
- dataIndex: 'num',
- width: 50,
- render: (num, record, index) => `${index + 1}`
- },
- {
- title: '选项名称',
- dataIndex: 'name'
- },
- {
- title: '状态',
- dataIndex: 'enable',
- render: text => (
- <div>
- <span
- className={classNames('w-4 h-4 rounded-1/2', text ? 'bg-green-500' : 'bg-red-500')}
- />
- <span className="ml-1">{text ? '已启用' : '已停用'}</span>
- </div>
- )
- },
- {
- title: '操作',
- dataIndex: 'opreate',
- render: (_, record) => (
- <Button
- type="text"
- onClick={() => {
- formRef.current?.setFieldsValue({ ...record })
- setState({ ...state, modalType: ModalType.UPDATE })
- }}>
- 编辑
- </Button>
- )
- }
- ]
- const onSortEnd = ({ oldIndex, newIndex }: SortEnd) => {
- if (oldIndex !== newIndex) {
- const newData = arrayMoveImmutable(dataSource.slice(), oldIndex, newIndex).filter(
- (el: DataType) => !!el
- )
- const newMenuData = menuData.map(item => {
- const newItem = { ...item }
- if (item.ID === state.activeID) {
- newItem.items = newData
- return newItem
- }
- return item
- })
- setState({ ...state, menuData: newMenuData })
- }
- }
- const DraggableContainer = (props: SortableContainerProps) => (
- <SortableBody
- useDragHandle
- disableAutoscroll
- helperClass="row-dragging"
- onSortEnd={onSortEnd}
- {...props}
- />
- )
- const DraggableBodyRow = ({ className, style, ...restProps }) => {
- const index = state.menuData
- .find(item => item.ID === state.activeID)
- ?.items.findIndex(x => x.index === restProps['data-row-key'])
- return <SortableItem index={index} {...restProps} />
- }
- return (
- <div className="flex flex-nowrap h-full">
- <LeftMenu
- onSelect={(key: string, node) =>
- setState({ ...state, activeID: key, menuDataItems: node.node.items })
- }
- showDelIcon={!state.menuDataItems.length}
- options={state.menuData}
- initFn={() => tryFetchList()}
- />
- <div className="ml-6 shadow-hex-3e2c5a" style={{ width: 'calc(100% - 12rem)' }}>
- <ProTable<API.DataSourceItem>
- columns={columns}
- search={false}
- dataSource={state.menuData.find(item => item.ID === state.activeID)?.items || []}
- rowKey="ID"
- toolbar={{
- actions: [
- <ModalForm
- labelCol={{ span: 6 }}
- key="form"
- width="30%"
- title="添加选项"
- formRef={formRef}
- layout="horizontal"
- onVisibleChange={visible => !visible && formRef.current?.resetFields()}
- initialValues={{ enable: true }}
- trigger={
- <Button size="small" type="primary" ghost>
- <PlusOutlined />
- 添加选项
- </Button>
- }
- onFinish={async values => {
- await tryAddDataSourceItem({
- ...values,
- dataSourceID: state.activeID
- })
- message.success('添加成功')
- return true
- }}>
- <ProFormText
- name="name"
- label="选项名称"
- rules={[{ required: true, message: '请输入选项名称' }]}
- />
- <ProFormRadio.Group
- name="enable"
- label="状态"
- options={[
- { label: '启用', value: true },
- { label: '停用', value: false }
- ]}
- rules={[{ required: true, message: '请选择启用/停用' }]}
- />
- </ModalForm>
- ]
- }}
- components={{
- body: {
- wrapper: DraggableContainer,
- row: DraggableBodyRow
- }
- }}
- />
- </div>
- </div>
- )
- }
- export default Option
|