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