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
536744e2
Commit
536744e2
authored
Jan 27, 2026
by
水玉婷
Browse files
feat:添加图表总结类型
parent
291b5da2
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/views/components/AiChat.vue
View file @
536744e2
...
@@ -342,6 +342,10 @@ const sendMessage = async (type: MessageType = 'text', params: MessageParams = {
...
@@ -342,6 +342,10 @@ const sendMessage = async (type: MessageType = 'text', params: MessageParams = {
// simulateLineChartMessage();
// simulateLineChartMessage();
// loading.value = false;
// loading.value = false;
// }, 1000);
// }, 1000);
// setTimeout(() => {
// simulateTips();
// loading.value = false;
// }, 2000);
// return;
// return;
// }
// }
...
@@ -386,7 +390,7 @@ const sendMessage = async (type: MessageType = 'text', params: MessageParams = {
...
@@ -386,7 +390,7 @@ const sendMessage = async (type: MessageType = 'text', params: MessageParams = {
});
});
// 重置文本输入框
// 重置文本输入框
if
(
textarea
.
value
)
{
if
(
textarea
.
value
)
{
textarea
.
value
.
style
.
height
=
'
5
0
px
'
;
textarea
.
value
.
style
.
height
=
'
5
2
px
'
;
}
}
messageText
.
value
=
''
;
messageText
.
value
=
''
;
break
;
break
;
...
@@ -551,7 +555,7 @@ const handleKeyPress = (e: KeyboardEvent) => {
...
@@ -551,7 +555,7 @@ const handleKeyPress = (e: KeyboardEvent) => {
const
adjustTextareaHeight
=
()
=>
{
const
adjustTextareaHeight
=
()
=>
{
if
(
textarea
.
value
)
{
if
(
textarea
.
value
)
{
textarea
.
value
.
style
.
height
=
'
auto
'
;
textarea
.
value
.
style
.
height
=
'
auto
'
;
textarea
.
value
.
style
.
height
=
`
${
Math
.
min
(
textarea
.
value
.
scrollHeight
,
6
5
)}
px`
;
textarea
.
value
.
style
.
height
=
`
${
Math
.
min
(
textarea
.
value
.
scrollHeight
,
5
2
)}
px`
;
}
}
};
};
...
@@ -607,6 +611,13 @@ onBeforeUnmount(() => {
...
@@ -607,6 +611,13 @@ onBeforeUnmount(() => {
// title:"2023年各医院月度运营数据汇总",
// title:"2023年各医院月度运营数据汇总",
// dimFields: ['月份', '地区', '医院类型', '科室'],
// dimFields: ['月份', '地区', '医院类型', '科室'],
// indexFields: ['用户总数', '费用汇总', '平均住院天数', '手术台数', '门诊量'],
// indexFields: ['用户总数', '费用汇总', '平均住院天数', '手术台数', '门诊量'],
// desc: `根据您提供的四川公司费用总额数据,我进行了详细分析和总结:
// 费用总额呈现持续增长趋势:从2025年1月的1068.3万元增长至3月的3906.0万元,三个月累计增长超过2837.7万元。
// 月度增长幅度显著:2月较1月增长1440.3万元,3月较2月增长1397.4万元,增长势头强劲。
// 同比分析:与上年同期相比,2025年同期费用总额均高于上年同期,显示公司业务规模持续扩大。
// 增长趋势稳定:从1月到3月,费用总额稳步上升,未出现明显波动或下降趋势。
// 数据完整性:所有数据点均完整,便于进行趋势分析和预测。
// 这些数据表明四川公司在2025年呈现出良好的业务发展态势,费用支出与业务增长保持同步。`,
// rows: [
// rows: [
// { '月份': '1月', '地区': '北京', '医院类型': '三甲医院', '科室': '内科', '用户总数': 100, '费用汇总': 5000, '平均住院天数': 7.2, '手术台数': 15, '门诊量': 1200 },
// { '月份': '1月', '地区': '北京', '医院类型': '三甲医院', '科室': '内科', '用户总数': 100, '费用汇总': 5000, '平均住院天数': 7.2, '手术台数': 15, '门诊量': 1200 },
// { '月份': '2月', '地区': '北京', '医院类型': '三甲医院', '科室': '内科', '用户总数': 150, '费用汇总': 6000, '平均住院天数': 6.8, '手术台数': 18, '门诊量': 1400 },
// { '月份': '2月', '地区': '北京', '医院类型': '三甲医院', '科室': '内科', '用户总数': 150, '费用汇总': 6000, '平均住院天数': 6.8, '手术台数': 18, '门诊量': 1400 },
...
@@ -621,27 +632,6 @@ onBeforeUnmount(() => {
...
@@ -621,27 +632,6 @@ onBeforeUnmount(() => {
// { '月份': '4月', '地区': '北京', '医院类型': '三甲医院', '科室': '外科', '用户总数': 150, '费用汇总': 12000, '平均住院天数': 7.8, '手术台数': 60, '门诊量': 1100 },
// { '月份': '4月', '地区': '北京', '医院类型': '三甲医院', '科室': '外科', '用户总数': 150, '费用汇总': 12000, '平均住院天数': 7.8, '手术台数': 60, '门诊量': 1100 },
// { '月份': '5月', '地区': '北京', '医院类型': '三甲医院', '科室': '外科', '用户总数': 180, '费用汇总': 14000, '平均住院天数': 7.5, '手术台数': 68, '门诊量': 1200 },
// { '月份': '5月', '地区': '北京', '医院类型': '三甲医院', '科室': '外科', '用户总数': 180, '费用汇总': 14000, '平均住院天数': 7.5, '手术台数': 68, '门诊量': 1200 },
// { '月份': '6月', '地区': '北京', '医院类型': '三甲医院', '科室': '外科', '用户总数': 220, '费用汇总': 16000, '平均住院天数': 7.2, '手术台数': 75, '门诊量': 1400 },
// { '月份': '6月', '地区': '北京', '医院类型': '三甲医院', '科室': '外科', '用户总数': 220, '费用汇总': 16000, '平均住院天数': 7.2, '手术台数': 75, '门诊量': 1400 },
// { '月份': '1月', '地区': '上海', '医院类型': '三甲医院', '科室': '内科', '用户总数': 80, '费用汇总': 4000, '平均住院天数': 6.8, '手术台数': 12, '门诊量': 1000 },
// { '月份': '2月', '地区': '上海', '医院类型': '三甲医院', '科室': '内科', '用户总数': 120, '费用汇总': 5000, '平均住院天数': 6.5, '手术台数': 15, '门诊量': 1200 },
// { '月份': '3月', '地区': '上海', '医院类型': '三甲医院', '科室': '内科', '用户总数': 100, '费用汇总': 4500, '平均住院天数': 7.0, '手术台数': 13, '门诊量': 1100 },
// { '月份': '4月', '地区': '上海', '医院类型': '三甲医院', '科室': '内科', '用户总数': 150, '费用汇总': 7000, '平均住院天数': 6.2, '手术台数': 18, '门诊量': 1400 },
// { '月份': '5月', '地区': '上海', '医院类型': '三甲医院', '科室': '内科', '用户总数': 180, '费用汇总': 8000, '平均住院天数': 5.9, '手术台数': 22, '门诊量': 1600 },
// { '月份': '6月', '地区': '上海', '医院类型': '三甲医院', '科室': '内科', '用户总数': 220, '费用汇总': 10000, '平均住院天数': 5.6, '手术台数': 28, '门诊量': 1800 },
// { '月份': '1月', '地区': '上海', '医院类型': '二甲医院', '科室': '内科', '用户总数': 60, '费用汇总': 2500, '平均住院天数': 5.5, '手术台数': 8, '门诊量': 600 },
// { '月份': '2月', '地区': '上海', '医院类型': '二甲医院', '科室': '内科', '用户总数': 90, '费用汇总': 3200, '平均住院天数': 5.2, '手术台数': 10, '门诊量': 700 },
// { '月份': '3月', '地区': '上海', '医院类型': '二甲医院', '科室': '内科', '用户总数': 80, '费用汇总': 2800, '平均住院天数': 5.8, '手术台数': 9, '门诊量': 650 },
// { '月份': '4月', '地区': '上海', '医院类型': '二甲医院', '科室': '内科', '用户总数': 120, '费用汇总': 4500, '平均住院天数': 5.0, '手术台数': 12, '门诊量': 800 },
// { '月份': '5月', '地区': '上海', '医院类型': '二甲医院', '科室': '内科', '用户总数': 150, '费用汇总': 5500, '平均住院天数': 4.8, '手术台数': 15, '门诊量': 900 },
// { '月份': '6月', '地区': '上海', '医院类型': '二甲医院', '科室': '内科', '用户总数': 180, '费用汇总': 6500, '平均住院天数': 4.5, '手术台数': 18, '门诊量': 1000 },
// { '月份': '1月', '地区': '广州', '医院类型': '三甲医院', '科室': '内科', '用户总数': 60, '费用汇总': 3000, '平均住院天数': 6.0, '手术台数': 10, '门诊量': 800 },
// { '月份': '2月', '地区': '广州', '医院类型': '三甲医院', '科室': '内科', '用户总数': 90, '费用汇总': 4000, '平均住院天数': 5.8, '手术台数': 12, '门诊量': 900 },
// { '月份': '3月', '地区': '广州', '医院类型': '三甲医院', '科室': '内科', '用户总数': 80, '费用汇总': 3500, '平均住院天数': 6.2, '手术台数': 11, '门诊量': 850 },
// { '月份': '4月', '地区': '广州', '医院类型': '三甲医院', '科室': '内科', '用户总数': 120, '费用汇总': 6000, '平均住院天数': 5.5, '手术台数': 15, '门诊量': 1100 },
// { '月份': '5月', '地区': '广州', '医院类型': '三甲医院', '科室': '内科', '用户总数': 150, '费用汇总': 7000, '平均住院天数': 5.2, '手术台数': 18, '门诊量': 1200 },
// { '月份': '6月', '地区': '广州', '医院类型': '三甲医院', '科室': '内科', '用户总数': 180, '费用汇总': 9000, '平均住院天数': 4.9, '手术台数': 22, '门诊量': 1400 }
// ],
// ],
// // chartType: 'line' // 设置默认图表类型为折线图
// // chartType: 'line' // 设置默认图表类型为折线图
// };
// };
...
@@ -653,6 +643,25 @@ onBeforeUnmount(() => {
...
@@ -653,6 +643,25 @@ onBeforeUnmount(() => {
// type: 2 // 表格数据
// type: 2 // 表格数据
// };
// };
// // 调用handleSSEMessage处理模拟消息
// handleSSEMessage(simulatedMessage);
// };
// const simulateTips = () => {
// console.log('模拟总结消息');
// // 模拟提示消息
// const simulatedMessage = {
// message: `根据您提供的四川公司费用总额数据,我进行了详细分析和总结:
// 费用总额呈现持续增长趋势:从2025年1月的1068.3万元增长至3月的3906.0万元,三个月累计增长超过2837.7万元。
// 月度增长幅度显著:2月较1月增长1440.3万元,3月较2月增长1397.4万元,增长势头强劲。
// 同比分析:与上年同期相比,2025年同期费用总额均高于上年同期,显示公司业务规模持续扩大。
// 增长趋势稳定:从1月到3月,费用总额稳步上升,未出现明显波动或下降趋势。
// 数据完整性:所有数据点均完整,便于进行趋势分析和预测。
// 这些数据表明四川公司在2025年呈现出良好的业务发展态势,费用支出与业务增长保持同步。`,
// status: 3, // 图表数据
// type: 6 // 总结消息
// };
// // 调用handleSSEMessage处理模拟消息
// // 调用handleSSEMessage处理模拟消息
// handleSSEMessage(simulatedMessage);
// handleSSEMessage(simulatedMessage);
// };
// };
...
...
src/views/components/ChartComponent.vue
View file @
536744e2
<
template
>
<
template
>
<div
class=
"chart-container"
>
<div
class=
"chart-container"
>
<div
class=
"tips"
>
<div
class=
"tips"
>
我是一段描述文字,用于介绍图表数据。
{{
chartData
?.
desc
}}
</div>
</div>
<!-- 图表类型选择器 -->
<!-- 图表类型选择器 -->
<div
class=
"chart-controls"
>
<div
class=
"chart-controls"
>
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
:mode=
"selectedChartType === CHART_TYPES.PIE ? undefined : 'multiple'"
:mode=
"selectedChartType === CHART_TYPES.PIE ? undefined : 'multiple'"
:maxTagCount=
"12"
:maxTagCount=
"12"
:maxTagTextLength=
"6"
:maxTagTextLength=
"6"
:showSearch=
"false"
:dropdownMatchSelectWidth=
"false"
:dropdownMatchSelectWidth=
"false"
:getPopupContainer=
"triggerNode => triggerNode.parentNode"
:getPopupContainer=
"triggerNode => triggerNode.parentNode"
placeholder=
"请选择维度"
placeholder=
"请选择维度"
...
@@ -142,12 +143,14 @@ import { ref, computed, watch, onMounted, defineAsyncComponent, type Ref } from
...
@@ -142,12 +143,14 @@ import { ref, computed, watch, onMounted, defineAsyncComponent, type Ref } from
import
{
Select
as
ASelect
,
SelectOption
as
ASelectOption
,
Tooltip
as
ATooltip
}
from
'
ant-design-vue
'
;
import
{
Select
as
ASelect
,
SelectOption
as
ASelectOption
,
Tooltip
as
ATooltip
}
from
'
ant-design-vue
'
;
import
{
QuestionCircleOutlined
}
from
'
@ant-design/icons-vue
'
;
import
{
QuestionCircleOutlined
}
from
'
@ant-design/icons-vue
'
;
import
TableComponent
from
'
./TableComponent.vue
'
;
import
TableComponent
from
'
./TableComponent.vue
'
;
import
{
p
}
from
'
vue-router/dist/router-CWoNjPRp.mjs
'
;
// 类型定义
// 类型定义
interface
ChartData
{
interface
ChartData
{
dimFields
?:
string
[];
dimFields
?:
string
[];
indexFields
?:
string
[];
indexFields
?:
string
[];
rows
?:
any
[];
rows
?:
any
[];
desc
?:
string
;
}
}
interface
ChartTypeOption
{
interface
ChartTypeOption
{
...
@@ -159,6 +162,7 @@ interface Props {
...
@@ -159,6 +162,7 @@ interface Props {
chartData
?:
ChartData
;
chartData
?:
ChartData
;
chartType
?:
number
|
string
;
chartType
?:
number
|
string
;
title
?:
string
;
title
?:
string
;
desc
?:
string
;
width
?:
number
|
string
;
width
?:
number
|
string
;
height
?:
number
|
string
;
height
?:
number
|
string
;
}
}
...
@@ -334,8 +338,6 @@ onMounted(() => {
...
@@ -334,8 +338,6 @@ onMounted(() => {
<
style
lang=
"less"
scoped
>
<
style
lang=
"less"
scoped
>
.chart-container {
.chart-container {
border-radius: 8px;
background-color: #fff;
overflow: hidden;
overflow: hidden;
width: 100% !important;
width: 100% !important;
max-width: 100% !important;
max-width: 100% !important;
...
@@ -412,7 +414,6 @@ onMounted(() => {
...
@@ -412,7 +414,6 @@ onMounted(() => {
}
}
.chart-render-area {
.chart-render-area {
padding: 0px 8px;
font-size: 0;
font-size: 0;
width: 100% !important;
width: 100% !important;
display: flex;
display: flex;
...
...
src/views/components/TableComponent.vue
View file @
536744e2
...
@@ -201,7 +201,6 @@ const renderCellContent = (header: string, value: any) => {
...
@@ -201,7 +201,6 @@ const renderCellContent = (header: string, value: any) => {
.table-container
{
.table-container
{
width
:
100%
;
width
:
100%
;
overflow-x
:
auto
;
-webkit-overflow-scrolling
:
touch
;
-webkit-overflow-scrolling
:
touch
;
}
}
...
@@ -322,5 +321,8 @@ const renderCellContent = (header: string, value: any) => {
...
@@ -322,5 +321,8 @@ const renderCellContent = (header: string, value: any) => {
.ant-table-tbody
>
tr
:last-child
>
td
{
.ant-table-tbody
>
tr
:last-child
>
td
{
border-bottom
:
none
;
border-bottom
:
none
;
}
}
.ant-table-pagination.ant-pagination
{
margin
:
12px
0
0
;
}
}
}
</
style
>
</
style
>
\ No newline at end of file
src/views/components/style.less
View file @
536744e2
...
@@ -333,12 +333,6 @@ li {
...
@@ -333,12 +333,6 @@ li {
.toggle-icon {
.toggle-icon {
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
transform: rotate(0deg);
}
// 展开状态下的图标旋转
&.expanded .toggle-icon {
transform: rotate(180deg);
}
}
.thinking-loading {
.thinking-loading {
...
@@ -1208,7 +1202,6 @@ li {
...
@@ -1208,7 +1202,6 @@ li {
@media (max-width: 768px) {
@media (max-width: 768px) {
:deep(.message-markdown) {
:deep(.message-markdown) {
.markdown-content {
.markdown-content {
font-size: 13px;
h1 {
h1 {
font-size: 18px;
font-size: 18px;
...
...
src/views/components/utils/contentTemplateService.ts
View file @
536744e2
...
@@ -322,6 +322,7 @@ export class ContentTemplateService {
...
@@ -322,6 +322,7 @@ export class ContentTemplateService {
break
;
break
;
case
4
:
// MD格式
case
4
:
// MD格式
case
6
:
// 表格总结文案
if
(
updatedResponse
)
{
if
(
updatedResponse
)
{
// 对于SSE流式数据,使用流式处理
// 对于SSE流式数据,使用流式处理
const
markdownContent
=
templateTools
?.
markdownTemplate
?
const
markdownContent
=
templateTools
?.
markdownTemplate
?
...
...
src/views/components/utils/sseService.ts
View file @
536744e2
...
@@ -106,7 +106,7 @@ export class SSEService {
...
@@ -106,7 +106,7 @@ export class SSEService {
errorString
.
includes
(
'
no activity
'
)
||
errorString
.
includes
(
'
no activity
'
)
||
errorString
.
includes
(
'
no activity within
'
)
||
errorString
.
includes
(
'
no activity within
'
)
||
errorString
.
includes
(
'
milliseconds
'
)
&&
errorString
.
includes
(
'
reconnecting
'
)
||
errorString
.
includes
(
'
milliseconds
'
)
&&
errorString
.
includes
(
'
reconnecting
'
)
||
errorString
.
includes
(
'
12
0000
'
)
&&
errorString
.
includes
(
'
reconnecting
'
);
errorString
.
includes
(
'
6
0000
'
)
&&
errorString
.
includes
(
'
reconnecting
'
);
// 如果是"No activity"错误且收到过keepalive,说明连接正常,忽略错误
// 如果是"No activity"错误且收到过keepalive,说明连接正常,忽略错误
if
(
isNoActivityError
&&
this
.
hasReceivedKeepalive
)
{
if
(
isNoActivityError
&&
this
.
hasReceivedKeepalive
)
{
...
...
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