pcm-agents 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/dist/cjs/index-BFPEnLbS.js +195 -0
- package/dist/cjs/index-BFPEnLbS.js.map +1 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/my-component.cjs.entry.js +2 -2
- package/dist/cjs/my-component.cjs.entry.js.map +1 -1
- package/dist/cjs/my-component.entry.cjs.js.map +1 -1
- package/dist/cjs/pcm-agents.cjs.js +1 -1
- package/dist/cjs/pcm-app-chat-modal.pcm-chat-message.pcm-hr-chat-modal.pcm-jlpx-modal.pcm-mnms-modal.pcm-video-chat-modal.pcm-zygh-modal.entry.cjs.js.map +1 -0
- package/dist/cjs/pcm-app-chat-modal_7.cjs.entry.js +6560 -0
- package/dist/cjs/pcm-app-chat-modal_7.cjs.entry.js.map +1 -0
- package/dist/cjs/pcm-chat-modal.cjs.entry.js +17 -32
- package/dist/cjs/pcm-chat-modal.cjs.entry.js.map +1 -1
- package/dist/cjs/pcm-chat-modal.entry.cjs.js.map +1 -1
- package/dist/collection/collection-manifest.json +2 -0
- package/dist/collection/components/my-component/my-component.css +3 -3
- package/dist/collection/components/my-component/my-component.js +1 -1
- package/dist/collection/components/my-component/my-component.js.map +1 -1
- package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.css +2 -1
- package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.js +137 -159
- package/dist/collection/components/pcm-app-chat-modal/pcm-app-chat-modal.js.map +1 -1
- package/dist/collection/components/pcm-chat-message/pcm-chat-message.css +66 -12
- package/dist/collection/components/pcm-chat-message/pcm-chat-message.js +106 -13
- package/dist/collection/components/pcm-chat-message/pcm-chat-message.js.map +1 -1
- package/dist/collection/components/pcm-chat-modal/pcm-chat-modal.js +39 -34
- package/dist/collection/components/pcm-chat-modal/pcm-chat-modal.js.map +1 -1
- package/dist/collection/components/pcm-hr-chat-modal/pcm-hr-chat-modal.js +76 -105
- package/dist/collection/components/pcm-hr-chat-modal/pcm-hr-chat-modal.js.map +1 -1
- package/dist/collection/components/pcm-jlpx-modal/pcm-jlpx-modal.css +162 -0
- package/dist/collection/components/pcm-jlpx-modal/pcm-jlpx-modal.js +616 -0
- package/dist/collection/components/pcm-jlpx-modal/pcm-jlpx-modal.js.map +1 -0
- package/dist/collection/components/pcm-mnms-modal/pcm-mnms-modal.css +0 -79
- package/dist/collection/components/pcm-mnms-modal/pcm-mnms-modal.js +133 -81
- package/dist/collection/components/pcm-mnms-modal/pcm-mnms-modal.js.map +1 -1
- package/dist/collection/components/pcm-video-chat-modal/pcm-video-chat-modal.js +77 -101
- package/dist/collection/components/pcm-video-chat-modal/pcm-video-chat-modal.js.map +1 -1
- package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.css +273 -0
- package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.js +613 -0
- package/dist/collection/components/pcm-zygh-modal/pcm-zygh-modal.js.map +1 -0
- package/dist/collection/global/global.css +324 -0
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/interfaces/chat.js.map +1 -1
- package/dist/collection/utils/utils.js +54 -113
- package/dist/collection/utils/utils.js.map +1 -1
- package/dist/components/index.js +1298 -11280
- package/dist/components/index.js.map +1 -1
- package/dist/components/my-component.js +2 -3
- package/dist/components/my-component.js.map +1 -1
- package/dist/components/{p-C4l_DOnx.js → p-BctfuDvG.js} +106 -147
- package/dist/components/p-BctfuDvG.js.map +1 -0
- package/dist/components/{p-D0s1Q-3O.js → p-LkDC0SN2.js} +343 -16
- package/dist/components/p-LkDC0SN2.js.map +1 -0
- package/dist/components/pcm-app-chat-modal.js +1 -1
- package/dist/components/pcm-chat-message.js +1 -1
- package/dist/components/pcm-chat-modal.js +19 -34
- package/dist/components/pcm-chat-modal.js.map +1 -1
- package/dist/components/pcm-hr-chat-modal.js +70 -100
- package/dist/components/pcm-hr-chat-modal.js.map +1 -1
- package/dist/components/pcm-jlpx-modal.d.ts +11 -0
- package/dist/components/pcm-jlpx-modal.js +339 -0
- package/dist/components/pcm-jlpx-modal.js.map +1 -0
- package/dist/components/pcm-mnms-modal.js +109 -57
- package/dist/components/pcm-mnms-modal.js.map +1 -1
- package/dist/components/pcm-video-chat-modal.js +74 -99
- package/dist/components/pcm-video-chat-modal.js.map +1 -1
- package/dist/components/pcm-zygh-modal.d.ts +11 -0
- package/dist/components/pcm-zygh-modal.js +330 -0
- package/dist/components/pcm-zygh-modal.js.map +1 -0
- package/dist/esm/index-nVjZGfA8.js +189 -0
- package/dist/esm/index-nVjZGfA8.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/my-component.entry.js +2 -2
- package/dist/esm/my-component.entry.js.map +1 -1
- package/dist/esm/pcm-agents.js +1 -1
- package/dist/esm/pcm-app-chat-modal.pcm-chat-message.pcm-hr-chat-modal.pcm-jlpx-modal.pcm-mnms-modal.pcm-video-chat-modal.pcm-zygh-modal.entry.js.map +1 -0
- package/dist/esm/pcm-app-chat-modal_7.entry.js +6552 -0
- package/dist/esm/pcm-app-chat-modal_7.entry.js.map +1 -0
- package/dist/esm/pcm-chat-modal.entry.js +17 -32
- package/dist/esm/pcm-chat-modal.entry.js.map +1 -1
- package/dist/pcm-agents/index.esm.js +1 -1
- package/dist/pcm-agents/my-component.entry.esm.js.map +1 -1
- package/dist/pcm-agents/p-55417392.entry.js +2 -0
- package/dist/pcm-agents/p-55417392.entry.js.map +1 -0
- package/dist/pcm-agents/p-a698b59f.entry.js +2 -0
- package/dist/pcm-agents/p-a698b59f.entry.js.map +1 -0
- package/dist/pcm-agents/p-f3ca99b4.entry.js +2 -0
- package/dist/pcm-agents/p-f3ca99b4.entry.js.map +1 -0
- package/dist/pcm-agents/p-nVjZGfA8.js +2 -0
- package/dist/pcm-agents/p-nVjZGfA8.js.map +1 -0
- package/dist/pcm-agents/pcm-agents.esm.js +1 -1
- package/dist/pcm-agents/pcm-app-chat-modal.pcm-chat-message.pcm-hr-chat-modal.pcm-jlpx-modal.pcm-mnms-modal.pcm-video-chat-modal.pcm-zygh-modal.entry.esm.js.map +1 -0
- package/dist/pcm-agents/pcm-chat-modal.entry.esm.js.map +1 -1
- package/dist/types/components/pcm-app-chat-modal/pcm-app-chat-modal.d.ts +13 -8
- package/dist/types/components/pcm-chat-message/pcm-chat-message.d.ts +5 -0
- package/dist/types/components/pcm-chat-modal/pcm-chat-modal.d.ts +8 -8
- package/dist/types/components/pcm-hr-chat-modal/pcm-hr-chat-modal.d.ts +6 -12
- package/dist/types/components/pcm-jlpx-modal/pcm-jlpx-modal.d.ts +113 -0
- package/dist/types/components/pcm-mnms-modal/pcm-mnms-modal.d.ts +19 -20
- package/dist/types/components/pcm-video-chat-modal/pcm-video-chat-modal.d.ts +4 -4
- package/dist/types/components/pcm-zygh-modal/pcm-zygh-modal.d.ts +117 -0
- package/dist/types/components.d.ts +429 -80
- package/dist/types/interfaces/chat.d.ts +0 -4
- package/dist/types/utils/utils.d.ts +29 -83
- package/package.json +61 -60
- package/readme.md +307 -307
- package/dist/cjs/index-DfIUl99H.js +0 -11413
- package/dist/cjs/index-DfIUl99H.js.map +0 -1
- package/dist/cjs/pcm-app-chat-modal.pcm-chat-message.pcm-mnms-modal.entry.cjs.js.map +0 -1
- package/dist/cjs/pcm-app-chat-modal_3.cjs.entry.js +0 -3734
- package/dist/cjs/pcm-app-chat-modal_3.cjs.entry.js.map +0 -1
- package/dist/cjs/pcm-hr-chat-modal.cjs.entry.js +0 -1078
- package/dist/cjs/pcm-hr-chat-modal.cjs.entry.js.map +0 -1
- package/dist/cjs/pcm-hr-chat-modal.entry.cjs.js.map +0 -1
- package/dist/cjs/pcm-video-chat-modal.cjs.entry.js +0 -927
- package/dist/cjs/pcm-video-chat-modal.cjs.entry.js.map +0 -1
- package/dist/cjs/pcm-video-chat-modal.entry.cjs.js.map +0 -1
- package/dist/components/p-C4l_DOnx.js.map +0 -1
- package/dist/components/p-CgDy4pJp.js +0 -1244
- package/dist/components/p-CgDy4pJp.js.map +0 -1
- package/dist/components/p-D0s1Q-3O.js.map +0 -1
- package/dist/esm/index-B2EtEi7v.js +0 -11409
- package/dist/esm/index-B2EtEi7v.js.map +0 -1
- package/dist/esm/pcm-app-chat-modal.pcm-chat-message.pcm-mnms-modal.entry.js.map +0 -1
- package/dist/esm/pcm-app-chat-modal_3.entry.js +0 -3730
- package/dist/esm/pcm-app-chat-modal_3.entry.js.map +0 -1
- package/dist/esm/pcm-hr-chat-modal.entry.js +0 -1076
- package/dist/esm/pcm-hr-chat-modal.entry.js.map +0 -1
- package/dist/esm/pcm-video-chat-modal.entry.js +0 -925
- package/dist/esm/pcm-video-chat-modal.entry.js.map +0 -1
- package/dist/pcm-agents/p-0ddd5c47.entry.js +0 -2
- package/dist/pcm-agents/p-0ddd5c47.entry.js.map +0 -1
- package/dist/pcm-agents/p-5f624943.entry.js +0 -2
- package/dist/pcm-agents/p-5f624943.entry.js.map +0 -1
- package/dist/pcm-agents/p-6c07f155.entry.js +0 -2
- package/dist/pcm-agents/p-6c07f155.entry.js.map +0 -1
- package/dist/pcm-agents/p-9a1fb6ca.entry.js +0 -2
- package/dist/pcm-agents/p-9a1fb6ca.entry.js.map +0 -1
- package/dist/pcm-agents/p-B2EtEi7v.js +0 -146
- package/dist/pcm-agents/p-B2EtEi7v.js.map +0 -1
- package/dist/pcm-agents/p-e21bc169.entry.js +0 -2
- package/dist/pcm-agents/p-e21bc169.entry.js.map +0 -1
- package/dist/pcm-agents/pcm-app-chat-modal.pcm-chat-message.pcm-mnms-modal.entry.esm.js.map +0 -1
- package/dist/pcm-agents/pcm-hr-chat-modal.entry.esm.js.map +0 -1
- package/dist/pcm-agents/pcm-video-chat-modal.entry.esm.js.map +0 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { h } from "@stencil/core";
|
|
2
2
|
import { marked } from "marked";
|
|
3
|
+
import extendedTables from "marked-extended-tables";
|
|
4
|
+
import { sendHttpRequest } from "../../utils/utils";
|
|
3
5
|
export class ChatMessageComponent {
|
|
4
6
|
/**
|
|
5
7
|
* 消息数据
|
|
@@ -13,6 +15,7 @@ export class ChatMessageComponent {
|
|
|
13
15
|
hostElement;
|
|
14
16
|
constructor() {
|
|
15
17
|
// 配置 marked 选项
|
|
18
|
+
marked.use(extendedTables);
|
|
16
19
|
marked.setOptions({
|
|
17
20
|
breaks: true,
|
|
18
21
|
gfm: true
|
|
@@ -35,7 +38,7 @@ export class ChatMessageComponent {
|
|
|
35
38
|
renderUserMessage() {
|
|
36
39
|
if (!this.message?.query?.trim())
|
|
37
40
|
return null;
|
|
38
|
-
return (h("div", { class: "user-message-container" }, h("div", { class: "message-bubble user-message" }, h("p", null, this.message.query)
|
|
41
|
+
return (h("div", { class: "user-message-container" }, h("div", { class: "message-bubble user-message" }, this.renderInputs(), h("p", null, this.message.query))));
|
|
39
42
|
}
|
|
40
43
|
// 渲染助手消息部分
|
|
41
44
|
renderAssistantMessage() {
|
|
@@ -48,7 +51,96 @@ export class ChatMessageComponent {
|
|
|
48
51
|
`请稍等...` :
|
|
49
52
|
htmlContent })), !showLoading && this.message.answer && (h("div", { class: "message-actions" }, h("button", { class: "copy-button", onClick: () => this.copyMessageContent(), title: "\u590D\u5236\u5185\u5BB9" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }), h("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })))))));
|
|
50
53
|
}
|
|
51
|
-
|
|
54
|
+
getFileIcon(fileName) {
|
|
55
|
+
const extension = fileName.split('.').pop()?.toLowerCase();
|
|
56
|
+
switch (extension) {
|
|
57
|
+
case 'pdf':
|
|
58
|
+
return {
|
|
59
|
+
icon: `<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
60
|
+
<path d="M19 3H9C7.89543 3 7 3.89543 7 5V27C7 28.1046 7.89543 29 9 29H23C24.1046 29 25 28.1046 25 27V9L19 3Z" stroke="#1677FF" stroke-width="2"/>
|
|
61
|
+
<path d="M19 3V9H25" stroke="#1677FF" stroke-width="2"/>
|
|
62
|
+
<text x="11" y="20" fill="#1677FF" font-size="8">PDF</text>
|
|
63
|
+
</svg>`,
|
|
64
|
+
color: '#1677FF'
|
|
65
|
+
};
|
|
66
|
+
case 'doc':
|
|
67
|
+
case 'docx':
|
|
68
|
+
return {
|
|
69
|
+
icon: `<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
70
|
+
<path d="M19 3H9C7.89543 3 7 3.89543 7 5V27C7 28.1046 7.89543 29 9 29H23C24.1046 29 25 28.1046 25 27V9L19 3Z" stroke="#1677FF" stroke-width="2"/>
|
|
71
|
+
<path d="M19 3V9H25" stroke="#1677FF" stroke-width="2"/>
|
|
72
|
+
<text x="11" y="20" fill="#1677FF" font-size="6">DOC</text>
|
|
73
|
+
</svg>`,
|
|
74
|
+
color: '#1677FF'
|
|
75
|
+
};
|
|
76
|
+
case 'jpg':
|
|
77
|
+
case 'jpeg':
|
|
78
|
+
case 'png':
|
|
79
|
+
case 'gif':
|
|
80
|
+
return {
|
|
81
|
+
icon: `<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
82
|
+
<path d="M19 3H9C7.89543 3 7 3.89543 7 5V27C7 28.1046 7.89543 29 9 29H23C24.1046 29 25 28.1046 25 27V9L19 3Z" stroke="#52C41A" stroke-width="2"/>
|
|
83
|
+
<path d="M19 3V9H25" stroke="#52C41A" stroke-width="2"/>
|
|
84
|
+
<path d="M12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14Z" fill="#52C41A"/>
|
|
85
|
+
<path d="M10 21L13 18L15 20L19 16L22 21H10Z" fill="#52C41A"/>
|
|
86
|
+
</svg>`,
|
|
87
|
+
color: '#52C41A'
|
|
88
|
+
};
|
|
89
|
+
default:
|
|
90
|
+
return {
|
|
91
|
+
icon: `<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
92
|
+
<path d="M19 3H9C7.89543 3 7 3.89543 7 5V27C7 28.1046 7.89543 29 9 29H23C24.1046 29 25 28.1046 25 27V9L19 3Z" stroke="#666666" stroke-width="2"/>
|
|
93
|
+
<path d="M19 3V9H25" stroke="#666666" stroke-width="2"/>
|
|
94
|
+
</svg>`,
|
|
95
|
+
color: '#666666'
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
getFileName(fileUrl) {
|
|
100
|
+
const parts = fileUrl.split('/');
|
|
101
|
+
return parts[parts.length - 1];
|
|
102
|
+
}
|
|
103
|
+
// 获取预览URL
|
|
104
|
+
async getCosPreviewUrl(cosKey) {
|
|
105
|
+
try {
|
|
106
|
+
const result = await sendHttpRequest({
|
|
107
|
+
url: '/sdk/v1/files/presigned-url',
|
|
108
|
+
method: 'GET',
|
|
109
|
+
headers: {
|
|
110
|
+
'authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6Ilx1NTMzYlx1ODA1OFx1NzMyYjgxMDMiLCJ1aWQiOjcsImNoYXRfdXNlciI6bnVsbCwiYm90X2lkIjoiMSIsInNlY3JldF9pZCI6Mzg5OTk1ODAyNTUxOTEwNDAsImV4cCI6MTc0NTA0OTAxM30.56OoTrp16avgl48YfWBKOHywAKHJ5qPGypqRCGCyVt0'
|
|
111
|
+
},
|
|
112
|
+
params: {
|
|
113
|
+
cos_key: cosKey
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
console.log(result);
|
|
117
|
+
if (result.success && result.data?.file_url) {
|
|
118
|
+
const baseUrl = result.data.file_url;
|
|
119
|
+
return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}ci-process=doc-preview©able=1&dstType=html`;
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error('获取预览URL失败:', error);
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// 处理文件点击
|
|
129
|
+
async handleFileClick(fileUrl) {
|
|
130
|
+
const previewUrl = await this.getCosPreviewUrl(fileUrl);
|
|
131
|
+
if (previewUrl) {
|
|
132
|
+
window.open(previewUrl, '_blank');
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
console.error('无法获取预览URL');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// 修改渲染文件项的部分
|
|
139
|
+
renderFileItem(fileName, fileUrl, index) {
|
|
140
|
+
const { icon } = this.getFileIcon(fileName);
|
|
141
|
+
return (h("div", { key: index, class: "input-view" }, h("div", { class: "input-label" }, "\u9644\u4EF6\uFF1A"), h("div", { class: "file-item", onClick: () => this.handleFileClick(fileUrl) }, h("div", { class: "file-icon", innerHTML: icon }), h("div", { class: "file-name" }, fileName))));
|
|
142
|
+
}
|
|
143
|
+
// 修改渲染输入数据的方法
|
|
52
144
|
renderInputs() {
|
|
53
145
|
if (!this.message.inputs)
|
|
54
146
|
return null;
|
|
@@ -56,17 +148,18 @@ export class ChatMessageComponent {
|
|
|
56
148
|
const value = this.message.inputs[key];
|
|
57
149
|
if (value && !key.startsWith('hide_') && key !== 'answer') {
|
|
58
150
|
if (key === 'file_url') {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
else if (key === 'file_urls' || key === 'fileUrls') {
|
|
62
|
-
const fileList = value.split(',');
|
|
63
|
-
return (h("div", { key: index, class: "flex flex-wrap" }, fileList.map((fileUrl, fileIndex) => (h("div", { key: fileIndex, class: "file-view" }, fileUrl)))));
|
|
151
|
+
const fileName = this.getFileName(value);
|
|
152
|
+
return this.renderFileItem(fileName, value, index);
|
|
64
153
|
}
|
|
65
|
-
else if (key === '
|
|
66
|
-
|
|
154
|
+
else if (key === 'file_urls') {
|
|
155
|
+
const fileList = Array.isArray(value) ? value : value.split(',');
|
|
156
|
+
return (h("div", { key: index, class: "file-list" }, fileList.map((fileUrl, fileIndex) => {
|
|
157
|
+
const fileName = this.getFileName(fileUrl);
|
|
158
|
+
return this.renderFileItem(fileName, fileUrl, fileIndex);
|
|
159
|
+
})));
|
|
67
160
|
}
|
|
68
|
-
else if (key === 'rule') {
|
|
69
|
-
return (h("div", { key: index, class: "input-view" }, h("div", { class: "input-label" },
|
|
161
|
+
else if (key === 'job_info' || key === 'rule') {
|
|
162
|
+
return (h("div", { key: index, class: "input-view" }, h("div", { class: "input-label" }, key === 'job_info' ? '职位信息' : '评估规则'), h("div", { class: "input-value" }, value)));
|
|
70
163
|
}
|
|
71
164
|
else {
|
|
72
165
|
return h("div", { key: index, class: "input-metadata" }, key, ": ", `${value}`);
|
|
@@ -76,7 +169,7 @@ export class ChatMessageComponent {
|
|
|
76
169
|
})));
|
|
77
170
|
}
|
|
78
171
|
render() {
|
|
79
|
-
return (h("div", { key: '
|
|
172
|
+
return (h("div", { key: '3d9014ffaf4a18e08e6cea97abce67d918512720', class: "message-round" }, this.renderUserMessage(), this.renderAssistantMessage()));
|
|
80
173
|
}
|
|
81
174
|
static get is() { return "pcm-chat-message"; }
|
|
82
175
|
static get encapsulation() { return "shadow"; }
|
|
@@ -130,7 +223,7 @@ export class ChatMessageComponent {
|
|
|
130
223
|
},
|
|
131
224
|
"complexType": {
|
|
132
225
|
"original": "Partial<ChatMessage>",
|
|
133
|
-
"resolved": "{ id?: string; query?: string; answer?: string; time?: string; conversation_id?: string; isStreaming?: boolean;
|
|
226
|
+
"resolved": "{ id?: string; query?: string; answer?: string; time?: string; conversation_id?: string; isStreaming?: boolean; inputs?: Record<string, any>; status?: \"error\" | \"normal\"; error?: any; }",
|
|
134
227
|
"references": {
|
|
135
228
|
"Partial": {
|
|
136
229
|
"location": "global",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pcm-chat-message.js","sourceRoot":"","sources":["../../../src/components/pcm-chat-message/pcm-chat-message.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAOhC,MAAM,OAAO,oBAAoB;IAC7B;;OAEG;IACK,OAAO,CAAc;IAE7B;;OAEG;IACM,aAAa,CAAqC;IAE3D,+BAA+B;IACpB,WAAW,CAAc;IAEpC;QACI,eAAe;QACf,MAAM,CAAC,UAAU,CAAC;YACd,MAAM,EAAE,IAAI;YACZ,GAAG,EAAE,IAAI;SACZ,CAAC,CAAC;KACN;IAED,aAAa;IACL,kBAAkB;QACtB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACtB,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;iBAC7C,IAAI,CAAC,GAAG,EAAE;gBACP,cAAc;gBACd,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAC7B,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,CAAC,EAAE;gBACT,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;QACX,CAAC;IACL,CAAC;IAED,WAAW;IACH,iBAAiB;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QAE9C,OAAO,CACH,WAAK,KAAK,EAAC,wBAAwB;YAC/B,WAAK,KAAK,EAAC,6BAA6B;gBACpC,aAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAK;gBAC1B,IAAI,CAAC,YAAY,EAAE,CAClB,CACJ,CACT,CAAC;IACN,CAAC;IAED,WAAW;IACH,sBAAsB;QAC1B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAEnE,6BAA6B;QAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE3E,OAAO,CACH,WAAK,KAAK,EAAC,6BAA6B;YACpC,WAAK,KAAK,EAAC,kCAAkC;gBACzC,WACI,KAAK,EAAC,gCAAgC,EACtC,SAAS,EAAE,WAAW,CAAC,CAAC;wBACpB,QAAQ,CAAC,CAAC;wBACV,WAAW,GAEZ,CACL;YACL,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAChC,WAAK,KAAK,EAAC,iBAAiB;gBACxB,cAAQ,KAAK,EAAC,aAAa,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAC,0BAAM;oBAC9E,WAAK,KAAK,EAAC,4BAA4B,EAAC,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,cAAc,kBAAc,GAAG,oBAAgB,OAAO,qBAAiB,OAAO;wBAChL,YAAM,CAAC,EAAC,GAAG,EAAC,CAAC,EAAC,GAAG,EAAC,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,GAAQ;wBAC9D,YAAM,CAAC,EAAC,yDAAyD,GAAQ,CACvE,CACD,CACP,CACT,CACH,CACT,CAAC;IACN,CAAC;IAED,SAAS;IACD,YAAY;QAChB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEtC,OAAO,CACH,eACK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACjD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACxD,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;oBACrB,OAAO,WAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAC,WAAW,IAAE,KAAK,CAAO,CAAC;gBAC5D,CAAC;qBAAM,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;oBACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAClC,OAAO,CACH,WAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAC,gBAAgB,IAClC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,CAClC,WAAK,GAAG,EAAE,SAAS,EAAE,KAAK,EAAC,WAAW,IAAE,OAAO,CAAO,CACzD,CAAC,CACA,CACT,CAAC;gBACN,CAAC;qBAAM,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;oBAC5B,OAAO,CACH,WAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAC,YAAY;wBAC/B,WAAK,KAAK,EAAC,aAAa,+BAAW;wBACnC,WAAK,KAAK,EAAC,aAAa,IAAE,KAAK,CAAO,CACpC,CACT,CAAC;gBACN,CAAC;qBAAM,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;oBACxB,OAAO,CACH,WAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAC,YAAY;wBAC/B,WAAK,KAAK,EAAC,aAAa,+BAAW;wBACnC,WAAK,KAAK,EAAC,aAAa,IAAE,KAAK,CAAO,CACpC,CACT,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,OAAO,WAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAC,gBAAgB;wBAAE,GAAG;;wBAAI,GAAG,KAAK,EAAE,CAAO,CAAC;gBAC7E,CAAC;YACL,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC,CAAC,CACA,CACT,CAAC;IACN,CAAC;IAED,MAAM;QACF,OAAO,CACH,4DAAK,KAAK,EAAC,eAAe;YACrB,IAAI,CAAC,iBAAiB,EAAE;YACxB,IAAI,CAAC,sBAAsB,EAAE,CAC5B,CACT,CAAC;IACN,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACJ","sourcesContent":["import { Component, Prop, h, Element, Event, EventEmitter } from '@stencil/core';\r\nimport { marked } from 'marked';\r\nimport { ChatMessage } from '../../interfaces/chat';\r\n@Component({\r\n tag: 'pcm-chat-message',\r\n styleUrl: 'pcm-chat-message.css',\r\n shadow: true,\r\n})\r\nexport class ChatMessageComponent {\r\n /**\r\n * 消息数据\r\n */\r\n @Prop() message: ChatMessage;\r\n\r\n /**\r\n * 消息变更事件\r\n */\r\n @Event() messageChange: EventEmitter<Partial<ChatMessage>>;\r\n\r\n // 使用 @Element 装饰器获取组件的 host 元素\r\n @Element() hostElement: HTMLElement;\r\n\r\n constructor() {\r\n // 配置 marked 选项\r\n marked.setOptions({\r\n breaks: true,\r\n gfm: true\r\n });\r\n }\r\n\r\n // 复制消息内容到剪贴板\r\n private copyMessageContent() {\r\n if (this.message.answer) {\r\n navigator.clipboard.writeText(this.message.answer)\r\n .then(() => {\r\n // 可以添加复制成功的提示\r\n console.log('内容已复制到剪贴板');\r\n })\r\n .catch(err => {\r\n console.error('复制失败:', err);\r\n });\r\n }\r\n }\r\n\r\n // 渲染用户消息部分\r\n private renderUserMessage() {\r\n if (!this.message?.query?.trim()) return null;\r\n\r\n return (\r\n <div class=\"user-message-container\">\r\n <div class=\"message-bubble user-message\">\r\n <p>{this.message.query}</p>\r\n {this.renderInputs()}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // 渲染助手消息部分\r\n private renderAssistantMessage() {\r\n if (!this.message.answer && !this.message.isStreaming) return null;\r\n\r\n // 只有在开始流式输出且还没有内容时才显示loading\r\n const showLoading = this.message.isStreaming && !this.message.answer;\r\n const htmlContent = this.message.answer ? marked(this.message.answer) : '';\r\n\r\n return (\r\n <div class=\"assistant-message-container\">\r\n <div class=\"message-bubble assistant-message\">\r\n <div\r\n class=\"markdown-content markdown-body\"\r\n innerHTML={showLoading ? \r\n `请稍等...` : \r\n htmlContent\r\n }\r\n ></div>\r\n </div>\r\n {!showLoading && this.message.answer && (\r\n <div class=\"message-actions\">\r\n <button class=\"copy-button\" onClick={() => this.copyMessageContent()} title=\"复制内容\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\r\n </svg>\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n // 渲染输入数据\r\n private renderInputs() {\r\n if (!this.message.inputs) return null;\r\n\r\n return (\r\n <div>\r\n {Object.keys(this.message.inputs).map((key, index) => {\r\n const value = this.message.inputs[key];\r\n if (value && !key.startsWith('hide_') && key !== 'answer') {\r\n if (key === 'file_url') {\r\n return <div key={index} class=\"file-view\">{value}</div>;\r\n } else if (key === 'file_urls' || key === 'fileUrls') {\r\n const fileList = value.split(',');\r\n return (\r\n <div key={index} class=\"flex flex-wrap\">\r\n {fileList.map((fileUrl, fileIndex) => (\r\n <div key={fileIndex} class=\"file-view\">{fileUrl}</div>\r\n ))}\r\n </div>\r\n );\r\n } else if (key === 'job_info') {\r\n return (\r\n <div key={index} class=\"input-view\">\r\n <div class=\"input-label\">职位信息</div>\r\n <div class=\"input-value\">{value}</div>\r\n </div>\r\n );\r\n } else if (key === 'rule') {\r\n return (\r\n <div key={index} class=\"input-view\">\r\n <div class=\"input-label\">评估规则</div>\r\n <div class=\"input-value\">{value}</div>\r\n </div>\r\n );\r\n } else {\r\n return <div key={index} class=\"input-metadata\">{key}: {`${value}`}</div>;\r\n }\r\n }\r\n return null;\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n render() {\r\n return (\r\n <div class=\"message-round\">\r\n {this.renderUserMessage()}\r\n {this.renderAssistantMessage()}\r\n </div>\r\n );\r\n }\r\n} "]}
|
|
1
|
+
{"version":3,"file":"pcm-chat-message.js","sourceRoot":"","sources":["../../../src/components/pcm-chat-message/pcm-chat-message.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Prop, h, Element, Event, EventEmitter } from '@stencil/core';\r\nimport { marked } from 'marked';\r\nimport extendedTables from 'marked-extended-tables';\r\nimport { ChatMessage } from '../../interfaces/chat';\r\nimport { sendHttpRequest } from '../../utils/utils';\r\n\r\n@Component({\r\n tag: 'pcm-chat-message',\r\n styleUrl: 'pcm-chat-message.css',\r\n shadow: true,\r\n})\r\nexport class ChatMessageComponent {\r\n /**\r\n * 消息数据\r\n */\r\n @Prop() message: ChatMessage;\r\n\r\n /**\r\n * 消息变更事件\r\n */\r\n @Event() messageChange: EventEmitter<Partial<ChatMessage>>;\r\n\r\n // 使用 @Element 装饰器获取组件的 host 元素\r\n @Element() hostElement: HTMLElement;\r\n\r\n constructor() {\r\n // 配置 marked 选项\r\n marked.use(extendedTables);\r\n marked.setOptions({\r\n breaks: true,\r\n gfm: true\r\n });\r\n }\r\n\r\n // 复制消息内容到剪贴板\r\n private copyMessageContent() {\r\n if (this.message.answer) {\r\n navigator.clipboard.writeText(this.message.answer)\r\n .then(() => {\r\n // 可以添加复制成功的提示\r\n console.log('内容已复制到剪贴板');\r\n })\r\n .catch(err => {\r\n console.error('复制失败:', err);\r\n });\r\n }\r\n }\r\n\r\n // 渲染用户消息部分\r\n private renderUserMessage() {\r\n if (!this.message?.query?.trim()) return null;\r\n\r\n return (\r\n <div class=\"user-message-container\">\r\n <div class=\"message-bubble user-message\">\r\n {this.renderInputs()}\r\n <p>{this.message.query}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // 渲染助手消息部分\r\n private renderAssistantMessage() {\r\n if (!this.message.answer && !this.message.isStreaming) return null;\r\n\r\n // 只有在开始流式输出且还没有内容时才显示loading\r\n const showLoading = this.message.isStreaming && !this.message.answer;\r\n const htmlContent = this.message.answer ? marked(this.message.answer) : '';\r\n\r\n return (\r\n <div class=\"assistant-message-container\">\r\n <div class=\"message-bubble assistant-message\">\r\n <div\r\n class=\"markdown-content markdown-body\"\r\n innerHTML={showLoading ?\r\n `请稍等...` :\r\n htmlContent\r\n }\r\n ></div>\r\n </div>\r\n {!showLoading && this.message.answer && (\r\n <div class=\"message-actions\">\r\n <button class=\"copy-button\" onClick={() => this.copyMessageContent()} title=\"复制内容\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\r\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\r\n </svg>\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n }\r\n\r\n private getFileIcon(fileName: string): { icon: string, color: string } {\r\n const extension = fileName.split('.').pop()?.toLowerCase();\r\n\r\n switch (extension) {\r\n case 'pdf':\r\n return {\r\n icon: `<svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M19 3H9C7.89543 3 7 3.89543 7 5V27C7 28.1046 7.89543 29 9 29H23C24.1046 29 25 28.1046 25 27V9L19 3Z\" stroke=\"#1677FF\" stroke-width=\"2\"/>\r\n <path d=\"M19 3V9H25\" stroke=\"#1677FF\" stroke-width=\"2\"/>\r\n <text x=\"11\" y=\"20\" fill=\"#1677FF\" font-size=\"8\">PDF</text>\r\n </svg>`,\r\n color: '#1677FF'\r\n };\r\n case 'doc':\r\n case 'docx':\r\n return {\r\n icon: `<svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M19 3H9C7.89543 3 7 3.89543 7 5V27C7 28.1046 7.89543 29 9 29H23C24.1046 29 25 28.1046 25 27V9L19 3Z\" stroke=\"#1677FF\" stroke-width=\"2\"/>\r\n <path d=\"M19 3V9H25\" stroke=\"#1677FF\" stroke-width=\"2\"/>\r\n <text x=\"11\" y=\"20\" fill=\"#1677FF\" font-size=\"6\">DOC</text>\r\n </svg>`,\r\n color: '#1677FF'\r\n };\r\n case 'jpg':\r\n case 'jpeg':\r\n case 'png':\r\n case 'gif':\r\n return {\r\n icon: `<svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M19 3H9C7.89543 3 7 3.89543 7 5V27C7 28.1046 7.89543 29 9 29H23C24.1046 29 25 28.1046 25 27V9L19 3Z\" stroke=\"#52C41A\" stroke-width=\"2\"/>\r\n <path d=\"M19 3V9H25\" stroke=\"#52C41A\" stroke-width=\"2\"/>\r\n <path d=\"M12 14C13.1046 14 14 13.1046 14 12C14 10.8954 13.1046 10 12 10C10.8954 10 10 10.8954 10 12C10 13.1046 10.8954 14 12 14Z\" fill=\"#52C41A\"/>\r\n <path d=\"M10 21L13 18L15 20L19 16L22 21H10Z\" fill=\"#52C41A\"/>\r\n </svg>`,\r\n color: '#52C41A'\r\n };\r\n default:\r\n return {\r\n icon: `<svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M19 3H9C7.89543 3 7 3.89543 7 5V27C7 28.1046 7.89543 29 9 29H23C24.1046 29 25 28.1046 25 27V9L19 3Z\" stroke=\"#666666\" stroke-width=\"2\"/>\r\n <path d=\"M19 3V9H25\" stroke=\"#666666\" stroke-width=\"2\"/>\r\n </svg>`,\r\n color: '#666666'\r\n };\r\n }\r\n }\r\n\r\n private getFileName(fileUrl: string): string {\r\n const parts = fileUrl.split('/');\r\n return parts[parts.length - 1];\r\n }\r\n\r\n // 获取预览URL\r\n private async getCosPreviewUrl(cosKey: string): Promise<string | null> {\r\n try {\r\n const result = await sendHttpRequest<{ file_url: string }>({\r\n url: '/sdk/v1/files/presigned-url',\r\n method: 'GET',\r\n headers: {\r\n 'authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6Ilx1NTMzYlx1ODA1OFx1NzMyYjgxMDMiLCJ1aWQiOjcsImNoYXRfdXNlciI6bnVsbCwiYm90X2lkIjoiMSIsInNlY3JldF9pZCI6Mzg5OTk1ODAyNTUxOTEwNDAsImV4cCI6MTc0NTA0OTAxM30.56OoTrp16avgl48YfWBKOHywAKHJ5qPGypqRCGCyVt0'\r\n },\r\n params: {\r\n cos_key: cosKey\r\n }\r\n });\r\n \r\n console.log(result);\r\n \r\n if (result.success && result.data?.file_url) {\r\n const baseUrl = result.data.file_url;\r\n return `${baseUrl}${baseUrl.includes('?') ? '&' : '?'}ci-process=doc-preview©able=1&dstType=html`;\r\n }\r\n return null;\r\n } catch (error) {\r\n console.error('获取预览URL失败:', error);\r\n return null;\r\n }\r\n }\r\n\r\n // 处理文件点击\r\n private async handleFileClick(fileUrl: string) {\r\n const previewUrl = await this.getCosPreviewUrl(fileUrl);\r\n if (previewUrl) {\r\n window.open(previewUrl, '_blank');\r\n } else {\r\n console.error('无法获取预览URL');\r\n }\r\n }\r\n\r\n // 修改渲染文件项的部分\r\n private renderFileItem(fileName: string, fileUrl: string, index: number) {\r\n const { icon } = this.getFileIcon(fileName);\r\n return (\r\n <div key={index} class=\"input-view\">\r\n <div class=\"input-label\">附件:</div>\r\n <div class=\"file-item\" onClick={() => this.handleFileClick(fileUrl)}>\r\n <div class=\"file-icon\" innerHTML={icon}></div>\r\n <div class=\"file-name\">{fileName}</div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n // 修改渲染输入数据的方法\r\n private renderInputs() {\r\n if (!this.message.inputs) return null;\r\n\r\n return (\r\n <div>\r\n {Object.keys(this.message.inputs).map((key, index) => {\r\n const value = this.message.inputs[key];\r\n if (value && !key.startsWith('hide_') && key !== 'answer') {\r\n if (key === 'file_url') {\r\n const fileName = this.getFileName(value);\r\n return this.renderFileItem(fileName, value, index);\r\n } else if (key === 'file_urls') {\r\n const fileList = Array.isArray(value) ? value : value.split(',');\r\n return (\r\n <div key={index} class=\"file-list\">\r\n {fileList.map((fileUrl, fileIndex) => {\r\n const fileName = this.getFileName(fileUrl);\r\n return this.renderFileItem(fileName, fileUrl, fileIndex);\r\n })}\r\n </div>\r\n );\r\n } else if (key === 'job_info' || key === 'rule') {\r\n return (\r\n <div key={index} class=\"input-view\">\r\n <div class=\"input-label\">{key === 'job_info' ? '职位信息' : '评估规则'}</div>\r\n <div class=\"input-value\">{value}</div>\r\n </div>\r\n );\r\n } else {\r\n return <div key={index} class=\"input-metadata\">{key}: {`${value}`}</div>;\r\n }\r\n }\r\n return null;\r\n })}\r\n </div>\r\n );\r\n }\r\n\r\n render() {\r\n return (\r\n <div class=\"message-round\">\r\n {this.renderUserMessage()}\r\n {this.renderAssistantMessage()}\r\n </div>\r\n );\r\n }\r\n} "]}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { h } from "@stencil/core";
|
|
2
|
-
import { convertWorkflowStreamNodeToMessageRound, sendSSERequest, sendHttpRequest } from "../../utils/utils";
|
|
2
|
+
import { convertWorkflowStreamNodeToMessageRound, sendSSERequest, sendHttpRequest, uploadFileToBackend } from "../../utils/utils";
|
|
3
3
|
export class ChatModal {
|
|
4
4
|
/**
|
|
5
5
|
* 模态框标题
|
|
6
6
|
*/
|
|
7
7
|
modalTitle = '在线客服';
|
|
8
|
+
/**
|
|
9
|
+
* API鉴权密钥
|
|
10
|
+
*/
|
|
11
|
+
apiKey = '';
|
|
8
12
|
/**
|
|
9
13
|
* 是否显示聊天模态框
|
|
10
14
|
*/
|
|
@@ -46,7 +50,7 @@ export class ChatModal {
|
|
|
46
50
|
*/
|
|
47
51
|
botId;
|
|
48
52
|
/**
|
|
49
|
-
* 会话ID
|
|
53
|
+
* 会话ID,传入继续对话,否则创建新会话
|
|
50
54
|
*/
|
|
51
55
|
conversationId;
|
|
52
56
|
/**
|
|
@@ -80,7 +84,7 @@ export class ChatModal {
|
|
|
80
84
|
*/
|
|
81
85
|
defaultQuery = '';
|
|
82
86
|
/**
|
|
83
|
-
*
|
|
87
|
+
* 是否以全屏模式打开,移动端建议设置为true
|
|
84
88
|
*/
|
|
85
89
|
fullscreen = false;
|
|
86
90
|
handleClose = () => {
|
|
@@ -95,15 +99,12 @@ export class ChatModal {
|
|
|
95
99
|
this.suggestedQuestionsLoading = true;
|
|
96
100
|
try {
|
|
97
101
|
const response = await sendHttpRequest({
|
|
98
|
-
url:
|
|
99
|
-
params: {
|
|
100
|
-
bot_id: this.botId
|
|
101
|
-
}
|
|
102
|
+
url: `/share/messages/${messageId}/suggested`,
|
|
102
103
|
});
|
|
103
104
|
if (this.stopSuggestedQuestionsRef.current)
|
|
104
105
|
return;
|
|
105
|
-
if (response.
|
|
106
|
-
this.suggestedQuestions = response.data
|
|
106
|
+
if (response.success && response.data) {
|
|
107
|
+
this.suggestedQuestions = response.data || [];
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
catch (error) {
|
|
@@ -130,22 +131,10 @@ export class ChatModal {
|
|
|
130
131
|
return;
|
|
131
132
|
this.isUploading = true;
|
|
132
133
|
try {
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
const response = await fetch('https://pcm_api.ylzhaopin.com/external/v1/files/upload', {
|
|
136
|
-
method: 'POST',
|
|
137
|
-
body: formData
|
|
134
|
+
const result = await uploadFileToBackend(this.selectedFile, {
|
|
135
|
+
'authorization': 'Bearer ' + this.apiKey
|
|
138
136
|
});
|
|
139
|
-
|
|
140
|
-
console.log('result', result);
|
|
141
|
-
if (result) {
|
|
142
|
-
this.uploadedFileInfo.push({
|
|
143
|
-
cos_key: result.cos_key,
|
|
144
|
-
filename: result.filename,
|
|
145
|
-
ext: result.ext,
|
|
146
|
-
presigned_url: result.presigned_url
|
|
147
|
-
});
|
|
148
|
-
}
|
|
137
|
+
this.uploadedFileInfo.push(result);
|
|
149
138
|
}
|
|
150
139
|
catch (error) {
|
|
151
140
|
console.error('文件上传错误:', error);
|
|
@@ -183,7 +172,6 @@ export class ChatModal {
|
|
|
183
172
|
time: time, // 消息时间
|
|
184
173
|
query: queryText, // 用户输入的消息内容
|
|
185
174
|
answer: '', // AI助手的回复内容
|
|
186
|
-
bot_id: this.botId, // 机器人ID
|
|
187
175
|
isStreaming: true, // 是否正在流式输出
|
|
188
176
|
conversation_id: this.conversationId, // 会话ID
|
|
189
177
|
inputs: {}, // 输入参数
|
|
@@ -197,7 +185,6 @@ export class ChatModal {
|
|
|
197
185
|
this.scrollToBottom();
|
|
198
186
|
// 准备请求数据
|
|
199
187
|
const requestData = {
|
|
200
|
-
bot_id: this.botId,
|
|
201
188
|
response_mode: 'streaming',
|
|
202
189
|
conversation_id: this.conversationId,
|
|
203
190
|
query: queryText,
|
|
@@ -212,7 +199,7 @@ export class ChatModal {
|
|
|
212
199
|
};
|
|
213
200
|
}
|
|
214
201
|
await sendSSERequest({
|
|
215
|
-
url:
|
|
202
|
+
url: `/sdk/v1/chat/chat-messages`,
|
|
216
203
|
method: 'POST',
|
|
217
204
|
data: requestData,
|
|
218
205
|
onMessage: (data) => {
|
|
@@ -334,19 +321,18 @@ export class ChatModal {
|
|
|
334
321
|
this.isLoadingHistory = true;
|
|
335
322
|
try {
|
|
336
323
|
const response = await sendHttpRequest({
|
|
337
|
-
url:
|
|
324
|
+
url: `/share/messages`,
|
|
338
325
|
params: {
|
|
339
326
|
conversation_id: this.conversationId,
|
|
340
|
-
bot_id: this.botId,
|
|
341
327
|
user: '1234567890',
|
|
342
328
|
limit: 20
|
|
343
329
|
}
|
|
344
330
|
});
|
|
345
|
-
if (!response.
|
|
331
|
+
if (!response.success || !response.data) {
|
|
346
332
|
throw new Error('加载历史消息失败');
|
|
347
333
|
}
|
|
348
334
|
// 适配新的接口返回格式
|
|
349
|
-
const historyData = response.data
|
|
335
|
+
const historyData = response.data || [];
|
|
350
336
|
// 清空现有消息,确保不会重复
|
|
351
337
|
this.currentStreamingMessage = null;
|
|
352
338
|
this.messages = [];
|
|
@@ -356,7 +342,6 @@ export class ChatModal {
|
|
|
356
342
|
return {
|
|
357
343
|
...msg,
|
|
358
344
|
time: timeStr,
|
|
359
|
-
bot_id: this.botId,
|
|
360
345
|
isStreaming: false,
|
|
361
346
|
status: msg.status === 'error' ? 'error' : 'normal'
|
|
362
347
|
};
|
|
@@ -448,6 +433,26 @@ export class ChatModal {
|
|
|
448
433
|
"reflect": false,
|
|
449
434
|
"defaultValue": "'\u5728\u7EBF\u5BA2\u670D'"
|
|
450
435
|
},
|
|
436
|
+
"apiKey": {
|
|
437
|
+
"type": "string",
|
|
438
|
+
"mutable": false,
|
|
439
|
+
"complexType": {
|
|
440
|
+
"original": "string",
|
|
441
|
+
"resolved": "string",
|
|
442
|
+
"references": {}
|
|
443
|
+
},
|
|
444
|
+
"required": false,
|
|
445
|
+
"optional": false,
|
|
446
|
+
"docs": {
|
|
447
|
+
"tags": [],
|
|
448
|
+
"text": "API\u9274\u6743\u5BC6\u94A5"
|
|
449
|
+
},
|
|
450
|
+
"getter": false,
|
|
451
|
+
"setter": false,
|
|
452
|
+
"attribute": "api-key",
|
|
453
|
+
"reflect": false,
|
|
454
|
+
"defaultValue": "''"
|
|
455
|
+
},
|
|
451
456
|
"isOpen": {
|
|
452
457
|
"type": "boolean",
|
|
453
458
|
"mutable": true,
|
|
@@ -578,7 +583,7 @@ export class ChatModal {
|
|
|
578
583
|
"optional": true,
|
|
579
584
|
"docs": {
|
|
580
585
|
"tags": [],
|
|
581
|
-
"text": "\u4F1A\u8BDDID"
|
|
586
|
+
"text": "\u4F1A\u8BDDID\uFF0C\u4F20\u5165\u7EE7\u7EED\u5BF9\u8BDD\uFF0C\u5426\u5219\u521B\u5EFA\u65B0\u4F1A\u8BDD"
|
|
582
587
|
},
|
|
583
588
|
"getter": false,
|
|
584
589
|
"setter": false,
|
|
@@ -617,7 +622,7 @@ export class ChatModal {
|
|
|
617
622
|
"optional": false,
|
|
618
623
|
"docs": {
|
|
619
624
|
"tags": [],
|
|
620
|
-
"text": "\u662F\u5426\u4EE5\u5168\u5C4F\u6A21\u5F0F\u6253\u5F00"
|
|
625
|
+
"text": "\u662F\u5426\u4EE5\u5168\u5C4F\u6A21\u5F0F\u6253\u5F00\uFF0C\u79FB\u52A8\u7AEF\u5EFA\u8BAE\u8BBE\u7F6E\u4E3Atrue"
|
|
621
626
|
},
|
|
622
627
|
"getter": false,
|
|
623
628
|
"setter": false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pcm-chat-modal.js","sourceRoot":"","sources":["../../../src/components/pcm-chat-modal/pcm-chat-modal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Prop, h, State, Event, EventEmitter, Element, Watch } from '@stencil/core';\r\nimport { convertWorkflowStreamNodeToMessageRound, UserInputMessageType, sendSSERequest, sendHttpRequest } from '../../utils/utils';\r\nimport { ChatMessage } from '../../interfaces/chat';\r\n\r\n@Component({\r\n tag: 'pcm-chat-modal',\r\n styleUrl: 'pcm-chat-modal.css',\r\n shadow: true,\r\n})\r\nexport class ChatModal {\r\n /**\r\n * 模态框标题\r\n */\r\n @Prop() modalTitle: string = '在线客服';\r\n\r\n /**\r\n * 是否显示聊天模态框\r\n */\r\n @Prop({ mutable: true }) isOpen: boolean = false;\r\n\r\n /**\r\n * 聊天消息历史\r\n */\r\n @State() messages: ChatMessage[] = [];\r\n\r\n /**\r\n * 当前输入的消息\r\n */\r\n @State() currentMessage: string = '';\r\n\r\n /**\r\n * 当发送消息时触发\r\n */\r\n @Event() messageSent: EventEmitter<string>;\r\n\r\n /**\r\n * 点击模态框关闭时触发\r\n */\r\n @Event() modalClosed: EventEmitter<void>;\r\n\r\n /**\r\n * 应用图标URL\r\n */\r\n @Prop() icon?: string;\r\n\r\n /**\r\n * 聊天框的页面层级\r\n */\r\n @Prop() zIndex?: number = 1000;\r\n\r\n /**\r\n * 是否展示顶部标题栏\r\n */\r\n @Prop() isShowHeader: boolean = true;\r\n\r\n /**\r\n * 是否展示右上角的关闭按钮\r\n */\r\n @Prop() isNeedClose: boolean = true;\r\n\r\n /**\r\n * 机器人ID\r\n */\r\n @Prop() botId: string;\r\n\r\n /**\r\n * 会话ID\r\n */\r\n @Prop({ mutable: true }) conversationId?: string;\r\n\r\n\r\n /**\r\n * 当前助手回复的消息\r\n */\r\n @State() currentAssistantMessage: string = '';\r\n\r\n /**\r\n * 是否正在加载回复\r\n */\r\n @State() isLoading: boolean = false;\r\n\r\n /**\r\n * 当前正在流式输出的消息\r\n */\r\n @State() currentStreamingMessage: ChatMessage | null = null;\r\n\r\n // 添加新的状态控制\r\n @State() shouldAutoScroll: boolean = true;\r\n private readonly SCROLL_THRESHOLD = 30;\r\n\r\n @State() isLoadingHistory: boolean = false;\r\n\r\n // 使用 @Element 装饰器获取组件的 host 元素\r\n @Element() hostElement: HTMLElement;\r\n\r\n // 添加新的 Event\r\n @Event() streamComplete: EventEmitter<{\r\n conversation_id: string;\r\n event: string;\r\n message_id: string;\r\n id: string;\r\n }>;\r\n\r\n @State() suggestedQuestions: string[] = [];\r\n @State() suggestedQuestionsLoading: boolean = false;\r\n private stopSuggestedQuestionsRef: { current: boolean } = { current: false };\r\n\r\n @State() selectedFile: File | null = null;\r\n @State() isUploading: boolean = false;\r\n @State() uploadedFileInfo: { cos_key: string, filename: string, ext: string, presigned_url: string }[] = [];\r\n\r\n /**\r\n * 默认查询文本\r\n */\r\n @Prop() defaultQuery: string = '';\r\n\r\n /**\r\n * 是否以全屏模式打开\r\n */\r\n @Prop() fullscreen: boolean = false;\r\n\r\n private handleClose = () => {\r\n this.modalClosed.emit();\r\n };\r\n\r\n private handleInputChange = (event: Event) => {\r\n const input = event.target as HTMLInputElement;\r\n this.currentMessage = input.value;\r\n };\r\n\r\n private async getSuggestedQuestions(messageId: string) {\r\n this.stopSuggestedQuestionsRef.current = false;\r\n this.suggestedQuestionsLoading = true;\r\n\r\n try {\r\n const response = await sendHttpRequest({\r\n url: `https://pcm_api.ylzhaopin.com/share/messages/${messageId}/suggested`,\r\n params: {\r\n bot_id: this.botId\r\n }\r\n });\r\n\r\n if (this.stopSuggestedQuestionsRef.current) return;\r\n\r\n if (response.isOk && response.data?.result === 'success') {\r\n this.suggestedQuestions = response.data?.data || [];\r\n }\r\n } catch (error) {\r\n console.error('获取问题建议失败:', error);\r\n } finally {\r\n this.suggestedQuestionsLoading = false;\r\n }\r\n }\r\n\r\n private handleStopSuggestedQuestions = () => {\r\n this.suggestedQuestions = [];\r\n this.stopSuggestedQuestionsRef.current = true;\r\n };\r\n\r\n private handleFileChange = async (event: Event) => {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files.length > 0) {\r\n this.selectedFile = input.files[0];\r\n \r\n // 文件选择后立即上传\r\n await this.uploadFile();\r\n }\r\n };\r\n\r\n private async uploadFile() {\r\n if (!this.selectedFile) return;\r\n \r\n this.isUploading = true;\r\n \r\n try {\r\n const formData = new FormData();\r\n formData.append('file', this.selectedFile);\r\n \r\n const response = await fetch('https://pcm_api.ylzhaopin.com/external/v1/files/upload', {\r\n method: 'POST',\r\n body: formData\r\n });\r\n \r\n \r\n const result = await response.json();\r\n console.log('result', result);\r\n if (result) {\r\n this.uploadedFileInfo.push({\r\n cos_key: result.cos_key,\r\n filename: result.filename,\r\n ext: result.ext,\r\n presigned_url: result.presigned_url\r\n });\r\n } \r\n } catch (error) {\r\n console.error('文件上传错误:', error);\r\n this.clearSelectedFile();\r\n alert('文件上传失败,请重试');\r\n } finally {\r\n this.isUploading = false;\r\n }\r\n }\r\n\r\n private handleUploadClick = () => {\r\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\r\n fileInput?.click();\r\n };\r\n\r\n private clearSelectedFile = () => {\r\n this.selectedFile = null;\r\n this.uploadedFileInfo = [];\r\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\r\n if (fileInput) {\r\n fileInput.value = '';\r\n }\r\n };\r\n\r\n\r\n private async sendMessageToAPI(message: string) {\r\n this.handleStopSuggestedQuestions();\r\n console.log('开始发送消息:', message);\r\n this.isLoading = true;\r\n let answer = '';\r\n\r\n const now = new Date();\r\n const time = `${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`;\r\n\r\n // 如果消息为空但有文件,使用默认文本\r\n const queryText = message.trim() || (this.uploadedFileInfo.length > 0 ? '请分析这个文件' : '');\r\n\r\n // 创建新的消息对象时确保必填字段都有值\r\n const newMessage: ChatMessage = {\r\n id: `temp-${Date.now()}`, // 消息唯一标识\r\n time: time, // 消息时间\r\n query: queryText, // 用户输入的消息内容\r\n answer: '', // AI助手的回复内容\r\n bot_id: this.botId, // 机器人ID\r\n isStreaming: true, // 是否正在流式输出\r\n conversation_id: this.conversationId, // 会话ID\r\n inputs: {}, // 输入参数\r\n status: \"normal\", // 消息状态\r\n error: null // 错误信息\r\n };\r\n\r\n // 设置当前流式消息\r\n this.currentStreamingMessage = newMessage;\r\n\r\n this.shouldAutoScroll = true;\r\n // 滚动到底部\r\n this.scrollToBottom();\r\n\r\n // 准备请求数据\r\n const requestData: any = {\r\n bot_id: this.botId,\r\n response_mode: 'streaming',\r\n conversation_id: this.conversationId,\r\n query: queryText,\r\n user: '1234567890'\r\n };\r\n // 如果有上传的文件,添加到inputs参数\r\n if (this.uploadedFileInfo.length > 0) {\r\n const fileUrls = this.uploadedFileInfo.map(fileInfo => fileInfo.cos_key).join(',');\r\n\r\n requestData.inputs = {\r\n ...requestData.inputs,\r\n input: fileUrls\r\n };\r\n }\r\n\r\n await sendSSERequest({\r\n url: `https://pcm_api.ylzhaopin.com/share/chat-messages`,\r\n method: 'POST',\r\n data: requestData,\r\n onMessage: (data) => {\r\n console.log('收到Stream数据:', data);\r\n\r\n if (data.conversation_id && !this.conversationId) {\r\n this.conversationId = data.conversation_id;\r\n this.updateUrlWithConversationId(data.conversation_id);\r\n }\r\n\r\n if (data.event === 'message') {\r\n const inputMessage: UserInputMessageType = { message: message };\r\n convertWorkflowStreamNodeToMessageRound('message', inputMessage, data);\r\n\r\n if (data.event === 'agent_message' || data.event === 'message') {\r\n if (data.answer) {\r\n answer += data.answer;\r\n const updatedMessage: ChatMessage = {\r\n ...this.currentStreamingMessage,\r\n answer,\r\n isStreaming: true\r\n };\r\n this.currentStreamingMessage = updatedMessage;\r\n this.scrollToBottom();\r\n }\r\n }\r\n }\r\n if (data.event === \"message_end\") {\r\n this.streamComplete.emit({\r\n conversation_id: data.conversation_id || '',\r\n event: data.event,\r\n message_id: data.message_id,\r\n id: data.id,\r\n });\r\n }\r\n },\r\n onError: (error) => {\r\n console.error('发生错误:', error);\r\n this.messages = [...this.messages, {\r\n ...newMessage,\r\n answer: '抱歉,发生了错误,请稍后再试。',\r\n error: error,\r\n isStreaming: false\r\n }];\r\n this.currentStreamingMessage = null;\r\n this.isLoading = false;\r\n },\r\n onComplete: () => {\r\n console.log('请求完成');\r\n this.isLoading = false;\r\n this.messages = [...this.messages, this.currentStreamingMessage];\r\n\r\n // 在消息完成后获取问题建议\r\n if (this.currentStreamingMessage) {\r\n this.getSuggestedQuestions(this.currentStreamingMessage.conversation_id);\r\n }\r\n\r\n this.currentStreamingMessage = null;\r\n }\r\n });\r\n }\r\n // 监听滚动事件,用于控制聊天历史记录的自动滚动行为。\r\n private handleScroll = () => {\r\n const chatHistory = this.hostElement.shadowRoot?.querySelector('.chat-history');\r\n if (!chatHistory) return;\r\n\r\n const { scrollTop, scrollHeight, clientHeight } = chatHistory;\r\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\r\n\r\n // 更新是否应该自动滚动的状态\r\n this.shouldAutoScroll = distanceFromBottom <= this.SCROLL_THRESHOLD;\r\n };\r\n\r\n private scrollToBottom() {\r\n if (!this.shouldAutoScroll) return;\r\n const chatHistory = this.hostElement.shadowRoot?.querySelector('.chat-history');\r\n console.log('chatHistory', chatHistory);\r\n if (chatHistory && this.isOpen) {\r\n // 强制浏览器重新计算布局\r\n chatHistory.scrollTop = chatHistory.scrollHeight;\r\n }\r\n }\r\n\r\n // 添加 componentDidRender 生命周期方法,用于在组件渲染后滚动到底部\r\n componentDidRender() {\r\n if (this.isLoadingHistory || (this.shouldAutoScroll && this.isOpen)) {\r\n const chatHistory = this.hostElement.shadowRoot?.querySelector('.chat-history');\r\n if (chatHistory) {\r\n chatHistory.scrollTop = chatHistory.scrollHeight;\r\n }\r\n }\r\n }\r\n\r\n private updateUrlWithConversationId(conversationId: string) {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n if (!urlParams.get('conversation_id')) {\r\n const newUrl = new URL(window.location.href);\r\n newUrl.searchParams.set('conversation_id', conversationId);\r\n window.history.replaceState({}, '', newUrl);\r\n }\r\n }\r\n\r\n private handleSendMessage = () => {\r\n if ((!this.currentMessage.trim() && this.uploadedFileInfo.length === 0) || this.isLoading) return;\r\n\r\n // 触发消息发送事件\r\n this.messageSent.emit(this.currentMessage);\r\n\r\n // 发送消息到API\r\n this.sendMessageToAPI(this.currentMessage);\r\n\r\n // 清空输入框\r\n this.currentMessage = '';\r\n \r\n // 清除已选择的文件\r\n this.clearSelectedFile();\r\n\r\n // 保持输入框焦点\r\n const inputElement = this.hostElement.shadowRoot?.querySelector('input');\r\n inputElement?.focus();\r\n };\r\n\r\n private handleKeyDown = (event: KeyboardEvent) => {\r\n if (event.key === 'Enter' && !event.shiftKey) {\r\n event.preventDefault();\r\n this.handleSendMessage();\r\n }\r\n };\r\n\r\n // 修改 loadHistoryMessages 方法\r\n private async loadHistoryMessages() {\r\n if (!this.conversationId) return;\r\n\r\n this.isLoadingHistory = true;\r\n\r\n try {\r\n const response = await sendHttpRequest({\r\n url: `https://pcm_api.ylzhaopin.com/share/messages`,\r\n params: {\r\n conversation_id: this.conversationId,\r\n bot_id: this.botId,\r\n user: '1234567890',\r\n limit: 20\r\n }\r\n });\r\n\r\n if (!response.isOk || !response.data) {\r\n throw new Error('加载历史消息失败');\r\n }\r\n\r\n // 适配新的接口返回格式\r\n const historyData = response.data.data || [];\r\n\r\n // 清空现有消息,确保不会重复\r\n this.currentStreamingMessage = null;\r\n this.messages = [];\r\n\r\n const formattedMessages: ChatMessage[] = historyData.map(msg => {\r\n const time = new Date(msg.created_at * 1000);\r\n const timeStr = `${time.getHours()}:${time.getMinutes().toString().padStart(2, '0')}`;\r\n\r\n return {\r\n ...msg,\r\n time: timeStr,\r\n bot_id: this.botId,\r\n isStreaming: false,\r\n status: msg.status === 'error' ? 'error' : 'normal' as const\r\n };\r\n });\r\n\r\n this.messages = formattedMessages;\r\n\r\n // 使用 requestAnimationFrame 确保在下一帧渲染后滚动\r\n requestAnimationFrame(() => {\r\n this.shouldAutoScroll = true;\r\n this.scrollToBottom();\r\n });\r\n\r\n } catch (error) {\r\n console.error('加载历史消息失败:', error);\r\n } finally {\r\n this.isLoadingHistory = false;\r\n }\r\n }\r\n\r\n\r\n // 添加 isOpen 的 watch 方法\r\n @Watch('isOpen')\r\n async handleIsOpenChange(newValue: boolean) {\r\n if (newValue && this.conversationId) {\r\n await this.loadHistoryMessages();\r\n }\r\n }\r\n\r\n @Watch('defaultQuery')\r\n handleDefaultQueryChange(newValue: string) {\r\n if (newValue && !this.currentMessage) {\r\n this.currentMessage = newValue;\r\n }\r\n }\r\n\r\n componentWillLoad() {\r\n // 组件加载时设置默认查询\r\n if (this.defaultQuery) {\r\n this.currentMessage = this.defaultQuery;\r\n }\r\n }\r\n\r\n render() {\r\n if (!this.isOpen) return null;\r\n\r\n const modalStyle = {\r\n zIndex: String(this.zIndex)\r\n };\r\n\r\n const containerClass = {\r\n 'modal-container': true,\r\n 'fullscreen': this.fullscreen\r\n };\r\n\r\n const overlayClass = {\r\n 'modal-overlay': true,\r\n 'fullscreen-overlay': this.fullscreen\r\n };\r\n\r\n return (\r\n <div class={overlayClass} style={modalStyle}>\r\n <div class={containerClass}>\r\n {this.isShowHeader && (\r\n <div class=\"modal-header\">\r\n <div class=\"header-left\">\r\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\r\n <h3>{this.modalTitle}</h3>\r\n </div>\r\n {this.isNeedClose && (\r\n <button class=\"close-button\" onClick={this.handleClose}>\r\n <span>×</span>\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n\r\n <div class=\"chat-history\" onScroll={this.handleScroll}>\r\n {this.isLoadingHistory ? (\r\n <div class=\"loading-container\">\r\n <div class=\"loading-spinner\"></div>\r\n <p>加载历史消息中...</p>\r\n </div>\r\n ) : (\r\n <>\r\n {this.messages.map((message) => (\r\n <div id={`message_${message.id}`} key={message.id}>\r\n <pcm-chat-message\r\n message={message}\r\n onMessageChange={(event) => {\r\n const updatedMessages = this.messages.map(msg =>\r\n msg.id === message.id ? { ...msg, ...event.detail } : msg\r\n );\r\n this.messages = updatedMessages;\r\n }}\r\n ></pcm-chat-message>\r\n </div>\r\n ))}\r\n {this.currentStreamingMessage && (\r\n <div id={`message_${this.currentStreamingMessage.id}`}>\r\n <pcm-chat-message\r\n message={this.currentStreamingMessage}\r\n ></pcm-chat-message>\r\n </div>\r\n )}\r\n {this.messages.length === 0 && !this.currentStreamingMessage && (\r\n <div class=\"empty-state\">\r\n <p>请输入消息</p>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {this.suggestedQuestionsLoading ? (\r\n <div class=\"loading-suggestions\">\r\n <div class=\"loading-spinner-small\"></div>\r\n </div>\r\n ) : (\r\n this.suggestedQuestions.length > 0 && (\r\n <div class=\"suggested-questions\">\r\n {this.suggestedQuestions.map((question, index) => (\r\n <div\r\n key={index}\r\n class=\"suggested-question\"\r\n onClick={() => {\r\n this.currentMessage = question;\r\n this.handleSendMessage();\r\n }}\r\n >\r\n {question}\r\n <span class=\"arrow-right\">→</span>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n )}\r\n </div>\r\n\r\n {/* 添加文件预览区域 */}\r\n {this.selectedFile && (\r\n <div class=\"file-preview\">\r\n <div class=\"file-info\">\r\n <span class=\"file-name\" title={this.selectedFile.name}>\r\n {this.selectedFile.name}\r\n {this.isUploading && <span class=\"uploading-indicator\"> (上传中...)</span>}\r\n {this.uploadedFileInfo.length > 0 && <span class=\"upload-success\"> (已上传)</span>}\r\n </span>\r\n <button class=\"remove-file\" onClick={this.clearSelectedFile}>\r\n ×\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div class=\"message-input\">\r\n <input\r\n type=\"file\"\r\n class=\"file-input\"\r\n onChange={this.handleFileChange}\r\n accept=\"image/*,.pdf,.doc,.docx,.txt\"\r\n />\r\n <button\r\n class=\"upload-button\"\r\n onClick={this.handleUploadClick}\r\n title=\"上传文件\"\r\n disabled={this.isUploading}\r\n >\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\">\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M12 4v16m0-16l-4 4m4-4l4 4\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div class=\"input-wrapper\">\r\n <input\r\n type=\"text\"\r\n placeholder=\"请输入消息...\"\r\n value={this.currentMessage}\r\n onInput={this.handleInputChange}\r\n onKeyDown={this.handleKeyDown}\r\n disabled={this.isLoading}\r\n />\r\n </div>\r\n\r\n <button\r\n class=\"send-button\"\r\n onClick={() => this.handleSendMessage()}\r\n disabled={(!this.currentMessage.trim() && this.uploadedFileInfo.length === 0) || this.isLoading || this.isUploading}\r\n >\r\n {this.isLoading ? '发送中...' : '发送'}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n} "]}
|
|
1
|
+
{"version":3,"file":"pcm-chat-modal.js","sourceRoot":"","sources":["../../../src/components/pcm-chat-modal/pcm-chat-modal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Prop, h, State, Event, EventEmitter, Element, Watch } from '@stencil/core';\r\nimport { convertWorkflowStreamNodeToMessageRound, UserInputMessageType, sendSSERequest, sendHttpRequest, uploadFileToBackend, FileUploadResponse } from '../../utils/utils';\r\nimport { ChatMessage } from '../../interfaces/chat';\r\n\r\n@Component({\r\n tag: 'pcm-chat-modal',\r\n styleUrl: 'pcm-chat-modal.css',\r\n shadow: true,\r\n})\r\nexport class ChatModal {\r\n /**\r\n * 模态框标题\r\n */\r\n @Prop() modalTitle: string = '在线客服';\r\n\r\n /**\r\n * API鉴权密钥\r\n */\r\n @Prop({ attribute: 'api-key' }) apiKey: string = '';\r\n\r\n /**\r\n * 是否显示聊天模态框\r\n */\r\n @Prop({ mutable: true }) isOpen: boolean = false;\r\n\r\n /**\r\n * 聊天消息历史\r\n */\r\n @State() messages: ChatMessage[] = [];\r\n\r\n /**\r\n * 当前输入的消息\r\n */\r\n @State() currentMessage: string = '';\r\n\r\n /**\r\n * 当发送消息时触发\r\n */\r\n @Event() messageSent: EventEmitter<string>;\r\n\r\n /**\r\n * 点击模态框关闭时触发\r\n */\r\n @Event() modalClosed: EventEmitter<void>;\r\n\r\n /**\r\n * 应用图标URL\r\n */\r\n @Prop() icon?: string;\r\n\r\n /**\r\n * 聊天框的页面层级\r\n */\r\n @Prop() zIndex?: number = 1000;\r\n\r\n /**\r\n * 是否展示顶部标题栏\r\n */\r\n @Prop() isShowHeader: boolean = true;\r\n\r\n /**\r\n * 是否展示右上角的关闭按钮\r\n */\r\n @Prop() isNeedClose: boolean = true;\r\n\r\n /**\r\n * 机器人ID\r\n */\r\n @Prop() botId: string;\r\n\r\n /**\r\n * 会话ID,传入继续对话,否则创建新会话\r\n */\r\n @Prop({ mutable: true }) conversationId?: string;\r\n\r\n\r\n /**\r\n * 当前助手回复的消息\r\n */\r\n @State() currentAssistantMessage: string = '';\r\n\r\n /**\r\n * 是否正在加载回复\r\n */\r\n @State() isLoading: boolean = false;\r\n\r\n /**\r\n * 当前正在流式输出的消息\r\n */\r\n @State() currentStreamingMessage: ChatMessage | null = null;\r\n\r\n // 添加新的状态控制\r\n @State() shouldAutoScroll: boolean = true;\r\n private readonly SCROLL_THRESHOLD = 30;\r\n\r\n @State() isLoadingHistory: boolean = false;\r\n\r\n // 使用 @Element 装饰器获取组件的 host 元素\r\n @Element() hostElement: HTMLElement;\r\n\r\n // 添加新的 Event\r\n @Event() streamComplete: EventEmitter<{\r\n conversation_id: string;\r\n event: string;\r\n message_id: string;\r\n id: string;\r\n }>;\r\n\r\n @State() suggestedQuestions: string[] = [];\r\n @State() suggestedQuestionsLoading: boolean = false;\r\n private stopSuggestedQuestionsRef: { current: boolean } = { current: false };\r\n\r\n @State() selectedFile: File | null = null;\r\n @State() isUploading: boolean = false;\r\n @State() uploadedFileInfo: FileUploadResponse[] = [];\r\n\r\n /**\r\n * 默认查询文本\r\n */\r\n @Prop() defaultQuery: string = '';\r\n\r\n /**\r\n * 是否以全屏模式打开,移动端建议设置为true\r\n */\r\n @Prop() fullscreen: boolean = false;\r\n\r\n private handleClose = () => {\r\n this.modalClosed.emit();\r\n };\r\n\r\n private handleInputChange = (event: Event) => {\r\n const input = event.target as HTMLInputElement;\r\n this.currentMessage = input.value;\r\n };\r\n\r\n private async getSuggestedQuestions(messageId: string) {\r\n this.stopSuggestedQuestionsRef.current = false;\r\n this.suggestedQuestionsLoading = true;\r\n\r\n try {\r\n const response = await sendHttpRequest({\r\n url: `/share/messages/${messageId}/suggested`,\r\n });\r\n\r\n if (this.stopSuggestedQuestionsRef.current) return;\r\n\r\n if (response.success && response.data) {\r\n this.suggestedQuestions = response.data || [];\r\n }\r\n } catch (error) {\r\n console.error('获取问题建议失败:', error);\r\n } finally {\r\n this.suggestedQuestionsLoading = false;\r\n }\r\n }\r\n\r\n private handleStopSuggestedQuestions = () => {\r\n this.suggestedQuestions = [];\r\n this.stopSuggestedQuestionsRef.current = true;\r\n };\r\n\r\n private handleFileChange = async (event: Event) => {\r\n const input = event.target as HTMLInputElement;\r\n if (input.files && input.files.length > 0) {\r\n this.selectedFile = input.files[0];\r\n \r\n // 文件选择后立即上传\r\n await this.uploadFile();\r\n }\r\n };\r\n\r\n private async uploadFile() {\r\n if (!this.selectedFile) return;\r\n \r\n this.isUploading = true;\r\n \r\n try {\r\n const result = await uploadFileToBackend(this.selectedFile, {\r\n 'authorization': 'Bearer ' + this.apiKey\r\n });\r\n \r\n this.uploadedFileInfo.push(result);\r\n } catch (error) {\r\n console.error('文件上传错误:', error);\r\n this.clearSelectedFile();\r\n alert('文件上传失败,请重试');\r\n } finally {\r\n this.isUploading = false;\r\n }\r\n }\r\n\r\n private handleUploadClick = () => {\r\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\r\n fileInput?.click();\r\n };\r\n\r\n private clearSelectedFile = () => {\r\n this.selectedFile = null;\r\n this.uploadedFileInfo = [];\r\n const fileInput = this.hostElement.shadowRoot?.querySelector('.file-input') as HTMLInputElement;\r\n if (fileInput) {\r\n fileInput.value = '';\r\n }\r\n };\r\n\r\n\r\n private async sendMessageToAPI(message: string) {\r\n this.handleStopSuggestedQuestions();\r\n console.log('开始发送消息:', message);\r\n this.isLoading = true;\r\n let answer = '';\r\n\r\n const now = new Date();\r\n const time = `${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`;\r\n\r\n // 如果消息为空但有文件,使用默认文本\r\n const queryText = message.trim() || (this.uploadedFileInfo.length > 0 ? '请分析这个文件' : '');\r\n\r\n // 创建新的消息对象时确保必填字段都有值\r\n const newMessage: ChatMessage = {\r\n id: `temp-${Date.now()}`, // 消息唯一标识\r\n time: time, // 消息时间\r\n query: queryText, // 用户输入的消息内容\r\n answer: '', // AI助手的回复内容\r\n isStreaming: true, // 是否正在流式输出\r\n conversation_id: this.conversationId, // 会话ID\r\n inputs: {}, // 输入参数\r\n status: \"normal\", // 消息状态\r\n error: null // 错误信息\r\n };\r\n\r\n // 设置当前流式消息\r\n this.currentStreamingMessage = newMessage;\r\n\r\n this.shouldAutoScroll = true;\r\n // 滚动到底部\r\n this.scrollToBottom();\r\n\r\n // 准备请求数据\r\n const requestData: any = {\r\n response_mode: 'streaming',\r\n conversation_id: this.conversationId,\r\n query: queryText,\r\n user: '1234567890'\r\n };\r\n // 如果有上传的文件,添加到inputs参数\r\n if (this.uploadedFileInfo.length > 0) {\r\n const fileUrls = this.uploadedFileInfo.map(fileInfo => fileInfo.cos_key).join(',');\r\n\r\n requestData.inputs = {\r\n ...requestData.inputs,\r\n input: fileUrls\r\n };\r\n }\r\n\r\n await sendSSERequest({\r\n url: `/sdk/v1/chat/chat-messages`,\r\n method: 'POST',\r\n data: requestData,\r\n onMessage: (data) => {\r\n console.log('收到Stream数据:', data);\r\n\r\n if (data.conversation_id && !this.conversationId) {\r\n this.conversationId = data.conversation_id;\r\n this.updateUrlWithConversationId(data.conversation_id);\r\n }\r\n\r\n if (data.event === 'message') {\r\n const inputMessage: UserInputMessageType = { message: message };\r\n convertWorkflowStreamNodeToMessageRound('message', inputMessage, data);\r\n\r\n if (data.event === 'agent_message' || data.event === 'message') {\r\n if (data.answer) {\r\n answer += data.answer;\r\n const updatedMessage: ChatMessage = {\r\n ...this.currentStreamingMessage,\r\n answer,\r\n isStreaming: true\r\n };\r\n this.currentStreamingMessage = updatedMessage;\r\n this.scrollToBottom();\r\n }\r\n }\r\n }\r\n if (data.event === \"message_end\") {\r\n this.streamComplete.emit({\r\n conversation_id: data.conversation_id || '',\r\n event: data.event,\r\n message_id: data.message_id,\r\n id: data.id,\r\n });\r\n }\r\n },\r\n onError: (error) => {\r\n console.error('发生错误:', error);\r\n this.messages = [...this.messages, {\r\n ...newMessage,\r\n answer: '抱歉,发生了错误,请稍后再试。',\r\n error: error,\r\n isStreaming: false\r\n }];\r\n this.currentStreamingMessage = null;\r\n this.isLoading = false;\r\n },\r\n onComplete: () => {\r\n console.log('请求完成');\r\n this.isLoading = false;\r\n this.messages = [...this.messages, this.currentStreamingMessage];\r\n\r\n // 在消息完成后获取问题建议\r\n if (this.currentStreamingMessage) {\r\n this.getSuggestedQuestions(this.currentStreamingMessage.conversation_id);\r\n }\r\n\r\n this.currentStreamingMessage = null;\r\n }\r\n });\r\n }\r\n // 监听滚动事件,用于控制聊天历史记录的自动滚动行为。\r\n private handleScroll = () => {\r\n const chatHistory = this.hostElement.shadowRoot?.querySelector('.chat-history');\r\n if (!chatHistory) return;\r\n\r\n const { scrollTop, scrollHeight, clientHeight } = chatHistory;\r\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\r\n\r\n // 更新是否应该自动滚动的状态\r\n this.shouldAutoScroll = distanceFromBottom <= this.SCROLL_THRESHOLD;\r\n };\r\n\r\n private scrollToBottom() {\r\n if (!this.shouldAutoScroll) return;\r\n const chatHistory = this.hostElement.shadowRoot?.querySelector('.chat-history');\r\n console.log('chatHistory', chatHistory);\r\n if (chatHistory && this.isOpen) {\r\n // 强制浏览器重新计算布局\r\n chatHistory.scrollTop = chatHistory.scrollHeight;\r\n }\r\n }\r\n\r\n // 添加 componentDidRender 生命周期方法,用于在组件渲染后滚动到底部\r\n componentDidRender() {\r\n if (this.isLoadingHistory || (this.shouldAutoScroll && this.isOpen)) {\r\n const chatHistory = this.hostElement.shadowRoot?.querySelector('.chat-history');\r\n if (chatHistory) {\r\n chatHistory.scrollTop = chatHistory.scrollHeight;\r\n }\r\n }\r\n }\r\n\r\n private updateUrlWithConversationId(conversationId: string) {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n if (!urlParams.get('conversation_id')) {\r\n const newUrl = new URL(window.location.href);\r\n newUrl.searchParams.set('conversation_id', conversationId);\r\n window.history.replaceState({}, '', newUrl);\r\n }\r\n }\r\n\r\n private handleSendMessage = () => {\r\n if ((!this.currentMessage.trim() && this.uploadedFileInfo.length === 0) || this.isLoading) return;\r\n\r\n // 触发消息发送事件\r\n this.messageSent.emit(this.currentMessage);\r\n\r\n // 发送消息到API\r\n this.sendMessageToAPI(this.currentMessage);\r\n\r\n // 清空输入框\r\n this.currentMessage = '';\r\n \r\n // 清除已选择的文件\r\n this.clearSelectedFile();\r\n\r\n // 保持输入框焦点\r\n const inputElement = this.hostElement.shadowRoot?.querySelector('input');\r\n inputElement?.focus();\r\n };\r\n\r\n private handleKeyDown = (event: KeyboardEvent) => {\r\n if (event.key === 'Enter' && !event.shiftKey) {\r\n event.preventDefault();\r\n this.handleSendMessage();\r\n }\r\n };\r\n\r\n // 修改 loadHistoryMessages 方法\r\n private async loadHistoryMessages() {\r\n if (!this.conversationId) return;\r\n\r\n this.isLoadingHistory = true;\r\n\r\n try {\r\n const response = await sendHttpRequest({\r\n url: `/share/messages`,\r\n params: {\r\n conversation_id: this.conversationId,\r\n user: '1234567890',\r\n limit: 20\r\n }\r\n });\r\n\r\n if (!response.success || !response.data) {\r\n throw new Error('加载历史消息失败');\r\n }\r\n\r\n // 适配新的接口返回格式\r\n const historyData = response.data || [];\r\n\r\n // 清空现有消息,确保不会重复\r\n this.currentStreamingMessage = null;\r\n this.messages = [];\r\n\r\n const formattedMessages: ChatMessage[] = historyData.map(msg => {\r\n const time = new Date(msg.created_at * 1000);\r\n const timeStr = `${time.getHours()}:${time.getMinutes().toString().padStart(2, '0')}`;\r\n\r\n return {\r\n ...msg,\r\n time: timeStr,\r\n isStreaming: false,\r\n status: msg.status === 'error' ? 'error' : 'normal' as const\r\n };\r\n });\r\n\r\n this.messages = formattedMessages;\r\n\r\n // 使用 requestAnimationFrame 确保在下一帧渲染后滚动\r\n requestAnimationFrame(() => {\r\n this.shouldAutoScroll = true;\r\n this.scrollToBottom();\r\n });\r\n\r\n } catch (error) {\r\n console.error('加载历史消息失败:', error);\r\n } finally {\r\n this.isLoadingHistory = false;\r\n }\r\n }\r\n\r\n\r\n // 添加 isOpen 的 watch 方法\r\n @Watch('isOpen')\r\n async handleIsOpenChange(newValue: boolean) {\r\n if (newValue && this.conversationId) {\r\n await this.loadHistoryMessages();\r\n }\r\n }\r\n\r\n @Watch('defaultQuery')\r\n handleDefaultQueryChange(newValue: string) {\r\n if (newValue && !this.currentMessage) {\r\n this.currentMessage = newValue;\r\n }\r\n }\r\n\r\n componentWillLoad() {\r\n // 组件加载时设置默认查询\r\n if (this.defaultQuery) {\r\n this.currentMessage = this.defaultQuery;\r\n }\r\n }\r\n\r\n render() {\r\n if (!this.isOpen) return null;\r\n\r\n const modalStyle = {\r\n zIndex: String(this.zIndex)\r\n };\r\n\r\n const containerClass = {\r\n 'modal-container': true,\r\n 'fullscreen': this.fullscreen\r\n };\r\n\r\n const overlayClass = {\r\n 'modal-overlay': true,\r\n 'fullscreen-overlay': this.fullscreen\r\n };\r\n\r\n return (\r\n <div class={overlayClass} style={modalStyle}>\r\n <div class={containerClass}>\r\n {this.isShowHeader && (\r\n <div class=\"modal-header\">\r\n <div class=\"header-left\">\r\n {this.icon && <img src={this.icon} class=\"header-icon\" alt=\"应用图标\" />}\r\n <h3>{this.modalTitle}</h3>\r\n </div>\r\n {this.isNeedClose && (\r\n <button class=\"close-button\" onClick={this.handleClose}>\r\n <span>×</span>\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n\r\n <div class=\"chat-history\" onScroll={this.handleScroll}>\r\n {this.isLoadingHistory ? (\r\n <div class=\"loading-container\">\r\n <div class=\"loading-spinner\"></div>\r\n <p>加载历史消息中...</p>\r\n </div>\r\n ) : (\r\n <>\r\n {this.messages.map((message) => (\r\n <div id={`message_${message.id}`} key={message.id}>\r\n <pcm-chat-message\r\n message={message}\r\n onMessageChange={(event) => {\r\n const updatedMessages = this.messages.map(msg =>\r\n msg.id === message.id ? { ...msg, ...event.detail } : msg\r\n );\r\n this.messages = updatedMessages;\r\n }}\r\n ></pcm-chat-message>\r\n </div>\r\n ))}\r\n {this.currentStreamingMessage && (\r\n <div id={`message_${this.currentStreamingMessage.id}`}>\r\n <pcm-chat-message\r\n message={this.currentStreamingMessage}\r\n ></pcm-chat-message>\r\n </div>\r\n )}\r\n {this.messages.length === 0 && !this.currentStreamingMessage && (\r\n <div class=\"empty-state\">\r\n <p>请输入消息</p>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {this.suggestedQuestionsLoading ? (\r\n <div class=\"loading-suggestions\">\r\n <div class=\"loading-spinner-small\"></div>\r\n </div>\r\n ) : (\r\n this.suggestedQuestions.length > 0 && (\r\n <div class=\"suggested-questions\">\r\n {this.suggestedQuestions.map((question, index) => (\r\n <div\r\n key={index}\r\n class=\"suggested-question\"\r\n onClick={() => {\r\n this.currentMessage = question;\r\n this.handleSendMessage();\r\n }}\r\n >\r\n {question}\r\n <span class=\"arrow-right\">→</span>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n )}\r\n </div>\r\n\r\n {/* 添加文件预览区域 */}\r\n {this.selectedFile && (\r\n <div class=\"file-preview\">\r\n <div class=\"file-info\">\r\n <span class=\"file-name\" title={this.selectedFile.name}>\r\n {this.selectedFile.name}\r\n {this.isUploading && <span class=\"uploading-indicator\"> (上传中...)</span>}\r\n {this.uploadedFileInfo.length > 0 && <span class=\"upload-success\"> (已上传)</span>}\r\n </span>\r\n <button class=\"remove-file\" onClick={this.clearSelectedFile}>\r\n ×\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div class=\"message-input\">\r\n <input\r\n type=\"file\"\r\n class=\"file-input\"\r\n onChange={this.handleFileChange}\r\n accept=\"image/*,.pdf,.doc,.docx,.txt\"\r\n />\r\n <button\r\n class=\"upload-button\"\r\n onClick={this.handleUploadClick}\r\n title=\"上传文件\"\r\n disabled={this.isUploading}\r\n >\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\">\r\n <path\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"2\"\r\n d=\"M12 4v16m0-16l-4 4m4-4l4 4\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n <div class=\"input-wrapper\">\r\n <input\r\n type=\"text\"\r\n placeholder=\"请输入消息...\"\r\n value={this.currentMessage}\r\n onInput={this.handleInputChange}\r\n onKeyDown={this.handleKeyDown}\r\n disabled={this.isLoading}\r\n />\r\n </div>\r\n\r\n <button\r\n class=\"send-button\"\r\n onClick={() => this.handleSendMessage()}\r\n disabled={(!this.currentMessage.trim() && this.uploadedFileInfo.length === 0) || this.isLoading || this.isUploading}\r\n >\r\n {this.isLoading ? '发送中...' : '发送'}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n} "]}
|