Browse Source

兼容pnmp安装依赖,修复type类型问题

main
李金 3 months ago
parent
commit
c4a4b65874
  1. 5
      package.json
  2. 302
      src/components/draggable-panel/FloatMode.tsx
  3. 2
      src/components/r-form/index.tsx
  4. 2
      src/components/r-form/utils/index.tsx
  5. 111
      src/pages/x-form/hooks/useApi.tsx
  6. 146
      src/pages/x-form/utils/index.tsx
  7. 4358
      yarn.lock

5
package.json

@ -11,8 +11,11 @@
"preview": "vite preview"
},
"dependencies": {
"@ant-design/cssinjs": "^1.21.1",
"@ant-design/icons": "^5.3.6",
"@ant-design/pro-components": "^2.7.0",
"@ant-design/pro-layout": "^7.19.12",
"@ant-design/pro-provider": "^2.14.9",
"@formily/antd-v5": "^1.2.0",
"@formily/core": "^2.3.1",
"@formily/react": "^2.3.1",
@ -34,6 +37,7 @@
"jotai-devtools": "^0.9.1",
"jotai-scope": "^0.5.1",
"jotai-tanstack-query": "^0.8.5",
"lodash": "^4.17.21",
"re-resizable": "^6.9.11",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@ -43,6 +47,7 @@
"react-rnd": "^10.4.2-test2",
"react-use": "^17.5.0",
"throttle-debounce": "^5.0.0",
"use-merge-value": "^1.2.0",
"wonka": "^6.3.4"
},
"devDependencies": {

302
src/components/draggable-panel/FloatMode.tsx

@ -8,84 +8,84 @@ import { Rnd } from 'react-rnd'
import { useStyle } from './style'
export interface FloatProps {
/**
*
* 使
*/
mode?: 'fixed' | 'float';
/**
*
* 使
*/
mode?: 'fixed' | 'float';
/**
*
* @default horizontal
*/
direction?: 'vertical' | 'horizontal';
/**
*
* @default horizontal
*/
direction?: 'vertical' | 'horizontal';
/**
*
*/
minWidth?: number;
/**
*
*/
minHeight?: number;
/**
*
*/
maxWidth?: number;
/**
*
*/
maxHeight?: number;
/**
*
*/
resize?: RndProps['enableResizing'];
/**
*
*
*/
size?: Partial<Size>;
onSizeChange?: (delta: NumberSize, size?: Size) => void;
/**
*
* @param delta
* @param size
*/
onSizeDragging?: (delta: NumberSize, size?: Size) => void;
/**
*
*/
minWidth?: number;
/**
*
*/
minHeight?: number;
/**
*
*/
maxWidth?: number;
/**
*
*/
maxHeight?: number;
/**
*
*/
resize?: RndProps['enableResizing'];
/**
*
*
*/
size?: Partial<Size>;
onSizeChange?: (delta: NumberSize, size?: Size) => void;
/**
*
* @param delta
* @param size
*/
onSizeDragging?: (delta: NumberSize, size?: Size) => void;
canResizing?: boolean;
/**
*
*
*/
position?: RndProps['position'];
/**
*
* width 320px height 100%
* width 320px height 400px
*/
defaultSize?: Partial<Size>;
/**
*
* @default [100,100]
*/
defaultPosition?: RndProps['position'];
/**
*
*/
onPositionChange?: (position: RndProps['position']) => void;
/**
*
*/
style?: CSSProperties;
/**
*
*/
className?: string;
/**
*
*/
children: ReactNode;
canResizing?: boolean;
/**
*
*
*/
position?: RndProps['position'];
/**
*
* width 320px height 100%
* width 320px height 400px
*/
defaultSize?: Partial<Size>;
/**
*
* @default [100,100]
*/
defaultPosition?: RndProps['position'];
/**
*
*/
onPositionChange?: (position: RndProps['position']) => void;
/**
*
*/
style?: CSSProperties;
/**
*
*/
className?: string;
/**
*
*/
children: ReactNode;
}
const DEFAULT_HEIGHT = 300
@ -93,90 +93,90 @@ const DEFAULT_WIDTH = 400
export const FloatMode: FC<FloatProps> = memo(
({
children,
direction,
resize,
style,
position,
onPositionChange,
size,
defaultSize: customizeDefaultSize,
defaultPosition: customizeDefaultPosition,
minWidth = 280,
minHeight = 200,
maxHeight,
maxWidth,
canResizing,
children,
direction,
resize,
style,
position,
onPositionChange,
size,
defaultSize: customizeDefaultSize,
defaultPosition: customizeDefaultPosition,
minWidth = 280,
minHeight = 200,
maxHeight,
maxWidth,
canResizing,
}) => {
const { styles } = useStyle()
const { styles } = useStyle()
const resizeHandleClassNames: HandleClassName = useMemo(() => {
if (!canResizing) return {}
const resizeHandleClassNames: HandleClassName = useMemo(() => {
if (!canResizing) return {}
return {
right: styles.rightHandle,
left: styles.leftHandle,
top: styles.topHandle,
bottom: styles.bottomHandle,
}
}, [ canResizing, direction ])
const resizing = useMemo(() => {
if (canResizing) return resize
return {
right: styles.rightHandle,
left: styles.leftHandle,
top: styles.topHandle,
bottom: styles.bottomHandle,
}
}, [ canResizing, direction ])
return {
top: true,
bottom: true,
right: true,
left: true,
topRight: true,
bottomRight: true,
bottomLeft: true,
topLeft: true,
...(resize as Enable),
}
}, [ canResizing, resize ])
const resizing = useMemo(() => {
if (canResizing) return resize
const defaultSize: Size = {
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
...customizeDefaultSize,
return {
top: true,
bottom: true,
right: true,
left: true,
topRight: true,
bottomRight: true,
bottomLeft: true,
topLeft: true,
...(resize as Enable),
}
}, [ canResizing, resize ])
const defaultPosition: Position = {
x: 100,
y: 100,
...customizeDefaultPosition,
}
const defaultSize: Size = {
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
...customizeDefaultSize,
}
const sizeProps = {
minWidth: Math.max(minWidth, 0),
minHeight: Math.max(minHeight, 0),
maxHeight: maxHeight ? Math.max(maxHeight, 0) : undefined,
maxWidth: maxWidth ? Math.max(maxWidth, 0) : undefined,
defaultSize,
size: size as Size,
style,
}
const defaultPosition: Position = {
x: 100,
y: 100,
...customizeDefaultPosition,
}
const sizeProps = {
minWidth: Math.max(minWidth, 0),
minHeight: Math.max(minHeight, 0),
maxHeight: maxHeight ? Math.max(maxHeight, 0) : undefined,
maxWidth: maxWidth ? Math.max(maxWidth, 0) : undefined,
defaultSize,
size: size as Size,
style,
}
return (
<Rnd
position={position}
resizeHandleClasses={resizeHandleClassNames}
default={{
...defaultPosition,
...defaultSize,
}}
onDragStop={(_e, data) => {
onPositionChange?.({ x: data.x, y: data.y })
}}
bound={'parent'}
enableResizing={resizing}
{...sizeProps}
className={styles.float}
>
{children}
</Rnd>
)
return (
<Rnd
position={position}
resizeHandleClasses={resizeHandleClassNames}
default={{
...defaultPosition,
...defaultSize,
} as any}
onDragStop={(_e, data) => {
onPositionChange?.({ x: data.x, y: data.y })
}}
bound={'parent'}
enableResizing={resizing}
{...sizeProps as any}
className={styles.float}
>
{children}
</Rnd>
)
},
)

2
src/components/r-form/index.tsx

@ -301,7 +301,7 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
}}
onFinish={async (values) => {
onFinish={async (values: any) => {
//处理,变成数组
Object.keys(values).forEach(key => {
if (typeof values[key] === 'string' && values[key].includes(',')) {

2
src/components/r-form/utils/index.tsx

@ -49,7 +49,7 @@ export const transformAntdTableProColumns = (columns: ProColumns[], overwriteCol
const type = getValueType(item)
const overwrite = overwriteColumns?.find(i => i.dataIndex === item.dataIndex || item.name)
const overwrite = overwriteColumns?.find(i => i.dataIndex === item.dataIndex)
if (overwrite) {
overwriteKeys.push(item.dataIndex)
}

111
src/pages/x-form/hooks/useApi.tsx

@ -1,111 +0,0 @@
import { useNavigate, useRouterState } from '@tanstack/react-router'
import { useAtom } from 'jotai/index'
import { apiAtom } from '@/store/x-form/model.ts'
import { useCallback, useEffect, useRef, useState } from 'react'
import { Input, message, Modal } from 'antd'
import { Route } from '@/pages/x-form'
import { useApiContext } from '@/context.ts'
export const useApi = () => {
const { location } = useRouterState()
const apiCtx = useApiContext()
const nav = useNavigate()
const [ api, setApi ] = useAtom(apiAtom)
const { api: apiParam } = Route.useSearch()
const [ isChange, setChange ] = useState(false)
const [ innerApi, setInnerApi ] = useState('')
const [ open, setOpen ] = useState(false)
const apiRef = useRef<string>(apiParam)
useEffect(() => {
if (apiCtx.isApi && apiCtx.api) {
apiRef.current = apiCtx.api
setApi(apiCtx.api)
return
}
if (!apiParam && api) {
apiRef.current = api
nav({
to: location.pathname,
search: {
api
}
})
return
}
if (apiParam && !api) {
apiRef.current = apiParam
setApi(apiParam)
return
}
//延时弹出
setTimeout(() => {
if (!apiRef.current) {
setOpen(true)
}
}, 2000)
}, [ api, apiParam, apiCtx ])
const onOK = useCallback(() => {
if (!innerApi) {
message.destroy()
message.error('请填写 api 参数')
return
}
setChange(false)
setOpen(false)
setApi(innerApi)
setChange(true)
nav({
to: location.pathname,
search: {
api: innerApi
}
})
}, [ innerApi ])
const holderElement = (
<>
<Modal
title={'请指定 api 参数'}
closable={false}
open={open}
maskClosable={false}
afterOpenChange={setOpen}
onCancel={() => {
setOpen(false)
}}
onOk={() => {
onOK()
}}
>
<Input value={innerApi}
onKeyDown={e => {
if (e.key === 'Enter') {
onOK()
}
}}
onChange={e => {
setInnerApi(e.target.value)
}}/>
</Modal>
</>
)
return {
holderElement,
updateApi: setOpen,
setApi,
apiChange: isChange,
api,
apiCtx,
} as const
}

146
src/pages/x-form/utils/index.tsx

@ -1,146 +0,0 @@
import { XFormTypes } from '@/types/x-form/model'
import { ProColumns } from '@ant-design/pro-components'
import Switch from '@/components/switch'
import { Checkbox, DatePicker, Input, Radio, Select, TreeSelect } from 'antd'
import request from '@/request'
import { convertToBool, genProTableColumnWidthProps } from '@/utils'
import { ReactNode } from 'react'
const getValueType = (column: XFormTypes.IColumn) => {
switch (column.type) {
case 'input':
return 'text'
case 'select':
return 'select'
case 'date':
return 'date'
case 'switch':
return 'switch'
case 'radio':
return 'radio'
case 'checkbox':
return 'checkbox'
case 'textarea':
return 'textarea'
case 'tree':
return 'treeSelect'
default:
return 'text'
}
}
//根据type返回对应的组件
const getComponent = (column: XFormTypes.IColumn) => {
const type = getValueType(column) as any
switch (type) {
case 'input':
return Input
case 'select':
return Select
case 'date':
return DatePicker
case 'switch':
return Switch
case 'radio':
return Radio
case 'checkbox':
return Checkbox
case 'textarea':
return Input.TextArea
case 'tree':
case 'treeSelect':
return TreeSelect
default:
return Input
}
}
export const transformAntdTableProColumns = (columns: XFormTypes.IColumn[]) => {
return (columns || []).map(item => {
const { value, props, multiple, checkStrictly } = item
const { width, fieldProps: _fieldProps } = genProTableColumnWidthProps(item.width)
const fieldProps: ProColumns['fieldProps'] = {
dataFiledNames: props,
...(multiple ? { multiple: true } : {}),
...(checkStrictly ? { treeCheckStrictly: true } : {}),
..._fieldProps,
}
const formItemProps: ProColumns['formItemProps'] = (form, config) => {
return {
rules: item.rules?.map(i => {
return {
required: i.required,
message: i.message
}
}),
...(value ? { valuePropName: value } : {})
}
}
const rowProps = item.gutter ? { gutter: item.gutter } : { gutter: [ 16, 0 ], }
const colProps = item.span ? { span: item.span } : {}
const type = getValueType(item)
return {
title: item.label,
dataIndex: item.prop,
key: item.prop,
width,
valueType: type,
hideInSearch: !item.search,
hideInTable: item.hide,
fieldProps,
formItemProps,
colProps,
rowProps,
request: item.dicUrl ? async (params, props) => {
const { fieldProps: { dataFiledNames } } = props
const { value, res: resKey, label } = dataFiledNames || {}
const url = `/${item.dicUrl.replace(/^:/, '/')}`
return request[item.dicMethod || 'get'](url, params).then(res => {
return (res.data?.[resKey] || res.data || []).map((i: any) => {
// console.log(i)
const disabled = 'disabled' in i ? i.disabled :
('status' in i ? !convertToBool(i.status) : false)
return {
title: i[label || 'label'],
label: i[label || 'label'],
value: i[value || 'id'],
disabled,
data: i
}
})
})
} : undefined,
renderFormItem: (_scheam, config) => {
const Component = getComponent(item) as any
const { options, ...props } = config as any
if ([ 'tree', 'treeSelect' ].includes(_scheam.valueType as string)) {
return <Component {...props} treeData={options}/>
}
if (_scheam.valueType as string === 'select') {
return <Select {...props} options={options}/>
}
return <Component {...config} />
},
render: (text: any, record: any) => {
if (type === 'switch' || type === 'checkbox' || type === 'radio') {
return <Switch size={'small'} value={record[item.prop]}/>
}
if (item.colorFormat) {
return <span style={{ color: item.colorFormat }}>{text}</span>
}
return text
}
} as ProColumns
})
}

4358
yarn.lock
File diff suppressed because it is too large
View File

Loading…
Cancel
Save