@yoka-ui/ui 1.1.1 → 1.1.5

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.
Files changed (84) hide show
  1. package/@Docs-yoka/exports.generated.md +53 -4
  2. package/dist/es/assets/image/skills.zip +0 -0
  3. package/dist/es/business/AiChat/index.js +15 -13
  4. package/dist/es/business/AiChat/index.js.map +2 -2
  5. package/dist/es/business/AiChat/useAiChat.js +41 -24
  6. package/dist/es/business/AiChat/useAiChat.js.map +2 -2
  7. package/dist/es/business/Editor/index.d.ts +2 -2
  8. package/dist/es/business/Editor/index.js.map +2 -2
  9. package/dist/es/business/Empty/index.d.ts +1 -1
  10. package/dist/es/business/Empty/index.js.map +1 -1
  11. package/dist/es/business/ModCommonFilter/index.d.ts +1 -0
  12. package/dist/es/business/ModCommonFilter/index.js.map +2 -2
  13. package/dist/es/business/YkLoginModule/index.d.ts +1 -0
  14. package/dist/es/business/YkLoginModule/index.js.map +2 -2
  15. package/dist/es/business/YkPorjectSelect/index.d.ts +3 -3
  16. package/dist/es/business/YkPorjectSelect/index.js +37 -51
  17. package/dist/es/business/YkPorjectSelect/index.js.map +2 -2
  18. package/dist/es/business/YkSqlEdit/index.d.ts +1 -0
  19. package/dist/es/business/YkSqlEdit/index.js.map +2 -2
  20. package/dist/es/components/Clock/index.d.ts +2 -2
  21. package/dist/es/components/Clock/index.js.map +2 -2
  22. package/dist/es/components/DebounceInput/index.d.ts +2 -2
  23. package/dist/es/components/DebounceInput/index.js.map +2 -2
  24. package/dist/es/components/MultipleSelect/index.d.ts +2 -2
  25. package/dist/es/components/MultipleSelect/index.js.map +2 -2
  26. package/dist/es/components/RefreshButton/index.d.ts +2 -2
  27. package/dist/es/components/RefreshButton/index.js.map +2 -2
  28. package/dist/es/components/SearchWithHistory/index.d.ts +1 -1
  29. package/dist/es/components/SearchWithHistory/index.js.map +1 -1
  30. package/dist/es/components/TextWithInput/index.d.ts +2 -5
  31. package/dist/es/components/TextWithInput/index.js.map +2 -2
  32. package/dist/es/components/TextWithToolTip/index.d.ts +2 -2
  33. package/dist/es/components/TextWithToolTip/index.js.map +2 -2
  34. package/dist/es/components/TreeTransfer/index.d.ts +1 -0
  35. package/dist/es/components/TreeTransfer/index.js.map +2 -2
  36. package/dist/es/index.d.ts +29 -0
  37. package/dist/es/index.js.map +2 -2
  38. package/dist/es/index.less +1 -0
  39. package/dist/es/layout/YkContainer/index.d.ts +24 -14
  40. package/dist/es/layout/YkContainer/index.js +7 -41
  41. package/dist/es/layout/YkContainer/index.js.map +2 -2
  42. package/dist/es/layout/YkContainer/index.module.less +73 -0
  43. package/dist/lib/assets/image/skills.zip +0 -0
  44. package/dist/lib/business/AiChat/index.js +15 -13
  45. package/dist/lib/business/AiChat/index.js.map +2 -2
  46. package/dist/lib/business/AiChat/useAiChat.js +40 -22
  47. package/dist/lib/business/AiChat/useAiChat.js.map +2 -2
  48. package/dist/lib/business/Editor/index.d.ts +2 -2
  49. package/dist/lib/business/Editor/index.js.map +2 -2
  50. package/dist/lib/business/Empty/index.d.ts +1 -1
  51. package/dist/lib/business/Empty/index.js.map +1 -1
  52. package/dist/lib/business/ModCommonFilter/index.d.ts +1 -0
  53. package/dist/lib/business/ModCommonFilter/index.js.map +2 -2
  54. package/dist/lib/business/YkLoginModule/index.d.ts +1 -0
  55. package/dist/lib/business/YkLoginModule/index.js.map +2 -2
  56. package/dist/lib/business/YkPorjectSelect/index.d.ts +3 -3
  57. package/dist/lib/business/YkPorjectSelect/index.js +33 -27
  58. package/dist/lib/business/YkPorjectSelect/index.js.map +2 -2
  59. package/dist/lib/business/YkSqlEdit/index.d.ts +1 -0
  60. package/dist/lib/business/YkSqlEdit/index.js.map +2 -2
  61. package/dist/lib/components/Clock/index.d.ts +2 -2
  62. package/dist/lib/components/Clock/index.js.map +2 -2
  63. package/dist/lib/components/DebounceInput/index.d.ts +2 -2
  64. package/dist/lib/components/DebounceInput/index.js.map +2 -2
  65. package/dist/lib/components/MultipleSelect/index.d.ts +2 -2
  66. package/dist/lib/components/MultipleSelect/index.js.map +2 -2
  67. package/dist/lib/components/RefreshButton/index.d.ts +2 -2
  68. package/dist/lib/components/RefreshButton/index.js.map +2 -2
  69. package/dist/lib/components/SearchWithHistory/index.d.ts +1 -1
  70. package/dist/lib/components/SearchWithHistory/index.js.map +1 -1
  71. package/dist/lib/components/TextWithInput/index.d.ts +2 -5
  72. package/dist/lib/components/TextWithInput/index.js.map +2 -2
  73. package/dist/lib/components/TextWithToolTip/index.d.ts +2 -2
  74. package/dist/lib/components/TextWithToolTip/index.js.map +2 -2
  75. package/dist/lib/components/TreeTransfer/index.d.ts +1 -0
  76. package/dist/lib/components/TreeTransfer/index.js.map +2 -2
  77. package/dist/lib/index.d.ts +29 -0
  78. package/dist/lib/index.js.map +2 -2
  79. package/dist/lib/index.less +1 -0
  80. package/dist/lib/layout/YkContainer/index.d.ts +24 -14
  81. package/dist/lib/layout/YkContainer/index.js +6 -39
  82. package/dist/lib/layout/YkContainer/index.js.map +3 -3
  83. package/dist/lib/layout/YkContainer/index.module.less +73 -0
  84. package/package.json +6 -5
@@ -29,47 +29,13 @@ var __objRest = (source, exclude) => {
29
29
 
30
30
  // src/layout/YkContainer/index.tsx
31
31
  import classNames from "classnames";
32
- import React from "react";
33
- var headerBarStyle = {
34
- position: "sticky",
35
- top: 0,
36
- zIndex: 10,
37
- display: "flex",
38
- alignItems: "center",
39
- justifyContent: "space-between",
40
- gap: 12,
41
- minHeight: 60,
42
- padding: "10px 20px",
43
- boxSizing: "border-box",
44
- background: "#fff"
45
- };
46
- var titleStyle = {
47
- margin: 0,
48
- fontSize: 18,
49
- fontWeight: 600,
50
- lineHeight: "24px",
51
- color: "#3b82fe"
52
- };
53
- var YkContainer = React.forwardRef(
54
- (_a, ref) => {
55
- var _b = _a, { className, style, children, title, headerLeft, headerRight, showHeader = true } = _b, rest = __objRest(_b, ["className", "style", "children", "title", "headerLeft", "headerRight", "showHeader"]);
56
- return /* @__PURE__ */ React.createElement(
57
- "div",
58
- __spreadValues({
59
- ref,
60
- className: classNames("yoka-container", className),
61
- style: __spreadValues({
62
- display: "flex",
63
- flexDirection: "column",
64
- gap: 10,
65
- padding: "0 10px 10px",
66
- boxSizing: "border-box"
67
- }, style)
68
- }, rest),
69
- showHeader ? /* @__PURE__ */ React.createElement("header", { style: headerBarStyle, className: "yoka-yk-container-header" }, /* @__PURE__ */ React.createElement("div", { style: { flex: 1, minWidth: 0, display: "flex", alignItems: "center" } }, headerLeft !== void 0 && headerLeft !== null ? headerLeft : title != null && title !== "" ? /* @__PURE__ */ React.createElement("div", { style: titleStyle }, title) : null), headerRight ? /* @__PURE__ */ React.createElement("div", { style: { flexShrink: 0, display: "flex", alignItems: "center" } }, headerRight) : null) : null,
70
- children
71
- );
72
- }
32
+ import React, { forwardRef, memo } from "react";
33
+ import styles from "./index.module.less";
34
+ var YkContainer = memo(
35
+ forwardRef((props, ref) => {
36
+ const _a = props, { className, style, children, title, subTitle, headerLeft, headerRight, showHeader = true } = _a, rest = __objRest(_a, ["className", "style", "children", "title", "subTitle", "headerLeft", "headerRight", "showHeader"]);
37
+ return /* @__PURE__ */ React.createElement("div", __spreadValues({ ref, className: classNames("yoka-container", styles.containerWrap, className), style }, rest), showHeader && /* @__PURE__ */ React.createElement("header", { className: styles.headerBar }, /* @__PURE__ */ React.createElement("div", { className: styles.headerLeftWrap }, headerLeft != null ? headerLeft : /* @__PURE__ */ React.createElement("div", { className: styles.titleRow }, title && /* @__PURE__ */ React.createElement("div", { className: styles.mainTitle }, title), subTitle && /* @__PURE__ */ React.createElement("div", { className: styles.subTitle }, subTitle))), headerRight && /* @__PURE__ */ React.createElement("div", { className: styles.headerRightWrap }, headerRight)), /* @__PURE__ */ React.createElement("div", { className: styles.contentWrap }, children));
38
+ })
73
39
  );
74
40
  YkContainer.displayName = "YkContainer";
75
41
  var YkContainer_default = YkContainer;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/layout/YkContainer/index.tsx"],
4
- "sourcesContent": ["import classNames from 'classnames';\nimport React from 'react';\n\nexport type YkContainerProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> & {\n /** 页头左侧标题,字号 18px、颜色 #3b82fe;存在 `headerLeft` 时不展示 */\n title?: React.ReactNode;\n /** 自定义页头左侧,优先级高于 `title` */\n headerLeft?: React.ReactNode;\n /** 页头右侧插槽 */\n headerRight?: React.ReactNode;\n /** 是否展示页头,默认 true */\n showHeader?: boolean;\n};\n\nconst headerBarStyle: React.CSSProperties = {\n position: 'sticky',\n top: 0,\n zIndex: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n minHeight: 60,\n padding: '10px 20px',\n boxSizing: 'border-box',\n background: '#fff',\n};\n\nconst titleStyle: React.CSSProperties = {\n margin: 0,\n fontSize: 18,\n fontWeight: 600,\n lineHeight: '24px',\n color: '#3b82fe',\n};\n\n/**\n * 页面内容区布局容器(语义上类似 Pro PageContainer 的内容包裹层):\n * 顶部可选固定(sticky)页头,左右插槽;下方区域左右与底部留白 10px、顶部与页头间距 10px;\n * 子元素纵向排列,间距 10px。\n */\nconst YkContainer = React.forwardRef<HTMLDivElement, YkContainerProps>(\n ({ className, style, children, title, headerLeft, headerRight, showHeader = true, ...rest }, ref) => (\n <div\n ref={ref}\n className={classNames('yoka-container', className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 10,\n padding: '0 10px 10px',\n boxSizing: 'border-box',\n ...style,\n }}\n {...rest}\n >\n {showHeader ? (\n <header style={headerBarStyle} className='yoka-yk-container-header'>\n <div style={{ flex: 1, minWidth: 0, display: 'flex', alignItems: 'center' }}>\n {headerLeft !== undefined && headerLeft !== null ? (\n headerLeft\n ) : title != null && title !== '' ? (\n <div style={titleStyle}>{title}</div>\n ) : null}\n </div>\n {headerRight ? (\n <div style={{ flexShrink: 0, display: 'flex', alignItems: 'center' }}>{headerRight}</div>\n ) : null}\n </header>\n ) : null}\n {children}\n </div>\n ),\n);\n\nYkContainer.displayName = 'YkContainer';\n\nexport default YkContainer;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,gBAAgB;AACvB,OAAO,WAAW;AAalB,IAAM,iBAAsC;AAAA,EAC1C,UAAU;AAAA,EACV,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,WAAW;AAAA,EACX,YAAY;AACd;AAEA,IAAM,aAAkC;AAAA,EACtC,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,OAAO;AACT;AAOA,IAAM,cAAc,MAAM;AAAA,EACxB,CAAC,IAA4F,QAAK;AAAjG,iBAAE,aAAW,OAAO,UAAU,OAAO,YAAY,aAAa,aAAa,KA1C9E,IA0CG,IAAoF,iBAApF,IAAoF,CAAlF,aAAW,SAAO,YAAU,SAAO,cAAY,eAAa;AAC7D;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,WAAW,kBAAkB,SAAS;AAAA,QACjD,OAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,KAAK;AAAA,UACL,SAAS;AAAA,UACT,WAAW;AAAA,WACR;AAAA,SAED;AAAA,MAEH,aACC,oCAAC,YAAO,OAAO,gBAAgB,WAAU,8BACvC,oCAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,QAAQ,YAAY,SAAS,KACvE,eAAe,UAAa,eAAe,OAC1C,aACE,SAAS,QAAQ,UAAU,KAC7B,oCAAC,SAAI,OAAO,cAAa,KAAM,IAC7B,IACN,GACC,cACC,oCAAC,SAAI,OAAO,EAAE,YAAY,GAAG,SAAS,QAAQ,YAAY,SAAS,KAAI,WAAY,IACjF,IACN,IACE;AAAA,MACH;AAAA,IACH;AAAA;AAEJ;AAEA,YAAY,cAAc;AAE1B,IAAO,sBAAQ;",
4
+ "sourcesContent": ["import classNames from 'classnames';\nimport React, { forwardRef, memo, ReactNode } from 'react';\nimport styles from './index.module.less';\n\nexport type YkContainerProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> & {\n /** 页头左侧主标题,字号18px、#3b82feheaderLeft存在时不展示title与subTitle */\n title?: React.ReactNode;\n /** 页头左侧二级副标题,与title同行、下边线对齐;headerLeft优先级更高 */\n subTitle?: React.ReactNode;\n /** 自定义左侧整区域,优先级 > title+subTitle */\n headerLeft?: React.ReactNode;\n /** 右侧操作插槽:元素过多自动换行展示为两行及以上 */\n headerRight?: React.ReactNode;\n /** 是否渲染顶部固定页头,默认true */\n showHeader?: boolean;\n};\n\n/**\n * Yoka页面全局容器组件\n * 1. 顶部sticky吸顶页头:左侧主/副标题同行下边线对齐、右侧自适应操作区(按钮过多自动换行两行)\n * 2. 容器内部上下左右留白,子内容纵向间距10px,适配BI报表页面布局\n * 3. 遵循项目antd/yoka-ui规范,样式使用CSS Modules Less\n * @param title 主标题\n * @param subTitle 二级副标题,与title同行\n * @param headerLeft 自定义左侧全量插槽\n * @param headerRight 右侧操作区域,内容自动换行\n * @param showHeader 是否显示头部\n */\nconst YkContainer = memo(\n forwardRef<HTMLDivElement, YkContainerProps>((props, ref) => {\n const { className, style, children, title, subTitle, headerLeft, headerRight, showHeader = true, ...rest } = props;\n\n return (\n <div ref={ref} className={classNames('yoka-container', styles.containerWrap, className)} style={style} {...rest}>\n {showHeader && (\n <header className={styles.headerBar}>\n {/* 左侧标题区 */}\n <div className={styles.headerLeftWrap}>\n {headerLeft ?? (\n <div className={styles.titleRow}>\n {title && <div className={styles.mainTitle}>{title}</div>}\n {subTitle && <div className={styles.subTitle}>{subTitle}</div>}\n </div>\n )}\n </div>\n {/* 右侧操作区:核心flex-wrap:wrap 超出自动换行两行 */}\n {headerRight && <div className={styles.headerRightWrap}>{headerRight}</div>}\n </header>\n )}\n {/* 页面主体内容 */}\n <div className={styles.contentWrap}>{children}</div>\n </div>\n );\n }),\n);\n\nYkContainer.displayName = 'YkContainer';\nexport default YkContainer;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,gBAAgB;AACvB,OAAO,SAAS,YAAY,YAAuB;AACnD,OAAO,YAAY;AA0BnB,IAAM,cAAc;AAAA,EAClB,WAA6C,CAAC,OAAO,QAAQ;AAC3D,UAA6G,YAArG,aAAW,OAAO,UAAU,OAAO,UAAU,YAAY,aAAa,aAAa,KA9B/F,IA8BiH,IAAT,iBAAS,IAAT,CAA5F,aAAW,SAAO,YAAU,SAAO,YAAU,cAAY,eAAa;AAE9E,WACE,oCAAC,wBAAI,KAAU,WAAW,WAAW,kBAAkB,OAAO,eAAe,SAAS,GAAG,SAAkB,OACxG,cACC,oCAAC,YAAO,WAAW,OAAO,aAExB,oCAAC,SAAI,WAAW,OAAO,kBACpB,kCACC,oCAAC,SAAI,WAAW,OAAO,YACpB,SAAS,oCAAC,SAAI,WAAW,OAAO,aAAY,KAAM,GAClD,YAAY,oCAAC,SAAI,WAAW,OAAO,YAAW,QAAS,CAC1D,CAEJ,GAEC,eAAe,oCAAC,SAAI,WAAW,OAAO,mBAAkB,WAAY,CACvE,GAGF,oCAAC,SAAI,WAAW,OAAO,eAAc,QAAS,CAChD;AAAA,EAEJ,CAAC;AACH;AAEA,YAAY,cAAc;AAC1B,IAAO,sBAAQ;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,73 @@
1
+ .containerWrap {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 10px;
5
+ padding: 0 10px 10px;
6
+ box-sizing: border-box;
7
+ }
8
+
9
+ // 顶部吸顶头部容器
10
+ .headerBar {
11
+ position: sticky;
12
+ top: 0;
13
+ z-index: 10;
14
+ display: flex;
15
+ align-items: flex-start;
16
+ justify-content: space-between;
17
+ padding: 10px 20px;
18
+ min-height: 60px;
19
+ background: #fff;
20
+ box-sizing: border-box;
21
+ gap: 12px;
22
+ }
23
+
24
+ // 左侧标题区域
25
+ .headerLeftWrap {
26
+ flex: 1;
27
+ min-width: 0;
28
+
29
+ .titleRow {
30
+ display: flex;
31
+ align-items: baseline;
32
+ gap: 12px;
33
+ }
34
+
35
+ .mainTitle {
36
+ margin: 0;
37
+ font-size: 18px;
38
+ font-weight: 600;
39
+ line-height: 24px;
40
+ color: #3b82fe;
41
+ white-space: nowrap;
42
+ flex-shrink: 0;
43
+ }
44
+
45
+ .subTitle {
46
+ font-size: 14px;
47
+ line-height: 24px;
48
+ color: #666;
49
+ word-break: break-all;
50
+ }
51
+ }
52
+
53
+ // 右侧操作区【关键:自动换行】
54
+ .headerRightWrap {
55
+ flex-shrink: 0;
56
+ display: flex;
57
+ flex-wrap: wrap; // 空间不足自动换行,实现两行布局
58
+ justify-content: flex-end;
59
+ align-items: center;
60
+ gap: 8px; // 按钮横向间距
61
+ row-gap: 8px; // 换行后两行纵向间距
62
+ max-width: 55%; // 限制最大宽度,避免挤压左侧标题
63
+
64
+ // 适配antd/yoka-ui按钮、标签等组件
65
+ :global(.ant-btn, .yoka-btn) {
66
+ flex-shrink: 0;
67
+ }
68
+ }
69
+
70
+ // 页面内容区
71
+ .contentWrap {
72
+ width: 100%;
73
+ }
Binary file
@@ -206,24 +206,26 @@ var AiChat = ({
206
206
  file,
207
207
  type: fileType
208
208
  });
209
- const uploadedFile = {
210
- uid: file.name,
211
- name: result.name || file.name,
212
- status: "done",
213
- url: result.url
214
- };
215
- setFileList([...fileList, uploadedFile]);
209
+ setFileList((prev) => [
210
+ ...prev,
211
+ {
212
+ uid: file.name,
213
+ name: result.name || file.name,
214
+ status: "done",
215
+ url: result.url
216
+ }
217
+ ]);
216
218
  import_antd.message.success(`${fileType === "image" ? "图片" : "文件"}上传成功`);
217
219
  } else {
218
- setFileList([...fileList, uploadFile]);
220
+ setFileList((prev) => [...prev, uploadFile]);
219
221
  }
220
222
  } catch (err) {
221
223
  console.error("文件上传失败:", err);
222
224
  import_antd.message.error("文件上传失败");
223
- setFileList(fileList.filter((f) => f.uid !== file.name));
225
+ setFileList((prev) => prev.filter((f) => f.uid !== file.name));
224
226
  }
225
227
  },
226
- [fileList, activeSession, onUploadFile]
228
+ [activeSession, onUploadFile]
227
229
  );
228
230
  const handleSend = (0, import_react.useCallback)(async () => {
229
231
  if (!inputValue.trim() && fileList.length === 0) {
@@ -573,10 +575,10 @@ var AiChat = ({
573
575
  gap: 4
574
576
  }
575
577
  },
576
- suggestions.slice(0, 3).map((suggestion, index) => /* @__PURE__ */ import_react.default.createElement(
578
+ suggestions.slice(0, 3).map((suggestion) => /* @__PURE__ */ import_react.default.createElement(
577
579
  import_antd.Button,
578
580
  {
579
- key: index,
581
+ key: suggestion,
580
582
  size: "small",
581
583
  type: "dashed",
582
584
  onClick: () => setInputValue(suggestion),
@@ -607,7 +609,7 @@ var AiChat = ({
607
609
  cursor: "pointer",
608
610
  fontSize: 10
609
611
  },
610
- onClick: () => setFileList(fileList.filter((f) => f.uid !== file.uid))
612
+ onClick: () => setFileList((prev) => prev.filter((f) => f.uid !== file.uid))
611
613
  }
612
614
  )
613
615
  ))),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/AiChat/index.tsx"],
4
- "sourcesContent": ["import {\n CloseOutlined,\n CompressOutlined,\n CopyOutlined,\n DeleteOutlined,\n ExpandOutlined,\n FileImageOutlined,\n MenuOutlined,\n MessageOutlined,\n PaperClipOutlined,\n PlusOutlined,\n ReloadOutlined,\n SendOutlined,\n StopOutlined,\n} from '@ant-design/icons';\nimport type { UploadFile } from 'antd';\nimport { Button, Input, List, message, Popconfirm, Space, Tooltip, Typography, Upload } from 'antd';\nimport type { CSSProperties, FC, ReactNode } from 'react';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport AiChatLogo from './aichat-logo.svg';\nimport styles from './index.module.less';\nimport { generateSuggestions, isTaskCreationIntent, recognizeIntent } from './intentRecognizer';\nimport MarkdownRender from './MarkdownRender';\nimport type { AiChatConfig, ChatSession, EnhancedAiChatConfig, Message } from './type';\nimport { useAiChat } from './useAiChat';\nimport { useTaskWorkflow } from './useTaskWorkflow';\n\nconst { TextArea } = Input;\nconst { Title } = Typography;\n\n// 合并Props类型\nexport interface AiChatProps extends AiChatConfig, Partial<EnhancedAiChatConfig> {\n className?: string;\n style?: CSSProperties;\n renderTrigger?: ReactNode;\n renderHeader?: ReactNode;\n renderFooter?: ReactNode;\n}\n\nconst AiChat: FC<AiChatProps> = ({\n apiPath = '/api/ai/chat-stream',\n storageKey = 'ai_chat_sessions',\n position: initialPosition = { bottom: 24, right: 24 },\n buttonSize = 56,\n zIndex = 1080,\n showSessionPanel = true,\n onBeforeSend,\n onError,\n onSuccess,\n onFetchSessions,\n onFetchSessionDetail,\n onCreateSession,\n onSendMessage,\n onUploadFile,\n className,\n style,\n renderTrigger,\n renderHeader,\n renderFooter,\n // 增强配置\n taskWorkflow,\n intentRecognition: intentConfig,\n navigation: navConfig,\n}) => {\n const {\n sessions,\n activeSession,\n loading,\n visible,\n createNewSession,\n switchSession,\n deleteSession,\n sendQuestion,\n regenerateAnswer,\n deleteSingleMsg,\n cancelRequest,\n toggleVisible,\n } = useAiChat({\n apiPath,\n storageKey,\n onBeforeSend,\n onError,\n onSuccess,\n onFetchSessions,\n onFetchSessionDetail,\n onCreateSession,\n onSendMessage,\n onUploadFile,\n });\n\n // 任务工作流\n const { updateUrlWithTaskId, executeTaskCreationWorkflow } = useTaskWorkflow({\n enabled: taskWorkflow?.enabled,\n createTaskApi: taskWorkflow?.createTaskApi,\n supportedTaskTypes: taskWorkflow?.supportedTaskTypes,\n autoNavigate: taskWorkflow?.autoNavigate,\n refreshDelay: navConfig?.refreshDelay,\n taskIdParamName: taskWorkflow?.taskIdParamName,\n taskTypeParamName: taskWorkflow?.taskTypeParamName,\n onTaskCreated: (taskId) => {\n // 添加系统消息到会话\n if (activeSession) {\n // 这里可以添加到消息列表的逻辑\n }\n },\n onError,\n });\n\n const [inputValue, setInputValue] = useState('');\n const [showSessions, setShowSessions] = useState(false);\n const [suggestions, setSuggestions] = useState<string[]>([]);\n const [fileList, setFileList] = useState<UploadFile<any>[]>([]);\n const [isMaximized, setIsMaximized] = useState(false);\n const [dialogPosition, setDialogPosition] = useState({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const dragOffset = useRef({ x: 0, y: 0 });\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [activeSession?.messages]);\n\n // 拖拽处理 - 拖拽整个组件位置\n const handleTriggerMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (visible) return; // 对话框展开时不处理\n const target = e.target as HTMLElement;\n if (target.closest('.ant-upload, .ant-btn')) return; // 排除按钮和上传元素\n\n e.preventDefault();\n const triggerEl = triggerRef.current;\n if (!triggerEl) return;\n\n const rect = triggerEl.getBoundingClientRect();\n dragOffset.current = {\n x: e.clientX - rect.left,\n y: e.clientY - rect.top,\n };\n setIsDragging(true);\n },\n [visible],\n );\n\n const handleTriggerMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isDragging || visible) return;\n setDialogPosition({\n x: e.clientX - dragOffset.current.x,\n y: e.clientY - dragOffset.current.y,\n });\n },\n [isDragging, visible],\n );\n\n const handleTriggerMouseUp = useCallback(() => {\n setIsDragging(false);\n }, []);\n\n useEffect(() => {\n if (isDragging && !visible) {\n document.addEventListener('mousemove', handleTriggerMouseMove);\n document.addEventListener('mouseup', handleTriggerMouseUp);\n return () => {\n document.removeEventListener('mousemove', handleTriggerMouseMove);\n document.removeEventListener('mouseup', handleTriggerMouseUp);\n };\n }\n return undefined;\n }, [isDragging, visible, handleTriggerMouseMove, handleTriggerMouseUp]);\n\n // 实时分析输入内容生成建议\n const handleInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const value = e.target.value;\n setInputValue(value);\n\n if (value.length > 3) {\n const intent = recognizeIntent(value);\n const newSuggestions = generateSuggestions(value, intent);\n setSuggestions(newSuggestions);\n } else {\n setSuggestions([]);\n }\n }, []);\n\n // 文件上传处理\n const handleFileChange = useCallback(\n async (info: { fileList: UploadFile<any>[]; file?: UploadFile<any> }) => {\n const uploadFile = info.file;\n if (!uploadFile || !uploadFile.originFileObj) {\n setFileList(info.fileList);\n return;\n }\n\n const file = uploadFile.originFileObj as File;\n const isImage = file.type.startsWith('image/');\n const fileType: 'image' | 'document' = isImage ? 'image' : 'document';\n\n try {\n // 调用 onUploadFile 回调\n if (onUploadFile && activeSession) {\n const result = await onUploadFile({\n sessionId: activeSession.id,\n file: file as any,\n type: fileType,\n });\n\n // 将上传结果添加到文件列表\n const uploadedFile: UploadFile = {\n uid: file.name,\n name: result.name || file.name,\n status: 'done',\n url: result.url,\n };\n setFileList([...fileList, uploadedFile]);\n message.success(`${fileType === 'image' ? '图片' : '文件'}上传成功`);\n } else {\n // 没有回调时,仅本地记录\n setFileList([...fileList, uploadFile]);\n }\n } catch (err) {\n console.error('文件上传失败:', err);\n message.error('文件上传失败');\n setFileList(fileList.filter((f) => f.uid !== file.name));\n }\n },\n [fileList, activeSession, onUploadFile],\n );\n\n // 判断是否为任务创建意图并执行工作流\n const handleSend = useCallback(async () => {\n if (!inputValue.trim() && fileList.length === 0) {\n message.warning('请输入问题或上传文件');\n return;\n }\n\n let content = inputValue.trim();\n\n // 如果有文件,附加文件信息\n if (fileList.length > 0) {\n const fileInfo = fileList.map((f) => f.name).join(', ');\n content += `\\n[附件: ${fileInfo}]`;\n }\n\n setInputValue('');\n setSuggestions([]);\n setFileList([]);\n\n // 检查是否为任务创建意图\n const intentEnabled = intentConfig?.enabled !== false;\n if (intentEnabled && isTaskCreationIntent(content)) {\n // 执行任务创建工作流\n await executeTaskCreationWorkflow(content);\n return;\n }\n\n // 普通问答\n sendQuestion(content);\n }, [inputValue, fileList, intentConfig?.enabled, executeTaskCreationWorkflow, sendQuestion]);\n\n const copyMsg = (c: string) => {\n navigator.clipboard.writeText(c);\n message.success('复制成功');\n };\n\n const toggleMaximize = useCallback(() => {\n setIsMaximized((prev) => !prev);\n }, []);\n\n const renderMsg = (item: Message) => (\n <List.Item\n key={item.id}\n style={{\n justifyContent: item.role === 'user' ? 'flex-end' : 'flex-start',\n marginBottom: 12,\n padding: '4px 0',\n }}\n >\n <div\n style={{\n maxWidth: '85%',\n padding: '10px 14px',\n borderRadius: 12,\n backgroundColor: item.role === 'user' ? '#1677ff' : item.role === 'system' ? '#f6ffed' : '#fafafa',\n color: item.role === 'user' ? '#fff' : '#333',\n border: item.role === 'ai' ? '1px solid #f0f0f0' : item.role === 'system' ? '1px solid #b7eb8f' : 'none',\n boxShadow:\n item.role === 'user'\n ? '0 2px 8px rgba(22, 119, 255, 0.3)'\n : item.role === 'system'\n ? '0 1px 4px rgba(82, 196, 26, 0.1)'\n : '0 1px 4px rgba(0,0,0,0.05)',\n }}\n >\n {item.role === 'user' ? (\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}>\n <span>{item.content}</span>\n <CopyOutlined\n onClick={() => copyMsg(item.content)}\n style={{\n fontSize: 12,\n color: 'rgba(255,255,255,0.7)',\n cursor: 'pointer',\n flexShrink: 0,\n }}\n />\n </div>\n ) : item.role === 'system' ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 13,\n }}\n >\n <span style={{ color: '#52c41a' }}>✓</span>\n <span>{item.content}</span>\n {item.taskId && (\n <Button\n type='link'\n size='small'\n style={{ padding: 0, fontSize: 12 }}\n onClick={() => updateUrlWithTaskId(item.taskId!)}\n >\n 查看任务\n </Button>\n )}\n </div>\n ) : (\n <>\n <div style={{ minHeight: 20 }}>\n <MarkdownRender content={item.content} msgId={item.id} isAi={true} onDelete={deleteSingleMsg} />\n </div>\n {item.loading && <span style={{ color: '#1677ff', fontSize: 12 }}> 思考中...</span>}\n {!item.loading && (\n <Space size={8} style={{ fontSize: 12, marginTop: 6, display: 'flex' }}>\n <Tooltip title='复制'>\n <CopyOutlined onClick={() => copyMsg(item.content)} style={{ cursor: 'pointer', color: '#999' }} />\n </Tooltip>\n <Tooltip title='重新生成'>\n <ReloadOutlined onClick={() => regenerateAnswer(item)} style={{ cursor: 'pointer', color: '#999' }} />\n </Tooltip>\n </Space>\n )}\n </>\n )}\n </div>\n </List.Item>\n );\n\n const renderSession = (s: ChatSession) => (\n <List.Item\n key={s.id}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest('.ant-popover, .ant-popconfirm')) {\n return;\n }\n switchSession(s.id);\n }}\n style={{\n padding: '10px 12px',\n borderRadius: 8,\n cursor: 'pointer',\n backgroundColor: activeSession?.id === s.id ? '#e6f7ff' : '#fff',\n transition: 'all 0.2s',\n marginBottom: 8,\n }}\n >\n <div\n style={{\n flex: 1,\n overflow: 'hidden',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <div style={{ flex: 1, overflow: 'hidden' }}>\n <div\n style={{\n fontSize: 14,\n fontWeight: 500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {s.title}\n </div>\n <div style={{ fontSize: 12, color: '#999', marginTop: 2 }}>\n {new Date(s.createTime).toLocaleString().slice(0, 16)}\n </div>\n </div>\n <Popconfirm\n title='确定删除?'\n onConfirm={(e: any) => {\n deleteSession(s.id, e as React.MouseEvent);\n }}\n >\n <DeleteOutlined\n style={{ color: '#ff4d4f', cursor: 'pointer', marginLeft: 8 }}\n onClick={(e) => e.stopPropagation()}\n />\n </Popconfirm>\n </div>\n </List.Item>\n );\n\n // 计算对话框位置和大小\n const getDialogStyle = (): CSSProperties => {\n if (isMaximized) {\n return {\n position: 'fixed',\n top: 0,\n left: 0,\n width: '100vw',\n height: '100vh',\n borderRadius: 0,\n };\n }\n\n const baseStyle: CSSProperties = {\n position: 'relative',\n width: showSessions ? 960 : 720,\n height: 680,\n borderRadius: 12,\n };\n\n if (dialogPosition.x !== 0 || dialogPosition.y !== 0) {\n return {\n ...baseStyle,\n transform: `translate(${dialogPosition.x}px, ${dialogPosition.y}px)`,\n };\n }\n\n return baseStyle;\n };\n\n return (\n <div\n className={className}\n style={{\n position: 'fixed',\n bottom: initialPosition.bottom,\n right: initialPosition.right,\n zIndex,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n transform:\n dialogPosition.x !== 0 || dialogPosition.y !== 0\n ? `translate(${dialogPosition.x}px, ${dialogPosition.y}px)`\n : undefined,\n ...style,\n }}\n >\n {!visible ? (\n renderTrigger ? (\n <div\n ref={triggerRef}\n onMouseDown={handleTriggerMouseDown}\n onClick={() => !isDragging && toggleVisible(true)}\n style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n >\n {renderTrigger}\n </div>\n ) : (\n <div\n ref={triggerRef}\n onMouseDown={handleTriggerMouseDown}\n onClick={() => !isDragging && toggleVisible(true)}\n style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n >\n {/* <Button\n type='primary'\n shape='circle'\n size='large'\n icon={ <img src={AiChatLogo} width={buttonSize} height={buttonSize} />}\n style={{\n width: buttonSize,\n height: buttonSize,\n boxShadow: '0 4px 16px rgba(22, 119, 255, 0.4)',\n }}\n /> */}\n <div className={styles['ai-chat-btn']}>\n <img src={AiChatLogo} width={28} height={28} />\n </div>\n </div>\n )\n ) : (\n <div\n style={{\n ...getDialogStyle(),\n background: '#fff',\n boxShadow: '0 4px 20px rgba(0,0,0,0.15)',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'row',\n marginBottom: isMaximized ? 0 : 12,\n transition: 'all 0.3s ease',\n }}\n >\n {/* 历史会话面板 - 左侧 */}\n {showSessionPanel && showSessions && (\n <div\n style={{\n width: 280,\n borderRight: '1px solid #f0f0f0',\n background: '#fafafa',\n display: 'flex',\n flexDirection: 'column',\n flexShrink: 0,\n }}\n >\n <div\n style={{\n padding: '12px 16px',\n borderBottom: '1px solid #f0f0f0',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <Title level={5} style={{ margin: 0, fontSize: 16 }}>\n 历史会话\n </Title>\n <Button type='text' size='small' icon={<CloseOutlined />} onClick={() => setShowSessions(false)} />\n </div>\n <div style={{ flex: 1, padding: 16, overflowY: 'auto' }}>\n <Button\n type='primary'\n block\n icon={<PlusOutlined />}\n onClick={createNewSession}\n style={{ marginBottom: 12 }}\n >\n 新建会话\n </Button>\n <List dataSource={sessions} renderItem={renderSession} locale={{ emptyText: '暂无会话' }} />\n </div>\n </div>\n )}\n\n {/* 主对话区域 */}\n <div\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n }}\n >\n {renderHeader || (\n <div\n className='ai-chat-header'\n style={{\n padding: '12px 16px',\n background: '#fafafa',\n borderBottom: '1px solid #f0f0f0',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexShrink: 0,\n }}\n >\n <Space>\n {showSessionPanel && (\n <Button\n type={showSessions ? 'primary' : 'text'}\n icon={<MenuOutlined />}\n size='small'\n onClick={() => setShowSessions(!showSessions)}\n >\n {showSessions ? '收起' : '会话'}\n </Button>\n )}\n <Button type='text' icon={<PlusOutlined />} onClick={createNewSession} size='small'>\n 新会话\n </Button>\n </Space>\n <Space>\n <Tooltip title={isMaximized ? '还原' : '最大化'}>\n <Button\n type='text'\n icon={isMaximized ? <CompressOutlined /> : <ExpandOutlined />}\n onClick={toggleMaximize}\n size='small'\n />\n </Tooltip>\n <Tooltip title='关闭'>\n <Button type='text' icon={<CloseOutlined />} onClick={() => toggleVisible(false)} size='small' />\n </Tooltip>\n </Space>\n </div>\n )}\n\n <div\n style={{\n flex: 1,\n padding: 16,\n overflowY: 'auto',\n }}\n >\n {!activeSession || activeSession.messages.length === 0 ? (\n <div\n style={{\n textAlign: 'center',\n padding: '60px 0',\n color: '#999',\n }}\n >\n <MessageOutlined style={{ fontSize: 48, color: '#d9d9d9' }} />\n <div style={{ marginTop: 16, fontSize: 16 }}>开始你的 AI 对话</div>\n <div style={{ marginTop: 8, fontSize: 13, color: '#bfbfbf' }}>我可以帮你解答问题、创建任务</div>\n <Button type='primary' onClick={createNewSession} style={{ marginTop: 20 }}>\n 新建会话\n </Button>\n </div>\n ) : (\n <List dataSource={activeSession.messages} renderItem={renderMsg} />\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {renderFooter || (\n <div\n style={{\n padding: 12,\n borderTop: '1px solid #f0f0f0',\n background: '#fafafa',\n flexShrink: 0,\n }}\n >\n {/* 智能建议 */}\n {suggestions.length > 0 && (\n <div\n style={{\n marginBottom: 8,\n display: 'flex',\n flexWrap: 'wrap',\n gap: 4,\n }}\n >\n {suggestions.slice(0, 3).map((suggestion, index) => (\n <Button\n key={index}\n size='small'\n type='dashed'\n onClick={() => setInputValue(suggestion)}\n style={{ fontSize: 12 }}\n >\n {suggestion}\n </Button>\n ))}\n </div>\n )}\n\n {/* 文件预览 */}\n {fileList.length > 0 && (\n <div style={{ marginBottom: 8 }}>\n {fileList.map((file) => (\n <div\n key={file.uid}\n style={{\n display: 'inline-block',\n padding: '4px 8px',\n background: '#e6f7ff',\n borderRadius: 4,\n marginRight: 8,\n fontSize: 12,\n }}\n >\n {file.name}\n <CloseOutlined\n style={{\n marginLeft: 8,\n cursor: 'pointer',\n fontSize: 10,\n }}\n onClick={() => setFileList(fileList.filter((f) => f.uid !== file.uid))}\n />\n </div>\n ))}\n </div>\n )}\n\n <div style={{ position: 'relative' }}>\n <TextArea\n value={inputValue}\n onChange={handleInputChange}\n placeholder='输入问题或任务描述,如:帮我创建一个paimon调用任务'\n autoSize={{ minRows: 2, maxRows: 4 }}\n onPressEnter={(e) => {\n if (!e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n }}\n style={{\n marginBottom: 8,\n borderRadius: 8,\n paddingRight: 80,\n }}\n disabled={loading}\n />\n {/* 上传文件和图片按钮 */}\n <div\n style={{\n position: 'absolute',\n right: 12,\n bottom: 16,\n display: 'flex',\n gap: 8,\n }}\n >\n <Upload\n fileList={fileList}\n onChange={handleFileChange}\n beforeUpload={() => false}\n showUploadList={false}\n accept='image/*'\n >\n <Tooltip title='上传图片'>\n <Button type='text' size='small' icon={<FileImageOutlined />} />\n </Tooltip>\n </Upload>\n <Upload\n fileList={fileList}\n onChange={handleFileChange}\n beforeUpload={() => false}\n showUploadList={false}\n >\n <Tooltip title='上传文件'>\n <Button type='text' size='small' icon={<PaperClipOutlined />} />\n </Tooltip>\n </Upload>\n </div>\n </div>\n <div style={{ display: 'flex', justifyContent: 'flex-end' }}>\n <Space>\n {loading && (\n <Button danger icon={<StopOutlined />} onClick={cancelRequest} size='small'>\n 终止\n </Button>\n )}\n <Button\n type='primary'\n icon={<SendOutlined />}\n onClick={handleSend}\n loading={loading}\n disabled={!inputValue.trim() && fileList.length === 0}\n size='small'\n >\n 发送\n </Button>\n </Space>\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default AiChat;\nexport { generateSuggestions, isTaskCreationIntent, parseTaskDescription, recognizeIntent } from './intentRecognizer';\nexport { delay, NavigationManager } from './navigationManager';\nexport type {\n AiChatConfig,\n ChatSession,\n EnhancedAiChatConfig,\n Intent,\n IntentType,\n Message,\n NavigationOptions,\n Task,\n TaskCategory,\n TaskCreationResult,\n TaskPriority,\n TaskStatus,\n UseAiChatOptions,\n UseAiChatReturn,\n} from './type';\nexport { useAiChat } from './useAiChat';\nexport { useTaskWorkflow } from './useTaskWorkflow';\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n CloseOutlined,\n CompressOutlined,\n CopyOutlined,\n DeleteOutlined,\n ExpandOutlined,\n FileImageOutlined,\n MenuOutlined,\n MessageOutlined,\n PaperClipOutlined,\n PlusOutlined,\n ReloadOutlined,\n SendOutlined,\n StopOutlined,\n} from '@ant-design/icons';\nimport type { UploadFile } from 'antd';\nimport { Button, Input, List, message, Popconfirm, Space, Tooltip, Typography, Upload } from 'antd';\nimport type { CSSProperties, FC, ReactNode } from 'react';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport AiChatLogo from './aichat-logo.svg';\nimport styles from './index.module.less';\nimport { generateSuggestions, isTaskCreationIntent, recognizeIntent } from './intentRecognizer';\nimport MarkdownRender from './MarkdownRender';\nimport type { AiChatConfig, ChatSession, EnhancedAiChatConfig, Message } from './type';\nimport { useAiChat } from './useAiChat';\nimport { useTaskWorkflow } from './useTaskWorkflow';\n\nconst { TextArea } = Input;\nconst { Title } = Typography;\n\n// 合并Props类型\nexport interface AiChatProps extends AiChatConfig, Partial<EnhancedAiChatConfig> {\n className?: string;\n style?: CSSProperties;\n renderTrigger?: ReactNode;\n renderHeader?: ReactNode;\n renderFooter?: ReactNode;\n}\n\nconst AiChat: FC<AiChatProps> = ({\n apiPath = '/api/ai/chat-stream',\n storageKey = 'ai_chat_sessions',\n position: initialPosition = { bottom: 24, right: 24 },\n buttonSize = 56,\n zIndex = 1080,\n showSessionPanel = true,\n onBeforeSend,\n onError,\n onSuccess,\n onFetchSessions,\n onFetchSessionDetail,\n onCreateSession,\n onSendMessage,\n onUploadFile,\n className,\n style,\n renderTrigger,\n renderHeader,\n renderFooter,\n // 增强配置\n taskWorkflow,\n intentRecognition: intentConfig,\n navigation: navConfig,\n}) => {\n const {\n sessions,\n activeSession,\n loading,\n visible,\n createNewSession,\n switchSession,\n deleteSession,\n sendQuestion,\n regenerateAnswer,\n deleteSingleMsg,\n cancelRequest,\n toggleVisible,\n } = useAiChat({\n apiPath,\n storageKey,\n onBeforeSend,\n onError,\n onSuccess,\n onFetchSessions,\n onFetchSessionDetail,\n onCreateSession,\n onSendMessage,\n onUploadFile,\n });\n\n // 任务工作流\n const { updateUrlWithTaskId, executeTaskCreationWorkflow } = useTaskWorkflow({\n enabled: taskWorkflow?.enabled,\n createTaskApi: taskWorkflow?.createTaskApi,\n supportedTaskTypes: taskWorkflow?.supportedTaskTypes,\n autoNavigate: taskWorkflow?.autoNavigate,\n refreshDelay: navConfig?.refreshDelay,\n taskIdParamName: taskWorkflow?.taskIdParamName,\n taskTypeParamName: taskWorkflow?.taskTypeParamName,\n onTaskCreated: (taskId) => {\n // 添加系统消息到会话\n if (activeSession) {\n // 这里可以添加到消息列表的逻辑\n }\n },\n onError,\n });\n\n const [inputValue, setInputValue] = useState('');\n const [showSessions, setShowSessions] = useState(false);\n const [suggestions, setSuggestions] = useState<string[]>([]);\n const [fileList, setFileList] = useState<UploadFile<any>[]>([]);\n const [isMaximized, setIsMaximized] = useState(false);\n const [dialogPosition, setDialogPosition] = useState({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = useState(false);\n const dragOffset = useRef({ x: 0, y: 0 });\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [activeSession?.messages]);\n\n // 拖拽处理 - 拖拽整个组件位置\n const handleTriggerMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (visible) return; // 对话框展开时不处理\n const target = e.target as HTMLElement;\n if (target.closest('.ant-upload, .ant-btn')) return; // 排除按钮和上传元素\n\n e.preventDefault();\n const triggerEl = triggerRef.current;\n if (!triggerEl) return;\n\n const rect = triggerEl.getBoundingClientRect();\n dragOffset.current = {\n x: e.clientX - rect.left,\n y: e.clientY - rect.top,\n };\n setIsDragging(true);\n },\n [visible],\n );\n\n const handleTriggerMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isDragging || visible) return;\n setDialogPosition({\n x: e.clientX - dragOffset.current.x,\n y: e.clientY - dragOffset.current.y,\n });\n },\n [isDragging, visible],\n );\n\n const handleTriggerMouseUp = useCallback(() => {\n setIsDragging(false);\n }, []);\n\n useEffect(() => {\n if (isDragging && !visible) {\n document.addEventListener('mousemove', handleTriggerMouseMove);\n document.addEventListener('mouseup', handleTriggerMouseUp);\n return () => {\n document.removeEventListener('mousemove', handleTriggerMouseMove);\n document.removeEventListener('mouseup', handleTriggerMouseUp);\n };\n }\n return undefined;\n }, [isDragging, visible, handleTriggerMouseMove, handleTriggerMouseUp]);\n\n // 实时分析输入内容生成建议\n const handleInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const value = e.target.value;\n setInputValue(value);\n\n if (value.length > 3) {\n const intent = recognizeIntent(value);\n const newSuggestions = generateSuggestions(value, intent);\n setSuggestions(newSuggestions);\n } else {\n setSuggestions([]);\n }\n }, []);\n\n // 文件上传处理\n const handleFileChange = useCallback(\n async (info: { fileList: UploadFile<any>[]; file?: UploadFile<any> }) => {\n const uploadFile = info.file;\n if (!uploadFile || !uploadFile.originFileObj) {\n setFileList(info.fileList);\n return;\n }\n\n const file = uploadFile.originFileObj as File;\n const isImage = file.type.startsWith('image/');\n const fileType: 'image' | 'document' = isImage ? 'image' : 'document';\n\n try {\n // 调用 onUploadFile 回调\n if (onUploadFile && activeSession) {\n const result = await onUploadFile({\n sessionId: activeSession.id,\n file: file as any,\n type: fileType,\n });\n\n // 将上传结果添加到文件列表(使用函数式更新避免并发竞态)\n setFileList((prev) => [\n ...prev,\n {\n uid: file.name,\n name: result.name || file.name,\n status: 'done',\n url: result.url,\n } as UploadFile,\n ]);\n message.success(`${fileType === 'image' ? '图片' : '文件'}上传成功`);\n } else {\n // 没有回调时,仅本地记录(使用函数式更新)\n setFileList((prev) => [...prev, uploadFile]);\n }\n } catch (err) {\n console.error('文件上传失败:', err);\n message.error('文件上传失败');\n setFileList((prev) => prev.filter((f) => f.uid !== file.name));\n }\n },\n [activeSession, onUploadFile],\n );\n\n // 判断是否为任务创建意图并执行工作流\n const handleSend = useCallback(async () => {\n if (!inputValue.trim() && fileList.length === 0) {\n message.warning('请输入问题或上传文件');\n return;\n }\n\n let content = inputValue.trim();\n\n // 如果有文件,附加文件信息\n if (fileList.length > 0) {\n const fileInfo = fileList.map((f) => f.name).join(', ');\n content += `\\n[附件: ${fileInfo}]`;\n }\n\n setInputValue('');\n setSuggestions([]);\n setFileList([]);\n\n // 检查是否为任务创建意图\n const intentEnabled = intentConfig?.enabled !== false;\n if (intentEnabled && isTaskCreationIntent(content)) {\n // 执行任务创建工作流\n await executeTaskCreationWorkflow(content);\n return;\n }\n\n // 普通问答\n sendQuestion(content);\n }, [inputValue, fileList, intentConfig?.enabled, executeTaskCreationWorkflow, sendQuestion]);\n\n const copyMsg = (c: string) => {\n navigator.clipboard.writeText(c);\n message.success('复制成功');\n };\n\n const toggleMaximize = useCallback(() => {\n setIsMaximized((prev) => !prev);\n }, []);\n\n const renderMsg = (item: Message) => (\n <List.Item\n key={item.id}\n style={{\n justifyContent: item.role === 'user' ? 'flex-end' : 'flex-start',\n marginBottom: 12,\n padding: '4px 0',\n }}\n >\n <div\n style={{\n maxWidth: '85%',\n padding: '10px 14px',\n borderRadius: 12,\n backgroundColor: item.role === 'user' ? '#1677ff' : item.role === 'system' ? '#f6ffed' : '#fafafa',\n color: item.role === 'user' ? '#fff' : '#333',\n border: item.role === 'ai' ? '1px solid #f0f0f0' : item.role === 'system' ? '1px solid #b7eb8f' : 'none',\n boxShadow:\n item.role === 'user'\n ? '0 2px 8px rgba(22, 119, 255, 0.3)'\n : item.role === 'system'\n ? '0 1px 4px rgba(82, 196, 26, 0.1)'\n : '0 1px 4px rgba(0,0,0,0.05)',\n }}\n >\n {item.role === 'user' ? (\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}>\n <span>{item.content}</span>\n <CopyOutlined\n onClick={() => copyMsg(item.content)}\n style={{\n fontSize: 12,\n color: 'rgba(255,255,255,0.7)',\n cursor: 'pointer',\n flexShrink: 0,\n }}\n />\n </div>\n ) : item.role === 'system' ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n fontSize: 13,\n }}\n >\n <span style={{ color: '#52c41a' }}>✓</span>\n <span>{item.content}</span>\n {item.taskId && (\n <Button\n type='link'\n size='small'\n style={{ padding: 0, fontSize: 12 }}\n onClick={() => updateUrlWithTaskId(item.taskId!)}\n >\n 查看任务\n </Button>\n )}\n </div>\n ) : (\n <>\n <div style={{ minHeight: 20 }}>\n <MarkdownRender content={item.content} msgId={item.id} isAi={true} onDelete={deleteSingleMsg} />\n </div>\n {item.loading && <span style={{ color: '#1677ff', fontSize: 12 }}> 思考中...</span>}\n {!item.loading && (\n <Space size={8} style={{ fontSize: 12, marginTop: 6, display: 'flex' }}>\n <Tooltip title='复制'>\n <CopyOutlined onClick={() => copyMsg(item.content)} style={{ cursor: 'pointer', color: '#999' }} />\n </Tooltip>\n <Tooltip title='重新生成'>\n <ReloadOutlined onClick={() => regenerateAnswer(item)} style={{ cursor: 'pointer', color: '#999' }} />\n </Tooltip>\n </Space>\n )}\n </>\n )}\n </div>\n </List.Item>\n );\n\n const renderSession = (s: ChatSession) => (\n <List.Item\n key={s.id}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest('.ant-popover, .ant-popconfirm')) {\n return;\n }\n switchSession(s.id);\n }}\n style={{\n padding: '10px 12px',\n borderRadius: 8,\n cursor: 'pointer',\n backgroundColor: activeSession?.id === s.id ? '#e6f7ff' : '#fff',\n transition: 'all 0.2s',\n marginBottom: 8,\n }}\n >\n <div\n style={{\n flex: 1,\n overflow: 'hidden',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <div style={{ flex: 1, overflow: 'hidden' }}>\n <div\n style={{\n fontSize: 14,\n fontWeight: 500,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {s.title}\n </div>\n <div style={{ fontSize: 12, color: '#999', marginTop: 2 }}>\n {new Date(s.createTime).toLocaleString().slice(0, 16)}\n </div>\n </div>\n <Popconfirm\n title='确定删除?'\n onConfirm={(e: any) => {\n deleteSession(s.id, e as React.MouseEvent);\n }}\n >\n <DeleteOutlined\n style={{ color: '#ff4d4f', cursor: 'pointer', marginLeft: 8 }}\n onClick={(e) => e.stopPropagation()}\n />\n </Popconfirm>\n </div>\n </List.Item>\n );\n\n // 计算对话框位置和大小\n const getDialogStyle = (): CSSProperties => {\n if (isMaximized) {\n return {\n position: 'fixed',\n top: 0,\n left: 0,\n width: '100vw',\n height: '100vh',\n borderRadius: 0,\n };\n }\n\n const baseStyle: CSSProperties = {\n position: 'relative',\n width: showSessions ? 960 : 720,\n height: 680,\n borderRadius: 12,\n };\n\n if (dialogPosition.x !== 0 || dialogPosition.y !== 0) {\n return {\n ...baseStyle,\n transform: `translate(${dialogPosition.x}px, ${dialogPosition.y}px)`,\n };\n }\n\n return baseStyle;\n };\n\n return (\n <div\n className={className}\n style={{\n position: 'fixed',\n bottom: initialPosition.bottom,\n right: initialPosition.right,\n zIndex,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-end',\n transform:\n dialogPosition.x !== 0 || dialogPosition.y !== 0\n ? `translate(${dialogPosition.x}px, ${dialogPosition.y}px)`\n : undefined,\n ...style,\n }}\n >\n {!visible ? (\n renderTrigger ? (\n <div\n ref={triggerRef}\n onMouseDown={handleTriggerMouseDown}\n onClick={() => !isDragging && toggleVisible(true)}\n style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n >\n {renderTrigger}\n </div>\n ) : (\n <div\n ref={triggerRef}\n onMouseDown={handleTriggerMouseDown}\n onClick={() => !isDragging && toggleVisible(true)}\n style={{ cursor: isDragging ? 'grabbing' : 'grab' }}\n >\n {/* <Button\n type='primary'\n shape='circle'\n size='large'\n icon={ <img src={AiChatLogo} width={buttonSize} height={buttonSize} />}\n style={{\n width: buttonSize,\n height: buttonSize,\n boxShadow: '0 4px 16px rgba(22, 119, 255, 0.4)',\n }}\n /> */}\n <div className={styles['ai-chat-btn']}>\n <img src={AiChatLogo} width={28} height={28} />\n </div>\n </div>\n )\n ) : (\n <div\n style={{\n ...getDialogStyle(),\n background: '#fff',\n boxShadow: '0 4px 20px rgba(0,0,0,0.15)',\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'row',\n marginBottom: isMaximized ? 0 : 12,\n transition: 'all 0.3s ease',\n }}\n >\n {/* 历史会话面板 - 左侧 */}\n {showSessionPanel && showSessions && (\n <div\n style={{\n width: 280,\n borderRight: '1px solid #f0f0f0',\n background: '#fafafa',\n display: 'flex',\n flexDirection: 'column',\n flexShrink: 0,\n }}\n >\n <div\n style={{\n padding: '12px 16px',\n borderBottom: '1px solid #f0f0f0',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <Title level={5} style={{ margin: 0, fontSize: 16 }}>\n 历史会话\n </Title>\n <Button type='text' size='small' icon={<CloseOutlined />} onClick={() => setShowSessions(false)} />\n </div>\n <div style={{ flex: 1, padding: 16, overflowY: 'auto' }}>\n <Button\n type='primary'\n block\n icon={<PlusOutlined />}\n onClick={createNewSession}\n style={{ marginBottom: 12 }}\n >\n 新建会话\n </Button>\n <List dataSource={sessions} renderItem={renderSession} locale={{ emptyText: '暂无会话' }} />\n </div>\n </div>\n )}\n\n {/* 主对话区域 */}\n <div\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n }}\n >\n {renderHeader || (\n <div\n className='ai-chat-header'\n style={{\n padding: '12px 16px',\n background: '#fafafa',\n borderBottom: '1px solid #f0f0f0',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexShrink: 0,\n }}\n >\n <Space>\n {showSessionPanel && (\n <Button\n type={showSessions ? 'primary' : 'text'}\n icon={<MenuOutlined />}\n size='small'\n onClick={() => setShowSessions(!showSessions)}\n >\n {showSessions ? '收起' : '会话'}\n </Button>\n )}\n <Button type='text' icon={<PlusOutlined />} onClick={createNewSession} size='small'>\n 新会话\n </Button>\n </Space>\n <Space>\n <Tooltip title={isMaximized ? '还原' : '最大化'}>\n <Button\n type='text'\n icon={isMaximized ? <CompressOutlined /> : <ExpandOutlined />}\n onClick={toggleMaximize}\n size='small'\n />\n </Tooltip>\n <Tooltip title='关闭'>\n <Button type='text' icon={<CloseOutlined />} onClick={() => toggleVisible(false)} size='small' />\n </Tooltip>\n </Space>\n </div>\n )}\n\n <div\n style={{\n flex: 1,\n padding: 16,\n overflowY: 'auto',\n }}\n >\n {!activeSession || activeSession.messages.length === 0 ? (\n <div\n style={{\n textAlign: 'center',\n padding: '60px 0',\n color: '#999',\n }}\n >\n <MessageOutlined style={{ fontSize: 48, color: '#d9d9d9' }} />\n <div style={{ marginTop: 16, fontSize: 16 }}>开始你的 AI 对话</div>\n <div style={{ marginTop: 8, fontSize: 13, color: '#bfbfbf' }}>我可以帮你解答问题、创建任务</div>\n <Button type='primary' onClick={createNewSession} style={{ marginTop: 20 }}>\n 新建会话\n </Button>\n </div>\n ) : (\n <List dataSource={activeSession.messages} renderItem={renderMsg} />\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {renderFooter || (\n <div\n style={{\n padding: 12,\n borderTop: '1px solid #f0f0f0',\n background: '#fafafa',\n flexShrink: 0,\n }}\n >\n {/* 智能建议 */}\n {suggestions.length > 0 && (\n <div\n style={{\n marginBottom: 8,\n display: 'flex',\n flexWrap: 'wrap',\n gap: 4,\n }}\n >\n {suggestions.slice(0, 3).map((suggestion) => (\n <Button\n key={suggestion}\n size='small'\n type='dashed'\n onClick={() => setInputValue(suggestion)}\n style={{ fontSize: 12 }}\n >\n {suggestion}\n </Button>\n ))}\n </div>\n )}\n\n {/* 文件预览 */}\n {fileList.length > 0 && (\n <div style={{ marginBottom: 8 }}>\n {fileList.map((file) => (\n <div\n key={file.uid}\n style={{\n display: 'inline-block',\n padding: '4px 8px',\n background: '#e6f7ff',\n borderRadius: 4,\n marginRight: 8,\n fontSize: 12,\n }}\n >\n {file.name}\n <CloseOutlined\n style={{\n marginLeft: 8,\n cursor: 'pointer',\n fontSize: 10,\n }}\n onClick={() => setFileList((prev) => prev.filter((f) => f.uid !== file.uid))}\n />\n </div>\n ))}\n </div>\n )}\n\n <div style={{ position: 'relative' }}>\n <TextArea\n value={inputValue}\n onChange={handleInputChange}\n placeholder='输入问题或任务描述,如:帮我创建一个paimon调用任务'\n autoSize={{ minRows: 2, maxRows: 4 }}\n onPressEnter={(e) => {\n if (!e.shiftKey) {\n e.preventDefault();\n handleSend();\n }\n }}\n style={{\n marginBottom: 8,\n borderRadius: 8,\n paddingRight: 80,\n }}\n disabled={loading}\n />\n {/* 上传文件和图片按钮 */}\n <div\n style={{\n position: 'absolute',\n right: 12,\n bottom: 16,\n display: 'flex',\n gap: 8,\n }}\n >\n <Upload\n fileList={fileList}\n onChange={handleFileChange}\n beforeUpload={() => false}\n showUploadList={false}\n accept='image/*'\n >\n <Tooltip title='上传图片'>\n <Button type='text' size='small' icon={<FileImageOutlined />} />\n </Tooltip>\n </Upload>\n <Upload\n fileList={fileList}\n onChange={handleFileChange}\n beforeUpload={() => false}\n showUploadList={false}\n >\n <Tooltip title='上传文件'>\n <Button type='text' size='small' icon={<PaperClipOutlined />} />\n </Tooltip>\n </Upload>\n </div>\n </div>\n <div style={{ display: 'flex', justifyContent: 'flex-end' }}>\n <Space>\n {loading && (\n <Button danger icon={<StopOutlined />} onClick={cancelRequest} size='small'>\n 终止\n </Button>\n )}\n <Button\n type='primary'\n icon={<SendOutlined />}\n onClick={handleSend}\n loading={loading}\n disabled={!inputValue.trim() && fileList.length === 0}\n size='small'\n >\n 发送\n </Button>\n </Space>\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n\nexport default AiChat;\nexport { generateSuggestions, isTaskCreationIntent, parseTaskDescription, recognizeIntent } from './intentRecognizer';\nexport { delay, NavigationManager } from './navigationManager';\nexport type {\n AiChatConfig,\n ChatSession,\n EnhancedAiChatConfig,\n Intent,\n IntentType,\n Message,\n NavigationOptions,\n Task,\n TaskCategory,\n TaskCreationResult,\n TaskPriority,\n TaskStatus,\n UseAiChatOptions,\n UseAiChatReturn,\n} from './type';\nexport { useAiChat } from './useAiChat';\nexport { useTaskWorkflow } from './useTaskWorkflow';\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_intentRecognizer", "import_useAiChat", "import_useTaskWorkflow", "React", "MarkdownRender", "styles", "AiChatLogo"]
7
7
  }
@@ -33,6 +33,8 @@ function useAiChat(options) {
33
33
  const [loading, setLoading] = (0, import_react.useState)(false);
34
34
  const [cancelFn, setCancelFn] = (0, import_react.useState)(null);
35
35
  const [visible, setVisible] = (0, import_react.useState)(false);
36
+ const activeSessionRef = (0, import_react.useRef)(activeSession);
37
+ activeSessionRef.current = activeSession;
36
38
  (0, import_react.useEffect)(() => {
37
39
  const loadSessions = async () => {
38
40
  if (options == null ? void 0 : options.onFetchSessions) {
@@ -45,12 +47,16 @@ function useAiChat(options) {
45
47
  console.error("加载会话失败:", err);
46
48
  }
47
49
  } else {
48
- const saved = localStorage.getItem(storageKey);
49
- if (saved) {
50
- const list = JSON.parse(saved);
51
- setSessions(list);
52
- if (list.length > 0)
53
- setActiveSession(list[list.length - 1]);
50
+ try {
51
+ const saved = localStorage.getItem(storageKey);
52
+ if (saved) {
53
+ const list = JSON.parse(saved);
54
+ setSessions(list);
55
+ if (list.length > 0)
56
+ setActiveSession(list[list.length - 1]);
57
+ }
58
+ } catch (err) {
59
+ console.error("localStorage 解析失败:", err);
54
60
  }
55
61
  }
56
62
  };
@@ -106,12 +112,16 @@ function useAiChat(options) {
106
112
  const deleteSession = (0, import_react.useCallback)(
107
113
  (id, e) => {
108
114
  e.stopPropagation();
109
- const ns = sessions.filter((x) => x.id !== id);
110
- setSessions(ns);
111
- if ((activeSession == null ? void 0 : activeSession.id) === id)
112
- setActiveSession(ns.at(-1) ?? null);
115
+ setSessions((prev) => {
116
+ var _a;
117
+ const ns = prev.filter((x) => x.id !== id);
118
+ if (((_a = activeSessionRef.current) == null ? void 0 : _a.id) === id) {
119
+ setActiveSession(ns.at(-1) ?? null);
120
+ }
121
+ return ns;
122
+ });
113
123
  },
114
- [sessions, activeSession]
124
+ []
115
125
  );
116
126
  const sendQuestion = (0, import_react.useCallback)(
117
127
  async (content, regenId) => {
@@ -173,20 +183,28 @@ function useAiChat(options) {
173
183
  sessionId: activeSession.id
174
184
  },
175
185
  (text) => {
176
- if (!activeSession)
186
+ if (!activeSessionRef.current)
177
187
  return;
178
- const ms = updated.messages.map((m) => m.loading ? { ...m, content: m.content + text } : m);
179
- const su = { ...updated, messages: ms };
180
- setActiveSession(su);
181
- setSessions((prev) => prev.map((x) => x.id === su.id ? su : x));
188
+ setActiveSession((cur) => {
189
+ if (!cur)
190
+ return cur;
191
+ const ms = cur.messages.map((m) => m.loading ? { ...m, content: m.content + text } : m);
192
+ const su = { ...cur, messages: ms };
193
+ setSessions((prev) => prev.map((x) => x.id === su.id ? su : x));
194
+ return su;
195
+ });
182
196
  },
183
197
  () => {
184
198
  var _a2;
185
199
  setLoading(false);
186
- const ms = updated.messages.map((m) => m.loading ? { ...m, loading: false } : m);
187
- const su = { ...updated, messages: ms };
188
- setActiveSession(su);
189
- setSessions((prev) => prev.map((x) => x.id === su.id ? su : x));
200
+ setActiveSession((cur) => {
201
+ if (!cur)
202
+ return cur;
203
+ const ms = cur.messages.map((m) => m.loading ? { ...m, loading: false } : m);
204
+ const su = { ...cur, messages: ms };
205
+ setSessions((prev) => prev.map((x) => x.id === su.id ? su : x));
206
+ return su;
207
+ });
190
208
  (_a2 = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a2.call(options);
191
209
  },
192
210
  (err) => {
@@ -197,7 +215,7 @@ function useAiChat(options) {
197
215
  (_a2 = options == null ? void 0 : options.onError) == null ? void 0 : _a2.call(options, err);
198
216
  }
199
217
  );
200
- setCancelFn(() => cancel);
218
+ setCancelFn(cancel);
201
219
  }
202
220
  },
203
221
  [activeSession, apiPath, options]
@@ -229,7 +247,7 @@ function useAiChat(options) {
229
247
  cancelFn == null ? void 0 : cancelFn();
230
248
  setLoading(false);
231
249
  }, [cancelFn]);
232
- const toggleVisible = (0, import_react.useCallback)((v) => setVisible(v ?? !visible), [visible]);
250
+ const toggleVisible = (0, import_react.useCallback)((v) => setVisible(v ?? ((prev) => !prev)), []);
233
251
  return {
234
252
  sessions,
235
253
  activeSession,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/business/AiChat/useAiChat.ts"],
4
- "sourcesContent": ["import { message } from 'antd';\nimport { useCallback, useEffect, useState } from 'react';\nimport { createSSE } from './sse';\nimport type { ChatSession, Message, UseAiChatOptions, UseAiChatReturn } from './type';\n\nexport function useAiChat(options?: UseAiChatOptions): UseAiChatReturn {\n const apiPath = options?.apiPath || '/api/ai/chat-stream';\n const storageKey = options?.storageKey || 'ai_chat_sessions';\n\n const [sessions, setSessions] = useState<ChatSession[]>([]);\n const [activeSession, setActiveSession] = useState<ChatSession | null>(null);\n const [loading, setLoading] = useState(false);\n const [cancelFn, setCancelFn] = useState<(() => void) | null>(null);\n const [visible, setVisible] = useState(false);\n\n useEffect(() => {\n const loadSessions = async () => {\n if (options?.onFetchSessions) {\n try {\n const list = await options.onFetchSessions();\n setSessions(list);\n if (list.length > 0) setActiveSession(list[list.length - 1]);\n } catch (err) {\n console.error('加载会话失败:', err);\n }\n } else {\n const saved = localStorage.getItem(storageKey);\n if (saved) {\n const list = JSON.parse(saved);\n setSessions(list);\n if (list.length > 0) setActiveSession(list[list.length - 1]);\n }\n }\n };\n loadSessions();\n }, [storageKey, options?.onFetchSessions]);\n\n useEffect(() => {\n if (!options?.onFetchSessions && sessions.length) {\n localStorage.setItem(storageKey, JSON.stringify(sessions));\n }\n }, [sessions, storageKey, options?.onFetchSessions]);\n\n const createNewSession = useCallback(async () => {\n let newSessionId: string;\n\n if (options?.onCreateSession) {\n try {\n const result = await options.onCreateSession();\n newSessionId = result.sessionId;\n } catch (err) {\n console.error('创建会话失败:', err);\n message.error('创建会话失败');\n return;\n }\n } else {\n newSessionId = Date.now().toString();\n }\n\n const s: ChatSession = {\n id: newSessionId,\n title: '新会话',\n createTime: Date.now(),\n messages: [],\n };\n setSessions((prev) => [...prev, s]);\n setActiveSession(s);\n setVisible(true);\n }, [options?.onCreateSession]);\n\n const switchSession = useCallback(\n async (id: string) => {\n if (options?.onFetchSessionDetail) {\n try {\n const detail = await options.onFetchSessionDetail(id);\n setActiveSession(detail);\n } catch (err) {\n console.error('获取会话详情失败:', err);\n message.error('获取会话详情失败');\n }\n } else {\n const s = sessions.find((x) => x.id === id);\n if (s) setActiveSession(s);\n }\n },\n [sessions, options?.onFetchSessionDetail],\n );\n\n const deleteSession = useCallback(\n (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const ns = sessions.filter((x) => x.id !== id);\n setSessions(ns);\n if (activeSession?.id === id) setActiveSession(ns.at(-1) ?? null);\n },\n [sessions, activeSession],\n );\n\n const sendQuestion = useCallback(\n async (content: string, regenId?: string) => {\n if (!content.trim() || !activeSession) return;\n\n if (options?.onBeforeSend) {\n const canSend = await options.onBeforeSend(content);\n if (!canSend) return;\n }\n\n const user: Message = { id: `${Date.now()}_u`, role: 'user', content };\n const ai: Message = {\n id: `${Date.now()}_ai`,\n role: 'ai',\n content: '',\n loading: true,\n };\n\n let newMsgs: Message[] = [];\n if (regenId) {\n newMsgs = activeSession.messages.map((m) => (m.id === regenId ? ai : m));\n } else {\n newMsgs = [...activeSession.messages, user, ai];\n }\n\n const updated: ChatSession = {\n ...activeSession,\n title: activeSession.messages.length === 0 ? content.slice(0, 20) : activeSession.title,\n messages: newMsgs,\n };\n setActiveSession(updated);\n setSessions((prev) => prev.map((x) => (x.id === updated.id ? updated : x)));\n\n setLoading(true);\n\n // 如果提供了 onSendMessage 回调,则使用自定义发送逻辑\n if (options?.onSendMessage) {\n try {\n await options.onSendMessage({\n sessionId: activeSession.id,\n prompt: content,\n history: updated.messages.filter((m) => !m.loading),\n });\n setLoading(false);\n const ms = updated.messages.map((m) => (m.loading ? { ...m, loading: false } : m));\n const su = { ...updated, messages: ms };\n setActiveSession(su);\n setSessions((prev) => prev.map((x) => (x.id === su.id ? su : x)));\n options?.onSuccess?.();\n } catch (err) {\n setLoading(false);\n const error = err as Error;\n message.error(`请求异常:${error.message}`);\n options?.onError?.(error);\n }\n } else {\n // 使用默认 SSE 逻辑\n const cancel = await createSSE(\n apiPath,\n {\n prompt: content,\n history: updated.messages.filter((m) => !m.loading),\n useMcp: true,\n sessionId: activeSession.id,\n },\n (text) => {\n if (!activeSession) return;\n const ms = updated.messages.map((m) => (m.loading ? { ...m, content: m.content + text } : m));\n const su = { ...updated, messages: ms };\n setActiveSession(su);\n setSessions((prev) => prev.map((x) => (x.id === su.id ? su : x)));\n },\n () => {\n setLoading(false);\n const ms = updated.messages.map((m) => (m.loading ? { ...m, loading: false } : m));\n const su = { ...updated, messages: ms };\n setActiveSession(su);\n setSessions((prev) => prev.map((x) => (x.id === su.id ? su : x)));\n options?.onSuccess?.();\n },\n (err) => {\n setLoading(false);\n const errorMsg = err.message;\n message.error(`请求异常:${errorMsg}`);\n options?.onError?.(err);\n },\n );\n setCancelFn(() => cancel);\n }\n },\n [activeSession, apiPath, options],\n );\n\n const regenerateAnswer = useCallback(\n (msg: Message) => {\n if (!activeSession) return;\n const idx = activeSession.messages.findIndex((x) => x.id === msg.id);\n const userMsg = activeSession.messages[idx - 1];\n if (userMsg?.role === 'user') sendQuestion(userMsg.content, msg.id);\n },\n [activeSession, sendQuestion],\n );\n\n const deleteSingleMsg = useCallback(\n (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n if (!activeSession) return;\n const ms = activeSession.messages.filter((x) => x.id !== id);\n const up = { ...activeSession, messages: ms };\n setActiveSession(up);\n setSessions((prev) => prev.map((x) => (x.id === up.id ? up : x)));\n },\n [activeSession],\n );\n\n const cancelRequest = useCallback(() => {\n cancelFn?.();\n setLoading(false);\n }, [cancelFn]);\n\n const toggleVisible = useCallback((v?: boolean) => setVisible(v ?? !visible), [visible]);\n\n return {\n sessions,\n activeSession,\n loading,\n visible,\n createNewSession,\n switchSession,\n deleteSession,\n sendQuestion,\n regenerateAnswer,\n deleteSingleMsg,\n cancelRequest,\n toggleVisible,\n };\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AACxB,mBAAiD;AACjD,iBAA0B;AAGnB,SAAS,UAAU,SAA6C;AACrE,QAAM,WAAU,mCAAS,YAAW;AACpC,QAAM,cAAa,mCAAS,eAAc;AAE1C,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAwB,CAAC,CAAC;AAC1D,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAA6B,IAAI;AAC3E,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAC5C,QAAM,CAAC,UAAU,WAAW,QAAI,uBAA8B,IAAI;AAClE,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAE5C,8BAAU,MAAM;AACd,UAAM,eAAe,YAAY;AAC/B,UAAI,mCAAS,iBAAiB;AAC5B,YAAI;AACF,gBAAM,OAAO,MAAM,QAAQ,gBAAgB;AAC3C,sBAAY,IAAI;AAChB,cAAI,KAAK,SAAS;AAAG,6BAAiB,KAAK,KAAK,SAAS,CAAC,CAAC;AAAA,QAC7D,SAAS,KAAP;AACA,kBAAQ,MAAM,WAAW,GAAG;AAAA,QAC9B;AAAA,MACF,OAAO;AACL,cAAM,QAAQ,aAAa,QAAQ,UAAU;AAC7C,YAAI,OAAO;AACT,gBAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,sBAAY,IAAI;AAChB,cAAI,KAAK,SAAS;AAAG,6BAAiB,KAAK,KAAK,SAAS,CAAC,CAAC;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AACA,iBAAa;AAAA,EACf,GAAG,CAAC,YAAY,mCAAS,eAAe,CAAC;AAEzC,8BAAU,MAAM;AACd,QAAI,EAAC,mCAAS,oBAAmB,SAAS,QAAQ;AAChD,mBAAa,QAAQ,YAAY,KAAK,UAAU,QAAQ,CAAC;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,UAAU,YAAY,mCAAS,eAAe,CAAC;AAEnD,QAAM,uBAAmB,0BAAY,YAAY;AAC/C,QAAI;AAEJ,QAAI,mCAAS,iBAAiB;AAC5B,UAAI;AACF,cAAM,SAAS,MAAM,QAAQ,gBAAgB;AAC7C,uBAAe,OAAO;AAAA,MACxB,SAAS,KAAP;AACA,gBAAQ,MAAM,WAAW,GAAG;AAC5B,4BAAQ,MAAM,QAAQ;AACtB;AAAA,MACF;AAAA,IACF,OAAO;AACL,qBAAe,KAAK,IAAI,EAAE,SAAS;AAAA,IACrC;AAEA,UAAM,IAAiB;AAAA,MACrB,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,YAAY,KAAK,IAAI;AAAA,MACrB,UAAU,CAAC;AAAA,IACb;AACA,gBAAY,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC;AAClC,qBAAiB,CAAC;AAClB,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,mCAAS,eAAe,CAAC;AAE7B,QAAM,oBAAgB;AAAA,IACpB,OAAO,OAAe;AACpB,UAAI,mCAAS,sBAAsB;AACjC,YAAI;AACF,gBAAM,SAAS,MAAM,QAAQ,qBAAqB,EAAE;AACpD,2BAAiB,MAAM;AAAA,QACzB,SAAS,KAAP;AACA,kBAAQ,MAAM,aAAa,GAAG;AAC9B,8BAAQ,MAAM,UAAU;AAAA,QAC1B;AAAA,MACF,OAAO;AACL,cAAM,IAAI,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC1C,YAAI;AAAG,2BAAiB,CAAC;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,CAAC,UAAU,mCAAS,oBAAoB;AAAA,EAC1C;AAEA,QAAM,oBAAgB;AAAA,IACpB,CAAC,IAAY,MAAwB;AACnC,QAAE,gBAAgB;AAClB,YAAM,KAAK,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAC7C,kBAAY,EAAE;AACd,WAAI,+CAAe,QAAO;AAAI,yBAAiB,GAAG,GAAG,EAAE,KAAK,IAAI;AAAA,IAClE;AAAA,IACA,CAAC,UAAU,aAAa;AAAA,EAC1B;AAEA,QAAM,mBAAe;AAAA,IACnB,OAAO,SAAiB,YAAqB;AAnGjD;AAoGM,UAAI,CAAC,QAAQ,KAAK,KAAK,CAAC;AAAe;AAEvC,UAAI,mCAAS,cAAc;AACzB,cAAM,UAAU,MAAM,QAAQ,aAAa,OAAO;AAClD,YAAI,CAAC;AAAS;AAAA,MAChB;AAEA,YAAM,OAAgB,EAAE,IAAI,GAAG,KAAK,IAAI,OAAO,MAAM,QAAQ,QAAQ;AACrE,YAAM,KAAc;AAAA,QAClB,IAAI,GAAG,KAAK,IAAI;AAAA,QAChB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAEA,UAAI,UAAqB,CAAC;AAC1B,UAAI,SAAS;AACX,kBAAU,cAAc,SAAS,IAAI,CAAC,MAAO,EAAE,OAAO,UAAU,KAAK,CAAE;AAAA,MACzE,OAAO;AACL,kBAAU,CAAC,GAAG,cAAc,UAAU,MAAM,EAAE;AAAA,MAChD;AAEA,YAAM,UAAuB;AAAA,QAC3B,GAAG;AAAA,QACH,OAAO,cAAc,SAAS,WAAW,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,cAAc;AAAA,QAClF,UAAU;AAAA,MACZ;AACA,uBAAiB,OAAO;AACxB,kBAAY,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,QAAQ,KAAK,UAAU,CAAE,CAAC;AAE1E,iBAAW,IAAI;AAGf,UAAI,mCAAS,eAAe;AAC1B,YAAI;AACF,gBAAM,QAAQ,cAAc;AAAA,YAC1B,WAAW,cAAc;AAAA,YACzB,QAAQ;AAAA,YACR,SAAS,QAAQ,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO;AAAA,UACpD,CAAC;AACD,qBAAW,KAAK;AAChB,gBAAM,KAAK,QAAQ,SAAS,IAAI,CAAC,MAAO,EAAE,UAAU,EAAE,GAAG,GAAG,SAAS,MAAM,IAAI,CAAE;AACjF,gBAAM,KAAK,EAAE,GAAG,SAAS,UAAU,GAAG;AACtC,2BAAiB,EAAE;AACnB,sBAAY,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,GAAG,KAAK,KAAK,CAAE,CAAC;AAChE,mDAAS,cAAT;AAAA,QACF,SAAS,KAAP;AACA,qBAAW,KAAK;AAChB,gBAAM,QAAQ;AACd,8BAAQ,MAAM,QAAQ,MAAM,SAAS;AACrC,mDAAS,YAAT,iCAAmB;AAAA,QACrB;AAAA,MACF,OAAO;AAEL,cAAM,SAAS,UAAM;AAAA,UACnB;AAAA,UACA;AAAA,YACE,QAAQ;AAAA,YACR,SAAS,QAAQ,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO;AAAA,YAClD,QAAQ;AAAA,YACR,WAAW,cAAc;AAAA,UAC3B;AAAA,UACA,CAAC,SAAS;AACR,gBAAI,CAAC;AAAe;AACpB,kBAAM,KAAK,QAAQ,SAAS,IAAI,CAAC,MAAO,EAAE,UAAU,EAAE,GAAG,GAAG,SAAS,EAAE,UAAU,KAAK,IAAI,CAAE;AAC5F,kBAAM,KAAK,EAAE,GAAG,SAAS,UAAU,GAAG;AACtC,6BAAiB,EAAE;AACnB,wBAAY,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,GAAG,KAAK,KAAK,CAAE,CAAC;AAAA,UAClE;AAAA,UACA,MAAM;AAzKhB,gBAAAA;AA0KY,uBAAW,KAAK;AAChB,kBAAM,KAAK,QAAQ,SAAS,IAAI,CAAC,MAAO,EAAE,UAAU,EAAE,GAAG,GAAG,SAAS,MAAM,IAAI,CAAE;AACjF,kBAAM,KAAK,EAAE,GAAG,SAAS,UAAU,GAAG;AACtC,6BAAiB,EAAE;AACnB,wBAAY,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,GAAG,KAAK,KAAK,CAAE,CAAC;AAChE,aAAAA,MAAA,mCAAS,cAAT,gBAAAA,IAAA;AAAA,UACF;AAAA,UACA,CAAC,QAAQ;AAjLnB,gBAAAA;AAkLY,uBAAW,KAAK;AAChB,kBAAM,WAAW,IAAI;AACrB,gCAAQ,MAAM,QAAQ,UAAU;AAChC,aAAAA,MAAA,mCAAS,YAAT,gBAAAA,IAAA,cAAmB;AAAA,UACrB;AAAA,QACF;AACA,oBAAY,MAAM,MAAM;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,CAAC,eAAe,SAAS,OAAO;AAAA,EAClC;AAEA,QAAM,uBAAmB;AAAA,IACvB,CAAC,QAAiB;AAChB,UAAI,CAAC;AAAe;AACpB,YAAM,MAAM,cAAc,SAAS,UAAU,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE;AACnE,YAAM,UAAU,cAAc,SAAS,MAAM,CAAC;AAC9C,WAAI,mCAAS,UAAS;AAAQ,qBAAa,QAAQ,SAAS,IAAI,EAAE;AAAA,IACpE;AAAA,IACA,CAAC,eAAe,YAAY;AAAA,EAC9B;AAEA,QAAM,sBAAkB;AAAA,IACtB,CAAC,IAAY,MAAwB;AACnC,QAAE,gBAAgB;AAClB,UAAI,CAAC;AAAe;AACpB,YAAM,KAAK,cAAc,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAC3D,YAAM,KAAK,EAAE,GAAG,eAAe,UAAU,GAAG;AAC5C,uBAAiB,EAAE;AACnB,kBAAY,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,GAAG,KAAK,KAAK,CAAE,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,oBAAgB,0BAAY,MAAM;AACtC;AACA,eAAW,KAAK;AAAA,EAClB,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,oBAAgB,0BAAY,CAAC,MAAgB,WAAW,KAAK,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC;AAEvF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { message } from 'antd';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { createSSE } from './sse';\nimport type { ChatSession, Message, UseAiChatOptions, UseAiChatReturn } from './type';\n\nexport function useAiChat(options?: UseAiChatOptions): UseAiChatReturn {\n const apiPath = options?.apiPath || '/api/ai/chat-stream';\n const storageKey = options?.storageKey || 'ai_chat_sessions';\n\n const [sessions, setSessions] = useState<ChatSession[]>([]);\n const [activeSession, setActiveSession] = useState<ChatSession | null>(null);\n const [loading, setLoading] = useState(false);\n const [cancelFn, setCancelFn] = useState<(() => void) | null>(null);\n const [visible, setVisible] = useState(false);\n\n // 使用 ref 避免 SSE 回调中的 stale closure\n const activeSessionRef = useRef(activeSession);\n activeSessionRef.current = activeSession;\n\n useEffect(() => {\n const loadSessions = async () => {\n if (options?.onFetchSessions) {\n try {\n const list = await options.onFetchSessions();\n setSessions(list);\n if (list.length > 0) setActiveSession(list[list.length - 1]);\n } catch (err) {\n console.error('加载会话失败:', err);\n }\n } else {\n try {\n const saved = localStorage.getItem(storageKey);\n if (saved) {\n const list = JSON.parse(saved);\n setSessions(list);\n if (list.length > 0) setActiveSession(list[list.length - 1]);\n }\n } catch (err) {\n console.error('localStorage 解析失败:', err);\n }\n }\n };\n loadSessions();\n }, [storageKey, options?.onFetchSessions]);\n\n useEffect(() => {\n if (!options?.onFetchSessions && sessions.length) {\n localStorage.setItem(storageKey, JSON.stringify(sessions));\n }\n }, [sessions, storageKey, options?.onFetchSessions]);\n\n const createNewSession = useCallback(async () => {\n let newSessionId: string;\n\n if (options?.onCreateSession) {\n try {\n const result = await options.onCreateSession();\n newSessionId = result.sessionId;\n } catch (err) {\n console.error('创建会话失败:', err);\n message.error('创建会话失败');\n return;\n }\n } else {\n newSessionId = Date.now().toString();\n }\n\n const s: ChatSession = {\n id: newSessionId,\n title: '新会话',\n createTime: Date.now(),\n messages: [],\n };\n setSessions((prev) => [...prev, s]);\n setActiveSession(s);\n setVisible(true);\n }, [options?.onCreateSession]);\n\n const switchSession = useCallback(\n async (id: string) => {\n if (options?.onFetchSessionDetail) {\n try {\n const detail = await options.onFetchSessionDetail(id);\n setActiveSession(detail);\n } catch (err) {\n console.error('获取会话详情失败:', err);\n message.error('获取会话详情失败');\n }\n } else {\n const s = sessions.find((x) => x.id === id);\n if (s) setActiveSession(s);\n }\n },\n [sessions, options?.onFetchSessionDetail],\n );\n\n const deleteSession = useCallback(\n (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n setSessions((prev) => {\n const ns = prev.filter((x) => x.id !== id);\n // 若删除的是当前活跃会话,切换到最后一个\n if (activeSessionRef.current?.id === id) {\n setActiveSession(ns.at(-1) ?? null);\n }\n return ns;\n });\n },\n [],\n );\n\n const sendQuestion = useCallback(\n async (content: string, regenId?: string) => {\n if (!content.trim() || !activeSession) return;\n\n if (options?.onBeforeSend) {\n const canSend = await options.onBeforeSend(content);\n if (!canSend) return;\n }\n\n const user: Message = { id: `${Date.now()}_u`, role: 'user', content };\n const ai: Message = {\n id: `${Date.now()}_ai`,\n role: 'ai',\n content: '',\n loading: true,\n };\n\n let newMsgs: Message[] = [];\n if (regenId) {\n newMsgs = activeSession.messages.map((m) => (m.id === regenId ? ai : m));\n } else {\n newMsgs = [...activeSession.messages, user, ai];\n }\n\n const updated: ChatSession = {\n ...activeSession,\n title: activeSession.messages.length === 0 ? content.slice(0, 20) : activeSession.title,\n messages: newMsgs,\n };\n setActiveSession(updated);\n setSessions((prev) => prev.map((x) => (x.id === updated.id ? updated : x)));\n\n setLoading(true);\n\n // 如果提供了 onSendMessage 回调,则使用自定义发送逻辑\n if (options?.onSendMessage) {\n try {\n await options.onSendMessage({\n sessionId: activeSession.id,\n prompt: content,\n history: updated.messages.filter((m) => !m.loading),\n });\n setLoading(false);\n const ms = updated.messages.map((m) => (m.loading ? { ...m, loading: false } : m));\n const su = { ...updated, messages: ms };\n setActiveSession(su);\n setSessions((prev) => prev.map((x) => (x.id === su.id ? su : x)));\n options?.onSuccess?.();\n } catch (err) {\n setLoading(false);\n const error = err as Error;\n message.error(`请求异常:${error.message}`);\n options?.onError?.(error);\n }\n } else {\n // 使用默认 SSE 逻辑\n const cancel = await createSSE(\n apiPath,\n {\n prompt: content,\n history: updated.messages.filter((m) => !m.loading),\n useMcp: true,\n sessionId: activeSession.id,\n },\n (text) => {\n if (!activeSessionRef.current) return;\n setActiveSession((cur) => {\n if (!cur) return cur;\n const ms = cur.messages.map((m) => (m.loading ? { ...m, content: m.content + text } : m));\n const su = { ...cur, messages: ms };\n setSessions((prev) => prev.map((x) => (x.id === su.id ? su : x)));\n return su;\n });\n },\n () => {\n setLoading(false);\n setActiveSession((cur) => {\n if (!cur) return cur;\n const ms = cur.messages.map((m) => (m.loading ? { ...m, loading: false } : m));\n const su = { ...cur, messages: ms };\n setSessions((prev) => prev.map((x) => (x.id === su.id ? su : x)));\n return su;\n });\n options?.onSuccess?.();\n },\n (err) => {\n setLoading(false);\n const errorMsg = err.message;\n message.error(`请求异常:${errorMsg}`);\n options?.onError?.(err);\n },\n );\n setCancelFn(cancel);\n }\n },\n [activeSession, apiPath, options],\n );\n\n const regenerateAnswer = useCallback(\n (msg: Message) => {\n if (!activeSession) return;\n const idx = activeSession.messages.findIndex((x) => x.id === msg.id);\n const userMsg = activeSession.messages[idx - 1];\n if (userMsg?.role === 'user') sendQuestion(userMsg.content, msg.id);\n },\n [activeSession, sendQuestion],\n );\n\n const deleteSingleMsg = useCallback(\n (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n if (!activeSession) return;\n const ms = activeSession.messages.filter((x) => x.id !== id);\n const up = { ...activeSession, messages: ms };\n setActiveSession(up);\n setSessions((prev) => prev.map((x) => (x.id === up.id ? up : x)));\n },\n [activeSession],\n );\n\n const cancelRequest = useCallback(() => {\n cancelFn?.();\n setLoading(false);\n }, [cancelFn]);\n\n const toggleVisible = useCallback((v?: boolean) => setVisible(v ?? ((prev) => !prev)), []);\n\n return {\n sessions,\n activeSession,\n loading,\n visible,\n createNewSession,\n switchSession,\n deleteSession,\n sendQuestion,\n regenerateAnswer,\n deleteSingleMsg,\n cancelRequest,\n toggleVisible,\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["_a"]
7
7
  }