@myun/gimi-chat 0.7.4 → 0.7.6

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.
@@ -82,6 +82,10 @@ var AskCard = function AskCard(_ref) {
82
82
  }, /*#__PURE__*/React.createElement("img", {
83
83
  src: item.disableUploadFile ? 'https://simg01.gaodunwangxiao.com/uploadimgs/tmp/upload/202509/19/b1e04_20250919162201.png' : 'https://simg01.gaodunwangxiao.com/uploadimgs/tmp/upload/202509/11/83ad4_20250911153220.png',
84
84
  alt: ""
85
- }), "\u6587\u4EF6\u4E0A\u4F20"))));
85
+ }), /*#__PURE__*/React.createElement("span", {
86
+ style: item.disableUploadFile ? {
87
+ color: '#d9dce5'
88
+ } : {}
89
+ }, "\u6587\u4EF6\u4E0A\u4F20")))));
86
90
  };
87
91
  export default AskCard;
@@ -1,5 +1,5 @@
1
1
  .askList {
2
- width: clamp(380px, 100%, 600px);
2
+ width: clamp(360px, 90%, 600px);
3
3
  flex-shrink: 0;
4
4
  padding: 20px;
5
5
  border-radius: 16px;
@@ -50,6 +50,7 @@ var extractText = function extractText() {
50
50
  }).join('');
51
51
  };
52
52
  var ChatInput = /*#__PURE__*/React.forwardRef(function (props, ref) {
53
+ var _messageList;
53
54
  var fileList = useAppSelector(function (state) {
54
55
  return state.gimiMenu.fileList;
55
56
  });
@@ -74,6 +75,7 @@ var ChatInput = /*#__PURE__*/React.forwardRef(function (props, ref) {
74
75
  var businessParams = useAppSelector(function (state) {
75
76
  return state.gimiMenu.businessParams;
76
77
  });
78
+ var isAskProcess = ((_messageList = messageList[messageList.length - 1]) === null || _messageList === void 0 ? void 0 : _messageList.moduleType) === 'ask';
77
79
  var dispatch = useAppDispatch();
78
80
  var inputWrapRef = React.useRef(null);
79
81
  var preInputValueRef = React.useRef('');
@@ -182,32 +184,39 @@ var ChatInput = /*#__PURE__*/React.forwardRef(function (props, ref) {
182
184
  }
183
185
  }, [props.asrText, props.isRecording, props.isVoiceGetting, handleQuickInput]);
184
186
  var handleTip = function handleTip() {
185
- return Toast.info('最多上传一个文件哦');
187
+ if ((fileList === null || fileList === void 0 ? void 0 : fileList.length) > 0) {
188
+ return Toast.info('最多上传一个文件哦');
189
+ }
190
+ return Toast.info('当前流程不支持该按钮的使用,请等待正在进行的流程结束或按对话卡片指示继续流程');
186
191
  };
187
192
  var UploadFileTool = React.useMemo(function () {
188
- if (!props.enableFileUpload || messageList.length > 0 || (agentObj === null || agentObj === void 0 ? void 0 : agentObj.openUploadFile) === 0) {
193
+ if (!props.enableFileUpload || (agentObj === null || agentObj === void 0 ? void 0 : agentObj.openUploadFile) === 0) {
189
194
  return null;
190
195
  }
196
+ var shouldDisableUploadFile = props.disabled || (fileList === null || fileList === void 0 ? void 0 : fileList.length) > 0 || isAskProcess;
191
197
  return /*#__PURE__*/React.createElement(FileUpload, {
192
198
  ref: uploadFileRef,
193
199
  accept: props.accept,
194
- disabled: props.disabled || (fileList === null || fileList === void 0 ? void 0 : fileList.length) > 0,
200
+ disabled: shouldDisableUploadFile,
195
201
  onFileUploaded: props.onFileUploaded
196
202
  }, /*#__PURE__*/React.createElement(Tooltip, {
197
203
  content: '上传文件'
198
- }, (fileList === null || fileList === void 0 ? void 0 : fileList.length) === 0 ? /*#__PURE__*/React.createElement("div", {
199
- className: styles.uploadIcon
204
+ }, shouldDisableUploadFile ? /*#__PURE__*/React.createElement("div", {
205
+ className: styles.uploadIcon,
206
+ onClick: handleTip,
207
+ style: {
208
+ cursor: 'not-allowed'
209
+ }
200
210
  }, /*#__PURE__*/React.createElement("img", {
201
- src: 'https://simg01.gaodunwangxiao.com/uploadimgs/tmp/upload/202509/11/83ad4_20250911153220.png',
211
+ src: 'https://simg01.gaodunwangxiao.com/uploadimgs/tmp/upload/202509/24/6726e_20250924141448.png',
202
212
  alt: ""
203
213
  })) : /*#__PURE__*/React.createElement("div", {
204
- className: styles.uploadIcon,
205
- onClick: handleTip
214
+ className: styles.uploadIcon
206
215
  }, /*#__PURE__*/React.createElement("img", {
207
- src: 'https://simg01.gaodunwangxiao.com/uploadimgs/tmp/upload/202509/24/6726e_20250924141448.png',
216
+ src: 'https://simg01.gaodunwangxiao.com/uploadimgs/tmp/upload/202509/11/83ad4_20250911153220.png',
208
217
  alt: ""
209
218
  }))));
210
- }, [props.enableFileUpload, props.accept, props.disabled, messageList, agentObj === null || agentObj === void 0 ? void 0 : agentObj.openUploadFile, fileList]);
219
+ }, [props.enableFileUpload, props.accept, props.disabled, messageList, agentObj === null || agentObj === void 0 ? void 0 : agentObj.openUploadFile, fileList, isAskProcess]);
211
220
  var openChatCommunication = React.useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
212
221
  var params, res, _props$onConversation;
213
222
  return _regeneratorRuntime().wrap(function _callee$(_context) {
@@ -386,10 +395,12 @@ var ChatInput = /*#__PURE__*/React.forwardRef(function (props, ref) {
386
395
  }
387
396
  }, [fileList]);
388
397
  var renderReference = React.useCallback(function () {
398
+ var lastMessage = messageList[messageList.length - 1];
399
+ var disabledUploadFileList = isAskProcess || (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.role) === 0 && (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.messageFiles);
389
400
  return /*#__PURE__*/React.createElement("div", {
390
401
  className: styles.reference,
391
402
  key: "reference"
392
- }, !props.isRecording && (fileList === null || fileList === void 0 ? void 0 : fileList.length) > 0 && messageList.length === 0 && /*#__PURE__*/React.createElement(UploadList, {
403
+ }, !props.isRecording && (fileList === null || fileList === void 0 ? void 0 : fileList.length) > 0 && !disabledUploadFileList && /*#__PURE__*/React.createElement(UploadList, {
393
404
  file: fileList[0],
394
405
  handleReTry: handleReTry,
395
406
  handleDelFile: handleDelFile
@@ -412,7 +423,7 @@ var ChatInput = /*#__PURE__*/React.forwardRef(function (props, ref) {
412
423
  flex: 1
413
424
  }
414
425
  }, "\u6B63\u5728\u83B7\u53D6\u8BED\u97F3\u5185\u5BB9...")));
415
- }, [fileList, props.isRecording, props.isVoiceGetting, messageList, quoteProductList, quoteTeachModelList, handleDelFile, handleReTry]);
426
+ }, [fileList, props.isRecording, props.isVoiceGetting, messageList, quoteProductList, quoteTeachModelList, handleDelFile, handleReTry, isAskProcess]);
416
427
  var handleHangUp = function handleHangUp() {
417
428
  var continueFlag = true;
418
429
  if (props.onMicHangUp) {
@@ -6,7 +6,7 @@
6
6
  background: linear-gradient(180deg, #F9FEFE 0%, #FFFFFF 100%);
7
7
  border-radius: 16px;
8
8
  padding: 16px;
9
- width: clamp(380px, 100%, 680px);
9
+ width: clamp(360px, 90%, 680px);
10
10
  border: 1px solid rgb(233, 235, 242);
11
11
  box-shadow: 0px 2px 2px 0px rgb(255, 255, 255) inset;
12
12
  transition: all 0.5s ease-in-out;
@@ -48,8 +48,7 @@ export var FileCard = function FileCard(_ref) {
48
48
  }, /*#__PURE__*/React.createElement("div", {
49
49
  className: styles.nameSize
50
50
  }, /*#__PURE__*/React.createElement(Tooltip, {
51
- content: decodeURIComponent(fileName),
52
- position: "topLeft"
51
+ content: decodeURIComponent(fileName)
53
52
  }, /*#__PURE__*/React.createElement("div", {
54
53
  className: styles.name
55
54
  }, decodeURIComponent(fileName))), /*#__PURE__*/React.createElement("div", {
@@ -10,7 +10,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
10
10
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
11
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
12
12
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
13
- import React, { useCallback, useEffect, useState } from 'react';
13
+ import React, { useCallback, useLayoutEffect, useMemo, useState } from 'react';
14
14
  import classNames from 'classnames';
15
15
  import styles from "./index.module.css";
16
16
  import { Spin } from '@douyinfe/semi-ui';
@@ -59,13 +59,13 @@ var MessageList = function MessageList(_ref) {
59
59
  var _useGimiFileUpload = useGimiFileUpload(),
60
60
  handleSSEFileAnalyize = _useGimiFileUpload.handleSSEFileAnalyize,
61
61
  fileUpload = _useGimiFileUpload.fileUpload;
62
- var handleReTry = function handleReTry(file) {
62
+ var handleReTry = React.useCallback(function (file) {
63
63
  if (file.status === FileStatus.ANALYSE_FAILED) {
64
64
  handleSSEFileAnalyize(file);
65
65
  } else {
66
66
  fileUpload(file);
67
67
  }
68
- };
68
+ }, [handleSSEFileAnalyize, fileUpload]);
69
69
 
70
70
  // 使用 useChatActions hook 管理用户操作
71
71
  // 注意:由于 handleSend 和 startChat 的复杂依赖,暂时保留部分原有函数
@@ -74,9 +74,9 @@ var MessageList = function MessageList(_ref) {
74
74
  var showOpera = chatActions.showOpera,
75
75
  showCommend = chatActions.showCommend,
76
76
  handleClickAskList = chatActions.handleClickAskList;
77
- var handleClickPromptWord = function handleClickPromptWord(prompt) {
77
+ var handleClickPromptWord = React.useCallback(function (prompt) {
78
78
  handleSend(prompt);
79
- };
79
+ }, [handleSend]);
80
80
 
81
81
  // 搜索弹框 - 使用 chatUI hook
82
82
  // const handleShowSearchResult = useCallback(
@@ -120,19 +120,22 @@ var MessageList = function MessageList(_ref) {
120
120
  _useState2 = _slicedToArray(_useState, 2),
121
121
  scrollParent = _useState2[0],
122
122
  setScrollParent = _useState2[1];
123
- useEffect(function () {
124
- if (containerRef.current) {
125
- setScrollParent(containerRef.current);
126
- }
123
+ useLayoutEffect(function () {
124
+ var _containerRef$current;
125
+ setScrollParent((_containerRef$current = containerRef.current) !== null && _containerRef$current !== void 0 ? _containerRef$current : null);
127
126
  }, [containerRef]);
127
+ var visibleChatList = useMemo(function () {
128
+ return (chatList || []).filter(function (item) {
129
+ if (!item) return false;
130
+ if (item.isSystemAuto === 1) return false;
131
+ if (hideUserMessage && item.type === 0) return false;
132
+ return true;
133
+ });
134
+ }, [chatList, hideUserMessage]);
128
135
  var renderItem = useCallback(function (_, v) {
129
136
  var _v$quoteTeachModelLis, _v$quoteProductList;
130
- if (!v || v.isSystemAuto === 1) {
131
- return /*#__PURE__*/React.createElement("div", null);
132
- }
133
- return /*#__PURE__*/React.createElement("div", {
134
- key: v.id
135
- }, /*#__PURE__*/React.createElement("div", {
137
+ if (!v) return null;
138
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
136
139
  className: classNames(styles.textItem, _defineProperty({}, styles.question, (v === null || v === void 0 ? void 0 : v.type) === 0)),
137
140
  onMouseLeave: function onMouseLeave() {
138
141
  return chatUI.setShowCopyId(0);
@@ -195,18 +198,22 @@ var MessageList = function MessageList(_ref) {
195
198
  className: classNames(styles.main),
196
199
  style: buildStyle()
197
200
  }, /*#__PURE__*/React.createElement("div", {
198
- className: classNames(model === 'sidebar' ? styles.small_container : styles.container)
199
- }, chatList.length > 0 && /*#__PURE__*/React.createElement("div", {
201
+ className: classNames(styles.container)
202
+ }, visibleChatList.length > 0 && /*#__PURE__*/React.createElement("div", {
200
203
  className: styles.textWrap
201
- }, /*#__PURE__*/React.createElement(Virtuoso, {
204
+ }, scrollParent && /*#__PURE__*/React.createElement(Virtuoso, {
202
205
  style: {
203
- height: '100%'
206
+ height: '100%',
207
+ minHeight: 1
204
208
  },
205
- customScrollParent: scrollParent || undefined,
206
- data: chatList,
209
+ customScrollParent: scrollParent,
210
+ data: visibleChatList,
207
211
  itemContent: renderItem
208
- }), msgLoading && /*#__PURE__*/React.createElement("div", {
209
- className: styles.answerLoading
212
+ }), /*#__PURE__*/React.createElement("div", {
213
+ className: styles.answerLoading,
214
+ style: {
215
+ visibility: msgLoading ? 'visible' : 'hidden'
216
+ }
210
217
  }, /*#__PURE__*/React.createElement(LottieImg, {
211
218
  name: "aiLoading",
212
219
  size: [20, 40]
@@ -13,21 +13,18 @@
13
13
  }
14
14
  .main .container {
15
15
  width: 100%;
16
- max-width: var(--container-max);
16
+ min-width: 380px;
17
17
  margin: 0 auto;
18
18
  box-sizing: border-box;
19
19
  padding: 0 16px;
20
20
  }
21
21
  .main .small_container {
22
- width: min(100%, var(--container-max));
23
- max-width: var(--container-max);
22
+ width: 100%;
23
+ min-width: 380px;
24
24
  margin: 0 auto;
25
25
  box-sizing: border-box;
26
26
  padding: 0 16px;
27
27
  }
28
- .main .textWrap {
29
- padding-bottom: 40px;
30
- }
31
28
  .main .textWrap .textItem {
32
29
  width: 100%;
33
30
  cursor: default;
@@ -234,7 +231,7 @@
234
231
  }
235
232
  .main .textWrap .answerLoading {
236
233
  width: 40px;
237
- margin-top: 20px;
234
+ margin: 20px 0;
238
235
  }
239
236
  .main .emptyWrap {
240
237
  text-align: center;
@@ -1,6 +1,6 @@
1
1
  @charset "UTF-8";
2
2
  .container {
3
- max-width: clamp(380px, 60vw, 800px);
3
+ max-width: clamp(360px, 90%, 800px);
4
4
  padding: 0 20px;
5
5
  border-left: 2px solid #d9dce5;
6
6
  margin-bottom: 16px;
@@ -5,6 +5,7 @@
5
5
  display: flex;
6
6
  gap: 20px;
7
7
  position: relative;
8
+ overflow-x: hidden;
8
9
  }
9
10
 
10
11
  .chat_content {
@@ -104,6 +104,7 @@ var useChatHistory = function useChatHistory(checkUnfinishedMessage, scrollBotto
104
104
  newChatList,
105
105
  lastUserRequestMessage,
106
106
  lastMessage,
107
+ waitForStableHeight,
107
108
  _lastUserRequestMessa,
108
109
  container,
109
110
  _args = arguments;
@@ -132,7 +133,7 @@ var useChatHistory = function useChatHistory(checkUnfinishedMessage, scrollBotto
132
133
  case 11:
133
134
  res = _context.sent;
134
135
  if (!(res && res.status === 0)) {
135
- _context.next = 37;
136
+ _context.next = 38;
136
137
  break;
137
138
  }
138
139
  resData = formatFields(res.result.data, res.result.first ? [] : currentMessageList) || [];
@@ -147,7 +148,7 @@ var useChatHistory = function useChatHistory(checkUnfinishedMessage, scrollBotto
147
148
  }
148
149
  hasMore.current = res.result.last === undefined ? false : !res.result.last;
149
150
  if (!res.result.first) {
150
- _context.next = 27;
151
+ _context.next = 28;
151
152
  break;
152
153
  }
153
154
  dispatch(setMessageList({
@@ -156,15 +157,44 @@ var useChatHistory = function useChatHistory(checkUnfinishedMessage, scrollBotto
156
157
  _context.next = 24;
157
158
  return checkUnfinishedMessage(_newResData);
158
159
  case 24:
159
- setTimeout(function () {
160
- scrollBottomForce(true);
161
- setTimeout(function () {
162
- scrollBottomForce(true);
163
- }, 50);
164
- }, 0);
165
- _context.next = 35;
160
+ // 3. 滚动到底部:待稳定高度后再滚动
161
+ waitForStableHeight = function waitForStableHeight() {
162
+ var maxFrames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 32;
163
+ var lastHeight = -1;
164
+ var stableFrames = 0;
165
+ var frames = 0;
166
+ return new Promise(function (resolve) {
167
+ var tick = function tick() {
168
+ var container = containerRef.current;
169
+ if (!container) {
170
+ resolve();
171
+ return;
172
+ }
173
+ var h = container.scrollHeight;
174
+ if (h === lastHeight) {
175
+ stableFrames += 1;
176
+ } else {
177
+ stableFrames = 0;
178
+ lastHeight = h;
179
+ }
180
+ frames += 1;
181
+ if (stableFrames >= 2 || frames >= maxFrames) {
182
+ resolve();
183
+ return;
184
+ }
185
+ requestAnimationFrame(tick);
186
+ };
187
+ requestAnimationFrame(tick);
188
+ });
189
+ };
190
+ requestAnimationFrame(function () {
191
+ waitForStableHeight().then(function () {
192
+ scrollBottomForce(false);
193
+ });
194
+ });
195
+ _context.next = 36;
166
196
  break;
167
- case 27:
197
+ case 28:
168
198
  container = containerRef.current;
169
199
  if (container) {
170
200
  historyScrollRef.current = {
@@ -176,41 +206,41 @@ var useChatHistory = function useChatHistory(checkUnfinishedMessage, scrollBotto
176
206
  // 2. 更新数据
177
207
  // 判断是否需要重写推荐列表
178
208
  if (!((currentAgentObj === null || currentAgentObj === void 0 ? void 0 : currentAgentObj.isEnableRelated) === 1 && !((_lastUserRequestMessa = lastUserRequestMessage) !== null && _lastUserRequestMessa !== void 0 && _lastUserRequestMessa.relatedResourceList) && ((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.moduleType) === 'end' || (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.moduleType) === 'COMPLETED'))) {
179
- _context.next = 34;
209
+ _context.next = 35;
180
210
  break;
181
211
  }
182
- _context.next = 32;
212
+ _context.next = 33;
183
213
  return rewriteRecommendListFormHistory(newChatList, lastUserRequestMessage.chatId);
184
- case 32:
185
- _context.next = 35;
214
+ case 33:
215
+ _context.next = 36;
186
216
  break;
187
- case 34:
217
+ case 35:
188
218
  dispatch(setMessageList({
189
219
  messageList: newChatList
190
220
  }));
191
- case 35:
192
- _context.next = 38;
221
+ case 36:
222
+ _context.next = 39;
193
223
  break;
194
- case 37:
224
+ case 38:
195
225
  if (res.status === 1034) {
196
226
  Toast.error(res.message || '获取历史记录失败');
197
227
  }
198
- case 38:
228
+ case 39:
199
229
  isMoreLoadingRef.current = false;
200
230
  setIsMoreLoading(false);
201
- _context.next = 47;
231
+ _context.next = 48;
202
232
  break;
203
- case 42:
204
- _context.prev = 42;
233
+ case 43:
234
+ _context.prev = 43;
205
235
  _context.t0 = _context["catch"](5);
206
236
  console.error(_context.t0);
207
237
  isMoreLoadingRef.current = false;
208
238
  setIsMoreLoading(false);
209
- case 47:
239
+ case 48:
210
240
  case "end":
211
241
  return _context.stop();
212
242
  }
213
- }, _callee, null, [[5, 42]]);
243
+ }, _callee, null, [[5, 43]]);
214
244
  })), [checkUnfinishedMessage, containerRef, dispatch, getMessageList, param.pageIndex, param.pageSize, rewriteRecommendListFormHistory, scrollBottomForce]);
215
245
  var loadMore = useCallback(function () {
216
246
  if (!hasMore.current || isMoreLoadingRef.current || isMsgRecievingRef.current || !conversationIdRef.current) {
@@ -905,7 +905,7 @@ var useCommonChatAPI = function useCommonChatAPI(props) {
905
905
  } else {
906
906
  setMsgLoading(true);
907
907
  // 系统自动上传,直接开始会话,不更新列表
908
- startChat([].concat(_toConsumableArray(prevChatList), [userChat]), isSystemAuto, conversationId);
908
+ startChat(_toConsumableArray(prevChatList), isSystemAuto, conversationId);
909
909
  }
910
910
  case 24:
911
911
  case "end":
@@ -1131,24 +1131,24 @@ var useCommonChatAPI = function useCommonChatAPI(props) {
1131
1131
  Toast.error('无法连接到网络');
1132
1132
  return;
1133
1133
  }
1134
- if (status === 2 || msgLoading) {
1134
+ if (status === 2) {
1135
1135
  Toast.error('AI正在输出中,请稍后');
1136
1136
  return;
1137
1137
  }
1138
1138
  setMsgLoading(true);
1139
1139
  startChat(messageList, false, undefined, true);
1140
- }, [startChat, status, msgLoading]);
1140
+ }, [startChat, status]);
1141
1141
  React.useEffect(function () {
1142
- var _fileListRef$current;
1143
- var hasValidFile = ((_fileListRef$current = fileListRef.current) === null || _fileListRef$current === void 0 ? void 0 : _fileListRef$current.length) > 0;
1142
+ var hasValidFile = (fileList === null || fileList === void 0 ? void 0 : fileList.length) > 0;
1144
1143
  var messageList = messageListRef.current || [];
1145
1144
  var lastMessage = messageList[messageList.length - 1];
1145
+ var targetMessage = messageList[messageList.length - 2];
1146
1146
  if (hasValidFile && lastMessage) {
1147
1147
  setDisableSend(true);
1148
1148
  var uploadFile = fileList[0];
1149
1149
  var isLastMessageEmptyUserChat = (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.moduleType) === 'ask'; // 空内容
1150
+ // const isDerectlySend = Boolean(lastMessage.role === 0 && lastMessage.messageFiles?.content); // 最后一条消息是用户上传的excel
1150
1151
  if (!isLastMessageEmptyUserChat) {
1151
- var _fileList$, _messageList;
1152
1152
  var shouldEnableUpload = uploadFile.status === FileStatus.UPLOAD_FAILED || uploadFile.status === FileStatus.ANALYSE_FAILED;
1153
1153
  var newMessageList = [].concat(_toConsumableArray(messageList.slice(0, -2)), [_objectSpread(_objectSpread({}, messageList[messageList.length - 2]), {}, {
1154
1154
  disableUploadFile: !shouldEnableUpload
@@ -1159,11 +1159,9 @@ var useCommonChatAPI = function useCommonChatAPI(props) {
1159
1159
  messageList: newMessageList
1160
1160
  }));
1161
1161
  // 当有文件内容时处理请求
1162
- if ((_fileList$ = fileList[0]) !== null && _fileList$ !== void 0 && _fileList$.content && ((_messageList = messageList[messageList.length - 2]) === null || _messageList === void 0 ? void 0 : _messageList.moduleType) === 'ask') {
1163
- var _reverse$find2, _messageListRef$curre;
1164
- var moduleInfo = (_reverse$find2 = _toConsumableArray(messageList).reverse().find(function (v) {
1165
- return v.moduleType === 'ask';
1166
- })) === null || _reverse$find2 === void 0 ? void 0 : _reverse$find2.moduleInfo;
1162
+ if (uploadFile !== null && uploadFile !== void 0 && uploadFile.content && (targetMessage === null || targetMessage === void 0 ? void 0 : targetMessage.moduleType) === 'ask') {
1163
+ var _messageListRef$curre;
1164
+ var moduleInfo = targetMessage === null || targetMessage === void 0 ? void 0 : targetMessage.moduleInfo;
1167
1165
  var _inputModel = _defineProperty({}, "".concat(moduleInfo === null || moduleInfo === void 0 ? void 0 : moduleInfo.id, ".input"), '');
1168
1166
  inputModelRef.current = _inputModel;
1169
1167
  if (((_messageListRef$curre = messageListRef.current) === null || _messageListRef$curre === void 0 ? void 0 : _messageListRef$curre.length) > 0) {
@@ -26,8 +26,23 @@ var useScroll = function useScroll(containerRef) {
26
26
  scrollTimeout: 0,
27
27
  interactionTimer: null,
28
28
  lastScrollTop: 0,
29
- isUserInteracting: false
29
+ isUserInteracting: false,
30
+ wasAtBottom: true,
31
+ lastWheelAt: 0
30
32
  }).current;
33
+ var scrollBottomNow = React.useCallback(function () {
34
+ var tries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 4;
35
+ var count = 0;
36
+ var tick = function tick() {
37
+ var container = containerRef.current;
38
+ if (!container) return;
39
+ container.scrollTop = container.scrollHeight;
40
+ count += 1;
41
+ if (count < tries) requestAnimationFrame(tick);
42
+ };
43
+ requestAnimationFrame(tick);
44
+ setTimeout(tick, 0);
45
+ }, [containerRef]);
31
46
 
32
47
  // 标记用户交互状态
33
48
  var markUserInteraction = React.useCallback(function (isInteracting) {
@@ -50,18 +65,8 @@ var useScroll = function useScroll(containerRef) {
50
65
 
51
66
  // 基础滚动到底部
52
67
  var scrollBottom = React.useCallback(function () {
53
- var container = containerRef.current;
54
- if (container) {
55
- // 使用 requestAnimationFrame 确保在浏览器渲染前执行,
56
- // 并且如果一次不行,尝试在下一帧再做一次,以应对复杂的布局变化
57
- var doScroll = function doScroll() {
58
- container.scrollTop = container.scrollHeight;
59
- };
60
- requestAnimationFrame(doScroll);
61
- // 双重保证
62
- setTimeout(doScroll, 0);
63
- }
64
- }, [containerRef.current]);
68
+ scrollBottomNow(2);
69
+ }, [scrollBottomNow]);
65
70
 
66
71
  // 智能滚动到底部(只在非用户交互时执行)
67
72
  var throttledScrollToBottom = React.useCallback(throttle(function () {
@@ -78,15 +83,24 @@ var useScroll = function useScroll(containerRef) {
78
83
  markUserInteraction(false); // 重置为用户非交互状态
79
84
 
80
85
  if (animate) {
81
- container.scrollTo({
82
- top: container.scrollHeight,
83
- behavior: 'smooth'
84
- });
86
+ var smoothScroll = function smoothScroll() {
87
+ var current = containerRef.current;
88
+ if (!current) return;
89
+ current.scrollTo({
90
+ top: current.scrollHeight,
91
+ behavior: 'smooth'
92
+ });
93
+ };
94
+ smoothScroll();
95
+ setTimeout(smoothScroll, 120);
96
+ setTimeout(function () {
97
+ if (!refs.isUserInteracting) scrollBottomNow(3);
98
+ }, 420);
85
99
  } else {
86
100
  scrollBottom();
87
101
  }
88
102
  }
89
- }, [containerRef.current, markUserInteraction, scrollBottom]);
103
+ }, [containerRef.current, markUserInteraction, refs, scrollBottom, scrollBottomNow]);
90
104
 
91
105
  // 更新滚动位置
92
106
  var updateScrollHeight = React.useCallback(function () {
@@ -102,6 +116,7 @@ var useScroll = function useScroll(containerRef) {
102
116
  var handleWheel = React.useCallback(throttle(function (e) {
103
117
  var container = containerRef.current;
104
118
  if (!container) return;
119
+ refs.lastWheelAt = Date.now();
105
120
  var scrollTop = container.scrollTop,
106
121
  scrollHeight = container.scrollHeight,
107
122
  clientHeight = container.clientHeight;
@@ -113,7 +128,7 @@ var useScroll = function useScroll(containerRef) {
113
128
  } else if (e.deltaY > 2 && position <= bottomPosition) {
114
129
  markUserInteraction(false);
115
130
  }
116
- }, 100), [containerRef.current, bottomPosition, markUserInteraction]);
131
+ }, 100), [containerRef.current, bottomPosition, markUserInteraction, refs]);
117
132
  var handleScroll = React.useCallback(throttle(function () {
118
133
  if (!containerRef.current) return;
119
134
  var _containerRef$current2 = containerRef.current,
@@ -123,10 +138,14 @@ var useScroll = function useScroll(containerRef) {
123
138
  var position = Math.max(0, scrollHeight - clientHeight - scrollTop);
124
139
  setCurrentPosition(position);
125
140
  setIsScrolling(true);
141
+ refs.wasAtBottom = position <= bottomPosition * 2;
126
142
  var scrollDelta = scrollTop - refs.lastScrollTop;
127
143
  if (Math.abs(scrollDelta) > 2) {
128
144
  if (scrollDelta < 0) {
129
- markUserInteraction(true);
145
+ var now = Date.now();
146
+ if (refs.isUserInteracting || now - refs.lastWheelAt < 600) {
147
+ markUserInteraction(true);
148
+ }
130
149
  } else if (scrollDelta > 0 && position <= bottomPosition) {
131
150
  markUserInteraction(false);
132
151
  }
@@ -168,15 +187,8 @@ var useScroll = function useScroll(containerRef) {
168
187
  scrollHeight = container.scrollHeight,
169
188
  clientHeight = container.clientHeight;
170
189
  var distanceToBottom = scrollHeight - clientHeight - scrollTop;
171
-
172
- // 如果之前就在底部附近,则在新内容加入时保持在底部
173
- // 注意:这里的判定逻辑需要考虑到新内容可能还没撑开高度
174
- // 所以我们直接尝试在下一帧滚动
175
- if (distanceToBottom <= bottomPosition * 5) {
176
- // 稍微放宽判定范围,因为新内容可能已经改变了 scrollHeight
177
- requestAnimationFrame(function () {
178
- container.scrollTop = container.scrollHeight;
179
- });
190
+ if (refs.wasAtBottom || distanceToBottom <= bottomPosition * 5) {
191
+ scrollBottomNow(4);
180
192
  }
181
193
  });
182
194
  observer.observe(container, {
@@ -187,7 +199,7 @@ var useScroll = function useScroll(containerRef) {
187
199
  return function () {
188
200
  return observer.disconnect();
189
201
  };
190
- }, [containerRef.current, bottomPosition]);
202
+ }, [containerRef.current, bottomPosition, refs, scrollBottomNow]);
191
203
  return [throttledScrollToBottom, scrollBottomForce, currentPosition, scrollBottom, updateScrollHeight, isScrolling, isUserScroll];
192
204
  };
193
205
  export default useScroll;