Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-bi
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-bi
Commits
25767edf
提交
25767edf
authored
3月 25, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
b5a25e0b
隐藏空白字符变更
内嵌
并排
正在显示
42 个修改的文件
包含
867 行增加
和
505 行删除
+867
-505
AppProgressSteps.tsx
src/components/AppProgressSteps.tsx
+24
-2
DataRender.tsx
src/components/data/DataRender.tsx
+2
-2
FunctionInput.tsx
src/components/data/FunctionInput.tsx
+25
-0
SelectFieldButtonModal.tsx
src/components/data/SelectFieldButtonModal.tsx
+55
-0
DataLayout.tsx
src/components/layout/DataLayout.tsx
+2
-2
useQuery.ts
src/hooks/useQuery.ts
+1
-1
styles.scss
src/modules/data/dashboard/styles.scss
+1
-1
ButtonModal.tsx
src/modules/data/digging/linear/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
src/modules/data/digging/svm/components/ButtonModal.tsx
+4
-28
ButtonModal.tsx
src/modules/data/preprocess/error/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
src/modules/data/preprocess/max/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
src/modules/data/preprocess/min/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
src/modules/data/preprocess/null/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
...modules/data/preprocess/repeat/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
src/modules/data/preprocess/space/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
...modules/data/preprocess/splice/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
src/modules/data/preprocess/split/components/ButtonModal.tsx
+4
-28
ButtonModal.tsx
...modules/data/preprocess/symbol/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
src/modules/data/preprocess/type/components/ButtonModal.tsx
+3
-21
ButtonModal.tsx
src/modules/data/process/binning/components/ButtonModal.tsx
+4
-37
api.ts
src/modules/data/process/date/api.ts
+1
-1
ButtonModal.tsx
src/modules/data/process/date/components/ButtonModal.tsx
+69
-78
query.ts
src/modules/data/process/date/query.ts
+1
-1
types.ts
src/modules/data/process/date/types.ts
+1
-6
ButtonModal.tsx
...s/data/process/desensitization/components/ButtonModal.tsx
+4
-37
ButtonModal.tsx
src/modules/data/process/group/components/ButtonModal.tsx
+4
-28
api.ts
src/modules/data/process/logic/api.ts
+7
-0
ButtonModal.tsx
src/modules/data/process/logic/components/ButtonModal.tsx
+170
-0
query.ts
src/modules/data/process/logic/query.ts
+24
-0
types.ts
src/modules/data/process/logic/types.ts
+6
-0
Index.tsx
src/modules/data/process/logic/views/Index.tsx
+3
-2
ButtonModal.tsx
src/modules/data/process/mapping/components/ButtonModal.tsx
+4
-37
api.ts
src/modules/data/process/number/api.ts
+7
-0
ButtonModal.tsx
src/modules/data/process/number/components/ButtonModal.tsx
+170
-0
query.ts
src/modules/data/process/number/query.ts
+24
-0
types.ts
src/modules/data/process/number/types.ts
+6
-0
Index.tsx
src/modules/data/process/number/views/Index.tsx
+3
-2
api.ts
src/modules/data/process/string/api.ts
+7
-0
ButtonModal.tsx
src/modules/data/process/string/components/ButtonModal.tsx
+171
-0
query.ts
src/modules/data/process/string/query.ts
+24
-0
types.ts
src/modules/data/process/string/types.ts
+6
-0
Index.tsx
src/modules/data/process/string/views/Index.tsx
+3
-2
没有找到文件。
src/components/AppProgressSteps.tsx
浏览文件 @
25767edf
import
type
{
StepsProps
}
from
'antd'
import
{
Spin
,
Steps
}
from
'antd'
export
default
function
AppSteps
({
...
props
}:
StepsProps
)
{
function
stepToChinese
(
step
:
number
):
string
{
const
stepMap
=
[
'第一步'
,
'第二步'
,
'第三步'
,
'第四步'
,
'第五步'
,
'第六步'
]
return
stepMap
[
step
]
||
''
}
export
default
function
AppSteps
({
items
,
...
props
}:
StepsProps
)
{
const
customDot
=
(
dot
,
{
status
})
=>
{
const
statusMap
:
any
=
{
wait
:
'待处理'
,
...
...
@@ -16,5 +21,22 @@ export default function AppSteps({ ...props }: StepsProps) {
</>
)
}
return
<
Steps
className=
"app-process-steps"
progressDot=
{
customDot
}
labelPlacement=
"vertical"
{
...
props
}
></
Steps
>
return
(
<
Steps
className=
"app-process-steps"
progressDot=
{
customDot
}
labelPlacement=
"vertical"
{
...
props
}
>
{
items
?.
map
(({
title
,
...
item
},
index
)
=>
{
return
(
<
Steps
.
Step
key=
{
index
}
title=
{
<>
{
stepToChinese
(
index
)
}
<
br
/>
{
title
}
</>
}
{
...
item
}
></
Steps
.
Step
>
)
})
}
</
Steps
>
)
}
src/components/data/DataRender.tsx
浏览文件 @
25767edf
...
...
@@ -4,14 +4,14 @@ export default function DataRender({ pagination = {}, ...props }: TableProps) {
return
(
<
Table
bordered
scroll=
{
{
x
:
'max-content'
,
y
:
800
}
}
scroll=
{
{
x
:
'max-content'
}
}
tableLayout=
"auto"
size=
"middle"
pagination=
{
{
hideOnSinglePage
:
true
,
showSizeChanger
:
true
,
defaultPageSize
:
100
,
pageSizeOptions
:
[
100
,
200
,
500
],
pageSizeOptions
:
[
10
,
20
,
50
,
10
0
,
200
,
500
],
showTotal
:
(
total
:
number
)
=>
`共${total}条数据`
,
...
pagination
,
}
}
...
...
src/components/data/FunctionInput.tsx
0 → 100644
浏览文件 @
25767edf
import
{
Flex
,
Input
}
from
'antd'
import
SelectFieldButtonModal
from
'@/components/data/SelectFieldButtonModal'
export
default
function
FunctionInput
({
fieldType
,
...
props
}:
any
)
{
const
handleFieldSelect
=
(
fieldName
:
string
)
=>
{
const
value
=
(
props
.
value
||
''
)
as
string
let
updatedValue
=
''
if
(
value
.
endsWith
(
'()'
))
{
updatedValue
=
value
.
replace
(
'()'
,
`(
${
fieldName
}
)`
)
}
else
{
updatedValue
=
value
.
includes
(
'('
)
?
value
.
replace
(
')'
,
`,
${
fieldName
}
)`
)
:
`
${
value
}
,
${
fieldName
}
`
}
// 调用 props.onChange 通知父组件更新 value
props
.
onChange
?.(
updatedValue
)
}
return
(
<
Flex
gap=
{
10
}
align=
"center"
>
<
Input
.
TextArea
rows=
{
6
}
{
...
props
}
/>
<
SelectFieldButtonModal
onChange=
{
handleFieldSelect
}
fieldType=
{
fieldType
}
></
SelectFieldButtonModal
>
</
Flex
>
)
}
src/components/data/SelectFieldButtonModal.tsx
0 → 100644
浏览文件 @
25767edf
import
{
useState
}
from
'react'
import
{
Button
,
Flex
,
Modal
,
Select
}
from
'antd'
import
{
useDataFieldQuery
}
from
'@/hooks/useQuery'
export
default
function
SelectFieldButtonModal
({
fieldType
,
onChange
,
}:
{
fieldType
:
string
onChange
?:
(
value
:
string
)
=>
void
})
{
const
[
open
,
setOpen
]
=
useState
(
false
)
const
{
fieldOptions
}
=
useDataFieldQuery
()
const
[
value
,
setValue
]
=
useState
<
string
>
(
''
)
const
currentFieldOptions
=
fieldOptions
.
filter
((
option
)
=>
{
if
(
fieldType
===
'string'
)
return
option
.
type
.
includes
(
'VARCHAR'
)
if
(
fieldType
===
'number'
)
return
option
.
type
.
includes
(
'DECIMAL'
)
||
option
.
type
.
includes
(
'SMALLINT'
)
return
true
})
const
handleOk
=
()
=>
{
setOpen
(
false
)
if
(
value
&&
onChange
)
onChange
(
value
)
setValue
(
''
)
}
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
>
<
Button
type=
"primary"
onClick=
{
handleOk
}
>
确定
</
Button
>
</
Flex
>
)
}
return
(
<>
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
true
)
}
>
添加字段
</
Button
>
<
Modal
title=
"添加字段"
width=
{
400
}
open=
{
open
}
footer=
{
<
Footer
/>
}
onCancel=
{
()
=>
setOpen
(
false
)
}
>
<
div
style=
{
{
padding
:
'20px 0'
}
}
>
<
Select
placeholder=
"请选择字段"
options=
{
currentFieldOptions
}
value=
{
value
}
onChange=
{
setValue
}
style=
{
{
width
:
'100%'
}
}
></
Select
>
</
div
>
</
Modal
>
</>
)
}
src/components/layout/DataLayout.tsx
浏览文件 @
25767edf
...
...
@@ -80,7 +80,7 @@ const menus: MyMenuItem[] = [
{
name
:
'文本计算'
,
path
:
'/data/process/string'
},
{
name
:
'数值计算'
,
path
:
'/data/process/number'
},
{
name
:
'逻辑计算'
,
path
:
'/data/process/logic'
},
{
name
:
'数据透视'
,
path
:
'/data/process/perspective'
},
{
name
:
'数据透视'
,
path
:
'/data/process/perspective'
,
disabled
:
true
},
],
},
{
...
...
@@ -112,7 +112,7 @@ const menus: MyMenuItem[] = [
{
name
:
'散点图'
,
path
:
'/data/chart/point'
},
{
name
:
'气泡图'
,
path
:
'/data/chart/bubble'
},
{
name
:
'词云'
,
path
:
'/data/chart/wordCloud'
},
{
name
:
'地图'
,
path
:
'/data/chart/map'
},
{
name
:
'地图'
,
path
:
'/data/chart/map'
,
disabled
:
true
},
{
name
:
'指标卡'
,
path
:
'/data/chart/indicator'
},
{
name
:
'漏斗图'
,
path
:
'/data/chart/funnel'
},
{
name
:
'直方图'
,
path
:
'/data/chart/histogram'
},
...
...
src/hooks/useQuery.ts
浏览文件 @
25767edf
...
...
@@ -119,7 +119,7 @@ export function useProcessProgressQuery(params: { function_name: string }) {
},
select
:
(
res
)
=>
res
.
data
,
enabled
,
refetchInterval
:
enabled
?
1000
:
false
,
refetchInterval
:
enabled
?
1000
0
:
false
,
})
// 开始轮询的方法
...
...
src/modules/data/dashboard/styles.scss
浏览文件 @
25767edf
.dashboard
{
width
:
1240px
;
max-
width
:
1240px
;
margin
:
0
auto
;
}
.carousel-banner
{
...
...
src/modules/data/digging/linear/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -138,31 +138,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
启动
</>
),
title
:
<>
启动
</>,
},
{
title
:
(
<>
第二步
<
br
/>
计算
</>
),
title
:
<>
计算
</>,
},
{
title
:
(
<>
第三步
<
br
/>
计算结束
</>
),
title
:
<>
计算结束
</>,
},
]
}
/>
...
...
src/modules/data/digging/svm/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -66,40 +66,16 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
新建字段
</>
),
title
:
<>
新建字段
</>,
},
{
title
:
(
<>
第二步
<
br
/>
复制数据
</>
),
title
:
<>
复制数据
</>,
},
{
title
:
(
<>
第三步
<
br
/>
值映射处理
</>
),
title
:
<>
值映射处理
</>,
},
{
title
:
(
<>
第四步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
description
:
(
<>
累计处理XX个字段
...
...
src/modules/data/preprocess/error/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -94,31 +94,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
检查字段处理规则
</>
),
title
:
<>
检查字段处理规则
</>,
},
{
title
:
(
<>
第二步
<
br
/>
逻辑错误值处理
</>
),
title
:
<>
逻辑错误值处理
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
description
:
(
<>
累计处理XX个字段
...
...
src/modules/data/preprocess/max/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -94,31 +94,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
检查字段处理规则
</>
),
title
:
<>
检查字段处理规则
</>,
},
{
title
:
(
<>
第二步
<
br
/>
过大值处理
</>
),
title
:
<>
过大值处理
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
description
:
(
<>
累计处理XX个字段
...
...
src/modules/data/preprocess/min/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -94,31 +94,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
检查字段处理规则
</>
),
title
:
<>
检查字段处理规则
</>,
},
{
title
:
(
<>
第二步
<
br
/>
过小值处理
</>
),
title
:
<>
过小值处理
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
description
:
(
<>
累计处理XX个字段
...
...
src/modules/data/preprocess/null/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -156,31 +156,13 @@ export default function ButtonModal() {
current=
{
progress
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
检查字段处理规则
</>
),
title
:
<>
检查字段处理规则
</>,
},
{
title
:
(
<>
第二步
<
br
/>
缺失值处理
</>
),
title
:
<>
缺失值处理
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
description
:
<>
{
message
[
3
]
}
</>,
},
]
}
...
...
src/modules/data/preprocess/repeat/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -100,31 +100,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
检查字段处理规则
</>
),
title
:
<>
检查字段处理规则
</>,
},
{
title
:
(
<>
第二步
<
br
/>
重复值处理
</>
),
title
:
<>
重复值处理
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
description
:
(
<>
累计处理XX个字段
...
...
src/modules/data/preprocess/space/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -88,31 +88,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
检查字段处理规则
</>
),
title
:
<>
检查字段处理规则
</>,
},
{
title
:
(
<>
第二步
<
br
/>
数据去空格处理
</>
),
title
:
<>
数据去空格处理
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
description
:
(
<>
累计处理XX个字段
...
...
src/modules/data/preprocess/splice/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -178,31 +178,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
新增字段
</>
),
title
:
<>
新增字段
</>,
},
{
title
:
(
<>
第二步
<
br
/>
数据拼接
</>
),
title
:
<>
数据拼接
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
description
:
(
<>
累计处理
{
concatenatedFields
.
length
}
个字段
...
...
src/modules/data/preprocess/split/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -69,40 +69,16 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
计算拆分字段
</>
),
title
:
<>
计算拆分字段
</>,
},
{
title
:
(
<>
第二步
<
br
/>
数据库表增加拆分字段
</>
),
title
:
<>
数据库表增加拆分字段
</>,
},
{
title
:
(
<>
第三步
<
br
/>
更新拆分字段
</>
),
title
:
<>
更新拆分字段
</>,
},
{
title
:
(
<>
第四步
<
br
/>
更新原始字段
</>
),
title
:
<>
更新原始字段
</>,
},
{
title
:
(
...
...
src/modules/data/preprocess/symbol/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -61,31 +61,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
开始
</>
),
title
:
<>
开始
</>,
},
{
title
:
(
<>
第二步
<
br
/>
数据去标点处理
</>
),
title
:
<>
数据去标点处理
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
},
]
}
/>
...
...
src/modules/data/preprocess/type/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -84,31 +84,13 @@ export default function ButtonModal() {
current=
{
step
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
开始
</>
),
title
:
<>
开始
</>,
},
{
title
:
(
<>
第二步
<
br
/>
数据类型转换
</>
),
title
:
<>
数据类型转换
</>,
},
{
title
:
(
<>
第三步
<
br
/>
处理结果
</>
),
title
:
<>
处理结果
</>,
},
]
}
/>
...
...
src/modules/data/process/binning/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -181,43 +181,10 @@ export default function ButtonModal() {
style=
{
{
margin
:
'80px'
}
}
current=
{
progress
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
新建字段
</>
),
},
{
title
:
(
<>
第二步
<
br
/>
复制数据
</>
),
},
{
title
:
(
<>
第三步
<
br
/>
数据分箱处理
</>
),
},
{
title
:
(
<>
第四步
<
br
/>
处理结果
</>
),
description
:
<>
{
message
[
3
]
}
</>,
},
{
title
:
'新建字段'
},
{
title
:
'复制数据'
},
{
title
:
'数据分箱处理'
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>
},
]
}
/>
</
Flex
>
...
...
src/modules/data/process/date/api.ts
浏览文件 @
25767edf
...
...
@@ -3,5 +3,5 @@ import type { ProcessDataParams } from './types'
// 数据分箱
export
function
processData
(
data
:
ProcessDataParams
)
{
return
httpRequest
.
post
(
'/api/resource/bi/v1/processing/processing/
anonymization
'
,
data
)
return
httpRequest
.
post
(
'/api/resource/bi/v1/processing/processing/
date
'
,
data
)
}
src/modules/data/process/date/components/ButtonModal.tsx
浏览文件 @
25767edf
import
{
useState
}
from
'react'
import
{
Button
,
Flex
,
Modal
,
Radio
,
Input
,
Form
,
Row
,
Col
,
S
pace
,
S
elect
}
from
'antd'
import
{
Button
,
Flex
,
Modal
,
Radio
,
Input
,
Form
,
Row
,
Col
,
Select
}
from
'antd'
import
{
useDataFieldQuery
}
from
'@/hooks/useQuery'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
FunctionInput
from
'@/components/data/FunctionInput'
import
{
useProcessData
}
from
'../query'
const
functionShortcutOptions
=
[
...
...
@@ -84,7 +85,7 @@ const functionOptions = [
]
export
default
function
ButtonModal
()
{
const
{
fieldOptions
,
getFieldName
}
=
useDataFieldQuery
()
const
{
fieldOptions
}
=
useDataFieldQuery
()
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
current
,
setCurrent
]
=
useState
(
0
)
...
...
@@ -107,7 +108,15 @@ export default function ButtonModal() {
// 开始处理
const
handleStart
=
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
params
=
{
...
values
,
rules
:
JSON
.
stringify
(
values
.
rules
),
action
:
'固定步长分箱'
}
const
content
=
values
.
content
||
''
// 提取 content 中的参数
const
fieldsMatch
=
content
.
match
(
/
\((
.*
?)\)
/
)
// 匹配括号内的内容
const
fields
=
fieldsMatch
?
fieldsMatch
[
1
].
split
(
','
).
map
((
field
:
string
)
=>
field
.
trim
())
:
[]
if
(
action
===
'快速日期计算'
)
{
fields
.
push
(
values
.
field
)
}
const
params
=
{
...
values
,
fields
:
JSON
.
stringify
(
fields
)
}
// 将提取的参数赋值给 fields
mutate
(
params
,
{
onSuccess
:
handleClose
,
})
...
...
@@ -119,6 +128,10 @@ export default function ButtonModal() {
setCurrent
(
0
)
}
const
handleFunctionChange
=
(
value
:
string
)
=>
{
form
.
setFieldsValue
({
content
:
`
${
value
}
()`
})
}
// 步骤定义
const
steps
=
[
{
...
...
@@ -141,41 +154,48 @@ export default function ButtonModal() {
title
:
'配置日期计算规则'
,
content
:
(
<>
<
Form
.
Item
label=
"请选择日期计算方法"
name=
"action"
>
<
Form
.
Item
label=
"请选择日期计算方法"
name=
"action"
rules=
{
[{
required
:
true
,
message
:
'请选择方法'
}]
}
>
<
Radio
.
Group
options=
{
[
'快速日期计算'
,
'日期函数计算'
]
}
/>
</
Form
.
Item
>
{
action
===
'快速日期计算'
&&
(
<>
<
Form
.
Item
label=
"请选择快速日期计算方法"
name=
"function"
>
<
Form
.
Item
label=
"请选择快速日期计算方法"
name=
"function"
rules=
{
[{
required
:
true
,
message
:
'请选择方法'
}]
}
>
<
Radio
.
Group
style=
{
{
width
:
'100%'
}
}
>
{
functionShortcutOptions
.
map
((
item
)
=>
(
<
Flex
>
<
Radio
value=
{
item
.
value
}
>
<
Space
key=
{
item
.
value
}
>
<
p
style=
{
{
minWidth
:
200
}
}
>
{
item
.
label
}
</
p
>
<
p
style=
{
{
color
:
'#999'
}
}
>
{
item
.
demo
}
</
p
>
<
/
Space
>
</
Radio
>
</
Flex
>
<
Row
gutter=
{
[
10
,
10
]
}
key=
{
item
.
value
}
style=
{
{
marginBottom
:
10
}
}
>
<
Col
span=
{
12
}
>
<
Radio
value=
{
item
.
value
}
>
{
item
.
label
}
</
Radio
>
</
Col
>
<
Col
span=
{
12
}
>
<
p
style=
{
{
color
:
'#999'
}
}
>
{
item
.
demo
}
</
p
>
</
Col
>
</
Row
>
))
}
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
"请选择字段"
name=
"field"
rules=
{
[{
required
:
true
,
message
:
'请选择字段'
}]
}
>
<
Radio
.
Group
>
<
Row
gutter=
{
[
10
,
10
]
}
>
{
fieldOptions
.
map
((
item
)
=>
(
<
Col
span=
{
8
}
key=
{
item
.
value
}
>
<
Radio
value=
{
item
.
value
}
>
{
item
.
label
}
</
Radio
>
</
Col
>
))
}
</
Row
>
</
Radio
.
Group
>
</
Form
.
Item
>
</>
)
}
{
action
===
'日期函数计算'
&&
(
<>
<
Form
.
Item
label=
"请选择函数"
name=
"function"
>
<
Select
options=
{
functionOptions
}
/>
<
Form
.
Item
label=
"请选择函数"
name=
"function"
rules=
{
[{
required
:
true
,
message
:
'请选择函数'
}]
}
>
<
Select
options=
{
functionOptions
}
onChange=
{
handleFunctionChange
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"请输入函数公式"
>
<
Flex
gap=
{
10
}
>
<
Form
.
Item
name=
"content"
noStyle
>
<
Input
.
TextArea
rows=
{
4
}
/>
</
Form
.
Item
>
<
Button
type=
"primary"
style=
{
{
height
:
100
}
}
>
添加字段
</
Button
>
</
Flex
>
<
Form
.
Item
label=
"请输入函数公式"
name=
"content"
rules=
{
[{
required
:
true
,
message
:
'请输入函数公式'
}]
}
>
<
FunctionInput
/>
</
Form
.
Item
>
</>
)
}
...
...
@@ -194,43 +214,10 @@ export default function ButtonModal() {
style=
{
{
margin
:
'80px'
}
}
current=
{
progress
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
新建字段
</>
),
},
{
title
:
(
<>
第二步
<
br
/>
复制数据
</>
),
},
{
title
:
(
<>
第三步
<
br
/>
日期计算处理
</>
),
},
{
title
:
(
<>
第四步
<
br
/>
处理结果
</>
),
description
:
<>
{
message
[
3
]
}
</>,
},
{
title
:
'新建字段'
},
{
title
:
'复制数据'
},
{
title
:
'日期计算处理'
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>
},
]
}
/>
</
Flex
>
...
...
@@ -239,6 +226,25 @@ export default function ButtonModal() {
},
]
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
action
===
'日期函数计算'
&&
<
Button
type=
"primary"
>
AI智能建议
</
Button
>
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
下一步
</
Button
>
)
}
{
current
===
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleClose
}
disabled=
{
isPending
}
>
关闭
</
Button
>
)
}
</
Flex
>
)
}
return
(
<>
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
true
)
}
>
...
...
@@ -247,27 +253,12 @@ export default function ButtonModal() {
<
Modal
title=
{
steps
[
current
]?.
title
}
open=
{
open
}
footer=
{
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
action
===
'日期函数计算'
&&
<
Button
type=
"primary"
>
AI智能建议
</
Button
>
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
下一步
</
Button
>
)
}
{
current
===
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleClose
}
disabled=
{
isPending
}
>
关闭
</
Button
>
)
}
</
Flex
>
}
footer=
{
<
Footer
/>
}
destroyOnClose
width=
{
800
}
onCancel=
{
handleClose
}
>
<
div
style=
{
{
minHeight
:
300
,
padding
:
'20px 0'
}
}
>
<
Form
form=
{
form
}
labelCol=
{
{
span
:
5
}
}
preserve=
{
false
}
initialValues=
{
{
action
:
'快速日期计算'
}
}
>
<
Form
form=
{
form
}
labelCol=
{
{
span
:
6
}
}
preserve=
{
false
}
initialValues=
{
{
action
:
'快速日期计算'
}
}
>
{
steps
.
map
((
item
,
index
)
=>
(
<
div
key=
{
index
}
hidden=
{
current
!==
index
}
style=
{
{
marginTop
:
'20px'
}
}
>
{
item
.
content
}
...
...
src/modules/data/process/date/query.ts
浏览文件 @
25767edf
...
...
@@ -7,7 +7,7 @@ import { useProcessProgressQuery } from '@/hooks/useQuery'
// 处理数据
export
function
useProcessData
()
{
const
queryClient
=
useQueryClient
()
const
{
data
,
start
,
stop
}
=
useProcessProgressQuery
({
function_name
:
'
anonymization
'
})
const
{
data
,
start
,
stop
}
=
useProcessProgressQuery
({
function_name
:
'
date
'
})
const
query
=
useMutation
({
mutationFn
:
(
data
:
ProcessDataParams
)
=>
{
...
...
src/modules/data/process/date/types.ts
浏览文件 @
25767edf
export
interface
ProcessDataParams
{
name
:
string
english_name
:
string
field
:
string
action
:
string
function
:
string
char
?:
string
sm_fun
?:
string
start
?:
string
end
?:
string
fields
:
string
}
src/modules/data/process/desensitization/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -201,43 +201,10 @@ export default function ButtonModal() {
style=
{
{
margin
:
'80px'
}
}
current=
{
progress
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
新建字段
</>
),
},
{
title
:
(
<>
第二步
<
br
/>
复制数据
</>
),
},
{
title
:
(
<>
第三步
<
br
/>
数据脱敏处理
</>
),
},
{
title
:
(
<>
第四步
<
br
/>
处理结果
</>
),
description
:
<>
{
message
[
3
]
}
</>,
},
{
title
:
'新建字段'
},
{
title
:
'复制数据'
},
{
title
:
'数据脱敏处理'
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>
},
]
}
/>
</
Flex
>
...
...
src/modules/data/process/group/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -161,40 +161,16 @@ export default function ButtonModal() {
current=
{
progress
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
新建字段
</>
),
title
:
'新建字段'
,
},
{
title
:
(
<>
第二步
<
br
/>
复制数据
</>
),
title
:
'复制数据'
,
},
{
title
:
(
<>
第三步
<
br
/>
数据分组处理
</>
),
title
:
'数据分组处理'
,
},
{
title
:
(
<>
第四步
<
br
/>
处理结果
</>
),
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>,
},
]
}
...
...
src/modules/data/process/logic/api.ts
0 → 100644
浏览文件 @
25767edf
import
httpRequest
from
'@/utils/axios'
import
type
{
ProcessDataParams
}
from
'./types'
// 数据分箱
export
function
processData
(
data
:
ProcessDataParams
)
{
return
httpRequest
.
post
(
'/api/resource/bi/v1/processing/processing/logic'
,
data
)
}
src/modules/data/process/logic/components/ButtonModal.tsx
0 → 100644
浏览文件 @
25767edf
import
{
useState
}
from
'react'
import
{
Button
,
Flex
,
Modal
,
Input
,
Form
,
Select
}
from
'antd'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
FunctionInput
from
'@/components/data/FunctionInput'
import
{
useProcessData
}
from
'../query'
const
functionOptions
=
[
{
label
:
'ABS:返回数字的绝对值'
,
value
:
'ABS'
},
{
label
:
'AVERAGE:计算数值的平均值'
,
value
:
'AVERAGE'
},
{
label
:
'CEILING:将数值向上舍入到指定基数的倍数'
,
value
:
'CEILING'
},
{
label
:
'COUNT:统计包含数字的单元格数量'
,
value
:
'COUNT'
},
{
label
:
'COUNTIF:统计满足条件的单元格数量'
,
value
:
'COUNTIF'
},
{
label
:
'FLOOR:将数值向下舍入到指定基数的倍数'
,
value
:
'FLOOR'
},
{
label
:
'INT:将数值向下舍入到最接近的整数'
,
value
:
'INT'
},
{
label
:
'MAX:返回一组数值中的最大值'
,
value
:
'MAX'
},
{
label
:
'MIN:返回一组数值中的最小值'
,
value
:
'MIN'
},
{
label
:
'MOD:返回两数相除的余数'
,
value
:
'MOD'
},
{
label
:
'POWER:计算数值的指定次幂'
,
value
:
'POWER'
},
{
label
:
'PRODUCT:计算所有参数的乘积'
,
value
:
'PRODUCT'
},
{
label
:
'ROUND:将数值四舍五入到指定小数位数'
,
value
:
'ROUND'
},
{
label
:
'ROUNDUP:将数值向上舍入到指定小数位数'
,
value
:
'ROUNDUP'
},
{
label
:
'ROUNDDOWN:将数值向下舍入到指定小数位数'
,
value
:
'ROUNDDOWN'
},
{
label
:
'SQRT:返回数值的平方根'
,
value
:
'SQRT'
},
{
label
:
'SUM:计算所有数值的总和'
,
value
:
'SUM'
},
{
label
:
'SUMIF:对满足条件的单元格求和'
,
value
:
'SUMIF'
},
{
label
:
'SUMPRODUCT:计算多个数组的对应元素乘积之和'
,
value
:
'SUMPRODUCT'
},
{
label
:
'TRUNC:截断数值的小数部分(不四舍五入)'
,
value
:
'TRUNC'
},
]
export
default
function
ButtonModal
()
{
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
current
,
setCurrent
]
=
useState
(
0
)
const
[
form
]
=
Form
.
useForm
()
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
// 第一步验证表单
await
form
.
validateFields
([
'name'
,
'english_name'
])
}
else
if
(
current
===
1
)
{
await
form
.
validateFields
()
}
setCurrent
(
current
+
1
)
}
const
{
mutate
,
isPending
,
progress
,
message
}
=
useProcessData
()
// 开始处理
const
handleStart
=
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
content
=
values
.
content
||
''
// 提取 content 中的参数
const
fieldsMatch
=
content
.
match
(
/
\((
.*
?)\)
/
)
// 匹配括号内的内容
const
fields
=
fieldsMatch
?
fieldsMatch
[
1
].
split
(
','
).
map
((
field
:
string
)
=>
field
.
trim
())
:
[]
const
params
=
{
...
values
,
fields
:
JSON
.
stringify
(
fields
)
}
// 将提取的参数赋值给 fields
mutate
(
params
,
{
onSuccess
:
handleClose
,
})
}
// 关闭并重置
const
handleClose
=
()
=>
{
setOpen
(
false
)
setCurrent
(
0
)
}
const
handleFunctionChange
=
(
value
:
string
)
=>
{
form
.
setFieldsValue
({
content
:
`
${
value
}
()`
})
}
// 步骤定义
const
steps
=
[
{
title
:
'请选择逻辑计算字段'
,
content
:
(
<>
<
Form
.
Item
label=
"逻辑计算字段名称"
name=
"name"
rules=
{
[{
required
:
true
,
message
:
'请输入字段名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"逻辑计算字段英文名称"
name=
"english_name"
rules=
{
[{
required
:
true
,
message
:
'请输入英文名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
</>
),
},
{
title
:
'配置逻辑计算规则'
,
content
:
(
<>
<
Form
.
Item
label=
"请选择函数"
name=
"function"
rules=
{
[{
required
:
true
,
message
:
'请选择函数'
}]
}
>
<
Select
options=
{
functionOptions
}
onChange=
{
handleFunctionChange
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"请输入函数公式"
name=
"content"
rules=
{
[{
required
:
true
,
message
:
'请输入函数公式'
}]
}
>
<
FunctionInput
fieldType=
"string"
/>
</
Form
.
Item
>
</>
),
},
{
title
:
'处理执行'
,
content
:
(
<>
<
Flex
vertical
align=
"center"
style=
{
{
marginTop
:
'20px'
}
}
>
<
Button
type=
"primary"
onClick=
{
handleStart
}
loading=
{
isPending
}
>
开始处理
</
Button
>
<
AppProgressSteps
style=
{
{
margin
:
'80px'
}
}
current=
{
progress
}
items=
{
[
{
title
:
'新建字段'
},
{
title
:
'复制数据'
},
{
title
:
'逻辑计算处理'
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>
},
]
}
/>
</
Flex
>
</>
),
},
]
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI检查函数公式
</
Button
>
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
下一步
</
Button
>
)
}
{
current
===
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleClose
}
disabled=
{
isPending
}
>
关闭
</
Button
>
)
}
</
Flex
>
)
}
return
(
<>
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
true
)
}
>
逻辑计算
</
Button
>
<
Modal
title=
{
steps
[
current
]?.
title
}
open=
{
open
}
footer=
{
<
Footer
/>
}
destroyOnClose
width=
{
800
}
onCancel=
{
handleClose
}
>
<
div
style=
{
{
minHeight
:
300
,
padding
:
'20px 0'
}
}
>
<
Form
form=
{
form
}
labelCol=
{
{
span
:
6
}
}
preserve=
{
false
}
>
{
steps
.
map
((
item
,
index
)
=>
(
<
div
key=
{
index
}
hidden=
{
current
!==
index
}
style=
{
{
marginTop
:
'20px'
}
}
>
{
item
.
content
}
</
div
>
))
}
</
Form
>
</
div
>
</
Modal
>
</>
)
}
src/modules/data/process/logic/query.ts
0 → 100644
浏览文件 @
25767edf
import
{
useMutation
,
useQueryClient
}
from
'@tanstack/react-query'
import
{
message
}
from
'antd'
import
{
processData
}
from
'./api'
import
type
{
ProcessDataParams
}
from
'./types'
import
{
useProcessProgressQuery
}
from
'@/hooks/useQuery'
// 处理数据
export
function
useProcessData
()
{
const
queryClient
=
useQueryClient
()
const
{
data
,
start
,
stop
}
=
useProcessProgressQuery
({
function_name
:
'logic'
})
const
query
=
useMutation
({
mutationFn
:
(
data
:
ProcessDataParams
)
=>
{
start
()
return
processData
(
data
)
},
onSuccess
:
()
=>
{
stop
()
message
.
success
(
'处理完成'
)
queryClient
.
invalidateQueries
({
queryKey
:
[
'data'
]
})
},
})
return
{
...
query
,
progress
:
data
?.
progress
??
-
1
,
message
:
data
?.
message
??
{}
}
}
src/modules/data/process/logic/types.ts
0 → 100644
浏览文件 @
25767edf
export
interface
ProcessDataParams
{
name
:
string
english_name
:
string
function
:
string
fields
:
string
}
src/modules/data/process/logic/views/Index.tsx
浏览文件 @
25767edf
import
{
lazy
}
from
'react'
import
DataWrap
from
'@/components/data/DataWrap'
import
{
Button
}
from
'antd'
const
ButtonModal
=
lazy
(()
=>
import
(
'../components/ButtonModal'
))
export
default
function
DataProcess
()
{
return
<
DataWrap
title=
"数据加工:逻辑计算"
buttons=
{
<
Button
type=
"primary"
>
逻辑计算
</
Button
>
}
></
DataWrap
>
return
<
DataWrap
title=
"数据加工:逻辑计算"
buttons=
{
<
Button
Modal
/
>
}
></
DataWrap
>
}
src/modules/data/process/mapping/components/ButtonModal.tsx
浏览文件 @
25767edf
...
...
@@ -137,43 +137,10 @@ export default function ButtonModal() {
style=
{
{
margin
:
'80px'
}
}
current=
{
progress
}
items=
{
[
{
title
:
(
<>
第一步
<
br
/>
新建字段
</>
),
},
{
title
:
(
<>
第二步
<
br
/>
复制数据
</>
),
},
{
title
:
(
<>
第三步
<
br
/>
值映射处理
</>
),
},
{
title
:
(
<>
第四步
<
br
/>
处理结果
</>
),
description
:
<>
{
message
[
3
]
}
</>,
},
{
title
:
'新建字段'
},
{
title
:
'复制数据'
},
{
title
:
'值映射处理'
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>
},
]
}
/>
</
Flex
>
...
...
src/modules/data/process/number/api.ts
0 → 100644
浏览文件 @
25767edf
import
httpRequest
from
'@/utils/axios'
import
type
{
ProcessDataParams
}
from
'./types'
// 数据分箱
export
function
processData
(
data
:
ProcessDataParams
)
{
return
httpRequest
.
post
(
'/api/resource/bi/v1/processing/processing/numeric'
,
data
)
}
src/modules/data/process/number/components/ButtonModal.tsx
0 → 100644
浏览文件 @
25767edf
import
{
useState
}
from
'react'
import
{
Button
,
Flex
,
Modal
,
Input
,
Form
,
Select
}
from
'antd'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
FunctionInput
from
'@/components/data/FunctionInput'
import
{
useProcessData
}
from
'../query'
const
functionOptions
=
[
{
label
:
'ABS:返回数字的绝对值'
,
value
:
'ABS'
},
{
label
:
'AVERAGE:计算数值的平均值'
,
value
:
'AVERAGE'
},
{
label
:
'CEILING:将数值向上舍入到指定基数的倍数'
,
value
:
'CEILING'
},
{
label
:
'COUNT:统计包含数字的单元格数量'
,
value
:
'COUNT'
},
{
label
:
'COUNTIF:统计满足条件的单元格数量'
,
value
:
'COUNTIF'
},
{
label
:
'FLOOR:将数值向下舍入到指定基数的倍数'
,
value
:
'FLOOR'
},
{
label
:
'INT:将数值向下舍入到最接近的整数'
,
value
:
'INT'
},
{
label
:
'MAX:返回一组数值中的最大值'
,
value
:
'MAX'
},
{
label
:
'MIN:返回一组数值中的最小值'
,
value
:
'MIN'
},
{
label
:
'MOD:返回两数相除的余数'
,
value
:
'MOD'
},
{
label
:
'POWER:计算数值的指定次幂'
,
value
:
'POWER'
},
{
label
:
'PRODUCT:计算所有参数的乘积'
,
value
:
'PRODUCT'
},
{
label
:
'ROUND:将数值四舍五入到指定小数位数'
,
value
:
'ROUND'
},
{
label
:
'ROUNDUP:将数值向上舍入到指定小数位数'
,
value
:
'ROUNDUP'
},
{
label
:
'ROUNDDOWN:将数值向下舍入到指定小数位数'
,
value
:
'ROUNDDOWN'
},
{
label
:
'SQRT:返回数值的平方根'
,
value
:
'SQRT'
},
{
label
:
'SUM:计算所有数值的总和'
,
value
:
'SUM'
},
{
label
:
'SUMIF:对满足条件的单元格求和'
,
value
:
'SUMIF'
},
{
label
:
'SUMPRODUCT:计算多个数组的对应元素乘积之和'
,
value
:
'SUMPRODUCT'
},
{
label
:
'TRUNC:截断数值的小数部分(不四舍五入)'
,
value
:
'TRUNC'
},
]
export
default
function
ButtonModal
()
{
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
current
,
setCurrent
]
=
useState
(
0
)
const
[
form
]
=
Form
.
useForm
()
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
// 第一步验证表单
await
form
.
validateFields
([
'name'
,
'english_name'
])
}
else
if
(
current
===
1
)
{
await
form
.
validateFields
()
}
setCurrent
(
current
+
1
)
}
const
{
mutate
,
isPending
,
progress
,
message
}
=
useProcessData
()
// 开始处理
const
handleStart
=
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
content
=
values
.
content
||
''
// 提取 content 中的参数
const
fieldsMatch
=
content
.
match
(
/
\((
.*
?)\)
/
)
// 匹配括号内的内容
const
fields
=
fieldsMatch
?
fieldsMatch
[
1
].
split
(
','
).
map
((
field
:
string
)
=>
field
.
trim
())
:
[]
const
params
=
{
...
values
,
fields
:
JSON
.
stringify
(
fields
)
}
// 将提取的参数赋值给 fields
mutate
(
params
,
{
onSuccess
:
handleClose
,
})
}
// 关闭并重置
const
handleClose
=
()
=>
{
setOpen
(
false
)
setCurrent
(
0
)
}
const
handleFunctionChange
=
(
value
:
string
)
=>
{
form
.
setFieldsValue
({
content
:
`
${
value
}
()`
})
}
// 步骤定义
const
steps
=
[
{
title
:
'请选择数值计算字段'
,
content
:
(
<>
<
Form
.
Item
label=
"数值计算字段名称"
name=
"name"
rules=
{
[{
required
:
true
,
message
:
'请输入字段名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"数值计算字段英文名称"
name=
"english_name"
rules=
{
[{
required
:
true
,
message
:
'请输入英文名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
</>
),
},
{
title
:
'配置数值计算规则'
,
content
:
(
<>
<
Form
.
Item
label=
"请选择函数"
name=
"function"
rules=
{
[{
required
:
true
,
message
:
'请选择函数'
}]
}
>
<
Select
options=
{
functionOptions
}
onChange=
{
handleFunctionChange
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"请输入函数公式"
name=
"content"
rules=
{
[{
required
:
true
,
message
:
'请输入函数公式'
}]
}
>
<
FunctionInput
fieldType=
"string"
/>
</
Form
.
Item
>
</>
),
},
{
title
:
'处理执行'
,
content
:
(
<>
<
Flex
vertical
align=
"center"
style=
{
{
marginTop
:
'20px'
}
}
>
<
Button
type=
"primary"
onClick=
{
handleStart
}
loading=
{
isPending
}
>
开始处理
</
Button
>
<
AppProgressSteps
style=
{
{
margin
:
'80px'
}
}
current=
{
progress
}
items=
{
[
{
title
:
'新建字段'
},
{
title
:
'复制数据'
},
{
title
:
'数值计算处理'
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>
},
]
}
/>
</
Flex
>
</>
),
},
]
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI检查函数公式
</
Button
>
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
下一步
</
Button
>
)
}
{
current
===
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleClose
}
disabled=
{
isPending
}
>
关闭
</
Button
>
)
}
</
Flex
>
)
}
return
(
<>
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
true
)
}
>
数值计算
</
Button
>
<
Modal
title=
{
steps
[
current
]?.
title
}
open=
{
open
}
footer=
{
<
Footer
/>
}
destroyOnClose
width=
{
800
}
onCancel=
{
handleClose
}
>
<
div
style=
{
{
minHeight
:
300
,
padding
:
'20px 0'
}
}
>
<
Form
form=
{
form
}
labelCol=
{
{
span
:
6
}
}
preserve=
{
false
}
>
{
steps
.
map
((
item
,
index
)
=>
(
<
div
key=
{
index
}
hidden=
{
current
!==
index
}
style=
{
{
marginTop
:
'20px'
}
}
>
{
item
.
content
}
</
div
>
))
}
</
Form
>
</
div
>
</
Modal
>
</>
)
}
src/modules/data/process/number/query.ts
0 → 100644
浏览文件 @
25767edf
import
{
useMutation
,
useQueryClient
}
from
'@tanstack/react-query'
import
{
message
}
from
'antd'
import
{
processData
}
from
'./api'
import
type
{
ProcessDataParams
}
from
'./types'
import
{
useProcessProgressQuery
}
from
'@/hooks/useQuery'
// 处理数据
export
function
useProcessData
()
{
const
queryClient
=
useQueryClient
()
const
{
data
,
start
,
stop
}
=
useProcessProgressQuery
({
function_name
:
'numeric'
})
const
query
=
useMutation
({
mutationFn
:
(
data
:
ProcessDataParams
)
=>
{
start
()
return
processData
(
data
)
},
onSuccess
:
()
=>
{
stop
()
message
.
success
(
'处理完成'
)
queryClient
.
invalidateQueries
({
queryKey
:
[
'data'
]
})
},
})
return
{
...
query
,
progress
:
data
?.
progress
??
-
1
,
message
:
data
?.
message
??
{}
}
}
src/modules/data/process/number/types.ts
0 → 100644
浏览文件 @
25767edf
export
interface
ProcessDataParams
{
name
:
string
english_name
:
string
function
:
string
fields
:
string
}
src/modules/data/process/number/views/Index.tsx
浏览文件 @
25767edf
import
{
lazy
}
from
'react'
import
DataWrap
from
'@/components/data/DataWrap'
import
{
Button
}
from
'antd'
const
ButtonModal
=
lazy
(()
=>
import
(
'../components/ButtonModal'
))
export
default
function
DataProcess
()
{
return
<
DataWrap
title=
"数据加工:数值计算"
buttons=
{
<
Button
type=
"primary"
>
数值计算
</
Button
>
}
></
DataWrap
>
return
<
DataWrap
title=
"数据加工:数值计算"
buttons=
{
<
Button
Modal
/
>
}
></
DataWrap
>
}
src/modules/data/process/string/api.ts
0 → 100644
浏览文件 @
25767edf
import
httpRequest
from
'@/utils/axios'
import
type
{
ProcessDataParams
}
from
'./types'
// 数据分箱
export
function
processData
(
data
:
ProcessDataParams
)
{
return
httpRequest
.
post
(
'/api/resource/bi/v1/processing/processing/text'
,
data
)
}
src/modules/data/process/string/components/ButtonModal.tsx
0 → 100644
浏览文件 @
25767edf
import
{
useState
}
from
'react'
import
{
Button
,
Flex
,
Modal
,
Input
,
Form
,
Select
}
from
'antd'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
FunctionInput
from
'@/components/data/FunctionInput'
import
{
useProcessData
}
from
'../query'
const
functionOptions
=
[
{
label
:
'CHAR:返回 ASCII 码对应的字符'
,
value
:
'CHAR'
},
{
label
:
'CLEAN:删除文本中所有不可打印字符(如换行符、制表符)'
,
value
:
'CLEAN'
},
{
label
:
'CODE:返回文本中首个字符的 ASCII 码'
,
value
:
'CODE'
},
{
label
:
'CONCAT:合并多个文本'
,
value
:
'CONCAT'
},
{
label
:
'EXACT:严格比较两个文本是否完全相同(区分大小写)'
,
value
:
'EXACT'
},
{
label
:
'FIND:查找子文本在字符串中的位置(区分大小写)'
,
value
:
'FIND'
},
{
label
:
'LEFT:从文本左侧提取指定数量的字符'
,
value
:
'LEFT'
},
{
label
:
'LEN:返回文本的字符数(包括空格)'
,
value
:
'LEN'
},
{
label
:
'LOWER:将文本转换为全小写'
,
value
:
'LOWER'
},
{
label
:
'MID:从指定位置提取文本中的子字符串'
,
value
:
'MID'
},
{
label
:
'PROPER:将文本中每个单词的首字母大写'
,
value
:
'PROPER'
},
{
label
:
'REPLACE:替换文本中指定位置的字符'
,
value
:
'REPLACE'
},
{
label
:
'REPT:重复文本指定次数'
,
value
:
'REPT'
},
{
label
:
'RIGHT:从文本右侧提取指定数量的字符'
,
value
:
'RIGHT'
},
{
label
:
'SEARCH:查找子文本在字符串中的位置(不区分大小写)'
,
value
:
'SEARCH'
},
{
label
:
'SUBSTITUTE:替换文本中的特定子字符串'
,
value
:
'SUBSTITUTE'
},
{
label
:
'TEXT:将数值/日期按指定格式转换为文本'
,
value
:
'TEXT'
},
{
label
:
'TEXTJOIN:用分隔符合并多个文本,可忽略空值'
,
value
:
'TEXTJOIN'
},
{
label
:
'TRIM:删除文本中多余的空格(保留单词间单个空格)'
,
value
:
'TRIM'
},
{
label
:
'UPPER:将文本转换为全大写'
,
value
:
'UPPER'
},
{
label
:
'VALUE:将文本格式的数字转换为数值'
,
value
:
'VALUE'
},
]
export
default
function
ButtonModal
()
{
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
current
,
setCurrent
]
=
useState
(
0
)
const
[
form
]
=
Form
.
useForm
()
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
// 第一步验证表单
await
form
.
validateFields
([
'name'
,
'english_name'
])
}
else
if
(
current
===
1
)
{
await
form
.
validateFields
()
}
setCurrent
(
current
+
1
)
}
const
{
mutate
,
isPending
,
progress
,
message
}
=
useProcessData
()
// 开始处理
const
handleStart
=
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
content
=
values
.
content
||
''
// 提取 content 中的参数
const
fieldsMatch
=
content
.
match
(
/
\((
.*
?)\)
/
)
// 匹配括号内的内容
const
fields
=
fieldsMatch
?
fieldsMatch
[
1
].
split
(
','
).
map
((
field
:
string
)
=>
field
.
trim
())
:
[]
const
params
=
{
...
values
,
fields
:
JSON
.
stringify
(
fields
)
}
// 将提取的参数赋值给 fields
mutate
(
params
,
{
onSuccess
:
handleClose
,
})
}
// 关闭并重置
const
handleClose
=
()
=>
{
setOpen
(
false
)
setCurrent
(
0
)
}
const
handleFunctionChange
=
(
value
:
string
)
=>
{
form
.
setFieldsValue
({
content
:
`
${
value
}
()`
})
}
// 步骤定义
const
steps
=
[
{
title
:
'请选择文本计算字段'
,
content
:
(
<>
<
Form
.
Item
label=
"文本计算字段名称"
name=
"name"
rules=
{
[{
required
:
true
,
message
:
'请输入字段名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"文本计算字段英文名称"
name=
"english_name"
rules=
{
[{
required
:
true
,
message
:
'请输入英文名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
</>
),
},
{
title
:
'配置文本计算规则'
,
content
:
(
<>
<
Form
.
Item
label=
"请选择函数"
name=
"function"
rules=
{
[{
required
:
true
,
message
:
'请选择函数'
}]
}
>
<
Select
options=
{
functionOptions
}
onChange=
{
handleFunctionChange
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"请输入函数公式"
name=
"content"
rules=
{
[{
required
:
true
,
message
:
'请输入函数公式'
}]
}
>
<
FunctionInput
fieldType=
"string"
/>
</
Form
.
Item
>
</>
),
},
{
title
:
'处理执行'
,
content
:
(
<>
<
Flex
vertical
align=
"center"
style=
{
{
marginTop
:
'20px'
}
}
>
<
Button
type=
"primary"
onClick=
{
handleStart
}
loading=
{
isPending
}
>
开始处理
</
Button
>
<
AppProgressSteps
style=
{
{
margin
:
'80px'
}
}
current=
{
progress
}
items=
{
[
{
title
:
'新建字段'
},
{
title
:
'复制数据'
},
{
title
:
'文本计算处理'
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>
},
]
}
/>
</
Flex
>
</>
),
},
]
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI检查函数公式
</
Button
>
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
下一步
</
Button
>
)
}
{
current
===
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleClose
}
disabled=
{
isPending
}
>
关闭
</
Button
>
)
}
</
Flex
>
)
}
return
(
<>
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
true
)
}
>
文本计算
</
Button
>
<
Modal
title=
{
steps
[
current
]?.
title
}
open=
{
open
}
footer=
{
<
Footer
/>
}
destroyOnClose
width=
{
800
}
onCancel=
{
handleClose
}
>
<
div
style=
{
{
minHeight
:
300
,
padding
:
'20px 0'
}
}
>
<
Form
form=
{
form
}
labelCol=
{
{
span
:
6
}
}
preserve=
{
false
}
>
{
steps
.
map
((
item
,
index
)
=>
(
<
div
key=
{
index
}
hidden=
{
current
!==
index
}
style=
{
{
marginTop
:
'20px'
}
}
>
{
item
.
content
}
</
div
>
))
}
</
Form
>
</
div
>
</
Modal
>
</>
)
}
src/modules/data/process/string/query.ts
0 → 100644
浏览文件 @
25767edf
import
{
useMutation
,
useQueryClient
}
from
'@tanstack/react-query'
import
{
message
}
from
'antd'
import
{
processData
}
from
'./api'
import
type
{
ProcessDataParams
}
from
'./types'
import
{
useProcessProgressQuery
}
from
'@/hooks/useQuery'
// 处理数据
export
function
useProcessData
()
{
const
queryClient
=
useQueryClient
()
const
{
data
,
start
,
stop
}
=
useProcessProgressQuery
({
function_name
:
'text'
})
const
query
=
useMutation
({
mutationFn
:
(
data
:
ProcessDataParams
)
=>
{
start
()
return
processData
(
data
)
},
onSuccess
:
()
=>
{
stop
()
message
.
success
(
'处理完成'
)
queryClient
.
invalidateQueries
({
queryKey
:
[
'data'
]
})
},
})
return
{
...
query
,
progress
:
data
?.
progress
??
-
1
,
message
:
data
?.
message
??
{}
}
}
src/modules/data/process/string/types.ts
0 → 100644
浏览文件 @
25767edf
export
interface
ProcessDataParams
{
name
:
string
english_name
:
string
function
:
string
fields
:
string
}
src/modules/data/process/string/views/Index.tsx
浏览文件 @
25767edf
import
{
lazy
}
from
'react'
import
DataWrap
from
'@/components/data/DataWrap'
import
{
Button
}
from
'antd'
const
ButtonModal
=
lazy
(()
=>
import
(
'../components/ButtonModal'
))
export
default
function
DataProcess
()
{
return
<
DataWrap
title=
"数据加工:文本计算"
buttons=
{
<
Button
type=
"primary"
>
文本计算
</
Button
>
}
></
DataWrap
>
return
<
DataWrap
title=
"数据加工:文本计算"
buttons=
{
<
Button
Modal
/
>
}
></
DataWrap
>
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论