Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
水玉婷
ai-wechat
Commits
219e9ed3
Commit
219e9ed3
authored
Nov 21, 2025
by
水玉婷
Browse files
feat:把表格模版抽离,修改表格样式
parent
5f3adbdc
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/views/Home.vue
View file @
219e9ed3
...
...
@@ -26,8 +26,8 @@
stage
:
'
wechat-demo
'
,
};
//
const dialogSessionId = '20251028143404893-00045166';
const
dialogSessionId
=
''
;
const
dialogSessionId
=
'
20251028143404893-00045166
'
;
//
const dialogSessionId = '';
const
detailData
=
ref
({
title
:
'
国械小智
'
,
});
...
...
src/views/components/AiChat.vue
View file @
219e9ed3
...
...
@@ -86,41 +86,7 @@ import { SendOutlined, UserOutlined } from '@ant-design/icons-vue';
import
dayjs
from
'
dayjs
'
;
import
defaultAvatar
from
'
@/assets/logo.png
'
;
import
ChartComponent
from
'
./ChartComponent.vue
'
;
// 导入独立的图表组件
// 定义消息类型 - 更新接口添加图表相关字段
interface
Message
{
type
:
'
received
'
|
'
sent
'
;
avatar
:
string
;
recordId
:
string
;
promptTokens
:
number
;
completionTokens
:
number
;
totalTokens
:
number
;
date
:
string
;
customClass
?:
string
;
contentBlocks
:
{
content
:
string
;
thinkContent
?:
string
;
hasThinkBox
:
boolean
;
thinkBoxExpanded
:
boolean
;
chartData
?:
any
;
// 添加图表数据字段
chartType
?:
number
|
string
;
// 添加图表类型字段
}[];
}
interface
Token
{
value
:
string
;
expire
:
number
;
}
interface
SSEData
{
message
:
any
;
status
:
number
|
string
;
}
interface
ChatParams
{
stage
?:
string
;
appId
?:
string
;
}
import
{
tableTemplate
}
from
'
./tableTemplate
'
;
// 导入表格模板工具
// 组件属性
const
props
=
withDefaults
(
...
...
@@ -148,7 +114,7 @@ const props = withDefaults(
},
);
// 内容模板生成器
// 内容模板生成器
- 简化版本,表格功能已抽离
const
contentTemplates
=
{
// 普通文本
text
:
(
content
:
string
)
=>
{
...
...
@@ -166,114 +132,9 @@ const contentTemplates = {
error
:
(
content
:
string
)
=>
{
return
`<div class="message-error">
${
content
}
</div>`
;
},
//
生成表格HTML
//
表格模板 - 使用独立的表格模板工具
table
:
(
tableData
:
any
)
=>
{
// 处理SSE返回的JSON数组数据
// tableData 就是SSE消息中的message字段,直接是你提供的JSON数组
const
data
=
Array
.
isArray
(
tableData
)
?
tableData
:
[];
if
(
data
.
length
===
0
)
{
return
`<div class="message-table">
<div class="table-title">数据表格</div>
<div class="table-empty">暂无数据</div>
</div>`
;
}
// 动态生成表头 - 使用第一条数据的键名
const
headers
=
Object
.
keys
(
data
[
0
]);
// 判断列是否为数字列
const
isNumericColumn
=
(
header
:
string
)
=>
{
return
data
.
some
(
row
=>
{
const
value
=
row
[
header
];
return
typeof
value
===
'
number
'
||
(
!
isNaN
(
parseFloat
(
value
))
&&
isFinite
(
value
));
});
};
// 数字格式化函数 - 万/亿格式化,保留两位小数,向上取整
const
formatNumber
=
(
value
:
any
)
=>
{
if
(
value
===
null
||
value
===
undefined
||
value
===
''
)
return
''
;
const
num
=
parseFloat
(
value
);
if
(
isNaN
(
num
))
return
value
;
if
(
num
>=
100000000
)
{
// 亿级别
const
result
=
Math
.
ceil
((
num
/
100000000
)
*
100
)
/
100
;
return
result
.
toFixed
(
2
)
+
'
亿
'
;
}
else
if
(
num
>=
10000
)
{
// 万级别
const
result
=
Math
.
ceil
((
num
/
10000
)
*
100
)
/
100
;
return
result
.
toFixed
(
2
)
+
'
万
'
;
}
else
{
// 小于万
return
Math
.
ceil
(
num
).
toString
();
}
};
// 处理单元格内容,特别处理趋势列和数字列
const
renderCellContent
=
(
header
:
string
,
value
:
any
)
=>
{
// 如果是趋势列,根据up/down值显示箭头图标
if
(
header
.
toLowerCase
().
includes
(
'
趋势
'
)
||
header
.
toLowerCase
().
includes
(
'
trend
'
))
{
const
trendValue
=
String
(
value
).
toLowerCase
().
trim
();
if
(
trendValue
===
'
up
'
||
trendValue
===
'
上升
'
||
trendValue
===
'
上涨
'
)
{
return
`<span class="trend-up">↑</span>`
;
}
else
if
(
trendValue
===
'
down
'
||
trendValue
===
'
下降
'
||
trendValue
===
'
下跌
'
)
{
return
`<span class="trend-down">↓</span>`
;
}
}
// 如果是数字列,进行格式化
if
(
isNumericColumn
(
header
))
{
return
formatNumber
(
value
);
}
// 其他列保持原样
return
value
;
};
// 判断列是否为趋势列
const
isTrendColumn
=
(
header
:
string
)
=>
{
return
header
.
toLowerCase
().
includes
(
'
趋势
'
)
||
header
.
toLowerCase
().
includes
(
'
trend
'
);
};
// 为不同列类型添加对应的样式类
const
getCellClass
=
(
header
:
string
)
=>
{
if
(
isTrendColumn
(
header
))
{
return
'
trend-cell
'
;
// 趋势列居中
}
else
if
(
isNumericColumn
(
header
))
{
return
'
numeric-cell
'
;
// 数字列右对齐
}
else
{
return
'
text-cell
'
;
// 文字列左对齐
}
};
const
tableHTML
=
`
<div class="message-table">
<div class="table-container">
<table class="data-table">
<thead>
<tr>
${
headers
.
map
(
header
=>
`<th class="
${
getCellClass
(
header
)}
">
${
header
}
</th>`
).
join
(
''
)}
</tr>
</thead>
<tbody>
${
data
.
map
(
row
=>
`
<tr>
${
headers
.
map
(
header
=>
`
<td class="
${
getCellClass
(
header
)}
">
${
renderCellContent
(
header
,
row
[
header
])}
</td>
`
).
join
(
''
)}
</tr>
`
).
join
(
''
)}
</tbody>
</table>
</div>
<div class="table-footer">共 <span>
${
data
.
length
}
</span> 条记录</div>
</div>
`
;
return
tableHTML
;
return
tableTemplate
(
tableData
);
},
// 简化的iframe模板 - 移除全屏功能,设置宽高100%固定
iframe
:
(
iframeData
:
any
)
=>
{
...
...
@@ -304,6 +165,41 @@ const contentTemplates = {
}
};
// 定义消息类型 - 更新接口添加图表相关字段
interface
Message
{
type
:
'
received
'
|
'
sent
'
;
avatar
:
string
;
recordId
:
string
;
promptTokens
:
number
;
completionTokens
:
number
;
totalTokens
:
number
;
date
:
string
;
customClass
?:
string
;
contentBlocks
:
{
content
:
string
;
thinkContent
?:
string
;
hasThinkBox
:
boolean
;
thinkBoxExpanded
:
boolean
;
chartData
?:
any
;
// 添加图表数据字段
chartType
?:
number
|
string
;
// 添加图表类型字段
}[];
}
interface
Token
{
value
:
string
;
expire
:
number
;
}
interface
SSEData
{
message
:
any
;
status
:
number
|
string
;
}
interface
ChatParams
{
stage
?:
string
;
appId
?:
string
;
}
// 响应式数据
const
messageText
=
ref
(
''
);
const
messages
=
ref
<
Message
[]
>
([]);
...
...
src/views/components/style.less
View file @
219e9ed3
...
...
@@ -480,18 +480,19 @@ p,h1,h2,h3,h4,h5,h6,ul,ol,li{
text-overflow: ellipsis;
vertical-align: middle; // 确保内容垂直居中
min-width: 80px; // 设置最小列宽,与表头保持一致
&:nth-child(odd) {
background-color: #f8faff; // 修改奇数行背景色为浅蓝色
}
&:nth-child(even) {
background-color: white;
}
}
// 将奇偶行背景色设置移动到tr元素上
tr:nth-child(odd) td {
background-color: #f8faff; // 奇数行背景色为浅蓝色
}
tr:nth-child(even) td {
background-color: white; // 偶数行背景色为白色
}
tr:hover td {
background-color: #
e8f6f4;
background-color: #
f0f5ff; // 修改为蓝色系的悬停背景色
}
tr:last-child td {
...
...
src/views/components/tableTemplate.ts
0 → 100644
View file @
219e9ed3
/**
* 表格模板工具类
* 用于生成和渲染数据表格
*/
// 表格数据接口
export
interface
TableData
{
[
key
:
string
]:
any
;
}
// 表格配置接口
export
interface
TableConfig
{
showFooter
?:
boolean
;
}
/**
* 生成表格HTML
* @param tableData 表格数据数组
* @param config 表格配置
* @returns 表格HTML字符串
*/
export
const
generateTableHTML
=
(
tableData
:
TableData
[],
config
:
TableConfig
=
{}):
string
=>
{
const
{
showFooter
=
true
}
=
config
;
// 处理空数据
if
(
!
Array
.
isArray
(
tableData
)
||
tableData
.
length
===
0
)
{
return
`
<div class="message-table">
<div class="table-title">数据表格</div>
<div class="table-empty">暂无数据</div>
</div>`
;
}
// 动态生成表头 - 使用第一条数据的键名
const
headers
=
Object
.
keys
(
tableData
[
0
]);
// 判断列是否为数字列
const
isNumericColumn
=
(
header
:
string
)
=>
{
return
tableData
.
some
(
row
=>
{
const
value
=
row
[
header
];
return
typeof
value
===
'
number
'
||
(
!
isNaN
(
parseFloat
(
value
))
&&
isFinite
(
value
));
});
};
// 数字格式化函数 - 万/亿格式化,保留两位小数,向上取整
const
formatNumber
=
(
value
:
any
)
=>
{
if
(
value
===
null
||
value
===
undefined
||
value
===
''
)
return
''
;
const
num
=
parseFloat
(
value
);
if
(
isNaN
(
num
))
return
value
;
if
(
num
>=
100000000
)
{
// 亿级别
const
result
=
Math
.
ceil
((
num
/
100000000
)
*
100
)
/
100
;
return
result
.
toFixed
(
2
)
+
'
亿
'
;
}
else
if
(
num
>=
10000
)
{
// 万级别
const
result
=
Math
.
ceil
((
num
/
10000
)
*
100
)
/
100
;
return
result
.
toFixed
(
2
)
+
'
万
'
;
}
else
{
// 小于万
return
Math
.
ceil
(
num
).
toString
();
}
};
// 处理单元格内容,特别处理趋势列和数字列
const
renderCellContent
=
(
header
:
string
,
value
:
any
)
=>
{
// 如果是趋势列,根据up/down值显示箭头图标
if
(
header
.
toLowerCase
().
includes
(
'
趋势
'
)
||
header
.
toLowerCase
().
includes
(
'
trend
'
))
{
const
trendValue
=
String
(
value
).
toLowerCase
().
trim
();
if
(
trendValue
===
'
up
'
||
trendValue
===
'
上升
'
||
trendValue
===
'
上涨
'
)
{
return
`<span class="trend-up">↑</span>`
;
}
else
if
(
trendValue
===
'
down
'
||
trendValue
===
'
下降
'
||
trendValue
===
'
下跌
'
)
{
return
`<span class="trend-down">↓</span>`
;
}
}
// 如果是数字列,进行格式化
if
(
isNumericColumn
(
header
))
{
return
formatNumber
(
value
);
}
// 其他列保持原样
return
value
;
};
// 判断列是否为趋势列
const
isTrendColumn
=
(
header
:
string
)
=>
{
return
header
.
toLowerCase
().
includes
(
'
趋势
'
)
||
header
.
toLowerCase
().
includes
(
'
trend
'
);
};
// 为不同列类型添加对应的样式类
const
getCellClass
=
(
header
:
string
)
=>
{
if
(
isTrendColumn
(
header
))
{
return
'
trend-cell
'
;
// 趋势列居中
}
else
if
(
isNumericColumn
(
header
))
{
return
'
numeric-cell
'
;
// 数字列右对齐
}
else
{
return
'
text-cell
'
;
// 文字列左对齐
}
};
return
`
<div class="message-table">
<div class="table-container">
<table class="data-table">
<thead>
<tr>
${
headers
.
map
(
header
=>
`<th class="
${
getCellClass
(
header
)}
">
${
header
}
</th>`
).
join
(
''
)}
</tr>
</thead>
<tbody>
${
tableData
.
map
(
row
=>
`
<tr>
${
headers
.
map
(
header
=>
`
<td class="
${
getCellClass
(
header
)}
">
${
renderCellContent
(
header
,
row
[
header
])}
</td>
`
).
join
(
''
)}
</tr>
`
).
join
(
''
)}
</tbody>
</table>
</div>
${
showFooter
?
`<div class="table-footer">共 <span>
${
tableData
.
length
}
</span> 条记录</div>`
:
''
}
</div>
`
;
};
/**
* 简化的表格生成函数(兼容旧版本)
* @param tableData 表格数据
* @returns 表格HTML字符串
*/
export
const
tableTemplate
=
(
tableData
:
any
):
string
=>
{
return
generateTableHTML
(
tableData
);
};
export
default
{
generateTableHTML
,
tableTemplate
};
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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