index.tsx 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import React, { forwardRef, useEffect, useImperativeHandle } from "react"
  2. import { SearchOutlined, SyncOutlined } from "@ant-design/icons";
  3. import './global.less'
  4. import { Button, Card, Checkbox, DatePicker, Form, Input, Radio, Select, Space } from "antd";
  5. import { useEventListener } from "ahooks";
  6. import { observer, useLocalObservable } from "mobx-react";
  7. import globaStores from "@/store"
  8. // let DatePickers: any = DatePicker
  9. // const { RangePicker }: { RangePicker: any } = DatePickers;
  10. const {RangePicker} = DatePicker
  11. interface PublicConfig {
  12. name: string,
  13. label?: string,
  14. placeholder?: string,
  15. allowClear?: boolean
  16. }
  17. // 选择
  18. interface SelectConfig extends PublicConfig {
  19. type: 'select',
  20. data: {
  21. label: any,
  22. value: any
  23. }[],
  24. mode?: "multiple" | "tags" | undefined
  25. showSearch?: boolean
  26. }
  27. // 输入框
  28. interface InputConfig extends PublicConfig {
  29. type: 'input',
  30. }
  31. // 多选框
  32. interface CheckboxConfig {
  33. type: 'checkbox',
  34. name: string,
  35. label?: string,
  36. checkboxName?: string
  37. }
  38. // 单日期选择
  39. interface DatePickerConfig extends PublicConfig {
  40. type: "datePicker",
  41. disabledDate?: any // 禁用不可选择日期
  42. format?: string// 展示的日期格式
  43. picker?: 'date' | 'week' | 'month' | 'quarter' | 'year'
  44. }
  45. // 双日期选择
  46. interface RangePickerConfig {
  47. type: 'rangePicker',
  48. name: string,
  49. label?: string,
  50. allowClear?: boolean
  51. placeholder?: [string, string],
  52. disabledDate?: any // 禁用不可选择日期
  53. format?: string// 展示的日期格式
  54. }
  55. // 单选框选择
  56. interface RadioGroupConfig {
  57. type: 'radioGroup',
  58. name: string,
  59. isButton?: boolean,
  60. label?: string,
  61. data: {
  62. label: any,
  63. value: any,
  64. disabled?: boolean
  65. }[],
  66. buttonStyle?: 'outline' | 'solid'
  67. }
  68. export type ConfigProps = Array<SelectConfig | InputConfig | CheckboxConfig | RangePickerConfig | DatePickerConfig | RadioGroupConfig>
  69. interface Props {
  70. onChange?: (data?: any) => void // 返回字段
  71. children?: JSX.Element, // 按钮组件
  72. config?: ConfigProps, // 搜索配置
  73. initialValues?: any, // 默认值
  74. onData?: (data: any) => void
  75. }
  76. const TopRightBtn = forwardRef((props: Props, ref: any) => {
  77. const { onChange, children, config = [], initialValues = {}, onData } = props
  78. /** -----变量开始----- */
  79. const { globaStore } = useLocalObservable(() => ({ globaStore: globaStores }))
  80. const { data: { isFullscreen } } = globaStore
  81. const [form] = Form.useForm()
  82. const isParentClassify = Form.useWatch('isParentClassify', form);
  83. /** -----变量结束----- */
  84. //映射ref方法
  85. // useImperativeHandle(ref, () => ({ isParentClassify }))
  86. useEffect(() => {
  87. onData && onData({ isParentClassify })
  88. }, [isParentClassify])
  89. useEventListener('keydown', (ev: any) => {
  90. if (ev.code === 'NumpadEnter') {
  91. onSearch()
  92. }
  93. });
  94. // 点击搜索
  95. const onSearch = async () => {
  96. form.submit()
  97. let data = await form.validateFields()
  98. onChange && onChange(data)
  99. }
  100. // 重置
  101. const reset = () => {
  102. form.resetFields();
  103. onSearch()
  104. }
  105. return <>
  106. {!isFullscreen && <Card hoverable>
  107. <Form layout="inline" className='queryForm' name="basic" form={form} initialValues={initialValues}>
  108. {config?.map((item: SelectConfig | InputConfig | CheckboxConfig | RangePickerConfig | DatePickerConfig | RadioGroupConfig, index: number) => {
  109. switch (item.type) {
  110. case 'select':
  111. return <Form.Item label={item.label || ''} name={item.name} key={'select' + index}>
  112. <Select
  113. // open={true}
  114. maxTagCount={1}
  115. mode={item?.mode}
  116. showSearch
  117. style={{ minWidth: 150 }}
  118. allowClear={item?.allowClear || true}
  119. placeholder={item.placeholder || '请选择'}
  120. filterOption={(input, option) =>
  121. (option?.children as any)?.toLowerCase().indexOf(input.toLowerCase()) >= 0
  122. }
  123. >
  124. {item.data?.map((item1: { label: any, value: any }, ind: number) => <Select.Option value={item1.label} key={item1.value + item1.label + ind}>{item1.value}</Select.Option>)}
  125. </Select>
  126. </Form.Item>
  127. case 'checkbox':
  128. return <Form.Item label={item.label || ''} valuePropName="checked" name={item.name} key={'checkbox' + index}>
  129. <Checkbox>{item?.checkboxName}</Checkbox>
  130. </Form.Item>
  131. case 'input':
  132. return <Form.Item label={item.label || ''} name={item.name} key={'input' + index}>
  133. <Input placeholder={item.placeholder || '请输入'} allowClear={item?.allowClear || true} style={{ width: 150 }} />
  134. </Form.Item>
  135. case 'datePicker':
  136. return <Form.Item label={item.label || ''} name={item.name} key={'datePicker' + index}>
  137. <DatePicker placeholder={item?.placeholder} picker={item?.picker} format={item?.format} disabledDate={item?.disabledDate} allowClear={item?.allowClear || true} />
  138. </Form.Item>
  139. case 'rangePicker':
  140. return <Form.Item label={item.label || ''} name={item.name} key={'rangePicker' + index}>
  141. <RangePicker style={{ width: 225 }} placeholder={item?.placeholder} format={item?.format} disabledDate={item?.disabledDate} allowClear={item?.allowClear || true} />
  142. </Form.Item>
  143. case 'radioGroup':
  144. return <Form.Item label={item.label || ''} name={item.name} key={'radioGroup' + index}>
  145. <Radio.Group buttonStyle={item?.buttonStyle}>
  146. {item?.data?.map((item1: { label: any, value: any, disabled?: boolean }, ind: number) => {
  147. if (item?.isButton) {
  148. return <Radio.Button value={item1.label} disabled={item1?.disabled} key={item1.value + item1.label + ind}>{item1.value}</Radio.Button>
  149. } else {
  150. return <Radio value={item1.label} disabled={item1?.disabled} key={item1.value + item1.label + ind}>{item1.value}</Radio>
  151. }
  152. })}
  153. </Radio.Group>
  154. </Form.Item>
  155. default:
  156. return null
  157. }
  158. })}
  159. <Form.Item>
  160. <Space>
  161. <Button type="primary" icon={<SearchOutlined />} onClick={onSearch}>搜索</Button>
  162. <Button icon={<SyncOutlined />} onClick={reset}>重置</Button>
  163. </Space>
  164. </Form.Item>
  165. </Form>
  166. {children && <div className="topRightBtn" style={{ marginTop: 10 }}>
  167. <div>{children}</div>
  168. </div>}
  169. </Card>}
  170. </>
  171. })
  172. export default React.memo(observer(TopRightBtn))