Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-bi
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-bi
Commits
5e707104
提交
5e707104
authored
4月 08, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
22ce87b3
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
574 行增加
和
104 行删除
+574
-104
App.tsx
src/App.tsx
+17
-2
SelectFieldButtonModal.tsx
src/components/data/SelectFieldButtonModal.tsx
+1
-0
ButtonModal.tsx
src/modules/data/process/binning/components/ButtonModal.tsx
+0
-0
ButtonModal.tsx
src/modules/data/process/date/components/ButtonModal.tsx
+88
-32
ButtonModal.tsx
...s/data/process/desensitization/components/ButtonModal.tsx
+90
-12
ButtonModal.tsx
src/modules/data/process/group/components/ButtonModal.tsx
+90
-18
ButtonModal.tsx
src/modules/data/process/logic/components/ButtonModal.tsx
+71
-24
ButtonModal.tsx
src/modules/data/process/mapping/components/ButtonModal.tsx
+73
-6
ButtonModal.tsx
src/modules/data/process/number/components/ButtonModal.tsx
+59
-4
ButtonModal.tsx
src/modules/data/process/string/components/ButtonModal.tsx
+59
-4
Index.tsx
src/modules/data/read/understanding/views/Index.tsx
+26
-2
没有找到文件。
src/App.tsx
浏览文件 @
5e707104
import
{
Suspense
}
from
'react'
import
{
Suspense
,
useEffect
}
from
'react'
import
{
Spin
}
from
'antd'
import
{
useRoutes
}
from
'react-router'
import
{
useRoutes
,
useSearchParams
,
useLocation
}
from
'react-router'
import
routes
from
'./router/routes'
import
'./App.scss'
const
params
=
new
URLSearchParams
(
window
.
location
.
search
)
const
experimentId
=
params
.
get
(
'experiment_id'
)
||
'7028276368903241728'
const
App
=
()
=>
{
const
element
=
useRoutes
(
routes
)
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
()
const
location
=
useLocation
()
useEffect
(()
=>
{
const
currentId
=
searchParams
.
get
(
'experiment_id'
)
if
(
!
currentId
)
{
const
newSearchParams
=
new
URLSearchParams
(
location
.
search
)
newSearchParams
.
set
(
'experiment_id'
,
experimentId
)
setSearchParams
(
newSearchParams
)
}
},
[
location
.
search
,
searchParams
,
setSearchParams
])
return
(
<
Suspense
fallback=
{
...
...
src/components/data/SelectFieldButtonModal.tsx
浏览文件 @
5e707104
...
...
@@ -46,6 +46,7 @@ export default function SelectFieldButtonModal({
placeholder=
"请选择字段"
options=
{
currentFieldOptions
}
value=
{
value
}
allowClear
onChange=
{
setValue
}
style=
{
{
width
:
'100%'
}
}
></
Select
>
</
div
>
...
...
src/modules/data/process/binning/components/ButtonModal.tsx
浏览文件 @
5e707104
差异被折叠。
点击展开。
src/modules/data/process/date/components/ButtonModal.tsx
浏览文件 @
5e707104
...
...
@@ -4,62 +4,64 @@ import { useDataFieldQuery } from '@/hooks/useQuery'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
FunctionInput
from
'@/components/data/FunctionInput'
import
{
useProcessData
}
from
'../query'
import
{
useAI
}
from
'@/hooks/useAI'
import
MarkdownRender
from
'@/components/MarkdownRender'
const
functionShortcutOptions
=
[
{
label
:
'获取
“年份”
信息'
,
label
:
'获取
"年份"
信息'
,
value
:
'YEAR'
,
demo
:
'如:
“2025年”
'
,
demo
:
'如:
"2025年"
'
,
},
// {
// label: '获取
“季度”
信息',
// label: '获取
"季度"
信息',
// value: 'YEAR',
// demo: '如:
“一季度”
',
// demo: '如:
"一季度"
',
// },
// {
// label: '获取
“年季度”
信息',
// label: '获取
"年季度"
信息',
// value: 'YEAR',
// demo: '如:
“2025年一季度”
',
// demo: '如:
"2025年一季度"
',
// },
{
label
:
'获取
“月份”
信息'
,
label
:
'获取
"月份"
信息'
,
value
:
'MONTH'
,
demo
:
'如:
“3月”
'
,
demo
:
'如:
"3月"
'
,
},
{
label
:
'获取
“年月份”
信息'
,
label
:
'获取
"年月份"
信息'
,
value
:
'DATE'
,
demo
:
'如:
“2025年3月”
'
,
demo
:
'如:
"2025年3月"
'
,
},
{
label
:
'获取
“周”
信息'
,
label
:
'获取
"周"
信息'
,
value
:
'NETWORKDAYS'
,
demo
:
'如:
“12周”
'
,
demo
:
'如:
"12周"
'
,
},
// {
// label: '获取
“年周”
信息',
// label: '获取
"年周"
信息',
// value: 'YEAR',
// demo: '如:
“2025年12周”
',
// demo: '如:
"2025年12周"
',
// },
{
label
:
'获取
“日”
信息'
,
label
:
'获取
"日"
信息'
,
value
:
'DAY'
,
demo
:
'如:
“21日”
'
,
demo
:
'如:
"21日"
'
,
},
{
label
:
'获取
“小时”
信息'
,
label
:
'获取
"小时"
信息'
,
value
:
'HOUR'
,
demo
:
'如:
“12时”
'
,
demo
:
'如:
"12时"
'
,
},
{
label
:
'获取
“分钟”
信息'
,
label
:
'获取
"分钟"
信息'
,
value
:
'MINUTE'
,
demo
:
'如:
“21分”
'
,
demo
:
'如:
"21分"
'
,
},
{
label
:
'获取
“秒”
信息'
,
label
:
'获取
"秒"
信息'
,
value
:
'SECOND'
,
demo
:
'如:
“18秒”
'
,
demo
:
'如:
"18秒"
'
,
},
]
...
...
@@ -67,21 +69,21 @@ const functionOptions = [
{
label
:
'DATE:组合年、月、日为标准日期'
,
value
:
'DATE'
},
{
label
:
'DATEDIF:计算两个日期间的年/月/日差值'
,
value
:
'DATEDIF'
},
{
label
:
'DATEVALUE:将文本日期转换为 Excel 可识别的序列号'
,
value
:
'DATEVALUE'
},
{
label
:
'DAY:提取日期中的
“日”
部分'
,
value
:
'DAY'
},
{
label
:
'DAY:提取日期中的
"日"
部分'
,
value
:
'DAY'
},
{
label
:
'EDATE:返回指定日期之前/之后几个月的日期'
,
value
:
'EDATE'
},
{
label
:
'EMONTH:返回指定日期之前/之后几个月的最后一天'
,
value
:
'EMONTH'
},
{
label
:
'HOUR:提取时间中的
“小时”
部分'
,
value
:
'HOUR'
},
{
label
:
'MINUTE:提取时间中的
“分钟”
部分'
,
value
:
'MINUTE'
},
{
label
:
'MONTH:提取日期中的
“月”
部分'
,
value
:
'MONTH'
},
{
label
:
'HOUR:提取时间中的
"小时"
部分'
,
value
:
'HOUR'
},
{
label
:
'MINUTE:提取时间中的
"分钟"
部分'
,
value
:
'MINUTE'
},
{
label
:
'MONTH:提取日期中的
"月"
部分'
,
value
:
'MONTH'
},
{
label
:
'NETWORKDAYS:计算两个日期之间的工作日天数(排除周末和节假日)'
,
value
:
'NETWORKDAYS'
},
{
label
:
'NOW:返回当前日期和时间(精确到秒)'
,
value
:
'NOW'
},
{
label
:
'SECOND:提取时间中的
“秒”
部分'
,
value
:
'SECOND'
},
{
label
:
'SECOND:提取时间中的
"秒"
部分'
,
value
:
'SECOND'
},
{
label
:
'TIME:组合时、分、秒为标准时间'
,
value
:
'TIME'
},
{
label
:
'TIMEVALUE:将文本时间转换为小数'
,
value
:
'TIMEVALUE'
},
{
label
:
'TODAY:返回当前系统日期(无参数)'
,
value
:
'TODAY'
},
{
label
:
'WEEKDAY:返回日期对应的星期几(数字形式)'
,
value
:
'WEEKDAY'
},
{
label
:
'WORKDAY:计算指定工作日天数后的日期(跳过周末和节假日)'
,
value
:
'WORKDAY'
},
{
label
:
'YEAR:提取日期中的
“年”
部分'
,
value
:
'YEAR'
},
{
label
:
'YEAR:提取日期中的
"年"
部分'
,
value
:
'YEAR'
},
]
export
default
function
ButtonModal
()
{
...
...
@@ -92,6 +94,44 @@ export default function ButtonModal() {
const
[
form
]
=
Form
.
useForm
()
const
action
=
Form
.
useWatch
(
'action'
,
form
)
const
[
result
,
setResult
]
=
useState
(
''
)
const
{
isLoading
,
post
}
=
useAI
({
onComplete
:
(
message
)
=>
{
setResult
(
message
?.
content
||
''
)
},
})
const
handleAI
=
async
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
selectedFunction
=
values
.
function
const
functionFormula
=
values
.
content
||
''
post
({
messages
:
[
{
role
:
'user'
,
content
:
`请检查以下日期函数公式是否正确,并提供改进建议:
1. 当前选择的函数:
${
selectedFunction
}
2. 输入的公式:
${
functionFormula
}
请按照以下格式回答:
1. 语法检查:检查函数语法是否正确,包括括号匹配、参数格式等
2. 参数检查:检查参数类型和数量是否符合函数要求
3. 逻辑检查:检查函数逻辑是否合理,是否符合预期用途
4. 改进建议:如果有问题,请提供具体的改进建议
5. 示例:提供一个正确的使用示例
注意:
- 请确保检查结果清晰易懂
- 如果公式完全正确,请明确指出
- 如果发现潜在问题,请详细说明原因
- 提供的示例应该与当前使用场景相关`
,
},
],
})
}
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
...
...
@@ -117,9 +157,7 @@ export default function ButtonModal() {
fields
.
push
(
values
.
field
)
}
const
params
=
{
...
values
,
fields
:
JSON
.
stringify
(
fields
)
}
// 将提取的参数赋值给 fields
mutate
(
params
,
{
onSuccess
:
handleClose
,
})
mutate
(
params
)
}
// 关闭并重置
...
...
@@ -127,6 +165,7 @@ export default function ButtonModal() {
setOpen
(
false
)
setCurrent
(
0
)
remove
()
setResult
(
''
)
}
const
handleFunctionChange
=
(
value
:
string
)
=>
{
form
.
setFieldsValue
({
content
:
`
${
value
}
()`
})
...
...
@@ -199,6 +238,19 @@ export default function ButtonModal() {
</
Form
.
Item
>
</>
)
}
{
result
&&
(
<
div
style=
{
{
marginTop
:
20
,
background
:
'#f5f5f5'
,
padding
:
20
,
maxHeight
:
300
,
overflow
:
'auto'
,
borderRadius
:
10
,
}
}
>
<
MarkdownRender
>
{
result
}
</
MarkdownRender
>
</
div
>
)
}
</>
),
},
...
...
@@ -228,7 +280,11 @@ export default function ButtonModal() {
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
action
===
'日期函数计算'
&&
<
Button
type=
"primary"
>
AI智能建议
</
Button
>
}
{
current
===
1
&&
action
===
'日期函数计算'
&&
(
<
Button
type=
"primary"
onClick=
{
handleAI
}
loading=
{
isLoading
}
>
AI检查函数公式
</
Button
>
)
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
...
...
src/modules/data/process/desensitization/components/ButtonModal.tsx
浏览文件 @
5e707104
...
...
@@ -3,6 +3,8 @@ import { Button, Flex, Modal, Radio, Input, Form, Row, Col } from 'antd'
import
{
useDataFieldQuery
}
from
'@/hooks/useQuery'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
{
useProcessData
}
from
'../query'
import
{
useAI
}
from
'@/hooks/useAI'
import
MarkdownRender
from
'@/components/MarkdownRender'
export
default
function
ButtonModal
()
{
const
{
fieldOptions
,
getFieldName
}
=
useDataFieldQuery
()
...
...
@@ -16,6 +18,63 @@ export default function ButtonModal() {
const
formFunction
=
Form
.
useWatch
(
'function'
,
form
)
const
formSmFun
=
Form
.
useWatch
(
'sm_fun'
,
form
)
const
[
result
,
setResult
]
=
useState
(
''
)
const
{
isLoading
,
post
}
=
useAI
({
onComplete
:
(
message
)
=>
{
setResult
(
message
?.
content
||
''
)
},
})
const
handleAI
=
async
()
=>
{
post
({
messages
:
[
{
role
:
'user'
,
content
:
`任务目标
分析指定字段的脱敏方法是否合理,包括 脱敏类型、遮蔽符号、遮蔽范围 的设置,并提供改进建议。
字段信息 :[
${
getFieldName
(
field
)}
]
脱敏参数 :
脱敏方法:
${
action
}
。
遮蔽符号:
${
form
.
getFieldValue
(
'char'
)}
。
遮蔽范围:
${
form
.
getFieldValue
(
'sm_fun'
)}
。
其他规则 :
${
form
.
getFieldValue
(
'char'
)}
。
输出格式:
| 序号 | 字段名称 | 当前脱敏方法 | 遮蔽符号 | 合理性判断 | 合理性判断依据 | 改进建议(格式:建议类型:描述,执行方式:自动/人工)
| 1 | 手机号 | 固定遮蔽 | * | 不合理 | 保留位数不足(仅最后2位可见) 建议类型:调整结束位数为-4,执行方式:自动
| 2 | 姓名 | 内容替换 | [敏感] | 合理 | 符合隐私保护要求 | 无需调整
执行要求
1.
合理性评估标准 :
○
隐私合规性 :是否符合数据保护法规(如GDPR、CCPA)。
○
信息可用性 :脱敏后是否仍能用于业务需求(如保留关键标识符)。
○
遮蔽范围合理性 :
■
部分遮蔽 :开始和结束位数是否有效(如不超出字段长度)。
■
全部遮蔽 :是否适用于无需保留任何信息的场景。
○
符号一致性 :遮蔽符号是否统一(如避免混用*和X)。`
,
},
],
})
}
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
...
...
@@ -33,9 +92,7 @@ export default function ButtonModal() {
const
handleStart
=
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
params
=
{
...
values
,
rules
:
JSON
.
stringify
(
values
.
rules
)
}
mutate
(
params
,
{
onSuccess
:
handleClose
,
})
mutate
(
params
)
}
// 关闭并重置
...
...
@@ -43,6 +100,7 @@ export default function ButtonModal() {
setOpen
(
false
)
setCurrent
(
0
)
remove
()
setResult
(
''
)
}
// 步骤定义
const
steps
=
[
...
...
@@ -82,12 +140,15 @@ export default function ButtonModal() {
<>
<
Form
.
Item
label=
"数据脱敏操作字段"
>
{
getFieldName
(
field
)
}
</
Form
.
Item
>
<
Form
.
Item
name=
"action"
>
<
Radio
.
Group
block
options=
{
[
'基础脱敏方法'
,
'高级脱敏方法'
,
'特殊脱敏方法'
]
}
optionType=
"button"
buttonStyle=
"solid"
/>
<
Flex
align=
"center"
justify=
"center"
style=
{
{
marginBottom
:
20
}
}
>
<
Form
.
Item
name=
"action"
noStyle
>
<
Radio
.
Group
options=
{
[
'基础脱敏方法'
,
'高级脱敏方法'
,
'特殊脱敏方法'
]
}
optionType=
"button"
buttonStyle=
"solid"
/>
</
Form
.
Item
>
</
Flex
>
</
Form
.
Item
>
{
action
===
'基础脱敏方法'
&&
(
<>
...
...
@@ -131,14 +192,14 @@ export default function ButtonModal() {
{
formFunction
===
'内容替换'
&&
(
<>
<
Form
.
Item
label=
"请输入替换内容"
name=
"
char
"
rules=
{
[{
required
:
true
,
message
:
'请输入'
}]
}
>
<
Form
.
Item
label=
"请输入替换内容"
name=
"
sm_fun
"
rules=
{
[{
required
:
true
,
message
:
'请输入'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
</>
)
}
{
formFunction
===
'内容模糊'
&&
(
<>
<
Form
.
Item
label=
"请输入模糊内容"
name=
"
char
"
rules=
{
[{
required
:
true
,
message
:
'请输入'
}]
}
>
<
Form
.
Item
label=
"请输入模糊内容"
name=
"
sm_fun
"
rules=
{
[{
required
:
true
,
message
:
'请输入'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
</>
...
...
@@ -186,6 +247,19 @@ export default function ButtonModal() {
</
Form
.
Item
>
</>
)
}
{
result
&&
(
<
div
style=
{
{
marginTop
:
20
,
background
:
'#f5f5f5'
,
padding
:
20
,
maxHeight
:
300
,
overflow
:
'auto'
,
borderRadius
:
10
,
}
}
>
<
MarkdownRender
>
{
result
}
</
MarkdownRender
>
</
div
>
)
}
</>
),
},
...
...
@@ -222,7 +296,11 @@ export default function ButtonModal() {
open=
{
open
}
footer=
{
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI智能建议
</
Button
>
}
{
current
===
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleAI
}
loading=
{
isLoading
}
>
AI智能建议
</
Button
>
)
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
...
...
src/modules/data/process/group/components/ButtonModal.tsx
浏览文件 @
5e707104
...
...
@@ -5,6 +5,8 @@ import AppProgressSteps from '@/components/AppProgressSteps'
import
{
useProcessData
}
from
'../query'
import
{
MinusCircleOutlined
}
from
'@ant-design/icons'
import
{
uniqBy
}
from
'lodash-es'
import
{
useAI
}
from
'@/hooks/useAI'
import
MarkdownRender
from
'@/components/MarkdownRender'
export
default
function
ButtonModal
()
{
const
{
data
=
{
list
:
[]
}
}
=
useDataQuery
()
...
...
@@ -33,6 +35,59 @@ export default function ButtonModal() {
}
},
[
field
,
data
.
list
])
const
[
result
,
setResult
]
=
useState
(
''
)
const
{
isLoading
,
post
}
=
useAI
({
onComplete
:
(
message
)
=>
{
setResult
(
message
?.
content
||
''
)
},
})
const
handleAI
=
async
()
=>
{
post
({
messages
:
[
{
role
:
'user'
,
content
:
`任务目标
分析指定字段的分组规则是否合理,包括 分组逻辑、数据分布、业务规则匹配 ,并提供改进建议。输入要求
字段信息 :[
${
getFieldName
(
field
)}
]
数据样本:
${
JSON
.
stringify
(
dataSource
)}
分组参数 :
分组规则 (如"按年龄段分组:0-18、19-65、65+")。
分组依据 (如"按销售额分组为低/中/高")。
输出格式:
| 序号 | 分组名称 | 当前分组合理性 | 合理性判断依据 | 改进建议(格式:建议类型:描述,执行方式:自动/人工)
| 1 | 0-18岁 | 不合理 | 无数据落入此区间 | 建议类型:删除此分组,执行方式:人工
| 2 | 19-65岁 | 合理 | 数据分布均匀 | 无需调整
| 1 | 65+岁 | 不合理 | 包含极端值(如年龄300岁) | 建议类型:调整上限为120岁,执行方式:人工
执行要求
合理性评估标准 :
■
数据覆盖 :分组是否覆盖所有数据值,无遗漏或重叠。
■
业务匹配 :是否符合业务需求(如医疗分组需符合年龄段标准)。
■
数据分布均衡性 :分组内数据量是否合理(如避免空组或数据堆积)。
■
逻辑一致性 :分组边界是否合理(如"65+岁"是否包含65岁)。`
,
},
],
})
}
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
...
...
@@ -60,9 +115,7 @@ export default function ButtonModal() {
})
),
}
mutate
(
params
,
{
onSuccess
:
handleClose
,
})
mutate
(
params
)
}
// 关闭并重置
...
...
@@ -70,6 +123,7 @@ export default function ButtonModal() {
setOpen
(
false
)
setCurrent
(
0
)
remove
()
setResult
(
''
)
}
const
[
groupName
,
setGroupName
]
=
useState
(
''
)
// 步骤定义
...
...
@@ -122,6 +176,7 @@ export default function ButtonModal() {
/>
<
Button
type=
"primary"
disabled=
{
!
groupName
}
onClick=
{
()
=>
{
if
(
!
groupName
)
return
add
({
name
:
groupName
,
fields
:
[]
})
// 添加新分组
...
...
@@ -136,7 +191,16 @@ export default function ButtonModal() {
<
Form
.
Item
{
...
restField
}
label=
{
rules
[
name
]?.
name
}
style=
{
{
flex
:
1
}
}
key=
{
key
}
>
<
Flex
gap=
{
10
}
>
<
Form
.
Item
name=
{
[
name
,
'fields'
]
}
noStyle
>
<
Select
options=
{
dataSource
}
mode=
"multiple"
style=
{
{
width
:
'60%'
}
}
/>
<
Select
options=
{
dataSource
.
filter
((
item
)
=>
{
return
!
rules
.
some
(
(
rule
:
any
,
index
:
number
)
=>
index
!==
name
&&
rule
.
fields
?.
includes
(
item
.
value
)
)
})
}
mode=
"multiple"
allowClear
style=
{
{
width
:
'60%'
}
}
/>
</
Form
.
Item
>
<
MinusCircleOutlined
onClick=
{
()
=>
remove
(
name
)
}
/>
</
Flex
>
...
...
@@ -145,6 +209,19 @@ export default function ButtonModal() {
</>
)
}
</
Form
.
List
>
{
result
&&
(
<
div
style=
{
{
marginTop
:
20
,
background
:
'#f5f5f5'
,
padding
:
20
,
maxHeight
:
300
,
overflow
:
'auto'
,
borderRadius
:
10
,
}
}
>
<
MarkdownRender
>
{
result
}
</
MarkdownRender
>
</
div
>
)
}
</>
),
},
...
...
@@ -159,19 +236,10 @@ export default function ButtonModal() {
<
AppProgressSteps
current=
{
progress
}
items=
{
[
{
title
:
'新建字段'
,
},
{
title
:
'复制数据'
,
},
{
title
:
'数据分组处理'
,
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>,
},
{
title
:
'新建字段'
},
{
title
:
'复制数据'
},
{
title
:
'数据分组处理'
},
{
title
:
'处理结果'
,
description
:
<>
{
message
[
3
]
}
</>
},
]
}
/>
</
Flex
>
...
...
@@ -190,7 +258,11 @@ export default function ButtonModal() {
open=
{
open
}
footer=
{
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI智能建议
</
Button
>
}
{
current
===
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleAI
}
loading=
{
isLoading
}
>
AI智能建议
</
Button
>
)
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
...
...
src/modules/data/process/logic/components/ButtonModal.tsx
浏览文件 @
5e707104
...
...
@@ -3,28 +3,21 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
FunctionInput
from
'@/components/data/FunctionInput'
import
{
useProcessData
}
from
'../query'
import
{
useAI
}
from
'@/hooks/useAI'
import
MarkdownRender
from
'@/components/MarkdownRender'
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'
},
{
label
:
'AND:所有条件均为 TRUE 时返回 TRUE,否则返回 FALSE'
,
value
:
'AND'
},
{
label
:
'FALSE:直接返回逻辑值 FALSE'
,
value
:
'FALSE'
},
{
label
:
'IF:根据条件返回不同结果'
,
value
:
'IF'
},
{
label
:
'IFERROR:捕获错误并替换为指定值'
,
value
:
'IFERROR'
},
{
label
:
'IFNA:专门处理 #N/A 错误'
,
value
:
'IFNA'
},
{
label
:
'IFS:多条件分支判断'
,
value
:
'IFS'
},
{
label
:
'NOT:对逻辑值取反'
,
value
:
'NOT'
},
{
label
:
'OR:任一条件为 TRUE 时返回 TRUE'
,
value
:
'OR'
},
{
label
:
'SWITCH:根据表达式匹配值返回对应结果'
,
value
:
'SWITCH'
},
{
label
:
'TRUE:直接返回逻辑值 TRUE'
,
value
:
'TRUE'
},
{
label
:
'XOR:异或逻辑,仅当奇数个条件为 TRUE 时返回 TRUE'
,
value
:
'XOR'
},
]
export
default
function
ButtonModal
()
{
...
...
@@ -32,6 +25,44 @@ export default function ButtonModal() {
const
[
current
,
setCurrent
]
=
useState
(
0
)
const
[
form
]
=
Form
.
useForm
()
const
[
result
,
setResult
]
=
useState
(
''
)
const
{
isLoading
,
post
}
=
useAI
({
onComplete
:
(
message
)
=>
{
setResult
(
message
?.
content
||
''
)
},
})
const
handleAI
=
async
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
selectedFunction
=
values
.
function
const
functionFormula
=
values
.
content
||
''
post
({
messages
:
[
{
role
:
'user'
,
content
:
`请检查以下逻辑计算函数公式是否正确,并提供改进建议:
1. 当前选择的函数:
${
selectedFunction
}
2. 输入的公式:
${
functionFormula
}
请按照以下格式回答:
1. 语法检查:检查函数语法是否正确,包括括号匹配、参数格式等
2. 参数检查:检查参数类型和数量是否符合函数要求
3. 逻辑检查:检查函数逻辑是否合理,是否符合预期用途
4. 改进建议:如果有问题,请提供具体的改进建议
5. 示例:提供一个正确的使用示例
注意:
- 请确保检查结果清晰易懂
- 如果公式完全正确,请明确指出
- 如果发现潜在问题,请详细说明原因
- 提供的示例应该与当前使用场景相关`
,
},
],
})
}
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
...
...
@@ -54,9 +85,7 @@ export default function ButtonModal() {
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
,
})
mutate
(
params
)
}
// 关闭并重置
...
...
@@ -64,6 +93,7 @@ export default function ButtonModal() {
setOpen
(
false
)
setCurrent
(
0
)
remove
()
setResult
(
''
)
}
const
handleFunctionChange
=
(
value
:
string
)
=>
{
form
.
setFieldsValue
({
content
:
`
${
value
}
()`
})
...
...
@@ -97,6 +127,19 @@ export default function ButtonModal() {
<
Form
.
Item
label=
"请输入函数公式"
name=
"content"
rules=
{
[{
required
:
true
,
message
:
'请输入函数公式'
}]
}
>
<
FunctionInput
fieldType=
"string"
/>
</
Form
.
Item
>
{
result
&&
(
<
div
style=
{
{
marginTop
:
20
,
background
:
'#f5f5f5'
,
padding
:
20
,
maxHeight
:
300
,
overflow
:
'auto'
,
borderRadius
:
10
,
}
}
>
<
MarkdownRender
>
{
result
}
</
MarkdownRender
>
</
div
>
)
}
</>
),
},
...
...
@@ -126,7 +169,11 @@ export default function ButtonModal() {
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI检查函数公式
</
Button
>
}
{
current
===
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleAI
}
loading=
{
isLoading
}
>
AI检查函数公式
</
Button
>
)
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
...
...
src/modules/data/process/mapping/components/ButtonModal.tsx
浏览文件 @
5e707104
...
...
@@ -4,16 +4,18 @@ import { useDataQuery, useDataFieldQuery } from '@/hooks/useQuery'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
{
uniqBy
}
from
'lodash-es'
import
{
useProcessData
}
from
'../query'
import
{
useAI
}
from
'@/hooks/useAI'
import
MarkdownRender
from
'@/components/MarkdownRender'
export
default
function
ButtonModal
()
{
const
{
data
=
{
list
:
[]
}
}
=
useDataQuery
()
const
{
fieldOptions
,
getFieldName
}
=
useDataFieldQuery
()
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
current
,
setCurrent
]
=
useState
(
0
)
const
[
form
]
=
Form
.
useForm
()
const
[
dataSource
,
setDataSource
]
=
useState
<
{
key
:
number
;
raw_value
:
string
;
new_value
:
string
}[]
>
([])
const
name
=
Form
.
useWatch
(
'name'
,
form
)
const
field
=
Form
.
useWatch
(
'field'
,
form
)
useEffect
(()
=>
{
...
...
@@ -36,6 +38,55 @@ export default function ButtonModal() {
)
}
const
[
result
,
setResult
]
=
useState
(
''
)
const
{
isLoading
,
post
}
=
useAI
({
onComplete
:
(
message
)
=>
{
setResult
(
message
?.
content
||
''
)
},
})
const
handleAI
=
async
()
=>
{
post
({
messages
:
[
{
role
:
'user'
,
content
:
`任务目标
分析指定字段值与目标字段的映射关系是否合理,并提供改进建议。
输入要求
1.
字段列表 :[
${
getFieldName
(
field
)}
→
${
name
}
]
2.
数据样本:
${
JSON
.
stringify
(
dataSource
)}
输出格式:
| 序号 | 字段对(源→目标) | 映射问题描述 | 合理性判断 | 改进建议(格式:建议名称:描述,执行方式:自动/人工)
| 1 | 省份→城市 | 省份为“北京”,城市为“上海” | 不合理 | 建议类型:修正城市为“北京”,执行方式:自动
| 2 | 订单状态→物流单号 | 状态为“已发货”,物流单号为空 | 不合理 | 建议类型:标记为异常需人工核查,执行方式:人工
执行要求
1.
合理性判断标准 :
○
逻辑一致性 :
■
检查字段值是否符合业务关联(如“省份→城市”是否匹配)。
■
检查数值范围是否合理(如“折扣率应≤100%”)。
○
业务规则匹配 :
■
若用户提供规则(如“性别字段应为“男/女”),则优先校验。
○
数据分布异常 :
■
检测是否存在矛盾值(如“年龄20岁,职业为退休人员”)。`
,
},
],
})
}
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
...
...
@@ -54,9 +105,7 @@ export default function ButtonModal() {
return
{
...
result
,
[
item
.
raw_value
]:
item
.
new_value
}
},
{})
const
params
=
{
...
values
,
rule
:
JSON
.
stringify
(
rule
)
}
mutate
(
params
,
{
onSuccess
:
handleClose
,
})
mutate
(
params
)
}
// 关闭并重置
...
...
@@ -64,6 +113,7 @@ export default function ButtonModal() {
setOpen
(
false
)
setCurrent
(
0
)
remove
()
setResult
(
''
)
}
// 步骤定义
const
steps
=
[
...
...
@@ -102,7 +152,7 @@ export default function ButtonModal() {
<
Form
.
Item
>
<
Table
bordered
pagination=
{
{
pageSize
:
10
}
}
pagination=
{
{
pageSize
:
10
,
hideOnSinglePage
:
true
}
}
columns=
{
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
align
:
'center'
,
width
:
80
},
{
title
:
'原始值'
,
dataIndex
:
'raw_value'
,
align
:
'center'
},
...
...
@@ -122,6 +172,19 @@ export default function ButtonModal() {
dataSource=
{
dataSource
}
/>
</
Form
.
Item
>
{
result
&&
(
<
div
style=
{
{
marginTop
:
20
,
background
:
'#f5f5f5'
,
padding
:
20
,
maxHeight
:
300
,
overflow
:
'auto'
,
borderRadius
:
10
,
}
}
>
<
MarkdownRender
>
{
result
}
</
MarkdownRender
>
</
div
>
)
}
</>
),
},
...
...
@@ -158,7 +221,11 @@ export default function ButtonModal() {
open=
{
open
}
footer=
{
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI智能建议
</
Button
>
}
{
current
===
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleAI
}
loading=
{
isLoading
}
>
AI智能建议
</
Button
>
)
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
...
...
src/modules/data/process/number/components/ButtonModal.tsx
浏览文件 @
5e707104
...
...
@@ -3,6 +3,8 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
FunctionInput
from
'@/components/data/FunctionInput'
import
{
useProcessData
}
from
'../query'
import
{
useAI
}
from
'@/hooks/useAI'
import
MarkdownRender
from
'@/components/MarkdownRender'
const
functionOptions
=
[
{
label
:
'ABS:返回数字的绝对值'
,
value
:
'ABS'
},
...
...
@@ -32,6 +34,43 @@ export default function ButtonModal() {
const
[
current
,
setCurrent
]
=
useState
(
0
)
const
[
form
]
=
Form
.
useForm
()
const
[
result
,
setResult
]
=
useState
(
''
)
const
{
isLoading
,
post
}
=
useAI
({
onComplete
:
(
message
)
=>
{
setResult
(
message
?.
content
||
''
)
},
})
const
handleAI
=
async
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
selectedFunction
=
values
.
function
const
functionFormula
=
values
.
content
||
''
post
({
messages
:
[
{
role
:
'user'
,
content
:
`请检查以下数值计算函数公式是否正确,并提供改进建议:
1. 当前选择的函数:
${
selectedFunction
}
2. 输入的公式:
${
functionFormula
}
请按照以下格式回答:
1. 语法检查:检查函数语法是否正确,包括括号匹配、参数格式等
2. 参数检查:检查参数类型和数量是否符合函数要求
3. 逻辑检查:检查函数逻辑是否合理,是否符合预期用途
4. 改进建议:如果有问题,请提供具体的改进建议
5. 示例:提供一个正确的使用示例
注意:
- 请确保检查结果清晰易懂
- 如果公式完全正确,请明确指出
- 如果发现潜在问题,请详细说明原因
- 提供的示例应该与当前使用场景相关`
,
},
],
})
}
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
if
(
current
===
0
)
{
...
...
@@ -54,9 +93,7 @@ export default function ButtonModal() {
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
,
})
mutate
(
params
)
}
// 关闭并重置
...
...
@@ -64,6 +101,7 @@ export default function ButtonModal() {
setOpen
(
false
)
setCurrent
(
0
)
remove
()
setResult
(
''
)
}
const
handleFunctionChange
=
(
value
:
string
)
=>
{
form
.
setFieldsValue
({
content
:
`
${
value
}
()`
})
...
...
@@ -97,6 +135,19 @@ export default function ButtonModal() {
<
Form
.
Item
label=
"请输入函数公式"
name=
"content"
rules=
{
[{
required
:
true
,
message
:
'请输入函数公式'
}]
}
>
<
FunctionInput
fieldType=
"string"
/>
</
Form
.
Item
>
{
result
&&
(
<
div
style=
{
{
marginTop
:
20
,
background
:
'#f5f5f5'
,
padding
:
20
,
maxHeight
:
300
,
overflow
:
'auto'
,
borderRadius
:
10
,
}
}
>
<
MarkdownRender
>
{
result
}
</
MarkdownRender
>
</
div
>
)
}
</>
),
},
...
...
@@ -126,7 +177,11 @@ export default function ButtonModal() {
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI检查函数公式
</
Button
>
}
{
current
===
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleAI
}
loading=
{
isLoading
}
>
AI检查函数公式
</
Button
>
)
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
...
...
src/modules/data/process/string/components/ButtonModal.tsx
浏览文件 @
5e707104
...
...
@@ -3,6 +3,8 @@ import { Button, Flex, Modal, Input, Form, Select } from 'antd'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
FunctionInput
from
'@/components/data/FunctionInput'
import
{
useProcessData
}
from
'../query'
import
{
useAI
}
from
'@/hooks/useAI'
import
MarkdownRender
from
'@/components/MarkdownRender'
const
functionOptions
=
[
{
label
:
'CHAR:返回 ASCII 码对应的字符'
,
value
:
'CHAR'
},
...
...
@@ -46,6 +48,43 @@ export default function ButtonModal() {
const
{
mutate
,
isPending
,
progress
,
message
,
remove
}
=
useProcessData
()
const
[
result
,
setResult
]
=
useState
(
''
)
const
{
isLoading
,
post
}
=
useAI
({
onComplete
:
(
message
)
=>
{
setResult
(
message
?.
content
||
''
)
},
})
const
handleAI
=
async
()
=>
{
const
values
=
form
.
getFieldsValue
()
const
selectedFunction
=
values
.
function
const
functionFormula
=
values
.
content
||
''
post
({
messages
:
[
{
role
:
'user'
,
content
:
`请检查以下文本计算函数公式是否正确,并提供改进建议:
1. 当前选择的函数:
${
selectedFunction
}
2. 输入的公式:
${
functionFormula
}
请按照以下格式回答:
1. 语法检查:检查函数语法是否正确,包括括号匹配、参数格式等
2. 参数检查:检查参数类型和数量是否符合函数要求
3. 逻辑检查:检查函数逻辑是否合理,是否符合预期用途
4. 改进建议:如果有问题,请提供具体的改进建议
5. 示例:提供一个正确的使用示例
注意:
- 请确保检查结果清晰易懂
- 如果公式完全正确,请明确指出
- 如果发现潜在问题,请详细说明原因
- 提供的示例应该与当前使用场景相关`
,
},
],
})
}
// 开始处理
const
handleStart
=
()
=>
{
const
values
=
form
.
getFieldsValue
()
...
...
@@ -55,9 +94,7 @@ export default function ButtonModal() {
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
,
})
mutate
(
params
)
}
// 关闭并重置
...
...
@@ -65,6 +102,7 @@ export default function ButtonModal() {
setOpen
(
false
)
setCurrent
(
0
)
remove
()
setResult
(
''
)
}
const
handleFunctionChange
=
(
value
:
string
)
=>
{
...
...
@@ -99,6 +137,19 @@ export default function ButtonModal() {
<
Form
.
Item
label=
"请输入函数公式"
name=
"content"
rules=
{
[{
required
:
true
,
message
:
'请输入函数公式'
}]
}
>
<
FunctionInput
fieldType=
"string"
/>
</
Form
.
Item
>
{
result
&&
(
<
div
style=
{
{
marginTop
:
20
,
background
:
'#f5f5f5'
,
padding
:
20
,
maxHeight
:
300
,
overflow
:
'auto'
,
borderRadius
:
10
,
}
}
>
<
MarkdownRender
>
{
result
}
</
MarkdownRender
>
</
div
>
)
}
</>
),
},
...
...
@@ -128,7 +179,11 @@ export default function ButtonModal() {
const
Footer
=
()
=>
{
return
(
<
Flex
justify=
"center"
gap=
{
20
}
>
{
current
===
1
&&
<
Button
type=
"primary"
>
AI检查函数公式
</
Button
>
}
{
current
===
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleAI
}
loading=
{
isLoading
}
>
AI检查函数公式
</
Button
>
)
}
{
current
>
0
&&
<
Button
onClick=
{
()
=>
setCurrent
(
current
-
1
)
}
>
上一步
</
Button
>
}
{
current
<
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
...
...
src/modules/data/read/understanding/views/Index.tsx
浏览文件 @
5e707104
...
...
@@ -12,7 +12,19 @@ export default function DataWriteUpload() {
messages
:
[
{
role
:
'user'
,
content
:
'请仔细阅读我给你的数据集里面的数据,然后帮助我详细解释一下数据集里面每一个字段的含义。'
,
content
:
`请基于提供的数据集,为每个字段生成结构化说明,需包含以下要素:
字段名称及定义
数据类型(如字符串/数值/时间戳等)
示例值展示
业务场景中的实际含义
数据采集来源说明(如可识别)
请以表格形式呈现,重点字段用★标注,并指出可能存在的数据异常情况`
,
},
],
})
...
...
@@ -21,7 +33,19 @@ export default function DataWriteUpload() {
messages
:
[
{
role
:
'user'
,
content
:
'请仔细阅读我给你的数据集里面的数据,然后帮助我梳理数据集里面字段与字段之间的业务逻辑关系。'
,
content
:
`作为数据分析专家,请基于提供的数据集,系统分析字段间的业务逻辑关系,
需包含:
1、核心业务流程图(订单-支付-物流-售后全链路)
2、关键字段的依赖关系(如:单价×销量=销售额)
3、业务规则验证(如优惠金额与实际付款的校验逻辑)
4、异常数据关联模式(如交易状态与物流状态矛盾案例)
【输出要求】 语言:中文口语化,禁用复杂术语`
,
},
],
})
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论