@wzyjs/components 0.2.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +42 -0
- package/src/BottomBar/index.tsx +28 -0
- package/src/CodeView/index.tsx +85 -0
- package/src/Collapse/index.tsx +26 -0
- package/src/Com2Canvas/index.tsx +60 -0
- package/src/CompileHtml/index.tsx +26 -0
- package/src/Crud/components/create.tsx +77 -0
- package/src/Crud/components/remove.tsx +33 -0
- package/src/Crud/components/update.tsx +75 -0
- package/src/Crud/index.tsx +144 -0
- package/src/Crud/powers/option.tsx +60 -0
- package/src/Crud/powers/validator.ts +73 -0
- package/src/Crud/types.ts +36 -0
- package/src/Crud/utils.ts +17 -0
- package/src/DateSwitcher/index.module.scss +10 -0
- package/src/DateSwitcher/index.tsx +75 -0
- package/src/DownloadLink/index.tsx +36 -0
- package/src/DragSort/index.tsx +77 -0
- package/src/FetchSelect/index.tsx +57 -0
- package/src/Fold/index.tsx +52 -0
- package/src/FormPro/index.tsx +28 -0
- package/src/HtmlPro/index.tsx +18 -0
- package/src/IframePro/index.tsx +52 -0
- package/src/JsonView/index.tsx +21 -0
- package/src/MultiImageDisplay/index.tsx +63 -0
- package/src/TablePro/index.tsx +66 -0
- package/src/Video/index.tsx +37 -0
- package/src/index.ts +17 -0
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wzyjs/components",
|
|
3
|
+
"version": "0.2.41",
|
|
4
|
+
"description": "description",
|
|
5
|
+
"author": "wzy",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"src"
|
|
9
|
+
],
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"ali-oss": "^6.21.0",
|
|
12
|
+
"echarts": "^5.4.3",
|
|
13
|
+
"echarts-for-react": "^3.0.2",
|
|
14
|
+
"handlebars": "^4.7.8",
|
|
15
|
+
"html2canvas": "^1.4.1",
|
|
16
|
+
"js-beautify": "^1.14.7",
|
|
17
|
+
"prettier": "^3.5.3",
|
|
18
|
+
"prismjs": "^1.29.0",
|
|
19
|
+
"react": "^19.0.0",
|
|
20
|
+
"react-beautiful-dnd": "^13.1.1",
|
|
21
|
+
"react-json-view": "^1.21.3",
|
|
22
|
+
"react-syntax-highlighter": "^15.5.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@wzyjs/antd": "^0.2.37",
|
|
26
|
+
"@wzyjs/hooks": "^0.2.37",
|
|
27
|
+
"@wzyjs/types": "^0.2.37",
|
|
28
|
+
"@wzyjs/utils": "^0.2.37"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/js-beautify": "^1.13.3",
|
|
32
|
+
"@types/prettier": "^2.7.2",
|
|
33
|
+
"@types/prismjs": "^1.26.0",
|
|
34
|
+
"@types/react": "^19.0.0",
|
|
35
|
+
"@types/react-beautiful-dnd": "^13.1.8",
|
|
36
|
+
"@types/react-syntax-highlighter": "^15.5.5"
|
|
37
|
+
},
|
|
38
|
+
"gitHead": "22795bdb9c670d3e37e9a6e83b544f916bab3c16",
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { ReactNode } from 'react'
|
|
4
|
+
|
|
5
|
+
interface BottomBarProps {
|
|
6
|
+
children?: ReactNode
|
|
7
|
+
collapsed?: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const style = {
|
|
11
|
+
display: 'flex',
|
|
12
|
+
justifyContent: 'center',
|
|
13
|
+
padding: 10,
|
|
14
|
+
right: 0,
|
|
15
|
+
bottom: 0,
|
|
16
|
+
boxShadow: '0 0 2px 0 rgba(0, 0, 0, 0.1)',
|
|
17
|
+
background: '#fff',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const BottomBar = (props: BottomBarProps) => {
|
|
21
|
+
const { children, collapsed } = props
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div style={{ ...style, left: collapsed ? 64 : 256, position: 'fixed' }}>
|
|
25
|
+
{children}
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { CSSProperties, useEffect, useMemo, useRef } from 'react'
|
|
4
|
+
|
|
5
|
+
import Prism from 'prismjs'
|
|
6
|
+
import { format } from 'prettier/standalone'
|
|
7
|
+
import parserBabel from 'prettier/parser-babel'
|
|
8
|
+
import parserTs from 'prettier/parser-typescript'
|
|
9
|
+
import { js_beautify, html_beautify, css_beautify } from 'js-beautify'
|
|
10
|
+
|
|
11
|
+
import 'prismjs/components/prism-jsx'
|
|
12
|
+
import 'prismjs/components/prism-tsx'
|
|
13
|
+
import 'prismjs/components/prism-json'
|
|
14
|
+
|
|
15
|
+
import 'prismjs/components/prism-javascript'
|
|
16
|
+
import 'prismjs/components/prism-typescript'
|
|
17
|
+
|
|
18
|
+
import 'prismjs/components/prism-css'
|
|
19
|
+
import 'prismjs/components/prism-less'
|
|
20
|
+
import 'prismjs/components/prism-sass'
|
|
21
|
+
import 'prismjs/components/prism-scss'
|
|
22
|
+
|
|
23
|
+
import 'prismjs/components/prism-bash'
|
|
24
|
+
import 'prismjs/components/prism-http'
|
|
25
|
+
import 'prismjs/components/prism-editorconfig'
|
|
26
|
+
import 'prismjs/components/prism-docker'
|
|
27
|
+
import 'prismjs/components/prism-git'
|
|
28
|
+
import 'prismjs/components/prism-ignore'
|
|
29
|
+
import 'prismjs/components/prism-yaml'
|
|
30
|
+
|
|
31
|
+
import 'prismjs/themes/prism.css'
|
|
32
|
+
|
|
33
|
+
interface CodeViewProps {
|
|
34
|
+
language?: 'html' | 'jsx' | 'tsx' | 'vue' | 'json' | 'javascript' | 'typescript' | 'css' | 'less' | 'sass' | 'scss' | 'bash' | 'http' | 'editorconfig' | 'dockerfile' | 'git' | 'ignore' | 'yaml'
|
|
35
|
+
code?: string,
|
|
36
|
+
children?: any,
|
|
37
|
+
style?: CSSProperties,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const CodeView = (props: CodeViewProps) => {
|
|
41
|
+
const { language = 'javascript', style, children, code = children } = props
|
|
42
|
+
|
|
43
|
+
const preRef = useRef(null)
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!preRef.current) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
Prism.highlightElement(preRef.current)
|
|
49
|
+
}, [])
|
|
50
|
+
|
|
51
|
+
const beautifydCode = useMemo(() => {
|
|
52
|
+
if (language === 'html') {
|
|
53
|
+
return html_beautify(code, { indent_size: 2 })
|
|
54
|
+
}
|
|
55
|
+
if (language === 'css') {
|
|
56
|
+
return css_beautify(code, { indent_size: 2 })
|
|
57
|
+
}
|
|
58
|
+
if (language === 'javascript') {
|
|
59
|
+
return js_beautify(code, { indent_size: 2 })
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
return format(code, {
|
|
64
|
+
semi: false,
|
|
65
|
+
parser: 'babel',
|
|
66
|
+
singleQuote: true,
|
|
67
|
+
tabWidth: 2,
|
|
68
|
+
jsxSingleQuote: true,
|
|
69
|
+
plugins: [parserBabel, parserTs],
|
|
70
|
+
})
|
|
71
|
+
} catch (e) {
|
|
72
|
+
return code
|
|
73
|
+
}
|
|
74
|
+
}, [code])
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div style={{ overflow: 'scroll', ...style }}>
|
|
78
|
+
<pre style={{ margin: 0, backgroundColor: 'transparent' }}>
|
|
79
|
+
<code ref={preRef} className={`language-${language}`}>
|
|
80
|
+
{beautifydCode}
|
|
81
|
+
</code>
|
|
82
|
+
</pre>
|
|
83
|
+
</div>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { ReactNode } from 'react'
|
|
4
|
+
import { useBoolean } from 'ahooks'
|
|
5
|
+
import { RightOutlined, LeftOutlined } from '@ant-design/icons'
|
|
6
|
+
|
|
7
|
+
interface CollapseProps {
|
|
8
|
+
children: ReactNode
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Collapse = (props: CollapseProps) => {
|
|
12
|
+
const { children } = props
|
|
13
|
+
|
|
14
|
+
const [collapse, { setTrue, setFalse }] = useBoolean(false)
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div>
|
|
18
|
+
<div style={{ transform: 'translateY(100px)' }}>
|
|
19
|
+
{collapse ? <LeftOutlined onClick={setFalse} /> : <RightOutlined onClick={setTrue} />}
|
|
20
|
+
</div>
|
|
21
|
+
<div style={{ width: collapse ? 0 : 'auto', visibility: collapse ? 'hidden' : 'visible' }}>
|
|
22
|
+
{children}
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useRef, ReactNode } from 'react'
|
|
4
|
+
import html2canvas from 'html2canvas'
|
|
5
|
+
import { useDebounceFn } from '@wzyjs/hooks'
|
|
6
|
+
import { getRandomColor } from '@wzyjs/utils'
|
|
7
|
+
|
|
8
|
+
interface Com2CanvasProps {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
downloadName?: string;
|
|
11
|
+
onChange: (url: string) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const Com2Canvas = (props: Com2CanvasProps) => {
|
|
15
|
+
const { children, downloadName, onChange } = props
|
|
16
|
+
|
|
17
|
+
const random = useRef(getRandomColor())
|
|
18
|
+
const htmlId = `h2c_html_${random.current}`
|
|
19
|
+
const canvasId = `htc_canvas_${random.current}`
|
|
20
|
+
|
|
21
|
+
const { run } = useDebounceFn(() => {
|
|
22
|
+
const el = document.querySelector(`#${canvasId}`) as HTMLElement
|
|
23
|
+
if (!el) {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
html2canvas(el, {
|
|
28
|
+
allowTaint: true, // 允许污染
|
|
29
|
+
useCORS: true, // 使用跨域(当allowTaint为true时这段代码没什么用)
|
|
30
|
+
scale: 2,
|
|
31
|
+
}).then((canvas: any) => {
|
|
32
|
+
el.innerHTML = ''
|
|
33
|
+
el.appendChild(canvas)
|
|
34
|
+
|
|
35
|
+
if (onChange) {
|
|
36
|
+
onChange(canvas.toDataURL('image/png'))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (downloadName) {
|
|
40
|
+
el.onclick = () => {
|
|
41
|
+
const a = document.createElement('a')
|
|
42
|
+
a.download = downloadName
|
|
43
|
+
a.href = canvas.toDataURL('image/png')
|
|
44
|
+
document.body.appendChild(a)
|
|
45
|
+
a.click()
|
|
46
|
+
a.remove()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
}, { wait: 500 })
|
|
51
|
+
|
|
52
|
+
useEffect(run, [children])
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<span style={{ position: 'relative' }}>
|
|
56
|
+
<span id={htmlId}>{children}</span>
|
|
57
|
+
<span id={canvasId} style={{ position: 'absolute', top: 0 }} />
|
|
58
|
+
</span>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { useMemo } from 'react'
|
|
4
|
+
import Handlebars from 'handlebars'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
template?: string
|
|
8
|
+
data: any
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default (props: Props) => {
|
|
12
|
+
const { template, data } = props
|
|
13
|
+
|
|
14
|
+
const html = useMemo(() => {
|
|
15
|
+
const html = Handlebars.compile(template || '')(data)
|
|
16
|
+
return html.replaceAll('\n', '').replaceAll('\t', '')
|
|
17
|
+
}, [template, data])
|
|
18
|
+
|
|
19
|
+
if (!html) {
|
|
20
|
+
return null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div dangerouslySetInnerHTML={{ __html: html }} />
|
|
25
|
+
)
|
|
26
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
|
|
5
|
+
import { Button } from 'antd'
|
|
6
|
+
import { FormPro } from '../../FormPro'
|
|
7
|
+
|
|
8
|
+
import { useUpdate } from '@wzyjs/hooks'
|
|
9
|
+
import { Apis, Column, ApiParams } from '../types'
|
|
10
|
+
|
|
11
|
+
interface CreateProps<I> {
|
|
12
|
+
name?: string,
|
|
13
|
+
columns: Column<I>[],
|
|
14
|
+
api: Apis<I>['create'],
|
|
15
|
+
title?: string,
|
|
16
|
+
layoutType?: 'ModalForm' | 'DrawerForm',
|
|
17
|
+
initialValues?: Partial<I>,
|
|
18
|
+
labelCol?: { span: number },
|
|
19
|
+
wrapperCol?: { span: number },
|
|
20
|
+
style?: React.CSSProperties,
|
|
21
|
+
convertValues?: (values: Partial<I>) => Partial<I>,
|
|
22
|
+
// 调用接口时的附加参数
|
|
23
|
+
apiParams?: ApiParams
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const Create = <I, >(props: CreateProps<I>) => {
|
|
27
|
+
const {
|
|
28
|
+
name = '',
|
|
29
|
+
style,
|
|
30
|
+
layoutType = 'ModalForm',
|
|
31
|
+
columns,
|
|
32
|
+
initialValues,
|
|
33
|
+
api,
|
|
34
|
+
title = '新建',
|
|
35
|
+
labelCol = { span: 4 },
|
|
36
|
+
wrapperCol = { span: 19 },
|
|
37
|
+
apiParams,
|
|
38
|
+
convertValues = values => values,
|
|
39
|
+
} = props
|
|
40
|
+
|
|
41
|
+
const update = useUpdate()
|
|
42
|
+
|
|
43
|
+
if (!api) {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<FormPro
|
|
49
|
+
style={style}
|
|
50
|
+
title={`${title}${name}`}
|
|
51
|
+
layout='horizontal'
|
|
52
|
+
layoutType={layoutType}
|
|
53
|
+
initialValues={initialValues as any}
|
|
54
|
+
labelCol={labelCol}
|
|
55
|
+
wrapperCol={wrapperCol}
|
|
56
|
+
{...({
|
|
57
|
+
ModalForm: {
|
|
58
|
+
modalProps: { destroyOnClose: true },
|
|
59
|
+
},
|
|
60
|
+
DrawerForm: {
|
|
61
|
+
drawerProps: { destroyOnClose: true },
|
|
62
|
+
},
|
|
63
|
+
})[layoutType]}
|
|
64
|
+
columns={columns.filter((column) => !column.hideInCreate) as any}
|
|
65
|
+
onFinish={async (formValues: Partial<I>) => {
|
|
66
|
+
if (!api) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
const { success } = await api(convertValues({ ...apiParams?.create, ...formValues }))
|
|
70
|
+
return success
|
|
71
|
+
}}
|
|
72
|
+
trigger={(
|
|
73
|
+
<Button onClick={() => setTimeout(update, 10)}>{title}</Button>
|
|
74
|
+
)}
|
|
75
|
+
/>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { ButtonPro } from '@wzyjs/antd'
|
|
5
|
+
import { Apis } from '../types'
|
|
6
|
+
|
|
7
|
+
interface RemoveProps<I> {
|
|
8
|
+
initialValues: I,
|
|
9
|
+
api: Apis<I>['remove'],
|
|
10
|
+
title?: string,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default <I extends { id: string }>(props: RemoveProps<I>) => {
|
|
14
|
+
const { api, initialValues, title = '删除' } = props
|
|
15
|
+
|
|
16
|
+
if (!api) {
|
|
17
|
+
return null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<ButtonPro.Confirm
|
|
22
|
+
title={`确认${title}?`}
|
|
23
|
+
btnProps={{
|
|
24
|
+
danger: true
|
|
25
|
+
}}
|
|
26
|
+
onConfirm={() => {
|
|
27
|
+
api(initialValues.id)
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
{title}
|
|
31
|
+
</ButtonPro.Confirm>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
|
|
5
|
+
import { Button } from 'antd'
|
|
6
|
+
import { FormPro } from '../../FormPro'
|
|
7
|
+
|
|
8
|
+
import { useUpdate } from '@wzyjs/hooks'
|
|
9
|
+
import { Apis, Column } from '../types'
|
|
10
|
+
|
|
11
|
+
interface UpdateProps<I> {
|
|
12
|
+
name?: string,
|
|
13
|
+
columns: Column<I>[],
|
|
14
|
+
initialValues: I,
|
|
15
|
+
api: Apis<I>['update'],
|
|
16
|
+
title?: string,
|
|
17
|
+
layoutType?: 'ModalForm' | 'DrawerForm',
|
|
18
|
+
labelCol?: { span: number },
|
|
19
|
+
wrapperCol?: { span: number },
|
|
20
|
+
style?: React.CSSProperties,
|
|
21
|
+
convertValues?: (values: Partial<I>) => Partial<I>,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default <I extends { id: string }>(props: UpdateProps<I>) => {
|
|
25
|
+
const {
|
|
26
|
+
name = '',
|
|
27
|
+
style,
|
|
28
|
+
layoutType = 'ModalForm',
|
|
29
|
+
columns,
|
|
30
|
+
initialValues,
|
|
31
|
+
api,
|
|
32
|
+
title = '编辑',
|
|
33
|
+
labelCol = { span: 4 },
|
|
34
|
+
wrapperCol = { span: 19 },
|
|
35
|
+
convertValues = values => values,
|
|
36
|
+
} = props
|
|
37
|
+
|
|
38
|
+
const update = useUpdate()
|
|
39
|
+
|
|
40
|
+
if (!api) {
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<FormPro
|
|
46
|
+
key={JSON.stringify(initialValues)}
|
|
47
|
+
style={style}
|
|
48
|
+
title={`${title}${name}`}
|
|
49
|
+
layout='horizontal'
|
|
50
|
+
layoutType={layoutType}
|
|
51
|
+
initialValues={initialValues}
|
|
52
|
+
labelCol={labelCol}
|
|
53
|
+
wrapperCol={wrapperCol}
|
|
54
|
+
{...({
|
|
55
|
+
ModalForm: {
|
|
56
|
+
modalProps: { destroyOnClose: true },
|
|
57
|
+
},
|
|
58
|
+
DrawerForm: {
|
|
59
|
+
drawerProps: { destroyOnClose: true },
|
|
60
|
+
},
|
|
61
|
+
})[layoutType]}
|
|
62
|
+
columns={columns.filter(column => !column.hideInUpdate) as any}
|
|
63
|
+
onFinish={async (formValues: Partial<I>) => {
|
|
64
|
+
if (!api) {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
const { success } = await api(initialValues.id, convertValues(formValues))
|
|
68
|
+
return success
|
|
69
|
+
}}
|
|
70
|
+
trigger={(
|
|
71
|
+
<Button type='link' onClick={() => setTimeout(update, 10)}>{title}</Button>
|
|
72
|
+
)}
|
|
73
|
+
/>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// 'use client'
|
|
2
|
+
//
|
|
3
|
+
// import React, { useRef, useImperativeHandle, useEffect } from 'react'
|
|
4
|
+
//
|
|
5
|
+
// import { Create } from './components/create'
|
|
6
|
+
// import { ActionType, TablePro, TableProProps } from '../TablePro'
|
|
7
|
+
//
|
|
8
|
+
// import { handleParams, dayjs } from '@wzyjs/utils'
|
|
9
|
+
// import { useRequestPro } from '@wzyjs/hooks'
|
|
10
|
+
// import { FilterParams, Pagination, SortParams } from '@wzyjs/types'
|
|
11
|
+
//
|
|
12
|
+
// import option from './powers/option'
|
|
13
|
+
// import validator from './powers/validator'
|
|
14
|
+
// import { handleColumns } from './utils'
|
|
15
|
+
// import { ApiParams, Apis, Column, Columns } from './types'
|
|
16
|
+
//
|
|
17
|
+
// export { getRequire, getRequireFormProps } from './utils'
|
|
18
|
+
//
|
|
19
|
+
// export * from './types'
|
|
20
|
+
//
|
|
21
|
+
// interface CrudProps<I> extends Omit<TableProProps<I, I>, 'columns'> {
|
|
22
|
+
// layoutType?: 'ModalForm' | 'DrawerForm',
|
|
23
|
+
// columns: Columns<I>,
|
|
24
|
+
// apis: Apis<I>,
|
|
25
|
+
// initialValues?: Partial<I>,
|
|
26
|
+
//
|
|
27
|
+
// // 获取到列表数据后传递给父组件
|
|
28
|
+
// onLoadData?: (data: I[]) => void,
|
|
29
|
+
// // 调用接口时的附加参数
|
|
30
|
+
// apiParams?: ApiParams
|
|
31
|
+
//
|
|
32
|
+
// // 转换列表数据
|
|
33
|
+
// convertData?: (values: I[]) => I[],
|
|
34
|
+
// // 处理创建或提交表单提交的数据
|
|
35
|
+
// convertValues?: (values: Partial<I>) => Partial<I>,
|
|
36
|
+
// }
|
|
37
|
+
//
|
|
38
|
+
// export const Crud = <I extends { id: string }>(props: CrudProps<I>) => {
|
|
39
|
+
// const {
|
|
40
|
+
// name = '',
|
|
41
|
+
// columns,
|
|
42
|
+
// apis,
|
|
43
|
+
// toolBarRender,
|
|
44
|
+
// initialValues,
|
|
45
|
+
// convertValues = values => values,
|
|
46
|
+
// convertData = data => data,
|
|
47
|
+
// onLoadData,
|
|
48
|
+
// apiParams,
|
|
49
|
+
// layoutType = 'ModalForm',
|
|
50
|
+
// } = props
|
|
51
|
+
//
|
|
52
|
+
// const actionRef = useRef<ActionType>()
|
|
53
|
+
//
|
|
54
|
+
// useImperativeHandle(props.actionRef, () => actionRef.current)
|
|
55
|
+
//
|
|
56
|
+
// const listState = useRequestPro(apis.list, {
|
|
57
|
+
// manual: true,
|
|
58
|
+
// })
|
|
59
|
+
// const createState = useRequestPro(apis.create, {
|
|
60
|
+
// manual: true,
|
|
61
|
+
// alertSuccessMessage: true,
|
|
62
|
+
// onSuccess: () => actionRef.current?.reload()
|
|
63
|
+
// })
|
|
64
|
+
// const updateState = useRequestPro(apis.update, {
|
|
65
|
+
// manual: true,
|
|
66
|
+
// alertSuccessMessage: true,
|
|
67
|
+
// onSuccess: () => actionRef.current?.reload()
|
|
68
|
+
// })
|
|
69
|
+
// const removeState = useRequestPro(apis.remove, {
|
|
70
|
+
// manual: true,
|
|
71
|
+
// alertSuccessMessage: true,
|
|
72
|
+
// onSuccess: () => actionRef.current?.reload()
|
|
73
|
+
// })
|
|
74
|
+
//
|
|
75
|
+
// const mvalidator = (columns: Column<I>[]) => validator({
|
|
76
|
+
// columns,
|
|
77
|
+
// findApi: apis.find,
|
|
78
|
+
// })
|
|
79
|
+
//
|
|
80
|
+
// const moption = (columns: Column<I>[]) => {
|
|
81
|
+
// columns.forEach(column => {
|
|
82
|
+
// if (column.valueType === 'dateTime') {
|
|
83
|
+
// column.render = (_, __) => {
|
|
84
|
+
// return dayjs(__?.[column.dataIndex]).format('YYYY-MM-DD HH:mm:ss')
|
|
85
|
+
// }
|
|
86
|
+
// }
|
|
87
|
+
// })
|
|
88
|
+
// return columns
|
|
89
|
+
// }
|
|
90
|
+
//
|
|
91
|
+
// const timeoption = (columns: Column<I>[]) => option({
|
|
92
|
+
// name,
|
|
93
|
+
// columns,
|
|
94
|
+
// layoutType,
|
|
95
|
+
// updateApi: apis.update && updateState?.runAsync,
|
|
96
|
+
// removeApi: apis.remove && removeState?.runAsync,
|
|
97
|
+
// mvalidator,
|
|
98
|
+
// convertValues,
|
|
99
|
+
// })
|
|
100
|
+
//
|
|
101
|
+
// const request = async (
|
|
102
|
+
// params: Pagination & I,
|
|
103
|
+
// sort: SortParams,
|
|
104
|
+
// filter: FilterParams,
|
|
105
|
+
// ) => {
|
|
106
|
+
// let { data = { data: [], total: 0 } } = await listState?.runAsync(
|
|
107
|
+
// handleParams(params, sort, filter, apiParams?.list),
|
|
108
|
+
// )
|
|
109
|
+
// onLoadData?.(data.data)
|
|
110
|
+
// return {
|
|
111
|
+
// data: convertData(data.data || []),
|
|
112
|
+
// total: data.total,
|
|
113
|
+
// }
|
|
114
|
+
// }
|
|
115
|
+
//
|
|
116
|
+
// useEffect(() => {
|
|
117
|
+
// actionRef.current?.reload()
|
|
118
|
+
// }, [JSON.stringify(apiParams?.list)])
|
|
119
|
+
//
|
|
120
|
+
// return (
|
|
121
|
+
// <TablePro
|
|
122
|
+
// {...props}
|
|
123
|
+
// headerTitle={`${name}列表`}
|
|
124
|
+
// actionRef={actionRef}
|
|
125
|
+
// request={request}
|
|
126
|
+
// columns={handleColumns(columns, { type: 'list', isList: true }, [moption, timeoption])}
|
|
127
|
+
// toolBarRender={(action, rows) => [
|
|
128
|
+
// ...(toolBarRender && toolBarRender?.(action, rows) || []),
|
|
129
|
+
// apis?.create && (
|
|
130
|
+
// <Create
|
|
131
|
+
// name={name}
|
|
132
|
+
// key='create'
|
|
133
|
+
// columns={handleColumns(columns, { type: 'create', isCreate: true }, [mvalidator])}
|
|
134
|
+
// layoutType={layoutType}
|
|
135
|
+
// apiParams={apiParams}
|
|
136
|
+
// api={createState?.runAsync}
|
|
137
|
+
// initialValues={initialValues}
|
|
138
|
+
// convertValues={convertValues}
|
|
139
|
+
// />
|
|
140
|
+
// ),
|
|
141
|
+
// ]}
|
|
142
|
+
// />
|
|
143
|
+
// )
|
|
144
|
+
// }
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { Space } from 'antd'
|
|
5
|
+
import Update from '../components/update'
|
|
6
|
+
import Remove from '../components/remove'
|
|
7
|
+
import { Apis, Column } from '../types'
|
|
8
|
+
import { handleColumns } from '../utils'
|
|
9
|
+
|
|
10
|
+
interface OptionProps<I> {
|
|
11
|
+
name?: string,
|
|
12
|
+
columns: Column<I>[],
|
|
13
|
+
layoutType?: 'ModalForm' | 'DrawerForm',
|
|
14
|
+
updateApi: Apis<I>['update'],
|
|
15
|
+
removeApi: Apis<I>['remove'],
|
|
16
|
+
mvalidator: (columns: Column<I>[]) => Column<I>[],
|
|
17
|
+
convertValues?: (values: Partial<I>) => Partial<I>,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default <I extends { id: string }>(props: OptionProps<I>): Column<I>[] => {
|
|
21
|
+
const { name, columns, convertValues, updateApi, removeApi, mvalidator, layoutType = 'ModalForm' } = props
|
|
22
|
+
|
|
23
|
+
// 编辑和删除按钮
|
|
24
|
+
const optionRender = {
|
|
25
|
+
title: '操作',
|
|
26
|
+
key: 'option',
|
|
27
|
+
render: (dom: React.ReactNode, record: I) => (
|
|
28
|
+
<Space key='option'>
|
|
29
|
+
{updateApi && (
|
|
30
|
+
<Update
|
|
31
|
+
name={name}
|
|
32
|
+
columns={handleColumns(columns, { type: 'update', isUpdate: true }, [mvalidator])}
|
|
33
|
+
layoutType={layoutType}
|
|
34
|
+
initialValues={record}
|
|
35
|
+
api={updateApi}
|
|
36
|
+
convertValues={convertValues}
|
|
37
|
+
/>
|
|
38
|
+
)}
|
|
39
|
+
{removeApi && (
|
|
40
|
+
<Remove
|
|
41
|
+
api={removeApi}
|
|
42
|
+
initialValues={record}
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
</Space>
|
|
46
|
+
),
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const last = columns[columns.length - 1]
|
|
50
|
+
if (last?.key === 'option') {
|
|
51
|
+
const originalRender = last.render
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
last.render = (dom: React.ReactNode, entity: I, index: number, action: any, schema: any) => [
|
|
54
|
+
(updateApi || removeApi) && optionRender.render(dom, entity),
|
|
55
|
+
originalRender?.(dom, entity, index, action, schema),
|
|
56
|
+
].flat()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return columns
|
|
60
|
+
}
|