Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-bi
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-bi
Commits
b8930cc2
提交
b8930cc2
authored
3月 20, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
2b798ac2
显示空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
143 行增加
和
50 行删除
+143
-50
DataLayout.tsx
src/components/layout/DataLayout.tsx
+24
-18
useQuery.ts
src/hooks/useQuery.ts
+25
-7
ButtonModal.tsx
src/modules/data/digging/svm/components/ButtonModal.tsx
+1
-1
ButtonModal.tsx
src/modules/data/preprocess/null/components/ButtonModal.tsx
+5
-4
ButtonModal.tsx
...modules/data/preprocess/repeat/components/ButtonModal.tsx
+1
-1
ButtonModal.tsx
src/modules/data/process/mapping/components/ButtonModal.tsx
+87
-19
没有找到文件。
src/components/layout/DataLayout.tsx
浏览文件 @
b8930cc2
import
{
useState
,
useEffect
,
useMemo
}
from
'react'
import
{
useState
,
useEffect
}
from
'react'
import
{
Outlet
,
NavLink
,
useLocation
}
from
'react-router'
import
{
CircleArrowRight
,
...
...
@@ -25,19 +25,7 @@ type MyMenuItem = {
type
MenuItem
=
Required
<
MenuProps
>
[
'items'
][
number
]
export
default
function
DataLayout
()
{
const
[
collapsed
,
setCollapsed
]
=
useState
(
false
)
const
[
openKeys
,
setOpenKeys
]
=
useState
<
string
[]
>
([])
const
toggleCollapsed
=
()
=>
{
setCollapsed
(
!
collapsed
)
}
const
location
=
useLocation
()
const
selectedKeys
=
[
location
.
pathname
]
const
menus
:
MyMenuItem
[]
=
useMemo
(()
=>
{
return
[
const
menus
:
MyMenuItem
[]
=
[
{
icon
:
<
Database
/>,
name
:
'数据采集'
,
...
...
@@ -138,8 +126,18 @@ export default function DataLayout() {
name
:
'数据可视化大屏'
,
path
:
'/data/screen'
,
},
]
},
[])
]
export
default
function
DataLayout
()
{
const
[
collapsed
,
setCollapsed
]
=
useState
(
false
)
const
[
openKeys
,
setOpenKeys
]
=
useState
<
string
[]
>
([])
const
toggleCollapsed
=
()
=>
{
setCollapsed
(
!
collapsed
)
}
const
location
=
useLocation
()
const
selectedKeys
=
[
location
.
pathname
]
useEffect
(()
=>
{
// 根据当前路径计算需要展开的菜单项
...
...
@@ -158,7 +156,7 @@ export default function DataLayout() {
return
[]
}
setOpenKeys
(
calculateOpenKeys
(
menus
))
},
[
location
.
pathname
,
menus
])
},
[
location
.
pathname
])
const
menusToMenuItems
=
(
menus
:
MyMenuItem
[]):
MenuItem
[]
=>
{
return
menus
.
map
((
item
)
=>
{
...
...
@@ -180,6 +178,14 @@ export default function DataLayout() {
const
items
=
menusToMenuItems
(
menus
)
const
onOpenChange
=
(
keys
:
string
[])
=>
{
if
(
keys
.
length
>
1
)
{
setOpenKeys
([
keys
[
keys
.
length
-
1
]])
}
else
{
setOpenKeys
(
keys
)
}
}
return
(
<
div
className=
{
`data-layout ${collapsed ? 'collapsed' : ''}`
}
>
<
div
className=
"data-layout-sidebar"
>
...
...
@@ -194,7 +200,7 @@ export default function DataLayout() {
inlineCollapsed=
{
collapsed
}
selectedKeys=
{
selectedKeys
}
openKeys=
{
openKeys
}
onOpenChange=
{
setOpenKeys
}
onOpenChange=
{
onOpenChange
}
/>
</
div
>
</
div
>
...
...
src/hooks/useQuery.ts
浏览文件 @
b8930cc2
...
...
@@ -46,27 +46,45 @@ export function useDataQuery() {
return
{
data
:
{
total
:
0
,
list
:
[],
title
:
[]
}
}
},
})
const
file
=
query
.
data
.
info
?.
source
||
{}
useExcelQuery
(
file
.
url
)
return
query
}
export
function
useExcelQuery
(
url
:
string
)
{
const
query
=
useQuery
({
queryKey
:
[
'excel'
,
url
],
queryFn
:
()
=>
{
return
axios
(
url
,
{
responseType
:
'arraybuffer'
})
},
select
:
(
res
)
=>
res
.
data
,
enabled
:
!!
url
,
})
useEffect
(()
=>
{
if
(
query
.
data
?.
info
)
{
const
file
=
query
.
data
.
info
.
source
axios
(
file
.
url
,
{
responseType
:
'arraybuffer'
}).
then
((
res
)
=>
{
const
workbook
=
read
(
res
.
data
)
if
(
query
.
data
)
{
const
workbook
=
read
(
query
.
data
)
const
sheetName
=
workbook
.
SheetNames
[
0
]
const
worksheet
=
workbook
.
Sheets
[
sheetName
]
const
jsonData
=
utils
.
sheet_to_json
(
worksheet
,
{
defval
:
''
})
localStorage
.
setItem
(
'dataset'
,
JSON
.
stringify
(
jsonData
))
})
}
},
[
query
.
data
])
}
return
query
interface
DataField
{
name
:
string
english_name
:
string
type
:
string
}
export
function
useDataFieldQuery
()
{
const
query
=
useQuery
({
queryKey
:
[
'dataFiled'
],
queryFn
:
getMyField
,
select
:
(
res
)
=>
res
.
data
,
select
:
(
res
)
:
DataField
[]
=>
res
.
data
,
placeholderData
:
():
any
=>
{
return
{
data
:
[]
}
},
...
...
src/modules/data/digging/svm/components/ButtonModal.tsx
浏览文件 @
b8930cc2
...
...
@@ -27,7 +27,7 @@ export default function ButtonModal() {
</
Form
.
Item
>
<
Form
.
Item
label=
"请选择值映射字段"
name=
"checked"
>
<
Radio
.
Group
>
<
Row
gutter=
{
10
}
>
<
Row
gutter=
{
[
10
,
10
]
}
>
{
data
.
map
((
item
)
=>
(
<
Col
span=
{
8
}
key=
{
item
.
english_name
}
>
<
Radio
value=
{
item
.
name
}
>
{
item
.
name
}
</
Radio
>
...
...
src/modules/data/preprocess/null/components/ButtonModal.tsx
浏览文件 @
b8930cc2
...
...
@@ -8,7 +8,7 @@ export default function ButtonModal() {
const
[
searchParams
]
=
useSearchParams
()
const
results
=
searchParams
.
get
(
'results'
)?.
split
(
','
)
||
[]
const
{
data
}
=
useDataFieldQuery
()
const
{
data
:
fields
=
[]
}
=
useDataFieldQuery
()
const
[
open
,
setOpen
]
=
useState
(
results
.
length
>
0
)
const
[
current
,
setCurrent
]
=
useState
(
0
)
...
...
@@ -16,6 +16,7 @@ export default function ButtonModal() {
const
initialValues
=
{
checkedList
:
results
,
method
:
'unified'
,
rule
:
'1'
,
}
const
checkedList
=
Form
.
useWatch
(
'checkedList'
,
form
)
||
[]
...
...
@@ -38,7 +39,7 @@ export default function ButtonModal() {
{
label
:
'热卡填充(下)'
,
value
:
'7'
},
]
const
[
step
,
setStep
]
=
useState
<
number
>
(
null
)
const
[
step
,
setStep
]
=
useState
<
number
>
(
-
1
)
const
steps
=
[
{
...
...
@@ -46,8 +47,8 @@ export default function ButtonModal() {
content
:
(
<
Form
.
Item
name=
"checkedList"
>
<
Checkbox
.
Group
>
<
Row
gutter=
{
10
}
>
{
data
.
map
((
item
)
=>
(
<
Row
gutter=
{
[
10
,
10
]
}
>
{
fields
.
map
((
item
)
=>
(
<
Col
span=
{
6
}
key=
{
item
.
english_name
}
>
<
Checkbox
value=
{
item
.
name
}
>
{
item
.
name
}
</
Checkbox
>
</
Col
>
...
...
src/modules/data/preprocess/repeat/components/ButtonModal.tsx
浏览文件 @
b8930cc2
...
...
@@ -38,7 +38,7 @@ export default function ButtonModal() {
content
:
(
<
Form
.
Item
name=
"checkedList"
>
<
Checkbox
.
Group
>
<
Row
gutter=
{
10
}
>
<
Row
gutter=
{
[
10
,
10
]
}
>
{
data
.
map
((
item
)
=>
(
<
Col
span=
{
6
}
key=
{
item
.
english_name
}
>
<
Checkbox
value=
{
item
.
name
}
>
{
item
.
name
}
</
Checkbox
>
...
...
src/modules/data/process/mapping/components/ButtonModal.tsx
浏览文件 @
b8930cc2
import
{
useState
}
from
'react'
import
{
use
Effect
,
use
State
}
from
'react'
import
{
Button
,
Flex
,
Modal
,
Radio
,
Input
,
Form
,
Row
,
Col
,
Table
}
from
'antd'
import
{
useDataFieldQuery
}
from
'@/hooks/useQuery'
import
{
useData
Query
,
useData
FieldQuery
}
from
'@/hooks/useQuery'
import
AppProgressSteps
from
'@/components/AppProgressSteps'
import
{
uniqBy
}
from
'lodash-es'
export
default
function
ButtonModal
()
{
const
{
data
}
=
useDataFieldQuery
()
const
{
data
=
{
list
:
[]
}
}
=
useDataQuery
()
// 添加默认值防止 data 为 undefined
const
{
data
:
fields
=
[]
}
=
useDataFieldQuery
()
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
current
,
setCurrent
]
=
useState
(
0
)
const
[
form
]
=
Form
.
useForm
()
const
[
dataSource
,
setDataSource
]
=
useState
<
{
key
:
number
;
raw_value
:
string
;
mapping_value
:
string
}[]
>
([])
const
[
step
,
setStep
]
=
useState
(
-
1
)
// 使用 Form.useWatch 监听表单值变化
const
checked
=
Form
.
useWatch
(
'checked'
,
form
)
const
[
step
,
setStep
]
=
useState
<
number
>
(
-
1
)
// 当 checked 或 data 变化时更新数据源
useEffect
(()
=>
{
if
(
checked
&&
data
.
list
?.
length
)
{
const
uniqList
=
uniqBy
(
data
.
list
,
checked
)
setDataSource
(
uniqList
.
map
((
item
:
any
,
index
)
=>
({
key
:
index
+
1
,
raw_value
:
item
[
checked
]
||
''
,
mapping_value
:
''
,
}))
)
}
},
[
checked
,
data
.
list
])
// 处理映射值变化
const
handleMappingValueChange
=
(
value
:
string
,
key
:
number
)
=>
{
setDataSource
((
prevDataSource
)
=>
prevDataSource
.
map
((
item
)
=>
(
item
.
key
===
key
?
{
...
item
,
mapping_value
:
value
}
:
item
))
)
}
// 步骤定义
const
steps
=
[
{
title
:
'请选择值映射字段'
,
content
:
(
<>
<
Form
.
Item
label=
"值映射字段名称"
name=
"name"
>
<
Form
.
Item
label=
"值映射字段名称"
name=
"name"
rules=
{
[{
required
:
true
,
message
:
'请输入字段名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"值映射字段英文名称"
name=
"english_name"
>
<
Form
.
Item
label=
"值映射字段英文名称"
name=
"english_name"
rules=
{
[{
required
:
true
,
message
:
'请输入英文名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"请选择值映射字段"
name=
"checked"
>
<
Form
.
Item
label=
"请选择值映射字段"
name=
"checked"
rules=
{
[{
required
:
true
,
message
:
'请选择值映射字段'
}]
}
>
<
Radio
.
Group
>
<
Row
gutter=
{
10
}
>
{
data
.
map
((
item
)
=>
(
<
Row
gutter=
{
[
10
,
10
]
}
>
{
fields
.
map
((
item
)
=>
(
<
Col
span=
{
8
}
key=
{
item
.
english_name
}
>
<
Radio
value=
{
item
.
name
}
>
{
item
.
name
}
</
Radio
>
<
Radio
value=
{
item
.
english_
name
}
>
{
item
.
name
}
</
Radio
>
</
Col
>
))
}
</
Row
>
...
...
@@ -47,8 +75,25 @@ export default function ButtonModal() {
<
Form
.
Item
>
<
Table
bordered
columns=
{
[{
title
:
'序号'
},
{
title
:
'原始值'
},
{
title
:
'映射值'
}]
}
dataSource=
{
[]
}
></
Table
>
pagination=
{
{
pageSize
:
10
}
}
columns=
{
[
{
title
:
'序号'
,
dataIndex
:
'key'
,
align
:
'center'
,
width
:
80
},
{
title
:
'原始值'
,
dataIndex
:
'raw_value'
,
align
:
'center'
},
{
title
:
'映射值'
,
dataIndex
:
'mapping_value'
,
align
:
'center'
,
render
:
(
_
,
record
)
=>
(
<
Input
value=
{
record
.
mapping_value
}
onChange=
{
(
e
)
=>
handleMappingValueChange
(
e
.
target
.
value
,
record
.
key
)
}
placeholder=
"请输入映射值"
/>
),
},
]
}
dataSource=
{
dataSource
}
/>
</
Form
.
Item
>
</>
),
...
...
@@ -102,9 +147,9 @@ export default function ButtonModal() {
),
description
:
(
<>
累计处理
XX
个字段
累计处理
{
dataSource
.
length
}
个字段
<
br
/>
累计处理
XX
条记录
累计处理
{
data
.
list
?.
length
||
0
}
条记录
</>
),
},
...
...
@@ -116,25 +161,48 @@ export default function ButtonModal() {
},
]
// 处理下一步按钮逻辑
const
handleNext
=
async
()
=>
{
try
{
if
(
current
===
0
)
{
// 第一步验证表单
await
form
.
validateFields
([
'name'
,
'english_name'
,
'checked'
])
}
setCurrent
(
current
+
1
)
}
catch
(
error
)
{
// 表单验证错误处理
console
.
error
(
'表单验证失败'
,
error
)
}
}
// 重置状态
const
handleClose
=
()
=>
{
setOpen
(
false
)
setCurrent
(
0
)
setStep
(
-
1
)
form
.
resetFields
()
setDataSource
([])
}
return
(
<>
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
true
)
}
>
值映射
</
Button
>
<
Modal
title=
{
steps
[
current
].
title
}
title=
{
steps
[
current
]
?
.
title
}
open=
{
open
}
footer=
{
<
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=
{
()
=>
setCurrent
(
current
+
1
)
}
disabled=
{
!
checked
?.
length
}
>
<
Button
type=
"primary"
onClick=
{
handleNext
}
>
下一步
</
Button
>
)
}
{
current
===
steps
.
length
-
1
&&
(
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
false
)
}
>
<
Button
type=
"primary"
onClick=
{
handleClose
}
>
关闭
</
Button
>
)
}
...
...
@@ -142,11 +210,11 @@ export default function ButtonModal() {
}
destroyOnClose
width=
{
800
}
onCancel=
{
()
=>
setOpen
(
false
)
}
>
onCancel=
{
handleClose
}
>
<
div
style=
{
{
minHeight
:
300
,
padding
:
'20px 0'
}
}
>
<
Form
form=
{
form
}
labelCol=
{
{
span
:
5
}
}
preserve=
{
false
}
>
{
steps
.
map
((
item
,
index
)
=>
(
<
div
key=
{
index
}
hidden=
{
current
!==
index
}
style=
{
{
marginTop
:
'20px'
}
}
>
<
div
key=
{
index
}
style=
{
{
display
:
current
===
index
?
'block'
:
'none'
,
marginTop
:
'20px'
}
}
>
{
item
.
content
}
</
div
>
))
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论