Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
V
Vue-Dashboard
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
高源
Vue-Dashboard
Commits
b5c25409
Commit
b5c25409
authored
Jun 20, 2025
by
User
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
表格搜索区域和数据源、配置获取优化
parent
74076394
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
264 additions
and
201 deletions
+264
-201
.env.test
.env.test
+1
-1
SearchForm.vue
src/views/tableComponent/codet/components/SearchForm.vue
+146
-112
TableSettingsDrawer.vue
...s/tableComponent/codet/components/TableSettingsDrawer.vue
+13
-9
index.vue
src/views/tableComponent/index.vue
+104
-79
No files found.
.env.test
View file @
b5c25409
# backend service base url, test environment
# backend service base url, test environment
VITE_SERVICE_BASE_URL
=
'http://
localhost:80
'
VITE_SERVICE_BASE_URL
=
'http://
datav.kivii.org
'
# other backend service base url, test environment
# other backend service base url, test environment
VITE_OTHER_SERVICE_BASE_URL
=
`{
VITE_OTHER_SERVICE_BASE_URL
=
`{
...
...
src/views/tableComponent/codet/components/SearchForm.vue
View file @
b5c25409
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
inject
}
from
'vue'
;
import
{
computed
,
inject
}
from
'vue'
;
defineOptions
({
defineOptions
({
name
:
'SearchForm'
name
:
'SearchForm'
});
});
...
@@ -19,44 +19,114 @@ const toggleExpand = () => {
...
@@ -19,44 +19,114 @@ const toggleExpand = () => {
const
openSettings
=
()
=>
{
const
openSettings
=
()
=>
{
tableState
.
showSettingDrawer
.
value
=
true
;
tableState
.
showSettingDrawer
.
value
=
true
;
};
};
// 计算是否需要显示展开按钮(字段超过5个时才显示)
const
showExpandButton
=
computed
(()
=>
{
return
formItems
.
value
&&
formItems
.
value
.
length
>
5
;
});
// 计算当前显示的字段数量
const
visibleFields
=
computed
(()
=>
{
if
(
!
formItems
.
value
)
return
[];
return
isExpanded
.
value
?
formItems
.
value
:
formItems
.
value
.
slice
(
0
,
5
);
});
// 计算第一行显示的字段(如果折叠且超过5个字段,第一行显示5个字段,操作按钮在下一行)
const
firstRowFields
=
computed
(()
=>
{
if
(
!
formItems
.
value
)
return
[];
// 如果字段数量
<=
5
,或者已展开,正常显示
if
(
formItems
.
value
.
length
<=
5
||
isExpanded
.
value
)
{
return
visibleFields
.
value
;
}
// 如果字段数量 > 5 且折叠状态,第一行显示5个字段
return
formItems
.
value
.
slice
(
0
,
5
);
});
// 计算是否需要在第一行显示操作按钮
const
showActionsInFirstRow
=
computed
(()
=>
{
return
false
;
// 操作按钮总是单独占一行
});
</
script
>
</
script
>
<
template
>
<
template
>
<NCard
class=
"search-card"
:bordered=
"false"
content-style=
"padding: 0 12px 8px;margin-top:10px"
>
<NCard
class=
"search-card"
:bordered=
"false"
content-style=
"padding: 12px;"
>
<NGrid
:cols=
"6"
x-gap=
"8"
y-gap=
"8"
>
<!-- 顶部配置按钮区域 -->
<!-- 默认显示前5个表单项 -->
<div
class=
"top-actions"
>
<NGridItem
v-for=
"item in formItems.slice(0, 5)"
:key=
"item.key"
>
<NSpace
:size=
"8"
align=
"center"
>
<NButton
type=
"primary"
size=
"small"
@
click=
"() => handleCreate(null)"
>
新建
</NButton>
<NButton
size=
"small"
title=
"刷新数据"
@
click=
"fetchData"
>
<template
#
icon
>
<NIcon>
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
viewBox=
"0 0 24 24"
>
<path
d=
"M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"
fill=
"currentColor"
></path>
</svg>
</NIcon>
</
template
>
</NButton>
<NButton
size=
"small"
@
click=
"openSettings"
>
<
template
#
icon
>
<NIcon>
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
viewBox=
"0 0 24 24"
>
<path
opacity=
".3"
d=
"M19.28 8.6l-.7-1.21l-1.27.51l-1.06.43l-.91-.7c-.39-.3-.8-.54-1.23-.71l-1.06-.43l-.16-1.13L12.7 4h-1.4l-.19 1.35l-.16 1.13l-1.06.44c-.41.17-.82.41-1.25.73l-.9.68l-1.05-.42l-1.27-.52l-.7 1.21l1.08.84l.89.7l-.14 1.13c-.03.3-.05.53-.05.73s.02.43.05.73l.14 1.13l-.89.7l-1.08.84l.7 1.21l1.27-.51l1.06-.43l.91.7c.39.3.8.54 1.23.71l1.06.43l.16 1.13l.19 1.36h1.39l.19-1.35l.16-1.13l1.06-.43c.41-.17.82-.41 1.25-.73l.9-.68l1.04.42l1.27.51l.7-1.21l-1.08-.84l-.89-.7l.14-1.13c.04-.31.05-.52.05-.73c0-.21-.02-.43-.05-.73l-.14-1.13l.89-.7l1.1-.84zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4s-1.79 4-4 4z"
fill=
"currentColor"
></path>
<path
d=
"M19.43 12.98c.04-.32.07-.64.07-.98c0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46a.5.5 0 0 0-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65A.488.488 0 0 0 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1a.566.566 0 0 0-.18-.03c-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46a.5.5 0 0 0 .61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.42.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03c.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73c0 .21-.02.43-.05.73l-.14 1.13l.89.7l1.08.84l-.7 1.21l-1.27-.51l-1.04-.42l-.9.68c-.43.32-.84.56-1.25.73l-1.06.43l-.16 1.13l-.2 1.35h-1.4l-.19-1.35l-.16-1.13l-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7l-1.06.43l-1.27.51l-.7-1.21l1.08-.84l.89-.7l-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13l-.89-.7l-1.08-.84l.7-1.21l1.27.51l1.04.42l.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43l.16-1.13l.2-1.35h1.39l.19 1.35l.16 1.13l1.06.43c.43.18.83.41 1.23.71l.91.7l1.06-.43l1.27-.51l.7 1.21l-1.07.85l-.89.7l.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4s4-1.79 4-4s-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2s2 .9 2 2s-.9 2-2 2z"
fill=
"currentColor"
></path>
</svg>
</NIcon>
</
template
>
</NButton>
</NSpace>
</div>
<!-- 搜索表单区域 -->
<div
class=
"search-form-area"
>
<NGrid
:cols=
"24"
x-gap=
"12"
y-gap=
"12"
>
<!-- 第一行:搜索字段 + 操作按钮(如果需要) -->
<
template
v-for=
"item in firstRowFields"
:key=
"item.key"
>
<NGridItem
:span=
"4"
>
<NFormItem
:label=
"item.label"
label-placement=
"left"
>
<NFormItem
:label=
"item.label"
label-placement=
"left"
>
<NInput
<NInput
v-if=
"item.type === 'input'"
v-if=
"item.type === 'input'"
v-model:value=
"searchForm[item.key]"
v-model:value=
"searchForm[item.key]"
:placeholder=
"item.placeholder"
:placeholder=
"item.placeholder"
size=
"small"
></NInput>
></NInput>
<NSelect
<NSelect
v-if=
"item.type === 'select'"
v-if=
"item.type === 'select'"
v-model:value=
"searchForm[item.key]"
v-model:value=
"searchForm[item.key]"
:options=
"item.options"
:options=
"item.options"
:placeholder=
"item.placeholder"
:placeholder=
"item.placeholder"
size=
"small"
></NSelect>
></NSelect>
<NDatePicker
<NDatePicker
v-if=
"item.type === 'date'"
v-if=
"item.type === 'date'"
v-model:value=
"searchForm[item.key]"
v-model:value=
"searchForm[item.key]"
type=
"daterange"
type=
"daterange"
:placeholder=
"item.placeholder"
:placeholder=
"item.placeholder"
size=
"small"
clearable
clearable
></NDatePicker>
></NDatePicker>
</NFormItem>
</NFormItem>
</NGridItem>
</NGridItem>
</
template
>
<!-- 未展开时的操作按钮 -->
<!-- 第一行的操作按钮(当折叠且字段超过5个时) -->
<NGridItem
v-if=
"!isExpanded"
>
<NGridItem
v-if=
"showActionsInFirstRow"
:span=
"8"
>
<div
class=
"operation-buttons"
>
<div
class=
"action-buttons"
>
<NSpace
:size=
"8"
align=
"center"
:wrap=
"false"
>
<NSpace
:size=
"8"
>
<NButton
type=
"primary"
size=
"small"
@
click=
"() => handleCreate(null)"
>
新建
</NButton>
<NButton
type=
"primary"
size=
"small"
@
click=
"handleSearch"
>
查询
</NButton>
<NButton
type=
"primary"
size=
"small"
@
click=
"handleSearch"
>
查询
</NButton>
<NButton
size=
"small"
@
click=
"resetSearch"
>
重置
</NButton>
<NButton
size=
"small"
@
click=
"resetSearch"
>
重置
</NButton>
<NButton
v-if=
"showExpandButton"
size=
"small"
@
click=
"toggleExpand"
>
<NButton
size=
"small"
@
click=
"toggleExpand"
>
<
template
#
icon
>
<
template
#
icon
>
<NIcon>
<NIcon>
<svg
<svg
...
@@ -70,79 +140,45 @@ const openSettings = () => {
...
@@ -70,79 +140,45 @@ const openSettings = () => {
</NIcon>
</NIcon>
</
template
>
</
template
>
</NButton>
</NButton>
<NButton
size=
"small"
title=
"刷新数据"
@
click=
"fetchData"
>
<
template
#
icon
>
<NIcon>
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
viewBox=
"0 0 24 24"
>
<path
d=
"M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"
fill=
"currentColor"
></path>
</svg>
</NIcon>
</
template
>
</NButton>
<NButton
size=
"small"
@
click=
"openSettings"
>
<
template
#
icon
>
<NIcon>
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
viewBox=
"0 0 24 24"
>
<path
opacity=
".3"
d=
"M19.28 8.6l-.7-1.21l-1.27.51l-1.06.43l-.91-.7c-.39-.3-.8-.54-1.23-.71l-1.06-.43l-.16-1.13L12.7 4h-1.4l-.19 1.35l-.16 1.13l-1.06.44c-.41.17-.82.41-1.25.73l-.9.68l-1.05-.42l-1.27-.52l-.7 1.21l1.08.84l.89.7l-.14 1.13c-.03.3-.05.53-.05.73s.02.43.05.73l.14 1.13l-.89.7l-1.08.84l.7 1.21l1.27-.51l1.06-.43l.91.7c.39.3.8.54 1.23.71l1.06.43l.16 1.13l.19 1.36h1.39l.19-1.35l.16-1.13l1.06-.43c.41-.17.82-.41 1.25-.73l.9-.68l1.04.42l1.27.51l.7-1.21l-1.08-.84l-.89-.7l.14-1.13c.04-.31.05-.52.05-.73c0-.21-.02-.43-.05-.73l-.14-1.13l.89-.7l1.1-.84zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4s-1.79 4-4 4z"
fill=
"currentColor"
></path>
<path
d=
"M19.43 12.98c.04-.32.07-.64.07-.98c0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46a.5.5 0 0 0-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65A.488.488 0 0 0 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1a.566.566 0 0 0-.18-.03c-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46a.5.5 0 0 0 .61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.42.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03c.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73c0 .21-.02.43-.05.73l-.14 1.13l.89.7l1.08.84l-.7 1.21l-1.27-.51l-1.04-.42l-.9.68c-.43.32-.84.56-1.25.73l-1.06.43l-.16 1.13l-.2 1.35h-1.4l-.19-1.35l-.16-1.13l-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7l-1.06.43l-1.27.51l-.7-1.21l1.08-.84l.89-.7l-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13l-.89-.7l-1.08-.84l.7-1.21l1.27.51l1.04.42l.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43l.16-1.13l.2-1.35h1.39l.19 1.35l.16 1.13l1.06.43c.43.18.83.41 1.23.71l.91.7l1.06-.43l1.27-.51l.7 1.21l-1.07.85l-.89.7l.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4s4-1.79 4-4s-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2s2 .9 2 2s-.9 2-2 2z"
fill=
"currentColor"
></path>
</svg>
</NIcon>
</
template
>
</NButton>
</NSpace>
</NSpace>
</div>
</div>
</NGridItem>
</NGridItem>
<!-- 展开后的额外表单项 -->
<!-- 展开后的额外字段(如果已展开且有超过5个字段) -->
<
template
v-if=
"isExpanded"
>
<
template
v-if=
"isExpanded && formItems && formItems.length > 5"
>
<NGridItem
v-for=
"item in formItems.slice(5)"
:key=
"item.key"
>
<template
v-for=
"item in formItems.slice(5)"
:key=
"item.key"
>
<NGridItem
:span=
"4"
>
<NFormItem
:label=
"item.label"
label-placement=
"left"
>
<NFormItem
:label=
"item.label"
label-placement=
"left"
>
<NInput
<NInput
v-if=
"item.type === 'input'"
v-if=
"item.type === 'input'"
v-model:value=
"searchForm[item.key]"
v-model:value=
"searchForm[item.key]"
:placeholder=
"item.placeholder"
:placeholder=
"item.placeholder"
size=
"small"
></NInput>
></NInput>
<NSelect
<NSelect
v-if=
"item.type === 'select'"
v-if=
"item.type === 'select'"
v-model:value=
"searchForm[item.key]"
v-model:value=
"searchForm[item.key]"
:options=
"item.options"
:options=
"item.options"
:placeholder=
"item.placeholder"
:placeholder=
"item.placeholder"
size=
"small"
></NSelect>
></NSelect>
<NDatePicker
<NDatePicker
v-if=
"item.type === 'date'"
v-if=
"item.type === 'date'"
v-model:value=
"searchForm[item.key]"
v-model:value=
"searchForm[item.key]"
type=
"daterange"
type=
"daterange"
:placeholder=
"item.placeholder"
:placeholder=
"item.placeholder"
size=
"small"
clearable
clearable
></NDatePicker>
></NDatePicker>
</NFormItem>
</NFormItem>
</NGridItem>
</NGridItem>
</
template
>
<!-- 展开后的操作按钮,独占一行并靠左对齐 -->
<!-- 展开状态下的操作按钮 -->
<NGridItem
:span=
"6"
>
<NGridItem
:span=
"4"
>
<div
class=
"operation-buttons-expanded"
>
<div
class=
"action-buttons"
>
<NSpace
:size=
"8"
align=
"center"
:wrap=
"false"
>
<NSpace
:size=
"8"
>
<NButton
size=
"small"
@
click=
"() => handleCreate(null)"
>
新建
</NButton>
<NButton
type=
"primary"
size=
"small"
@
click=
"handleSearch"
>
查询
</NButton>
<NButton
size=
"small"
@
click=
"handleSearch"
>
查询
</NButton>
<NButton
size=
"small"
@
click=
"resetSearch"
>
重置
</NButton>
<NButton
size=
"small"
@
click=
"resetSearch"
>
重置
</NButton>
<NButton
size=
"small"
@
click=
"toggleExpand"
>
<NButton
size=
"small"
@
click=
"toggleExpand"
>
<
template
#
icon
>
<
template
#
icon
>
...
@@ -162,23 +198,18 @@ const openSettings = () => {
...
@@ -162,23 +198,18 @@ const openSettings = () => {
</NIcon>
</NIcon>
</
template
>
</
template
>
</NButton>
</NButton>
<NButton
size=
"small"
title=
"刷新数据"
@
click=
"fetchData"
>
</NSpace>
<
template
#
icon
>
</div>
<NIcon>
</NGridItem>
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
viewBox=
"0 0 24 24"
>
<path
d=
"M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"
fill=
"currentColor"
></path>
</svg>
</NIcon>
</template>
</template>
</NButton>
<NButton
size=
"small"
@
click=
"openSettings"
>
<!-- 折叠状态下的操作按钮(当字段超过5个且折叠时) -->
<NGridItem
v-if=
"!isExpanded && showExpandButton"
:span=
"4"
>
<div
class=
"action-buttons"
>
<NSpace
:size=
"8"
>
<NButton
type=
"primary"
size=
"small"
@
click=
"handleSearch"
>
查询
</NButton>
<NButton
size=
"small"
@
click=
"resetSearch"
>
重置
</NButton>
<NButton
size=
"small"
@
click=
"toggleExpand"
>
<
template
#
icon
>
<
template
#
icon
>
<NIcon>
<NIcon>
<svg
<svg
...
@@ -186,15 +217,8 @@ const openSettings = () => {
...
@@ -186,15 +217,8 @@ const openSettings = () => {
xmlns:xlink=
"http://www.w3.org/1999/xlink"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
viewBox=
"0 0 24 24"
viewBox=
"0 0 24 24"
>
>
<path
<path
d=
"M18 6.41L16.59 5L12 9.58L7.41 5L6 6.41l6 6z"
fill=
"currentColor"
></path>
opacity=
".3"
<path
d=
"M18 13l-1.41-1.41L12 16.17l-4.59-4.58L6 13l6 6z"
fill=
"currentColor"
></path>
d=
"M19.28 8.6l-.7-1.21l-1.27.51l-1.06.43l-.91-.7c-.39-.3-.8-.54-1.23-.71l-1.06-.43l-.16-1.13L12.7 4h-1.4l-.19 1.35l-.16 1.13l-1.06.44c-.41.17-.82.41-1.25.73l-.9.68l-1.05-.42l-1.27-.52l-.7 1.21l1.08.84l.89.7l-.14 1.13c-.03.3-.05.53-.05.73s.02.43.05.73l.14 1.13l-.89.7l-1.08.84l.7 1.21l1.27-.51l1.06-.43l.91.7c.39.3.8.54 1.23.71l1.06.43l.16 1.13l.19 1.36h1.39l.19-1.35l.16-1.13l1.06-.43c.41-.17.82-.41 1.25-.73l.9-.68l1.04.42l1.27.51l.7-1.21l-1.08-.84l-.89-.7l.14-1.13c.04-.31.05-.52.05-.73c0-.21-.02-.43-.05-.73l-.14-1.13l.89-.7l1.1-.84zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4s4 1.79 4 4s-1.79 4-4 4z"
fill=
"currentColor"
></path>
<path
d=
"M19.43 12.98c.04-.32.07-.64.07-.98c0-.34-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46a.5.5 0 0 0-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65A.488.488 0 0 0 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1a.566.566 0 0 0-.18-.03c-.17 0-.34.09-.43.25l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46a.5.5 0 0 0 .61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.42.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.06.02.12.03.18.03c.17 0 .34-.09.43-.25l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zm-1.98-1.71c.04.31.05.52.05.73c0 .21-.02.43-.05.73l-.14 1.13l.89.7l1.08.84l-.7 1.21l-1.27-.51l-1.04-.42l-.9.68c-.43.32-.84.56-1.25.73l-1.06.43l-.16 1.13l-.2 1.35h-1.4l-.19-1.35l-.16-1.13l-1.06-.43c-.43-.18-.83-.41-1.23-.71l-.91-.7l-1.06.43l-1.27.51l-.7-1.21l1.08-.84l.89-.7l-.14-1.13c-.03-.31-.05-.54-.05-.74s.02-.43.05-.73l.14-1.13l-.89-.7l-1.08-.84l.7-1.21l1.27.51l1.04.42l.9-.68c.43-.32.84-.56 1.25-.73l1.06-.43l.16-1.13l.2-1.35h1.39l.19 1.35l.16 1.13l1.06.43c.43.18.83.41 1.23.71l.91.7l1.06-.43l1.27-.51l.7 1.21l-1.07.85l-.89.7l.14 1.13zM12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4s4-1.79 4-4s-1.79-4-4-4zm0 6c-1.1 0-2-.9-2-2s.9-2 2-2s2 .9 2 2s-.9 2-2 2z"
fill=
"currentColor"
></path>
</svg>
</svg>
</NIcon>
</NIcon>
</
template
>
</
template
>
...
@@ -202,8 +226,18 @@ const openSettings = () => {
...
@@ -202,8 +226,18 @@ const openSettings = () => {
</NSpace>
</NSpace>
</div>
</div>
</NGridItem>
</NGridItem>
</template>
<!-- 字段数量 <= 5 时的操作按钮 -->
<NGridItem
v-if=
"!showExpandButton"
:span=
"4"
>
<div
class=
"action-buttons"
>
<NSpace
:size=
"8"
>
<NButton
type=
"primary"
size=
"small"
@
click=
"handleSearch"
>
查询
</NButton>
<NButton
size=
"small"
@
click=
"resetSearch"
>
重置
</NButton>
</NSpace>
</div>
</NGridItem>
</NGrid>
</NGrid>
</div>
</NCard>
</NCard>
</template>
</template>
...
@@ -212,22 +246,16 @@ const openSettings = () => {
...
@@ -212,22 +246,16 @@ const openSettings = () => {
margin-bottom
:
8px
;
margin-bottom
:
8px
;
}
}
.
operation-butt
ons
{
.
top-acti
ons
{
display
:
flex
;
display
:
flex
;
align-items
:
center
;
height
:
100%
;
padding-bottom
:
2px
;
}
.operation-buttons-expanded
{
display
:
flex
;
align-items
:
center
;
padding
:
8px
0
0
0
;
justify-content
:
flex-end
;
justify-content
:
flex-end
;
margin-bottom
:
16px
;
padding-bottom
:
12px
;
border-bottom
:
1px
solid
var
(
--n-border-color
);
}
}
:deep
(
.n-space
)
{
.search-form-area
{
flex-wrap
:
nowrap
;
margin-top
:
8px
;
}
}
:deep
(
.n-form-item
)
{
:deep
(
.n-form-item
)
{
...
@@ -235,29 +263,24 @@ const openSettings = () => {
...
@@ -235,29 +263,24 @@ const openSettings = () => {
}
}
:deep
(
.n-form-item-label
)
{
:deep
(
.n-form-item-label
)
{
width
:
1
2
0px
;
width
:
1
0
0px
;
justify-content
:
flex-end
;
justify-content
:
flex-end
;
padding
:
0
;
padding-right
:
8px
;
margin-right
:
4px
;
font-size
:
14px
;
text-align
:
right
;
color
:
var
(
--n-text-color-2
);
white-space
:
normal
;
align-items
:
flex-start
;
display
:
flex
;
height
:
28px
;
padding-top
:
5px
;
}
}
:deep
(
.n-form-item-label
label
)
{
:deep
(
.n-form-item-label
label
)
{
display
:
inline-block
;
line-height
:
1
;
text-align
:
right
;
margin
:
0
;
width
:
100%
;
}
:deep
(
.n-form-item-label
label
:after
)
{
content
:
''
;
display
:
block
;
text-align
:
left
;
}
}
:deep
(
.n-form-item-blank
)
{
:deep
(
.n-form-item-blank
)
{
min-height
:
28px
;
min-height
:
28px
;
justify-content
:
flex-end
;
}
}
:deep
(
.n-input
)
{
:deep
(
.n-input
)
{
...
@@ -275,4 +298,15 @@ const openSettings = () => {
...
@@ -275,4 +298,15 @@ const openSettings = () => {
:deep
(
.n-form-item-feedback-wrapper
)
{
:deep
(
.n-form-item-feedback-wrapper
)
{
display
:
none
;
display
:
none
;
}
}
:deep
(
.n-card__content
)
{
padding
:
12px
!important
;
}
.action-buttons
{
margin-left
:
0px
;
/* 100px label宽度 + 8px padding-right */
height
:
28px
;
display
:
flex
;
align-items
:
center
;
}
</
style
>
</
style
>
src/views/tableComponent/codet/components/TableSettingsDrawer.vue
View file @
b5c25409
...
@@ -196,9 +196,9 @@ const applySettings = (settings: any) => {
...
@@ -196,9 +196,9 @@ const applySettings = (settings: any) => {
});
});
}
}
// 如果有转换规则,自动应用转换
// 如果有转换规则,自动应用转换
(静默模式,避免在数据未加载时显示错误)
if
(
settings
.
transformSettings
.
transformRules
?.
length
>
0
)
{
if
(
settings
.
transformSettings
.
transformRules
?.
length
>
0
)
{
tableMethods
.
applyTransformations
();
tableMethods
.
applyTransformations
(
true
);
}
}
}
}
};
};
...
@@ -208,10 +208,11 @@ const handleGetSettings = async () => {
...
@@ -208,10 +208,11 @@ const handleGetSettings = async () => {
try
{
try
{
// 在请求前检查必要的配置参数
// 在请求前检查必要的配置参数
if
(
!
uiConfig
.
GetUrl
||
!
uiConfig
.
Type
)
{
if
(
!
uiConfig
.
GetUrl
||
!
uiConfig
.
Type
)
{
// console.warn('缺少必要的配置参数,无法获取配置
');
console
.
log
(
'📋 缺少必要的配置参数,无法获取配置,需要调用字段匹配接口
'
);
return
;
return
false
;
// 返回false表示没有获取到配置
}
}
console
.
log
(
'📋 尝试从 GetUrl 获取配置:'
,
uiConfig
.
GetUrl
);
const
response
=
await
axios
.
post
(
uiConfig
.
GetUrl
,
{
const
response
=
await
axios
.
post
(
uiConfig
.
GetUrl
,
{
Type
:
uiConfig
.
Type
,
Type
:
uiConfig
.
Type
,
InternalCode
:
uiConfig
.
InternalCode
,
InternalCode
:
uiConfig
.
InternalCode
,
...
@@ -220,15 +221,18 @@ const handleGetSettings = async () => {
...
@@ -220,15 +221,18 @@ const handleGetSettings = async () => {
if
(
response
.
data
?.
Parameters
)
{
if
(
response
.
data
?.
Parameters
)
{
settings
.
value
=
JSON
.
parse
(
response
.
data
.
Parameters
);
settings
.
value
=
JSON
.
parse
(
response
.
data
.
Parameters
);
// console.log('
获取到的配置信息:', settings.value);
console
.
log
(
'✅
获取到的配置信息:'
,
settings
.
value
);
applySettings
(
settings
.
value
);
applySettings
(
settings
.
value
);
// window.$message?.success('配置信息获取成功');
console
.
log
(
'✅ 配置信息获取成功,跳过字段匹配接口'
);
return
true
;
// 返回true表示成功获取到配置
}
else
{
}
else
{
// console.log('没有获取到配置参数,使用默认配置');
console
.
log
(
'⚠️ 没有获取到配置参数,需要调用字段匹配接口'
);
return
false
;
// 返回false表示没有获取到配置
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
// console.error('获取配置失败:', error);
console
.
error
(
'❌ 获取配置失败:'
,
error
);
window
.
$message
?.
error
(
'获取配置失败'
);
// window.$message?.error('获取配置失败');
return
false
;
// 返回false表示获取配置失败
}
}
};
};
...
...
src/views/tableComponent/index.vue
View file @
b5c25409
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-underscore-dangle */
import
{
computed
,
defineProps
,
h
,
nextTick
,
onActivated
,
onMounted
,
provide
,
ref
,
watch
,
withDefaults
}
from
'vue'
;
import
{
computed
,
defineProps
,
h
,
onActivated
,
onMounted
,
provide
,
ref
,
watch
,
withDefaults
}
from
'vue'
;
import
SearchForm
from
'./codet/components/SearchForm.vue'
;
import
SearchForm
from
'./codet/components/SearchForm.vue'
;
import
DataTable
from
'./codet/components/DataTable.vue'
;
import
DataTable
from
'./codet/components/DataTable.vue'
;
import
TableSettingsDrawer
from
'./codet/components/TableSettingsDrawer.vue'
;
import
TableSettingsDrawer
from
'./codet/components/TableSettingsDrawer.vue'
;
...
@@ -9,7 +9,7 @@ import SearchFieldEditDrawer from './codet/components/SearchFieldEditDrawer.vue'
...
@@ -9,7 +9,7 @@ import SearchFieldEditDrawer from './codet/components/SearchFieldEditDrawer.vue'
import
AddFieldDrawer
from
'./codet/components/AddFieldDrawer.vue'
;
import
AddFieldDrawer
from
'./codet/components/AddFieldDrawer.vue'
;
import
DataTransform
from
'./codet/components/DataTransform.vue'
;
import
DataTransform
from
'./codet/components/DataTransform.vue'
;
import
CreateDialog
from
'./codet/components/CreateDialog.vue'
;
import
CreateDialog
from
'./codet/components/CreateDialog.vue'
;
//
使用封装的axios实例 - 已在main.ts中全局注册,支持代理
//
通过window对象使用axios - 已在main.ts中全局注册
const
axios
=
(
window
as
any
).
$axios
;
const
axios
=
(
window
as
any
).
$axios
;
// 定义组件名称,避免与HTML元素冲突
// 定义组件名称,避免与HTML元素冲突
...
@@ -32,7 +32,15 @@ interface Props {
...
@@ -32,7 +32,15 @@ interface Props {
}
}
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
uiConfig
:
()
=>
({})
uiConfig
:
()
=>
({
Type
:
'Kivii.Finances.Entities.Invoice'
,
InternalCode
:
'发票管理(tableField)'
,
IsDefault
:
true
,
InitQuery
:
'/Restful/Kivii.Finances.Entities.Invoice/Query.json'
,
GetUrl
:
'/Restful/Kivii.Basic.Entities.UiConfig/Get.json'
,
SetUrl
:
'/Restful/Kivii.Basic.Entities.UiConfig/Set.json'
,
CreateVueUrl
:
'/codet/invoiceContent.vue'
})
});
});
// 分页配置
// 分页配置
const
pagination
=
ref
({
const
pagination
=
ref
({
...
@@ -168,6 +176,11 @@ const generateColumns = (data: any): TableColumn[] => {
...
@@ -168,6 +176,11 @@ const generateColumns = (data: any): TableColumn[] => {
const
processField
=
(
obj
:
any
,
prefix
=
''
)
=>
{
const
processField
=
(
obj
:
any
,
prefix
=
''
)
=>
{
Object
.
entries
(
obj
).
forEach
(([
key
,
value
])
=>
{
Object
.
entries
(
obj
).
forEach
(([
key
,
value
])
=>
{
// 过滤掉 Metadata 字段和包含 Kvid 的字段
if
(
key
===
'Metadata'
||
key
.
toLowerCase
().
includes
(
'kvid'
))
{
return
;
// 跳过这些字段
}
// 处理数组类型字段
// 处理数组类型字段
if
(
Array
.
isArray
(
value
))
{
if
(
Array
.
isArray
(
value
))
{
const
columnKey
=
prefix
+
key
;
const
columnKey
=
prefix
+
key
;
...
@@ -205,6 +218,11 @@ const generateColumns = (data: any): TableColumn[] => {
...
@@ -205,6 +218,11 @@ const generateColumns = (data: any): TableColumn[] => {
// 处理嵌套对象
// 处理嵌套对象
else
if
(
value
&&
typeof
value
===
'object'
&&
!
Array
.
isArray
(
value
))
{
else
if
(
value
&&
typeof
value
===
'object'
&&
!
Array
.
isArray
(
value
))
{
Object
.
entries
(
value
as
object
).
forEach
(([
nestedKey
,
_
])
=>
{
Object
.
entries
(
value
as
object
).
forEach
(([
nestedKey
,
_
])
=>
{
// 也过滤嵌套对象中的 Metadata 和 Kvid 字段
if
(
nestedKey
===
'Metadata'
||
nestedKey
.
toLowerCase
().
includes
(
'kvid'
))
{
return
;
// 跳过这些字段
}
const
columnKey
=
`
${
key
}
.
${
nestedKey
}
`
;
const
columnKey
=
`
${
key
}
.
${
nestedKey
}
`
;
// 查找原有列的配置
// 查找原有列的配置
const
existingColumn
=
rawColumns
.
value
.
find
(
col
=>
col
.
key
===
columnKey
);
const
existingColumn
=
rawColumns
.
value
.
find
(
col
=>
col
.
key
===
columnKey
);
...
@@ -415,11 +433,6 @@ const newFilterLabel = ref('');
...
@@ -415,11 +433,6 @@ const newFilterLabel = ref('');
const
newFilterValue
=
ref
(
''
);
const
newFilterValue
=
ref
(
''
);
// 添加获取所有设置的方法
// 添加获取所有设置的方法
const
getAllTableSettings
=
async
()
=>
{
if
(
tableSettingsDrawerRef
.
value
)
{
await
tableSettingsDrawerRef
.
value
.
handleGetSettings
();
}
};
// 处理新建
// 处理新建
const
handleCreate
=
(
row
?:
any
)
=>
{
const
handleCreate
=
(
row
?:
any
)
=>
{
...
@@ -486,30 +499,27 @@ const buildSearchParams = () => {
...
@@ -486,30 +499,27 @@ const buildSearchParams = () => {
};
};
// 获取数据
// 获取数据
// 修正后的fetchData函数
async
function
fetchData
()
{
async
function
fetchData
()
{
console
.
log
(
'🚀 fetchData 被调用,axios 可用:'
,
Boolean
(
axios
));
loading
.
value
=
true
;
loading
.
value
=
true
;
try
{
try
{
const
searchParams
=
buildSearchParams
();
const
searchParams
=
buildSearchParams
();
// 自定义axios请求配置,使用自定义参数序列化函数
// ✅ 使用 window.$api.request 获取数据
console
.
log
(
'📡 发送请求到 /table.json'
);
const
{
data
:
response
,
error
}
=
await
window
.
$api
.
request
({
const
response
=
await
axios
.
get
(
'/codet/test.json'
,
{
method
:
'POST'
,
url
:
props
.
uiConfig
.
InitQuery
,
params
:
searchParams
,
params
:
searchParams
,
paramsSerializer
:
(
params
:
any
)
=>
{
paramsSerializer
:
(
params
:
any
)
=>
{
// 自定义参数序列化,避免数组被转换为key[]=value格式
const
queryParams
:
string
[]
=
[];
const
queryParams
:
string
[]
=
[];
for
(
const
key
in
params
)
{
for
(
const
key
in
params
)
{
if
(
params
[
key
]
!==
undefined
&&
params
[
key
]
!==
null
)
{
if
(
params
[
key
]
!==
undefined
&&
params
[
key
]
!==
null
)
{
if
(
Array
.
isArray
(
params
[
key
]))
{
if
(
Array
.
isArray
(
params
[
key
]))
{
// 只在数组不为空时添加参数
if
(
params
[
key
].
length
>
0
)
{
if
(
params
[
key
].
length
>
0
)
{
// 数组类型使用JSON.stringify处理,并将参数名变为复数形式
queryParams
.
push
(
`
${
encodeURIComponent
(
`
${
key
}
s`
)}
=
${
encodeURIComponent
(
JSON
.
stringify
(
params
[
key
]))}
`
);
queryParams
.
push
(
`
${
encodeURIComponent
(
`
${
key
}
s`
)}
=
${
encodeURIComponent
(
JSON
.
stringify
(
params
[
key
]))}
`
);
}
}
}
else
{
}
else
{
// 非数组类型参数保持原样
queryParams
.
push
(
`
${
encodeURIComponent
(
key
)}
=
${
encodeURIComponent
(
params
[
key
])}
`
);
queryParams
.
push
(
`
${
encodeURIComponent
(
key
)}
=
${
encodeURIComponent
(
params
[
key
])}
`
);
}
}
}
}
...
@@ -518,17 +528,24 @@ async function fetchData() {
...
@@ -518,17 +528,24 @@ async function fetchData() {
return
queryParams
.
join
(
'&'
);
return
queryParams
.
join
(
'&'
);
}
}
});
});
console
.
log
(
'✅ 请求成功,响应:'
,
response
.
status
,
response
.
data
?.
Results
?.
length
||
0
,
'条数据'
);
if
(
response
.
data
?.
Results
?.
length
)
{
// ✅ 处理第一个请求的错误
// 保存当前的filter状态
if
(
error
)
{
const
currentFilterState
:
Record
<
console
.
error
(
'❌ 数据请求失败:'
,
error
);
string
,
tableData
.
value
=
[];
{
pagination
.
value
.
itemCount
=
0
;
filter
:
boolean
;
return
;
filterOptions
?:
{
label
:
string
;
value
:
string
}[];
filterOptionValues
?:
string
[]
|
null
;
}
}
>
=
rawColumns
.
value
.
reduce
((
acc
:
Record
<
string
,
any
>
,
col
)
=>
{
// ✅ 正确访问返回的数据
console
.
log
(
'✅ 数据请求成功:'
,
response
);
// 检查数据结构 - response就是业务数据,不需要再访问.data
if
(
response
?.
Results
?.
length
)
{
console
.
log
(
'📊 获取到数据:'
,
response
.
Results
.
length
,
'条'
);
// 保存当前的filter状态
const
currentFilterState
:
Record
<
string
,
any
>
=
rawColumns
.
value
.
reduce
((
acc
:
Record
<
string
,
any
>
,
col
)
=>
{
if
(
col
.
filter
&&
col
.
filterOptionValues
)
{
if
(
col
.
filter
&&
col
.
filterOptionValues
)
{
acc
[
col
.
key
]
=
{
acc
[
col
.
key
]
=
{
filter
:
col
.
filter
,
filter
:
col
.
filter
,
...
@@ -539,18 +556,19 @@ async function fetchData() {
...
@@ -539,18 +556,19 @@ async function fetchData() {
return
acc
;
return
acc
;
},
{});
},
{});
//
先获取字段配置
//
✅ 获取字段配置用于生成基础列
let
fieldConfigs
=
[];
let
fieldConfigs
=
[];
try
{
const
{
data
:
entityData
,
error
:
entityError
}
=
await
window
.
$api
.
get
(
`/Server/Entity/
${
props
.
uiConfig
.
Type
}
`
);
const
entityResponse
=
await
axios
.
get
(
`/Server/Entity/
${
props
.
uiConfig
.
Type
}
`
);
if
(
entityResponse
.
data
?.
Results
)
{
if
(
entityError
)
{
fieldConfigs
=
entityResponse
.
data
.
Results
;
console
.
warn
(
'⚠️ 获取字段配置失败:'
,
entityError
);
}
// 不阻断主流程,使用空配置继续
}
catch
(
error
)
{
}
else
if
(
entityData
?.
Results
)
{
// console.error('获取字段配置失败:', error);
fieldConfigs
=
entityData
.
Results
;
console
.
log
(
'✅ 字段配置获取成功:'
,
fieldConfigs
.
length
,
'个字段'
);
}
}
// 生成列配置
时传入字段配置
// 生成列配置
- 使用response.Results而不是response.data.Results
const
generateColumnsWithConfig
=
(
data
:
any
,
configs
:
any
[]):
TableColumn
[]
=>
{
const
generateColumnsWithConfig
=
(
data
:
any
,
configs
:
any
[]):
TableColumn
[]
=>
{
if
(
!
data
)
return
[];
if
(
!
data
)
return
[];
const
newColumns
:
TableColumn
[]
=
[];
const
newColumns
:
TableColumn
[]
=
[];
...
@@ -568,11 +586,14 @@ async function fetchData() {
...
@@ -568,11 +586,14 @@ async function fetchData() {
const
processField
=
(
obj
:
any
,
prefix
=
''
)
=>
{
const
processField
=
(
obj
:
any
,
prefix
=
''
)
=>
{
Object
.
entries
(
obj
).
forEach
(([
key
,
value
])
=>
{
Object
.
entries
(
obj
).
forEach
(([
key
,
value
])
=>
{
// 查找字段配置
// 过滤掉 Metadata 字段和包含 Kvid 的字段
if
(
key
===
'Metadata'
||
key
.
toLowerCase
().
includes
(
'kvid'
))
{
return
;
// 跳过这些字段
}
const
fieldConfig
=
configs
.
find
(
field
=>
field
.
Name
===
key
);
const
fieldConfig
=
configs
.
find
(
field
=>
field
.
Name
===
key
);
const
displayName
=
fieldConfig
?.
DisplayName
||
key
;
const
displayName
=
fieldConfig
?.
DisplayName
||
key
;
// 处理数组类型字段
if
(
Array
.
isArray
(
value
))
{
if
(
Array
.
isArray
(
value
))
{
const
columnKey
=
prefix
+
key
;
const
columnKey
=
prefix
+
key
;
const
existingColumn
=
rawColumns
.
value
.
find
(
col
=>
col
.
key
===
columnKey
);
const
existingColumn
=
rawColumns
.
value
.
find
(
col
=>
col
.
key
===
columnKey
);
...
@@ -582,9 +603,7 @@ async function fetchData() {
...
@@ -582,9 +603,7 @@ async function fetchData() {
key
:
columnKey
,
key
:
columnKey
,
width
:
200
,
width
:
200
,
minWidth
:
150
,
minWidth
:
150
,
ellipsis
:
existingColumn
?.
ellipsis
??
{
ellipsis
:
existingColumn
?.
ellipsis
??
{
tooltip
:
true
},
tooltip
:
true
},
resizable
:
true
,
resizable
:
true
,
sortable
:
false
,
sortable
:
false
,
render
:
(
row
:
any
)
=>
{
render
:
(
row
:
any
)
=>
{
...
@@ -604,10 +623,13 @@ async function fetchData() {
...
@@ -604,10 +623,13 @@ async function fetchData() {
return
''
;
return
''
;
}
}
});
});
}
}
else
if
(
value
&&
typeof
value
===
'object'
&&
!
Array
.
isArray
(
value
))
{
// 处理嵌套对象
else
if
(
value
&&
typeof
value
===
'object'
&&
!
Array
.
isArray
(
value
))
{
Object
.
entries
(
value
as
object
).
forEach
(([
nestedKey
,
_
])
=>
{
Object
.
entries
(
value
as
object
).
forEach
(([
nestedKey
,
_
])
=>
{
// 也过滤嵌套对象中的 Metadata 和 Kvid 字段
if
(
nestedKey
===
'Metadata'
||
nestedKey
.
toLowerCase
().
includes
(
'kvid'
))
{
return
;
// 跳过这些字段
}
const
columnKey
=
`
${
key
}
.
${
nestedKey
}
`
;
const
columnKey
=
`
${
key
}
.
${
nestedKey
}
`
;
const
existingColumn
=
rawColumns
.
value
.
find
(
col
=>
col
.
key
===
columnKey
);
const
existingColumn
=
rawColumns
.
value
.
find
(
col
=>
col
.
key
===
columnKey
);
const
nestedFieldConfig
=
configs
.
find
(
field
=>
field
.
Name
===
nestedKey
);
const
nestedFieldConfig
=
configs
.
find
(
field
=>
field
.
Name
===
nestedKey
);
...
@@ -618,9 +640,7 @@ async function fetchData() {
...
@@ -618,9 +640,7 @@ async function fetchData() {
key
:
columnKey
,
key
:
columnKey
,
width
:
key
.
includes
(
'Time'
)
?
200
:
150
,
width
:
key
.
includes
(
'Time'
)
?
200
:
150
,
minWidth
:
100
,
minWidth
:
100
,
ellipsis
:
existingColumn
?.
ellipsis
??
{
ellipsis
:
existingColumn
?.
ellipsis
??
{
tooltip
:
true
},
tooltip
:
true
},
resizable
:
true
,
resizable
:
true
,
sortable
:
existingColumn
?.
sortable
??
false
,
sortable
:
existingColumn
?.
sortable
??
false
,
...(
existingColumn
?.
filter
...(
existingColumn
?.
filter
...
@@ -643,9 +663,7 @@ async function fetchData() {
...
@@ -643,9 +663,7 @@ async function fetchData() {
}
}
});
});
});
});
}
}
else
{
// 处理普通字段
else
{
const
columnKey
=
prefix
+
key
;
const
columnKey
=
prefix
+
key
;
const
existingColumn
=
rawColumns
.
value
.
find
(
col
=>
col
.
key
===
columnKey
);
const
existingColumn
=
rawColumns
.
value
.
find
(
col
=>
col
.
key
===
columnKey
);
...
@@ -654,9 +672,7 @@ async function fetchData() {
...
@@ -654,9 +672,7 @@ async function fetchData() {
key
:
columnKey
,
key
:
columnKey
,
width
:
key
.
includes
(
'Time'
)
?
200
:
150
,
width
:
key
.
includes
(
'Time'
)
?
200
:
150
,
minWidth
:
100
,
minWidth
:
100
,
ellipsis
:
existingColumn
?.
ellipsis
??
{
ellipsis
:
existingColumn
?.
ellipsis
??
{
tooltip
:
true
},
tooltip
:
true
},
resizable
:
true
,
resizable
:
true
,
sortable
:
existingColumn
?.
sortable
??
false
,
sortable
:
existingColumn
?.
sortable
??
false
,
...(
existingColumn
?.
filter
...(
existingColumn
?.
filter
...
@@ -683,13 +699,12 @@ async function fetchData() {
...
@@ -683,13 +699,12 @@ async function fetchData() {
return
newColumns
;
return
newColumns
;
};
};
// 使用新的生成函数生成列配置
// ✅ 生成基础列配置(无论是否有保存的配置都需要基础列)
rawColumns
.
value
=
generateColumnsWithConfig
(
response
.
data
.
Results
[
0
],
fieldConfigs
);
console
.
log
(
'📋 生成基础列配置'
);
rawColumns
.
value
=
generateColumnsWithConfig
(
response
.
Results
[
0
],
fieldConfigs
);
// 确保所有列在rawColumns更新后默认可见
visibleColumns
.
value
=
rawColumns
.
value
.
map
(
col
=>
col
.
key
);
visibleColumns
.
value
=
rawColumns
.
value
.
map
(
col
=>
col
.
key
);
// 恢复
之前的
筛选状态
// 恢复筛选状态
if
(
Object
.
keys
(
currentFilterState
).
length
>
0
)
{
if
(
Object
.
keys
(
currentFilterState
).
length
>
0
)
{
rawColumns
.
value
.
forEach
(
col
=>
{
rawColumns
.
value
.
forEach
(
col
=>
{
const
savedState
=
currentFilterState
[
col
.
key
];
const
savedState
=
currentFilterState
[
col
.
key
];
...
@@ -701,24 +716,29 @@ async function fetchData() {
...
@@ -701,24 +716,29 @@ async function fetchData() {
});
});
}
}
tableData
.
value
=
response
.
data
.
Results
;
// ✅ 尝试应用保存的配置来覆盖基础列设置
pagination
.
value
.
itemCount
=
response
.
data
.
Total
||
0
;
if
(
tableSettingsDrawerRef
.
value
?.
handleGetSettings
)
{
console
.
log
(
'📋 尝试应用保存的配置'
);
await
tableSettingsDrawerRef
.
value
.
handleGetSettings
();
}
// ✅ 使用正确的数据结构设置表格数据
tableData
.
value
=
response
.
Results
;
pagination
.
value
.
itemCount
=
response
.
Total
||
0
;
//
移除多余的判断,简化配置加载逻辑
//
标记配置已加载(用于其他逻辑判断)
if
(
!
isConfigLoaded
.
value
)
{
if
(
!
isConfigLoaded
.
value
)
{
// console.log('首次加载配置');
isConfigLoaded
.
value
=
true
;
isConfigLoaded
.
value
=
true
;
nextTick
(()
=>
{
getAllTableSettings
();
});
}
}
}
else
{
}
else
{
// 如果没有数据,清空表格数据并设置总数为0
// 没有数据的情况
console
.
log
(
'📝 没有获取到数据'
);
tableData
.
value
=
[];
tableData
.
value
=
[];
pagination
.
value
.
itemCount
=
response
.
data
?.
Total
||
0
;
pagination
.
value
.
itemCount
=
response
?.
Total
||
0
;
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
'❌ 请求失败:'
,
error
);
// ✅ 这个catch现在只处理真正的异常情况
console
.
error
(
'❌ fetchData执行过程中发生异常:'
,
error
);
tableData
.
value
=
[];
tableData
.
value
=
[];
pagination
.
value
.
itemCount
=
0
;
pagination
.
value
.
itemCount
=
0
;
}
finally
{
}
finally
{
...
@@ -1007,7 +1027,10 @@ const updateFieldVisibility = (field: any, visible: boolean) => {
...
@@ -1007,7 +1027,10 @@ const updateFieldVisibility = (field: any, visible: boolean) => {
// 获取可选择的列
// 获取可选择的列
const availableColumns = computed(() => {
const availableColumns = computed(() => {
const existingKeys = searchFields.value.map(f => f.key);
const existingKeys = searchFields.value.map(f => f.key);
return rawColumns.value.filter(col => !existingKeys.includes(col.key));
return rawColumns.value.filter(col => {
// 过滤掉已存在的字段、Metadata 字段和包含 Kvid 的字段
return !existingKeys.includes(col.key) && col.key !== 'Metadata' && !col.key.toLowerCase().includes('kvid');
});
});
});
// 在 script setup 部分添加以下响应式变量
// 在 script setup 部分添加以下响应式变量
...
@@ -1146,7 +1169,12 @@ const generateFilterOptions = (column: TableColumn) => {
...
@@ -1146,7 +1169,12 @@ const generateFilterOptions = (column: TableColumn) => {
const selectedField = ref('');
const selectedField = ref('');
const availableFields = computed(() => {
const availableFields = computed(() => {
return rawColumns.value.map((column: TableColumn) => ({
return rawColumns.value
.filter(column => {
// 过滤掉 Metadata 字段和包含 Kvid 的字段
return column.key !== 'Metadata' && !column.key.toLowerCase().includes('kvid');
})
.map((column: TableColumn) => ({
label: column.title,
label: column.title,
value: column.key
value: column.key
}));
}));
...
@@ -1233,9 +1261,12 @@ const updateTransformedColumnRenders = () => {
...
@@ -1233,9 +1261,12 @@ const updateTransformedColumnRenders = () => {
});
});
};
};
const applyTransformations = () => {
const applyTransformations = (
silent = false
) => {
if (!tableData.value || tableData.value.length === 0) {
if (!tableData.value || tableData.value.length === 0) {
// 如果是静默模式(配置恢复时),不显示错误信息
if (!silent) {
window.$message?.error('没有可转换的数据');
window.$message?.error('没有可转换的数据');
}
return;
return;
}
}
...
@@ -1250,8 +1281,10 @@ const applyTransformations = () => {
...
@@ -1250,8 +1281,10 @@ const applyTransformations = () => {
// window.$message?.success('数据转换成功应用到显示');
// window.$message?.success('数据转换成功应用到显示');
} catch (error: any) {
} catch (error: any) {
// console.error('转换过程中出错:', error);
// console.error('转换过程中出错:', error);
if (!silent) {
window.$message?.error(`
转换过程中出错
:
$
{
error
.
message
}
`);
window.$message?.error(`
转换过程中出错
:
$
{
error
.
message
}
`);
}
}
}
};
};
// 数据转换相关的方法
// 数据转换相关的方法
...
@@ -1355,16 +1388,8 @@ onMounted(() => {
...
@@ -1355,16 +1388,8 @@ onMounted(() => {
WangEditor: Boolean((window as any).$WangEditor)
WangEditor: Boolean((window as any).$WangEditor)
});
});
// 在组件挂载时
就确保配置加载完成
// 在组件挂载时
加载数据(配置获取已在fetchData中处理)
fetchData();
fetchData();
Promise.resolve()
.then(() => fetchData())
.then(() => {
nextTick(() => {
// console.log('组件挂载完成,初始化配置');
// getAllTableSettings();
});
});
});
});
onActivated(() => {
onActivated(() => {
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment