@bidding-group/ai-chat 1.0.1 → 1.0.3
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/README.md +73 -48
- package/dist/ai-chat.css +1 -1
- package/dist/ai-chat.js +490 -407
- package/dist/ai-chat.umd.cjs +2 -2
- package/package.json +2 -4
package/dist/ai-chat.js
CHANGED
|
@@ -1,64 +1,100 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { ChatDotRound as
|
|
3
|
-
import { defineStore as
|
|
4
|
-
import { ElScrollbar as
|
|
5
|
-
let
|
|
6
|
-
function
|
|
7
|
-
|
|
1
|
+
import { defineComponent as q, ref as E, computed as w, onMounted as Ce, onUnmounted as Ie, resolveComponent as z, openBlock as a, createElementBlock as d, normalizeStyle as Ae, normalizeClass as N, createVNode as i, withCtx as c, createElementVNode as g, unref as r, createBlock as V, Fragment as F, renderList as G, createCommentVNode as A, resolveDynamicComponent as Be, withDirectives as Ge, vShow as qe, toDisplayString as W, watch as we, nextTick as ne, Transition as ie, withModifiers as oe, createTextVNode as ae, withKeys as Ke } from "vue";
|
|
2
|
+
import { ChatDotRound as Ye, Monitor as Ze, User as Qe, ArrowDown as et, ArrowRight as tt, Grid as st, Menu as nt, FullScreen as it, Plus as ot, Close as Se, Loading as at, List as lt, Promotion as rt } from "@element-plus/icons-vue";
|
|
3
|
+
import { defineStore as ct } from "pinia";
|
|
4
|
+
import { ElScrollbar as ye, ElMessage as O } from "element-plus";
|
|
5
|
+
let re = null;
|
|
6
|
+
function dt(t) {
|
|
7
|
+
re = t;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
if (!
|
|
9
|
+
function ce() {
|
|
10
|
+
if (!re)
|
|
11
11
|
throw new Error("[@cgs/ai-chat] 插件未安装,请先调用 app.use(AiChat, options)");
|
|
12
|
-
return
|
|
12
|
+
return re;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
function ut(t) {
|
|
15
|
+
try {
|
|
16
|
+
const e = t.split(".");
|
|
17
|
+
if (e.length !== 3) return null;
|
|
18
|
+
const u = e[1].replace(/-/g, "+").replace(/_/g, "/"), l = decodeURIComponent(
|
|
19
|
+
atob(u).split("").map((o) => "%" + ("00" + o.charCodeAt(0).toString(16)).slice(-2)).join("")
|
|
20
|
+
);
|
|
21
|
+
return JSON.parse(l, (o, m) => typeof m == "number" && !Number.isSafeInteger(m) ? String(m) : m);
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function Me(t) {
|
|
27
|
+
const e = ce(), u = { ...t };
|
|
28
|
+
if (e.getToken) {
|
|
29
|
+
const l = e.getToken();
|
|
30
|
+
if (l) {
|
|
31
|
+
u["x-access-token"] = l;
|
|
32
|
+
const o = ut(l);
|
|
33
|
+
o && (o.details_user_id && (u.details_user_id = String(o.details_user_id)), o.details_username && (u.details_username = String(o.details_username)), o.details_tenant_id && (u.details_tenant_id = String(o.details_tenant_id)), o.details_app_id && (u.details_app_id = String(o.details_app_id)));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return u;
|
|
37
|
+
}
|
|
38
|
+
async function X(t, e, u) {
|
|
39
|
+
const l = ce(), o = Me({ "Content-Type": "application/json" });
|
|
40
|
+
let m = u;
|
|
41
|
+
u && typeof u == "object" ? (m = { ...u }, !m.tenantId && l.getTenantId && (m.tenantId = l.getTenantId()), !m.appId && l.getAppId && (m.appId = l.getAppId())) : (t === "POST" || t === "PUT") && !u && (m = {}, l.getTenantId && (m.tenantId = l.getTenantId()), l.getAppId && (m.appId = l.getAppId()));
|
|
42
|
+
const h = await fetch(`${l.baseUrl}${e}`, {
|
|
20
43
|
method: t,
|
|
21
|
-
headers:
|
|
22
|
-
body:
|
|
23
|
-
});
|
|
24
|
-
if (!
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
44
|
+
headers: o,
|
|
45
|
+
body: m !== void 0 ? JSON.stringify(m) : void 0
|
|
46
|
+
}), P = await h.text(), v = JSON.parse(P, (L, k) => typeof k == "number" && !Number.isSafeInteger(k) ? String(k) : k);
|
|
47
|
+
if (!h.ok) {
|
|
48
|
+
const L = v?.msg || v?.message || v?.detail || "";
|
|
49
|
+
throw new Error(`HTTP ${h.status}: ${e}${L ? ` — ${L}` : ""}`);
|
|
50
|
+
}
|
|
51
|
+
if (v?.code === 401)
|
|
52
|
+
throw new Error(`AUTH_EXPIRED:${v.msg || "认证失败,请重新登录"}`);
|
|
53
|
+
if (v?.code && v.code !== 200 && v.code !== 0)
|
|
54
|
+
throw new Error(`${v.msg || v.message || "请求失败"} (code: ${v.code})`);
|
|
55
|
+
return v.data;
|
|
28
56
|
}
|
|
29
|
-
const
|
|
57
|
+
const gt = () => X("POST", "/session/create"), Te = (t) => X("POST", "/session/page", t).then((e) => ({
|
|
30
58
|
list: e?.records ?? [],
|
|
31
59
|
total: e?.total ?? 0
|
|
32
|
-
})),
|
|
33
|
-
async function
|
|
34
|
-
const e = Me(),
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
e.getToken && (g["x-access-token"] = e.getToken()), e.getTenantId && (g["X-Tenant-Id"] = String(e.getTenantId()));
|
|
38
|
-
const h = await fetch(`${e.baseUrl}/chat/stream`, {
|
|
60
|
+
})), mt = (t) => X("GET", `/session/${t}/messages`), ht = (t) => X("DELETE", `/session/${t}`), ft = () => X("GET", "/usage/today");
|
|
61
|
+
async function pt(t) {
|
|
62
|
+
const e = ce(), u = Me({ "Content-Type": "application/json" }), l = { ...t };
|
|
63
|
+
!l.tenantId && e.getTenantId && (l.tenantId = e.getTenantId()), !l.appId && e.getAppId && (l.appId = e.getAppId());
|
|
64
|
+
const o = await fetch(`${e.baseUrl}/chat/stream`, {
|
|
39
65
|
method: "POST",
|
|
40
|
-
headers:
|
|
41
|
-
body: JSON.stringify(
|
|
66
|
+
headers: u,
|
|
67
|
+
body: JSON.stringify(l),
|
|
42
68
|
signal: t.signal
|
|
43
|
-
// 支持 AbortSignal
|
|
44
69
|
});
|
|
45
|
-
if (!
|
|
46
|
-
throw new Error(`流式请求失败: HTTP ${
|
|
47
|
-
|
|
70
|
+
if (!o.ok)
|
|
71
|
+
throw new Error(`流式请求失败: HTTP ${o.status}`);
|
|
72
|
+
const m = o.clone();
|
|
73
|
+
try {
|
|
74
|
+
const h = await m.json();
|
|
75
|
+
if (h?.code === 401)
|
|
76
|
+
throw new Error(`AUTH_EXPIRED:${h.msg || "认证失败,请重新登录"}`);
|
|
77
|
+
if (h?.code && h.code !== 200 && h.code !== 0)
|
|
78
|
+
throw new Error(`${h.msg || "请求失败"} (code: ${h.code})`);
|
|
79
|
+
} catch (h) {
|
|
80
|
+
if (h instanceof Error && h.message.startsWith("AUTH_EXPIRED:"))
|
|
81
|
+
throw h;
|
|
82
|
+
}
|
|
83
|
+
return o;
|
|
48
84
|
}
|
|
49
|
-
const
|
|
50
|
-
function
|
|
85
|
+
const Ee = "cgs-ai-chat-state";
|
|
86
|
+
function vt() {
|
|
51
87
|
try {
|
|
52
|
-
const t = localStorage.getItem(
|
|
88
|
+
const t = localStorage.getItem(Ee);
|
|
53
89
|
return t ? JSON.parse(t) : {};
|
|
54
90
|
} catch {
|
|
55
91
|
return {};
|
|
56
92
|
}
|
|
57
93
|
}
|
|
58
|
-
function
|
|
94
|
+
function _t(t) {
|
|
59
95
|
try {
|
|
60
96
|
localStorage.setItem(
|
|
61
|
-
|
|
97
|
+
Ee,
|
|
62
98
|
JSON.stringify({
|
|
63
99
|
currentSessionId: t.currentSessionId,
|
|
64
100
|
panelWidth: t.panelWidth,
|
|
@@ -68,10 +104,10 @@ function ut(t) {
|
|
|
68
104
|
} catch {
|
|
69
105
|
}
|
|
70
106
|
}
|
|
71
|
-
const
|
|
107
|
+
const be = 15, le = vt(), de = ct("cgs-ai-chat", {
|
|
72
108
|
state: () => ({
|
|
73
109
|
visible: !1,
|
|
74
|
-
currentSessionId:
|
|
110
|
+
currentSessionId: le.currentSessionId ?? null,
|
|
75
111
|
sessions: [],
|
|
76
112
|
sessionPage: 1,
|
|
77
113
|
sessionTotal: 0,
|
|
@@ -79,8 +115,8 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
79
115
|
messages: [],
|
|
80
116
|
loading: !1,
|
|
81
117
|
sending: !1,
|
|
82
|
-
panelWidth:
|
|
83
|
-
isFullScreen:
|
|
118
|
+
panelWidth: le.panelWidth ?? (typeof window < "u" ? Math.max(320, Math.round(window.innerWidth * 0.25)) : 420),
|
|
119
|
+
isFullScreen: le.isFullScreen ?? !1,
|
|
84
120
|
tokenUsage: null
|
|
85
121
|
}),
|
|
86
122
|
actions: {
|
|
@@ -96,10 +132,6 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
96
132
|
addMessage(t) {
|
|
97
133
|
this.messages.push(t);
|
|
98
134
|
},
|
|
99
|
-
/**
|
|
100
|
-
* 追加最后一条 AI 消息内容(流式场景)
|
|
101
|
-
* 使用 for 逆序 + 对象替换,避免 ES2023 findLast + 响应式问题
|
|
102
|
-
*/
|
|
103
135
|
updateLastAssistantMessage(t) {
|
|
104
136
|
for (let e = this.messages.length - 1; e >= 0; e--)
|
|
105
137
|
if (this.messages[e].role === "assistant") {
|
|
@@ -110,10 +142,20 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
110
142
|
break;
|
|
111
143
|
}
|
|
112
144
|
},
|
|
145
|
+
updateLastAssistantReasoning(t) {
|
|
146
|
+
for (let e = this.messages.length - 1; e >= 0; e--)
|
|
147
|
+
if (this.messages[e].role === "assistant") {
|
|
148
|
+
this.messages[e] = {
|
|
149
|
+
...this.messages[e],
|
|
150
|
+
reasoningContent: (this.messages[e].reasoningContent || "") + t
|
|
151
|
+
};
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
},
|
|
113
155
|
async loadSessions() {
|
|
114
156
|
this.loading = !0, this.sessionPage = 1;
|
|
115
157
|
try {
|
|
116
|
-
const t = await
|
|
158
|
+
const t = await Te({ pageNum: 1, pageSize: be });
|
|
117
159
|
this.sessions = t.list, this.sessionTotal = t.total;
|
|
118
160
|
} finally {
|
|
119
161
|
this.loading = !1;
|
|
@@ -124,7 +166,7 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
124
166
|
if (!(this.sessionLoadingMore || this.sessions.length >= this.sessionTotal)) {
|
|
125
167
|
this.sessionLoadingMore = !0;
|
|
126
168
|
try {
|
|
127
|
-
const t = this.sessionPage + 1, e = await
|
|
169
|
+
const t = this.sessionPage + 1, e = await Te({ pageNum: t, pageSize: be });
|
|
128
170
|
this.sessions = [...this.sessions, ...e.list], this.sessionTotal = e.total, this.sessionPage = t;
|
|
129
171
|
} finally {
|
|
130
172
|
this.sessionLoadingMore = !1;
|
|
@@ -134,7 +176,7 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
134
176
|
async loadMessages(t) {
|
|
135
177
|
this.loading = !0;
|
|
136
178
|
try {
|
|
137
|
-
const e = await
|
|
179
|
+
const e = await mt(t);
|
|
138
180
|
this.currentSessionId === t && (this.messages = e);
|
|
139
181
|
} finally {
|
|
140
182
|
this.loading = !1;
|
|
@@ -142,7 +184,7 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
142
184
|
},
|
|
143
185
|
async createSession() {
|
|
144
186
|
try {
|
|
145
|
-
const t = await
|
|
187
|
+
const t = await gt();
|
|
146
188
|
return await this.loadSessions(), t;
|
|
147
189
|
} catch (t) {
|
|
148
190
|
return console.error("[@cgs/ai-chat] 创建会话失败", t), null;
|
|
@@ -150,7 +192,7 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
150
192
|
},
|
|
151
193
|
async deleteSession(t) {
|
|
152
194
|
try {
|
|
153
|
-
await
|
|
195
|
+
await ht(t), await this.loadSessions(), this.currentSessionId === t && (this.currentSessionId = null, this.messages = [], this._persist());
|
|
154
196
|
} catch (e) {
|
|
155
197
|
console.error("[@cgs/ai-chat] 删除会话失败", e);
|
|
156
198
|
}
|
|
@@ -162,15 +204,15 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
162
204
|
this.messages = [];
|
|
163
205
|
},
|
|
164
206
|
setPanelWidth(t) {
|
|
165
|
-
const
|
|
166
|
-
this.panelWidth = Math.max(320, Math.min(
|
|
207
|
+
const u = Math.floor(window.innerWidth * 0.9);
|
|
208
|
+
this.panelWidth = Math.max(320, Math.min(u, t)), this.isFullScreen = !1, this._persist();
|
|
167
209
|
},
|
|
168
210
|
toggleFullScreen() {
|
|
169
211
|
this.isFullScreen = !this.isFullScreen, this._persist();
|
|
170
212
|
},
|
|
171
213
|
async loadTokenUsage() {
|
|
172
214
|
try {
|
|
173
|
-
this.tokenUsage = await
|
|
215
|
+
this.tokenUsage = await ft();
|
|
174
216
|
} catch (t) {
|
|
175
217
|
console.error("[@cgs/ai-chat] 加载 Token 用量失败", t);
|
|
176
218
|
}
|
|
@@ -183,7 +225,7 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
183
225
|
},
|
|
184
226
|
// 内部方法:持久化关键状态到 localStorage
|
|
185
227
|
_persist() {
|
|
186
|
-
|
|
228
|
+
_t(this.$state);
|
|
187
229
|
}
|
|
188
230
|
},
|
|
189
231
|
getters: {
|
|
@@ -197,46 +239,46 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
197
239
|
/** 是否还有更多会话可加载 */
|
|
198
240
|
sessionHasMore: (t) => t.sessions.length < t.sessionTotal
|
|
199
241
|
}
|
|
200
|
-
}),
|
|
242
|
+
}), kt = /* @__PURE__ */ q({
|
|
201
243
|
__name: "AiChatFloat",
|
|
202
244
|
setup(t) {
|
|
203
|
-
const e =
|
|
204
|
-
|
|
205
|
-
},
|
|
245
|
+
const e = de(), u = () => e.toggleVisible(), l = E(!1), o = () => {
|
|
246
|
+
l.value = window.innerWidth < 768;
|
|
247
|
+
}, m = w(() => l.value ? {
|
|
206
248
|
position: "fixed",
|
|
207
249
|
right: "50%",
|
|
208
250
|
bottom: "24px",
|
|
209
251
|
transform: "translateX(50%)",
|
|
210
|
-
zIndex: "
|
|
252
|
+
zIndex: "999"
|
|
211
253
|
} : {
|
|
212
254
|
position: "fixed",
|
|
213
255
|
right: "24px",
|
|
214
|
-
bottom: "
|
|
215
|
-
zIndex: "
|
|
256
|
+
bottom: "80px",
|
|
257
|
+
zIndex: "999"
|
|
216
258
|
});
|
|
217
|
-
return
|
|
218
|
-
|
|
219
|
-
}),
|
|
220
|
-
window.removeEventListener("resize",
|
|
221
|
-
}), (
|
|
222
|
-
const
|
|
223
|
-
return
|
|
224
|
-
class:
|
|
225
|
-
style:
|
|
226
|
-
onClick:
|
|
259
|
+
return Ce(() => {
|
|
260
|
+
o(), window.addEventListener("resize", o);
|
|
261
|
+
}), Ie(() => {
|
|
262
|
+
window.removeEventListener("resize", o);
|
|
263
|
+
}), (h, P) => {
|
|
264
|
+
const v = z("el-icon"), L = z("el-tooltip");
|
|
265
|
+
return a(), d("div", {
|
|
266
|
+
class: N(["ai-chat-float", { "is-mobile": l.value }]),
|
|
267
|
+
style: Ae(m.value),
|
|
268
|
+
onClick: u
|
|
227
269
|
}, [
|
|
228
|
-
i(
|
|
270
|
+
i(L, {
|
|
229
271
|
content: "AI助手",
|
|
230
272
|
placement: "left",
|
|
231
273
|
"show-after": 300
|
|
232
274
|
}, {
|
|
233
|
-
default:
|
|
234
|
-
|
|
235
|
-
class:
|
|
275
|
+
default: c(() => [
|
|
276
|
+
g("div", {
|
|
277
|
+
class: N(["float-btn", { "is-active": r(e).visible }])
|
|
236
278
|
}, [
|
|
237
|
-
i(
|
|
238
|
-
default:
|
|
239
|
-
i(r(
|
|
279
|
+
i(v, { size: 24 }, {
|
|
280
|
+
default: c(() => [
|
|
281
|
+
i(r(Ye))
|
|
240
282
|
]),
|
|
241
283
|
_: 1
|
|
242
284
|
})
|
|
@@ -247,319 +289,360 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
247
289
|
], 6);
|
|
248
290
|
};
|
|
249
291
|
}
|
|
250
|
-
}),
|
|
251
|
-
const
|
|
252
|
-
for (const [
|
|
253
|
-
|
|
254
|
-
return
|
|
255
|
-
},
|
|
292
|
+
}), K = (t, e) => {
|
|
293
|
+
const u = t.__vccOpts || t;
|
|
294
|
+
for (const [l, o] of e)
|
|
295
|
+
u[l] = o;
|
|
296
|
+
return u;
|
|
297
|
+
}, $e = /* @__PURE__ */ K(kt, [["__scopeId", "data-v-fc7be81c"]]), wt = { class: "avatar" }, St = { class: "content" }, yt = {
|
|
256
298
|
key: 0,
|
|
257
299
|
class: "message-images"
|
|
258
|
-
},
|
|
259
|
-
key:
|
|
300
|
+
}, Tt = ["src"], bt = ["innerHTML"], Ct = {
|
|
301
|
+
key: 0,
|
|
302
|
+
class: "reasoning-section"
|
|
303
|
+
}, It = ["innerHTML"], At = ["innerHTML"], Mt = {
|
|
304
|
+
key: 2,
|
|
305
|
+
class: "loading-placeholder"
|
|
306
|
+
}, Et = {
|
|
307
|
+
key: 3,
|
|
260
308
|
class: "loading-placeholder"
|
|
261
|
-
},
|
|
309
|
+
}, $t = { class: "time" }, xt = /* @__PURE__ */ q({
|
|
262
310
|
__name: "AiChatMessage",
|
|
263
311
|
props: {
|
|
264
312
|
message: {}
|
|
265
313
|
},
|
|
266
314
|
setup(t) {
|
|
267
|
-
const e = t,
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
315
|
+
const e = t, u = de(), l = E(!1), o = w({
|
|
316
|
+
get: () => u.sending ? !0 : l.value,
|
|
317
|
+
set: (k) => {
|
|
318
|
+
l.value = k;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
function m(k) {
|
|
322
|
+
if (!k) return "";
|
|
323
|
+
const S = [], C = (M) => {
|
|
324
|
+
const $ = S.length;
|
|
325
|
+
return S.push(M), `\0PH${$}\0`;
|
|
326
|
+
};
|
|
327
|
+
let f = k;
|
|
328
|
+
return f = f.replace(/```(\w*)\n([\s\S]*?)```/g, (M, $, H) => C(`<pre class="code-block"><code>${v(H)}</code></pre>`)), f = f.replace(/`([^`]+)`/g, (M, $) => C(`<code class="inline-code">${v($)}</code>`)), f = f.replace(/\*\*(.+?)\*\*/g, (M, $) => C(`<strong>${v($)}</strong>`)), f = v(f), f = f.replace(/\n/g, "<br>"), f = f.replace(/\x00PH(\d+)\x00/g, (M, $) => S[parseInt($)]), f;
|
|
329
|
+
}
|
|
330
|
+
const h = w(() => m(e.message.reasoningContent || "")), P = w(() => m(e.message.content || ""));
|
|
331
|
+
function v(k) {
|
|
332
|
+
return k.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
333
|
+
}
|
|
334
|
+
const L = (k) => k ? new Date(k).toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }) : "";
|
|
335
|
+
return (k, S) => {
|
|
336
|
+
const C = z("el-icon");
|
|
337
|
+
return a(), d("div", {
|
|
338
|
+
class: N(["message-item", [t.message.role]])
|
|
275
339
|
}, [
|
|
276
|
-
|
|
277
|
-
t.message.role === "assistant" ? (
|
|
340
|
+
g("div", wt, [
|
|
341
|
+
t.message.role === "assistant" ? (a(), V(C, {
|
|
278
342
|
key: 0,
|
|
279
343
|
size: 20
|
|
280
344
|
}, {
|
|
281
|
-
default:
|
|
282
|
-
i(r(
|
|
345
|
+
default: c(() => [
|
|
346
|
+
i(r(Ze))
|
|
283
347
|
]),
|
|
284
348
|
_: 1
|
|
285
|
-
})) : (
|
|
349
|
+
})) : (a(), V(C, {
|
|
286
350
|
key: 1,
|
|
287
351
|
size: 20
|
|
288
352
|
}, {
|
|
289
|
-
default:
|
|
290
|
-
i(r(
|
|
353
|
+
default: c(() => [
|
|
354
|
+
i(r(Qe))
|
|
291
355
|
]),
|
|
292
356
|
_: 1
|
|
293
357
|
}))
|
|
294
358
|
]),
|
|
295
|
-
|
|
296
|
-
t.message.role === "user" ? (
|
|
297
|
-
t.message.images && t.message.images.length > 0 ? (
|
|
298
|
-
(
|
|
299
|
-
key:
|
|
300
|
-
src:
|
|
359
|
+
g("div", St, [
|
|
360
|
+
t.message.role === "user" ? (a(), d(F, { key: 0 }, [
|
|
361
|
+
t.message.images && t.message.images.length > 0 ? (a(), d("div", yt, [
|
|
362
|
+
(a(!0), d(F, null, G(t.message.images, (f, M) => (a(), d("img", {
|
|
363
|
+
key: M,
|
|
364
|
+
src: f,
|
|
301
365
|
class: "message-image",
|
|
302
366
|
alt: "图片"
|
|
303
|
-
}, null, 8,
|
|
304
|
-
])) :
|
|
305
|
-
t.message.content && t.message.content !== "[图片]" ? (
|
|
367
|
+
}, null, 8, Tt))), 128))
|
|
368
|
+
])) : A("", !0),
|
|
369
|
+
t.message.content && t.message.content !== "[图片]" ? (a(), d("div", {
|
|
306
370
|
key: 1,
|
|
307
371
|
class: "text",
|
|
308
|
-
innerHTML:
|
|
309
|
-
}, null, 8,
|
|
310
|
-
], 64)) : (
|
|
311
|
-
t.message.
|
|
312
|
-
|
|
372
|
+
innerHTML: P.value
|
|
373
|
+
}, null, 8, bt)) : A("", !0)
|
|
374
|
+
], 64)) : (a(), d(F, { key: 1 }, [
|
|
375
|
+
t.message.reasoningContent ? (a(), d("div", Ct, [
|
|
376
|
+
g("div", {
|
|
377
|
+
class: "reasoning-toggle",
|
|
378
|
+
onClick: S[0] || (S[0] = (f) => o.value = !o.value)
|
|
379
|
+
}, [
|
|
380
|
+
i(C, { size: 14 }, {
|
|
381
|
+
default: c(() => [
|
|
382
|
+
(a(), V(Be(o.value ? r(et) : r(tt))))
|
|
383
|
+
]),
|
|
384
|
+
_: 1
|
|
385
|
+
}),
|
|
386
|
+
S[1] || (S[1] = g("span", null, "AI 思考过程", -1))
|
|
387
|
+
]),
|
|
388
|
+
Ge(g("div", {
|
|
389
|
+
class: "reasoning-body",
|
|
390
|
+
innerHTML: h.value
|
|
391
|
+
}, null, 8, It), [
|
|
392
|
+
[qe, o.value]
|
|
393
|
+
])
|
|
394
|
+
])) : A("", !0),
|
|
395
|
+
t.message.content ? (a(), d("div", {
|
|
396
|
+
key: 1,
|
|
313
397
|
class: "text",
|
|
314
|
-
innerHTML:
|
|
315
|
-
}, null, 8,
|
|
398
|
+
innerHTML: P.value
|
|
399
|
+
}, null, 8, At)) : t.message.reasoningContent ? (a(), d("div", Mt, "正在组织回答...")) : (a(), d("div", Et, "正在思考..."))
|
|
316
400
|
], 64)),
|
|
317
|
-
|
|
401
|
+
g("div", $t, W(L(t.message.createTime)), 1)
|
|
318
402
|
])
|
|
319
403
|
], 2);
|
|
320
404
|
};
|
|
321
405
|
}
|
|
322
|
-
}),
|
|
406
|
+
}), Lt = /* @__PURE__ */ K(xt, [["__scopeId", "data-v-ee95845e"]]), Rt = {
|
|
323
407
|
key: 0,
|
|
324
408
|
class: "width-tooltip"
|
|
325
|
-
},
|
|
409
|
+
}, Pt = { class: "panel-container" }, Ut = { class: "panel-header" }, Wt = { class: "header-left" }, zt = {
|
|
326
410
|
key: 0,
|
|
327
411
|
class: "token-usage"
|
|
328
|
-
},
|
|
412
|
+
}, Ft = {
|
|
329
413
|
key: 1,
|
|
330
414
|
class: "preset-btns"
|
|
331
|
-
},
|
|
415
|
+
}, Dt = { class: "header-right" }, Ht = { class: "chat-container" }, Ot = {
|
|
332
416
|
key: 0,
|
|
333
417
|
class: "session-list"
|
|
334
|
-
},
|
|
418
|
+
}, Nt = { class: "session-header" }, Vt = ["onClick"], Xt = { class: "session-title" }, jt = { class: "session-meta" }, Jt = {
|
|
335
419
|
key: 0,
|
|
336
420
|
class: "session-load-more"
|
|
337
|
-
},
|
|
421
|
+
}, Bt = {
|
|
338
422
|
key: 1,
|
|
339
423
|
class: "session-load-more session-no-more"
|
|
340
|
-
},
|
|
424
|
+
}, Gt = { class: "messages-area" }, qt = { class: "messages-content" }, Kt = {
|
|
341
425
|
key: 0,
|
|
342
426
|
class: "typing-indicator"
|
|
343
|
-
},
|
|
427
|
+
}, Yt = {
|
|
344
428
|
key: 0,
|
|
345
429
|
class: "pending-images"
|
|
346
|
-
},
|
|
430
|
+
}, Zt = { class: "image-index" }, Qt = ["src"], es = { class: "input-area" }, ts = 4, ss = 0.25, ns = 0.38, is = /* @__PURE__ */ q({
|
|
347
431
|
__name: "AiChatDrawer",
|
|
348
432
|
setup(t) {
|
|
349
|
-
const e =
|
|
350
|
-
let
|
|
351
|
-
const
|
|
433
|
+
const e = de();
|
|
434
|
+
let u = new AbortController();
|
|
435
|
+
const l = w({
|
|
352
436
|
get: () => e.visible,
|
|
353
437
|
set: (s) => e.setVisible(s)
|
|
354
|
-
}),
|
|
355
|
-
|
|
356
|
-
},
|
|
357
|
-
const s = {
|
|
358
|
-
position: "fixed",
|
|
359
|
-
top: "0",
|
|
360
|
-
height: "100vh",
|
|
361
|
-
zIndex: "10000",
|
|
362
|
-
display: "flex",
|
|
363
|
-
flexDirection: "row"
|
|
364
|
-
};
|
|
365
|
-
return y.value ? {
|
|
366
|
-
...s,
|
|
367
|
-
left: "0",
|
|
368
|
-
right: "0",
|
|
369
|
-
width: "100%"
|
|
370
|
-
} : k.value ? { ...s, right: "0", width: "100%" } : { ...s, right: "0", width: `${a.value}px` };
|
|
371
|
-
}), j = p(() => {
|
|
438
|
+
}), o = w(() => e.panelWidth), m = w(() => e.isFullScreen), h = E(!1), P = () => {
|
|
439
|
+
h.value = window.innerWidth < 768;
|
|
440
|
+
}, v = w(() => h.value ? { width: "100%" } : m.value ? { width: "100%" } : { width: `${o.value}px` }), L = w(() => {
|
|
372
441
|
const s = e.tokenUsage;
|
|
373
442
|
return s ? s.limitTokens === 0 ? `${s.usedTokens} tokens` : `${s.usedTokens}/${s.limitTokens}` : "";
|
|
374
|
-
}),
|
|
443
|
+
}), k = w(() => {
|
|
375
444
|
const s = e.tokenUsage;
|
|
376
445
|
return s ? s.limitTokens === 0 ? `今日已使用 ${s.usedTokens} tokens(不限制)` : s.limitReached ? "今日配额已用完,请明天再试" : `今日已使用 ${s.usedTokens}/${s.limitTokens} tokens,剩余 ${s.remainingTokens}` : "";
|
|
377
|
-
}),
|
|
378
|
-
|
|
379
|
-
},
|
|
380
|
-
let
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
},
|
|
384
|
-
s.touches.length === 1 && (
|
|
385
|
-
},
|
|
386
|
-
|
|
387
|
-
const n =
|
|
388
|
-
e.setPanelWidth(
|
|
446
|
+
}), S = E(""), C = E(!1), f = E([]), M = E(), $ = E(), H = E(window.innerWidth), ue = () => {
|
|
447
|
+
H.value = window.innerWidth, P();
|
|
448
|
+
}, ge = w(() => h.value ? window.innerWidth : Math.max(320, Math.round(H.value * ss))), me = w(() => h.value ? window.innerWidth : Math.max(420, Math.round(H.value * ns))), Y = w(() => o.value / H.value), Le = w(() => !m.value && Y.value <= 0.3), Re = w(() => !m.value && Y.value > 0.3 && Y.value <= 0.45), Pe = w(() => `窄 (${ge.value}px)`), Ue = w(() => `宽 (${me.value}px)`), D = E(!1), j = E(0), J = E(0);
|
|
449
|
+
let b = null;
|
|
450
|
+
const We = (s) => {
|
|
451
|
+
D.value = !0, j.value = s.clientX, J.value = o.value, document.addEventListener("mousemove", Z), document.addEventListener("mouseup", ee), document.body.style.cursor = "ew-resize", document.body.style.userSelect = "none";
|
|
452
|
+
}, ze = (s) => {
|
|
453
|
+
s.touches.length === 1 && (D.value = !0, j.value = s.touches[0].clientX, J.value = o.value, document.addEventListener("touchmove", Q), document.addEventListener("touchend", te));
|
|
454
|
+
}, Z = (s) => {
|
|
455
|
+
D.value && (b && cancelAnimationFrame(b), b = requestAnimationFrame(() => {
|
|
456
|
+
const n = J.value + (j.value - s.clientX), p = Math.max(320, Math.min(window.innerWidth / 2, n));
|
|
457
|
+
e.setPanelWidth(p);
|
|
389
458
|
}));
|
|
390
|
-
},
|
|
391
|
-
!
|
|
392
|
-
const n =
|
|
393
|
-
e.setPanelWidth(
|
|
459
|
+
}, Q = (s) => {
|
|
460
|
+
!D.value || s.touches.length !== 1 || (b && cancelAnimationFrame(b), b = requestAnimationFrame(() => {
|
|
461
|
+
const n = J.value + (j.value - s.touches[0].clientX), p = Math.max(320, Math.min(window.innerWidth / 2, n));
|
|
462
|
+
e.setPanelWidth(p);
|
|
394
463
|
}));
|
|
395
|
-
},
|
|
396
|
-
|
|
397
|
-
},
|
|
398
|
-
|
|
399
|
-
},
|
|
464
|
+
}, ee = () => {
|
|
465
|
+
D.value = !1, b && (cancelAnimationFrame(b), b = null), document.removeEventListener("mousemove", Z), document.removeEventListener("mouseup", ee), document.body.style.cursor = "", document.body.style.userSelect = "";
|
|
466
|
+
}, te = () => {
|
|
467
|
+
D.value = !1, b && (cancelAnimationFrame(b), b = null), document.removeEventListener("touchmove", Q), document.removeEventListener("touchend", te);
|
|
468
|
+
}, he = (s) => e.setPanelWidth(s), Fe = () => e.toggleFullScreen(), fe = () => e.setVisible(!1), De = async (s) => {
|
|
400
469
|
const n = s.clipboardData?.items;
|
|
401
470
|
if (n)
|
|
402
|
-
for (let
|
|
403
|
-
const
|
|
404
|
-
if (
|
|
405
|
-
if (s.preventDefault(),
|
|
406
|
-
|
|
471
|
+
for (let p = 0; p < n.length; p++) {
|
|
472
|
+
const y = n[p];
|
|
473
|
+
if (y.type.startsWith("image/")) {
|
|
474
|
+
if (s.preventDefault(), f.value.length >= ts) {
|
|
475
|
+
O.warning("最多只能上传4张图片");
|
|
407
476
|
return;
|
|
408
477
|
}
|
|
409
|
-
const
|
|
410
|
-
if (
|
|
411
|
-
const
|
|
412
|
-
|
|
478
|
+
const T = y.getAsFile();
|
|
479
|
+
if (T) {
|
|
480
|
+
const R = await He(T);
|
|
481
|
+
f.value.push(R);
|
|
413
482
|
}
|
|
414
483
|
}
|
|
415
484
|
}
|
|
416
|
-
},
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
}),
|
|
420
|
-
const n =
|
|
485
|
+
}, He = (s) => new Promise((n) => {
|
|
486
|
+
const p = new FileReader();
|
|
487
|
+
p.onload = (y) => n(y.target.result), p.readAsDataURL(s);
|
|
488
|
+
}), Oe = (s) => s?.length > 30 ? s.substring(0, 30) + "..." : s, Ne = ({ scrollTop: s }) => {
|
|
489
|
+
const n = $.value?.wrapRef;
|
|
421
490
|
n && s + n.clientHeight >= n.scrollHeight - 150 && e.loadMoreSessions();
|
|
422
|
-
},
|
|
423
|
-
|
|
491
|
+
}, se = () => {
|
|
492
|
+
M.value?.wrapRef && (M.value.wrapRef.scrollTop = M.value.wrapRef.scrollHeight);
|
|
424
493
|
};
|
|
425
|
-
|
|
426
|
-
s && (e.
|
|
494
|
+
we(() => e.messages.length, () => ne(se)), we(l, (s) => {
|
|
495
|
+
s && (e.currentSessionId || e.loadSessions(), e.loadTokenUsage());
|
|
427
496
|
});
|
|
428
497
|
const Ve = async () => {
|
|
429
498
|
const s = await e.createSession();
|
|
430
|
-
s ? (e.setCurrentSession(s, !1),
|
|
431
|
-
},
|
|
432
|
-
e.setCurrentSession(s.id),
|
|
433
|
-
},
|
|
499
|
+
s ? (e.setCurrentSession(s, !1), C.value = !1) : O.error("创建对话失败,请检查网络或重新登录");
|
|
500
|
+
}, Xe = (s) => {
|
|
501
|
+
e.setCurrentSession(s.id), C.value = !1;
|
|
502
|
+
}, je = async (s) => {
|
|
434
503
|
await e.deleteSession(s);
|
|
435
|
-
},
|
|
436
|
-
const s =
|
|
504
|
+
}, pe = async () => {
|
|
505
|
+
const s = S.value.trim(), n = [...f.value];
|
|
437
506
|
if (!s && n.length === 0 || e.sending) return;
|
|
438
|
-
|
|
439
|
-
let
|
|
440
|
-
|
|
441
|
-
|
|
507
|
+
S.value = "", f.value = [], e.setSending(!0), u = new AbortController();
|
|
508
|
+
let p = e.currentSessionId;
|
|
509
|
+
if (!p) {
|
|
510
|
+
if (p = await e.createSession(), !p) {
|
|
511
|
+
e.setSending(!1), S.value = s, f.value = n, O.error("创建对话失败,请检查网络或重新登录");
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
e.setCurrentSession(p, !1);
|
|
515
|
+
}
|
|
516
|
+
const y = {
|
|
442
517
|
id: Date.now(),
|
|
443
|
-
sessionId:
|
|
518
|
+
sessionId: p,
|
|
444
519
|
role: "user",
|
|
445
520
|
content: s || "[图片]",
|
|
446
521
|
images: n.length > 0 ? n : void 0,
|
|
447
522
|
createTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
448
523
|
};
|
|
449
|
-
e.addMessage(
|
|
450
|
-
const
|
|
524
|
+
e.addMessage(y);
|
|
525
|
+
const T = {
|
|
451
526
|
id: Date.now() + 1,
|
|
452
|
-
sessionId:
|
|
527
|
+
sessionId: p,
|
|
453
528
|
role: "assistant",
|
|
454
529
|
content: "",
|
|
455
530
|
createTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
456
531
|
};
|
|
457
|
-
e.addMessage(
|
|
532
|
+
e.addMessage(T);
|
|
458
533
|
try {
|
|
459
|
-
const
|
|
460
|
-
sessionId:
|
|
461
|
-
// string | undefined
|
|
534
|
+
const U = (await pt({
|
|
535
|
+
sessionId: p,
|
|
462
536
|
message: s || "[图片]",
|
|
463
537
|
images: n.length > 0 ? n : void 0,
|
|
464
|
-
signal:
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
let w = "";
|
|
538
|
+
signal: u.signal
|
|
539
|
+
})).body?.getReader(), _ = new TextDecoder();
|
|
540
|
+
if (U) {
|
|
541
|
+
let x = "";
|
|
469
542
|
for (; ; ) {
|
|
470
|
-
const { done:
|
|
471
|
-
if (
|
|
472
|
-
|
|
473
|
-
const
|
|
543
|
+
const { done: ve, value: Je } = await U.read();
|
|
544
|
+
if (ve) break;
|
|
545
|
+
x += _.decode(Je, { stream: !0 });
|
|
546
|
+
const _e = x.split(`
|
|
474
547
|
`);
|
|
475
|
-
|
|
476
|
-
let
|
|
477
|
-
for (const
|
|
478
|
-
if (
|
|
479
|
-
|
|
480
|
-
else if (
|
|
548
|
+
x = _e.pop() ?? "";
|
|
549
|
+
let ke = "";
|
|
550
|
+
for (const B of _e)
|
|
551
|
+
if (B.startsWith("event:"))
|
|
552
|
+
ke = B.slice(6).trim();
|
|
553
|
+
else if (B.startsWith("data:"))
|
|
481
554
|
try {
|
|
482
|
-
const
|
|
483
|
-
if (
|
|
484
|
-
e.updateLastAssistantMessage(
|
|
555
|
+
const I = JSON.parse(B.slice(5).trim());
|
|
556
|
+
if (ke === "error" || I.error) {
|
|
557
|
+
e.updateLastAssistantMessage(I.error || "服务异常,请重试。"), O.error(I.error || "服务异常,请重试");
|
|
485
558
|
break;
|
|
486
559
|
}
|
|
487
|
-
|
|
560
|
+
I.done || (I.reasoningContent && (e.updateLastAssistantReasoning(I.reasoningContent), ne(se)), I.content && (e.updateLastAssistantMessage(I.content), ne(se))), I.sessionId && !e.currentSessionId && e.setCurrentSession(I.sessionId), I.done && I.usage && e.updateTokenUsage(I.usage.totalTokens);
|
|
488
561
|
} catch {
|
|
489
562
|
}
|
|
490
563
|
}
|
|
491
564
|
}
|
|
492
|
-
} catch (
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
565
|
+
} catch (R) {
|
|
566
|
+
if (R.name === "AbortError")
|
|
567
|
+
console.log("[@cgs/ai-chat] 请求已取消");
|
|
568
|
+
else if (R.message?.startsWith("AUTH_EXPIRED:")) {
|
|
569
|
+
const U = R.message.replace("AUTH_EXPIRED:", "");
|
|
570
|
+
console.error("[@cgs/ai-chat] 认证过期", U), e.updateLastAssistantMessage(`认证失败:${U}`), O.error({
|
|
571
|
+
message: U,
|
|
572
|
+
duration: 5e3,
|
|
573
|
+
showClose: !0
|
|
574
|
+
});
|
|
575
|
+
} else
|
|
576
|
+
console.error("[@cgs/ai-chat] 发送消息失败", R), e.updateLastAssistantMessage("抱歉,发生了错误,请重试。"), O.error({
|
|
577
|
+
message: "消息发送失败,请检查网络连接",
|
|
578
|
+
duration: 3e3,
|
|
579
|
+
showClose: !0
|
|
580
|
+
});
|
|
498
581
|
} finally {
|
|
499
582
|
e.setSending(!1), e.loadSessions();
|
|
500
583
|
}
|
|
501
584
|
};
|
|
502
|
-
return
|
|
503
|
-
window.addEventListener("resize",
|
|
504
|
-
}),
|
|
505
|
-
|
|
585
|
+
return Ce(() => {
|
|
586
|
+
window.addEventListener("resize", ue), P();
|
|
587
|
+
}), Ie(() => {
|
|
588
|
+
u.abort(), window.removeEventListener("resize", ue), document.removeEventListener("mousemove", Z), document.removeEventListener("mouseup", ee), document.removeEventListener("touchmove", Q), document.removeEventListener("touchend", te), b && cancelAnimationFrame(b);
|
|
506
589
|
}), (s, n) => {
|
|
507
|
-
const
|
|
508
|
-
return
|
|
509
|
-
i(
|
|
510
|
-
default:
|
|
511
|
-
|
|
590
|
+
const p = z("el-tooltip"), y = z("el-icon"), T = z("el-button"), R = z("el-empty"), U = z("el-input");
|
|
591
|
+
return a(), d(F, null, [
|
|
592
|
+
i(ie, { name: "slide" }, {
|
|
593
|
+
default: c(() => [
|
|
594
|
+
l.value ? (a(), d("div", {
|
|
512
595
|
key: 0,
|
|
513
|
-
class:
|
|
514
|
-
style:
|
|
596
|
+
class: N(["ai-chat-panel", { "full-screen": m.value, "is-mobile": h.value }]),
|
|
597
|
+
style: Ae(v.value)
|
|
515
598
|
}, [
|
|
516
|
-
|
|
599
|
+
h.value ? A("", !0) : (a(), d("div", {
|
|
517
600
|
key: 0,
|
|
518
601
|
class: "resize-handle",
|
|
519
|
-
onMousedown:
|
|
520
|
-
onTouchstart:
|
|
602
|
+
onMousedown: We,
|
|
603
|
+
onTouchstart: oe(ze, ["prevent"])
|
|
521
604
|
}, [
|
|
522
|
-
n[5] || (n[5] =
|
|
523
|
-
i(
|
|
524
|
-
default:
|
|
525
|
-
|
|
605
|
+
n[5] || (n[5] = g("div", { class: "resize-bar" }, null, -1)),
|
|
606
|
+
i(ie, { name: "fade" }, {
|
|
607
|
+
default: c(() => [
|
|
608
|
+
D.value ? (a(), d("div", Rt, W(Math.round(o.value)) + "px ", 1)) : A("", !0)
|
|
526
609
|
]),
|
|
527
610
|
_: 1
|
|
528
611
|
})
|
|
529
612
|
], 32)),
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
n[6] || (n[6] =
|
|
534
|
-
r(e).tokenUsage ? (
|
|
535
|
-
i(
|
|
536
|
-
content:
|
|
613
|
+
g("div", Pt, [
|
|
614
|
+
g("div", Ut, [
|
|
615
|
+
g("div", Wt, [
|
|
616
|
+
n[6] || (n[6] = g("span", { class: "title" }, "AI助手", -1)),
|
|
617
|
+
r(e).tokenUsage ? (a(), d("div", zt, [
|
|
618
|
+
i(p, {
|
|
619
|
+
content: k.value,
|
|
537
620
|
placement: "bottom"
|
|
538
621
|
}, {
|
|
539
|
-
default:
|
|
540
|
-
|
|
541
|
-
class:
|
|
542
|
-
},
|
|
622
|
+
default: c(() => [
|
|
623
|
+
g("span", {
|
|
624
|
+
class: N({ "limit-warning": r(e).tokenUsage.limitReached })
|
|
625
|
+
}, W(L.value), 3)
|
|
543
626
|
]),
|
|
544
627
|
_: 1
|
|
545
628
|
}, 8, ["content"])
|
|
546
|
-
])) :
|
|
547
|
-
|
|
548
|
-
i(
|
|
549
|
-
content:
|
|
629
|
+
])) : A("", !0),
|
|
630
|
+
h.value ? A("", !0) : (a(), d("div", Ft, [
|
|
631
|
+
i(p, {
|
|
632
|
+
content: Pe.value,
|
|
550
633
|
placement: "bottom"
|
|
551
634
|
}, {
|
|
552
|
-
default:
|
|
553
|
-
i(
|
|
635
|
+
default: c(() => [
|
|
636
|
+
i(T, {
|
|
554
637
|
size: "small",
|
|
555
638
|
type: Le.value ? "primary" : "default",
|
|
556
639
|
link: "",
|
|
557
|
-
onClick: n[0] || (n[0] = (
|
|
640
|
+
onClick: n[0] || (n[0] = (_) => he(ge.value))
|
|
558
641
|
}, {
|
|
559
|
-
default:
|
|
560
|
-
i(
|
|
561
|
-
default:
|
|
562
|
-
i(r(
|
|
642
|
+
default: c(() => [
|
|
643
|
+
i(y, null, {
|
|
644
|
+
default: c(() => [
|
|
645
|
+
i(r(st))
|
|
563
646
|
]),
|
|
564
647
|
_: 1
|
|
565
648
|
})
|
|
@@ -569,21 +652,21 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
569
652
|
]),
|
|
570
653
|
_: 1
|
|
571
654
|
}, 8, ["content"]),
|
|
572
|
-
i(
|
|
573
|
-
content:
|
|
655
|
+
i(p, {
|
|
656
|
+
content: Ue.value,
|
|
574
657
|
placement: "bottom"
|
|
575
658
|
}, {
|
|
576
|
-
default:
|
|
577
|
-
i(
|
|
659
|
+
default: c(() => [
|
|
660
|
+
i(T, {
|
|
578
661
|
size: "small",
|
|
579
|
-
type:
|
|
662
|
+
type: Re.value ? "primary" : "default",
|
|
580
663
|
link: "",
|
|
581
|
-
onClick: n[1] || (n[1] = (
|
|
664
|
+
onClick: n[1] || (n[1] = (_) => he(me.value))
|
|
582
665
|
}, {
|
|
583
|
-
default:
|
|
584
|
-
i(
|
|
585
|
-
default:
|
|
586
|
-
i(r(
|
|
666
|
+
default: c(() => [
|
|
667
|
+
i(y, null, {
|
|
668
|
+
default: c(() => [
|
|
669
|
+
i(r(nt))
|
|
587
670
|
]),
|
|
588
671
|
_: 1
|
|
589
672
|
})
|
|
@@ -593,21 +676,21 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
593
676
|
]),
|
|
594
677
|
_: 1
|
|
595
678
|
}, 8, ["content"]),
|
|
596
|
-
i(
|
|
597
|
-
content:
|
|
679
|
+
i(p, {
|
|
680
|
+
content: m.value ? "退出全屏" : "全屏",
|
|
598
681
|
placement: "bottom"
|
|
599
682
|
}, {
|
|
600
|
-
default:
|
|
601
|
-
i(
|
|
683
|
+
default: c(() => [
|
|
684
|
+
i(T, {
|
|
602
685
|
size: "small",
|
|
603
|
-
type:
|
|
686
|
+
type: m.value ? "primary" : "default",
|
|
604
687
|
link: "",
|
|
605
|
-
onClick:
|
|
688
|
+
onClick: Fe
|
|
606
689
|
}, {
|
|
607
|
-
default:
|
|
608
|
-
i(
|
|
609
|
-
default:
|
|
610
|
-
i(r(
|
|
690
|
+
default: c(() => [
|
|
691
|
+
i(y, null, {
|
|
692
|
+
default: c(() => [
|
|
693
|
+
i(r(it))
|
|
611
694
|
]),
|
|
612
695
|
_: 1
|
|
613
696
|
})
|
|
@@ -619,32 +702,32 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
619
702
|
}, 8, ["content"])
|
|
620
703
|
]))
|
|
621
704
|
]),
|
|
622
|
-
|
|
623
|
-
i(
|
|
705
|
+
g("div", Dt, [
|
|
706
|
+
i(T, {
|
|
624
707
|
type: "primary",
|
|
625
708
|
link: "",
|
|
626
709
|
onClick: Ve
|
|
627
710
|
}, {
|
|
628
|
-
default:
|
|
629
|
-
i(
|
|
630
|
-
default:
|
|
631
|
-
i(r(
|
|
711
|
+
default: c(() => [
|
|
712
|
+
i(y, null, {
|
|
713
|
+
default: c(() => [
|
|
714
|
+
i(r(ot))
|
|
632
715
|
]),
|
|
633
716
|
_: 1
|
|
634
717
|
}),
|
|
635
|
-
n[7] || (n[7] =
|
|
718
|
+
n[7] || (n[7] = ae("新对话 ", -1))
|
|
636
719
|
]),
|
|
637
720
|
_: 1
|
|
638
721
|
}),
|
|
639
|
-
i(
|
|
722
|
+
i(T, {
|
|
640
723
|
type: "default",
|
|
641
724
|
link: "",
|
|
642
|
-
onClick:
|
|
725
|
+
onClick: fe
|
|
643
726
|
}, {
|
|
644
|
-
default:
|
|
645
|
-
i(
|
|
646
|
-
default:
|
|
647
|
-
i(r(
|
|
727
|
+
default: c(() => [
|
|
728
|
+
i(y, null, {
|
|
729
|
+
default: c(() => [
|
|
730
|
+
i(r(Se))
|
|
648
731
|
]),
|
|
649
732
|
_: 1
|
|
650
733
|
})
|
|
@@ -653,120 +736,120 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
653
736
|
})
|
|
654
737
|
])
|
|
655
738
|
]),
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
n[9] || (n[9] =
|
|
660
|
-
i(
|
|
739
|
+
g("div", Ht, [
|
|
740
|
+
C.value ? (a(), d("div", Ot, [
|
|
741
|
+
g("div", Nt, [
|
|
742
|
+
n[9] || (n[9] = g("span", null, "历史对话", -1)),
|
|
743
|
+
i(T, {
|
|
661
744
|
type: "primary",
|
|
662
745
|
link: "",
|
|
663
746
|
size: "small",
|
|
664
|
-
onClick: n[2] || (n[2] = (
|
|
747
|
+
onClick: n[2] || (n[2] = (_) => C.value = !1)
|
|
665
748
|
}, {
|
|
666
|
-
default:
|
|
667
|
-
|
|
749
|
+
default: c(() => [...n[8] || (n[8] = [
|
|
750
|
+
ae("返回聊天", -1)
|
|
668
751
|
])]),
|
|
669
752
|
_: 1
|
|
670
753
|
})
|
|
671
754
|
]),
|
|
672
|
-
i(r(
|
|
755
|
+
i(r(ye), {
|
|
673
756
|
ref_key: "sessionScrollbarRef",
|
|
674
|
-
ref:
|
|
675
|
-
height: (
|
|
757
|
+
ref: $,
|
|
758
|
+
height: (h.value, "calc(100vh - 200px)"),
|
|
676
759
|
onScroll: Ne
|
|
677
760
|
}, {
|
|
678
|
-
default:
|
|
679
|
-
(
|
|
680
|
-
key:
|
|
681
|
-
class:
|
|
682
|
-
onClick: (
|
|
761
|
+
default: c(() => [
|
|
762
|
+
(a(!0), d(F, null, G(r(e).sessions, (_) => (a(), d("div", {
|
|
763
|
+
key: _.id,
|
|
764
|
+
class: N(["session-item", { active: _.id === r(e).currentSessionId }]),
|
|
765
|
+
onClick: (x) => Xe(_)
|
|
683
766
|
}, [
|
|
684
|
-
i(
|
|
685
|
-
content:
|
|
767
|
+
i(p, {
|
|
768
|
+
content: _.title,
|
|
686
769
|
placement: "left",
|
|
687
770
|
"show-after": 500
|
|
688
771
|
}, {
|
|
689
|
-
default:
|
|
690
|
-
|
|
772
|
+
default: c(() => [
|
|
773
|
+
g("div", Xt, W(Oe(_.title)), 1)
|
|
691
774
|
]),
|
|
692
775
|
_: 2
|
|
693
776
|
}, 1032, ["content"]),
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
i(
|
|
777
|
+
g("div", jt, [
|
|
778
|
+
g("span", null, W(_.messageCount) + "条消息", 1),
|
|
779
|
+
i(T, {
|
|
697
780
|
type: "danger",
|
|
698
781
|
link: "",
|
|
699
782
|
size: "small",
|
|
700
|
-
onClick:
|
|
783
|
+
onClick: oe((x) => je(_.id), ["stop"])
|
|
701
784
|
}, {
|
|
702
|
-
default:
|
|
703
|
-
|
|
785
|
+
default: c(() => [...n[10] || (n[10] = [
|
|
786
|
+
ae("删除", -1)
|
|
704
787
|
])]),
|
|
705
788
|
_: 1
|
|
706
789
|
}, 8, ["onClick"])
|
|
707
790
|
])
|
|
708
|
-
], 10,
|
|
709
|
-
r(e).sessionLoadingMore ? (
|
|
710
|
-
i(
|
|
711
|
-
default:
|
|
712
|
-
i(r(
|
|
791
|
+
], 10, Vt))), 128)),
|
|
792
|
+
r(e).sessionLoadingMore ? (a(), d("div", Jt, [
|
|
793
|
+
i(y, { class: "is-loading" }, {
|
|
794
|
+
default: c(() => [
|
|
795
|
+
i(r(at))
|
|
713
796
|
]),
|
|
714
797
|
_: 1
|
|
715
798
|
}),
|
|
716
|
-
n[11] || (n[11] =
|
|
717
|
-
])) : r(e).sessions.length > 0 && !r(e).sessionHasMore ? (
|
|
718
|
-
r(e).sessions.length === 0 ? (
|
|
799
|
+
n[11] || (n[11] = g("span", null, "加载中...", -1))
|
|
800
|
+
])) : r(e).sessions.length > 0 && !r(e).sessionHasMore ? (a(), d("div", Bt, " 共 " + W(r(e).sessionTotal) + " 条对话 ", 1)) : A("", !0),
|
|
801
|
+
r(e).sessions.length === 0 ? (a(), V(R, {
|
|
719
802
|
key: 2,
|
|
720
803
|
description: "暂无历史对话"
|
|
721
|
-
})) :
|
|
804
|
+
})) : A("", !0)
|
|
722
805
|
]),
|
|
723
806
|
_: 1
|
|
724
807
|
}, 8, ["height"])
|
|
725
|
-
])) : (
|
|
726
|
-
|
|
727
|
-
i(r(
|
|
808
|
+
])) : (a(), d(F, { key: 1 }, [
|
|
809
|
+
g("div", Gt, [
|
|
810
|
+
i(r(ye), {
|
|
728
811
|
ref_key: "scrollbarRef",
|
|
729
|
-
ref:
|
|
812
|
+
ref: M,
|
|
730
813
|
height: "100%"
|
|
731
814
|
}, {
|
|
732
|
-
default:
|
|
733
|
-
|
|
734
|
-
(
|
|
735
|
-
key:
|
|
736
|
-
message:
|
|
815
|
+
default: c(() => [
|
|
816
|
+
g("div", qt, [
|
|
817
|
+
(a(!0), d(F, null, G(r(e).messages, (_, x) => (a(), V(Lt, {
|
|
818
|
+
key: x,
|
|
819
|
+
message: _
|
|
737
820
|
}, null, 8, ["message"]))), 128)),
|
|
738
|
-
r(e).sending ? (
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
])])) :
|
|
821
|
+
r(e).sending ? (a(), d("div", Kt, [...n[12] || (n[12] = [
|
|
822
|
+
g("span", null, null, -1),
|
|
823
|
+
g("span", null, null, -1),
|
|
824
|
+
g("span", null, null, -1)
|
|
825
|
+
])])) : A("", !0)
|
|
743
826
|
])
|
|
744
827
|
]),
|
|
745
828
|
_: 1
|
|
746
829
|
}, 512)
|
|
747
830
|
]),
|
|
748
|
-
|
|
749
|
-
(
|
|
750
|
-
key:
|
|
831
|
+
f.value.length > 0 ? (a(), d("div", Yt, [
|
|
832
|
+
(a(!0), d(F, null, G(f.value, (_, x) => (a(), d("div", {
|
|
833
|
+
key: x,
|
|
751
834
|
class: "pending-image-wrap"
|
|
752
835
|
}, [
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
src:
|
|
836
|
+
g("div", Zt, W(x + 1) + "/" + W(f.value.length), 1),
|
|
837
|
+
g("img", {
|
|
838
|
+
src: _,
|
|
756
839
|
class: "pending-image",
|
|
757
840
|
alt: "待发送图片"
|
|
758
|
-
}, null, 8,
|
|
759
|
-
i(
|
|
841
|
+
}, null, 8, Qt),
|
|
842
|
+
i(T, {
|
|
760
843
|
type: "danger",
|
|
761
844
|
circle: "",
|
|
762
845
|
size: "small",
|
|
763
846
|
class: "remove-img",
|
|
764
|
-
onClick: (
|
|
847
|
+
onClick: (ve) => f.value.splice(x, 1)
|
|
765
848
|
}, {
|
|
766
|
-
default:
|
|
767
|
-
i(
|
|
768
|
-
default:
|
|
769
|
-
i(r(
|
|
849
|
+
default: c(() => [
|
|
850
|
+
i(y, null, {
|
|
851
|
+
default: c(() => [
|
|
852
|
+
i(r(Se))
|
|
770
853
|
]),
|
|
771
854
|
_: 1
|
|
772
855
|
})
|
|
@@ -774,26 +857,26 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
774
857
|
_: 1
|
|
775
858
|
}, 8, ["onClick"])
|
|
776
859
|
]))), 128))
|
|
777
|
-
])) :
|
|
778
|
-
|
|
779
|
-
i(
|
|
860
|
+
])) : A("", !0),
|
|
861
|
+
g("div", es, [
|
|
862
|
+
i(T, {
|
|
780
863
|
type: "primary",
|
|
781
864
|
link: "",
|
|
782
|
-
onClick: n[3] || (n[3] = (
|
|
865
|
+
onClick: n[3] || (n[3] = (_) => C.value = !0)
|
|
783
866
|
}, {
|
|
784
|
-
default:
|
|
785
|
-
i(
|
|
786
|
-
default:
|
|
787
|
-
i(r(
|
|
867
|
+
default: c(() => [
|
|
868
|
+
i(y, null, {
|
|
869
|
+
default: c(() => [
|
|
870
|
+
i(r(lt))
|
|
788
871
|
]),
|
|
789
872
|
_: 1
|
|
790
873
|
})
|
|
791
874
|
]),
|
|
792
875
|
_: 1
|
|
793
876
|
}),
|
|
794
|
-
i(
|
|
795
|
-
modelValue:
|
|
796
|
-
"onUpdate:modelValue": n[4] || (n[4] = (
|
|
877
|
+
i(U, {
|
|
878
|
+
modelValue: S.value,
|
|
879
|
+
"onUpdate:modelValue": n[4] || (n[4] = (_) => S.value = _),
|
|
797
880
|
type: "textarea",
|
|
798
881
|
rows: 2,
|
|
799
882
|
maxlength: "2000",
|
|
@@ -801,56 +884,56 @@ const Se = 15, ne = dt(), xe = nt("cgs-ai-chat", {
|
|
|
801
884
|
placeholder: "输入消息... (Enter 发送,Shift+Enter 换行,Ctrl+V 粘贴截图)",
|
|
802
885
|
resize: "none",
|
|
803
886
|
disabled: r(e).sending || r(e).tokenUsage?.limitReached,
|
|
804
|
-
onKeydown:
|
|
805
|
-
onPaste:
|
|
887
|
+
onKeydown: Ke(oe(pe, ["exact", "prevent"]), ["enter"]),
|
|
888
|
+
onPaste: De
|
|
806
889
|
}, null, 8, ["modelValue", "disabled", "onKeydown"]),
|
|
807
|
-
i(
|
|
890
|
+
i(T, {
|
|
808
891
|
type: "primary",
|
|
809
|
-
icon: r(
|
|
892
|
+
icon: r(rt),
|
|
810
893
|
circle: "",
|
|
811
894
|
loading: r(e).sending,
|
|
812
|
-
disabled: !
|
|
813
|
-
onClick:
|
|
895
|
+
disabled: !S.value.trim() && f.value.length === 0 || r(e).sending || r(e).tokenUsage?.limitReached,
|
|
896
|
+
onClick: pe
|
|
814
897
|
}, null, 8, ["icon", "loading", "disabled"])
|
|
815
898
|
]),
|
|
816
|
-
n[13] || (n[13] =
|
|
899
|
+
n[13] || (n[13] = g("div", { class: "ai-disclaimer" }, "内容由AI生成,请仔细甄别", -1))
|
|
817
900
|
], 64))
|
|
818
901
|
])
|
|
819
902
|
])
|
|
820
|
-
], 6)) :
|
|
903
|
+
], 6)) : A("", !0)
|
|
821
904
|
]),
|
|
822
905
|
_: 1
|
|
823
906
|
}),
|
|
824
|
-
i(
|
|
825
|
-
default:
|
|
826
|
-
|
|
907
|
+
i(ie, { name: "fade" }, {
|
|
908
|
+
default: c(() => [
|
|
909
|
+
l.value ? (a(), d("div", {
|
|
827
910
|
key: 0,
|
|
828
911
|
class: "ai-panel-overlay",
|
|
829
|
-
onClick:
|
|
830
|
-
})) :
|
|
912
|
+
onClick: fe
|
|
913
|
+
})) : A("", !0)
|
|
831
914
|
]),
|
|
832
915
|
_: 1
|
|
833
916
|
})
|
|
834
917
|
], 64);
|
|
835
918
|
};
|
|
836
919
|
}
|
|
837
|
-
}),
|
|
920
|
+
}), xe = /* @__PURE__ */ K(is, [["__scopeId", "data-v-fde82f0b"]]), os = { class: "cgs-ai-chat-root" }, as = /* @__PURE__ */ q({
|
|
838
921
|
__name: "AiChat",
|
|
839
922
|
setup(t) {
|
|
840
|
-
return (e,
|
|
841
|
-
i(
|
|
842
|
-
i(
|
|
923
|
+
return (e, u) => (a(), d("div", os, [
|
|
924
|
+
i($e),
|
|
925
|
+
i(xe)
|
|
843
926
|
]));
|
|
844
927
|
}
|
|
845
|
-
}),
|
|
928
|
+
}), ls = /* @__PURE__ */ K(as, [["__scopeId", "data-v-4f2a75e5"]]), gs = {
|
|
846
929
|
install(t, e) {
|
|
847
|
-
e?.baseUrl || console.warn("[@cgs/ai-chat] 警告:未提供 baseUrl,组件可能无法正常工作"),
|
|
930
|
+
e?.baseUrl || console.warn("[@cgs/ai-chat] 警告:未提供 baseUrl,组件可能无法正常工作"), dt(e), t.component("AiChat", ls), t.component("AiChatFloat", $e), t.component("AiChatDrawer", xe);
|
|
848
931
|
}
|
|
849
932
|
};
|
|
850
933
|
export {
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
934
|
+
xe as AiChatDrawer,
|
|
935
|
+
$e as AiChatFloat,
|
|
936
|
+
Lt as AiChatMessage,
|
|
937
|
+
gs as default,
|
|
938
|
+
de as useAiStore
|
|
856
939
|
};
|