Commit d5be7bb1383fefba2990d4ffd8f31e8b96dcf68b
1 parent
12faefcd
ai
Showing
4 changed files
with
125 additions
and
73 deletions
src/mobile/Ai/AiChatStyles.css
| @@ -460,6 +460,8 @@ body { | @@ -460,6 +460,8 @@ body { | ||
| 460 | background-color: #f3f3f3; | 460 | background-color: #f3f3f3; |
| 461 | z-index: 210; | 461 | z-index: 210; |
| 462 | left: 50%; | 462 | left: 50%; |
| 463 | - top: 10%; | 463 | + top: 2%; |
| 464 | transform: translateX(-50%); | 464 | transform: translateX(-50%); |
| 465 | + padding: 10px; | ||
| 466 | + overflow-y: auto; | ||
| 465 | } | 467 | } |
src/mobile/Ai/AiChatStyles.less
| @@ -483,7 +483,9 @@ body { | @@ -483,7 +483,9 @@ body { | ||
| 483 | background-color: #f3f3f3; | 483 | background-color: #f3f3f3; |
| 484 | z-index: 210; | 484 | z-index: 210; |
| 485 | left: 50%; | 485 | left: 50%; |
| 486 | - top: 10%; | 486 | + top: 2%; |
| 487 | transform: translateX(-50%); | 487 | transform: translateX(-50%); |
| 488 | + padding: 10px; | ||
| 489 | + overflow-y: auto; | ||
| 488 | } | 490 | } |
| 489 | } | 491 | } |
| 490 | \ No newline at end of file | 492 | \ No newline at end of file |
src/mobile/Ai/newAi.jsx
| 1 | import React, { useState, useEffect, useRef, useCallback } from 'react'; | 1 | import React, { useState, useEffect, useRef, useCallback } from 'react'; |
| 2 | import ReactMarkdown from 'react-markdown'; | 2 | import ReactMarkdown from 'react-markdown'; |
| 3 | import remarkGfm from 'remark-gfm'; | 3 | import remarkGfm from 'remark-gfm'; |
| 4 | -import { Button } from "antd-mobile"; | ||
| 5 | -import { LocationOutline, PhoneFill } from "antd-mobile-icons"; | 4 | +import { PhoneFill, LocationOutline } from "antd-mobile-icons"; |
| 6 | import './AiChatStyles.less'; | 5 | import './AiChatStyles.less'; |
| 7 | - | 6 | +import { Toast, Input, Tabs, Selector, Grid, Image, Button, Checkbox, Switch, Dialog, Radio, Space, CenterPopup, ImageViewer, Collapse, CapsuleTabs } from "antd-mobile"; |
| 7 | +import VConsole from 'vconsole'; | ||
| 8 | +let vConsole; | ||
| 8 | const ChatInterface = () => { | 9 | const ChatInterface = () => { |
| 9 | // ==================== 状态管理 ==================== | 10 | // ==================== 状态管理 ==================== |
| 10 | const [sessionId, setSessionId] = useState(''); | 11 | const [sessionId, setSessionId] = useState(''); |
| @@ -16,13 +17,17 @@ const ChatInterface = () => { | @@ -16,13 +17,17 @@ const ChatInterface = () => { | ||
| 16 | const [currentModel, setCurrentModel] = useState('general'); | 17 | const [currentModel, setCurrentModel] = useState('general'); |
| 17 | const [chatHistory, setChatHistory] = useState([]); | 18 | const [chatHistory, setChatHistory] = useState([]); |
| 18 | const [welcomeContent, setWelcomeContent] = useState(''); | 19 | const [welcomeContent, setWelcomeContent] = useState(''); |
| 20 | + vConsole = new VConsole(); | ||
| 21 | + | ||
| 19 | 22 | ||
| 20 | // 语音输入状态 | 23 | // 语音输入状态 |
| 21 | - const [isVoiceModel, setIsVoiceModel] = useState(false); | ||
| 22 | const [isRecording, setIsRecording] = useState(false); | 24 | const [isRecording, setIsRecording] = useState(false); |
| 25 | + const [isRecordingModel, setIsRecordingModel] = useState(false); | ||
| 23 | const [isWsConnected, setIsWsConnected] = useState(false); | 26 | const [isWsConnected, setIsWsConnected] = useState(false); |
| 24 | const [isVoiceMode, setIsVoiceMode] = useState(false); | 27 | const [isVoiceMode, setIsVoiceMode] = useState(false); |
| 25 | const [recordingDuration, setRecordingDuration] = useState(0); | 28 | const [recordingDuration, setRecordingDuration] = useState(0); |
| 29 | + const [isFlushing, setIsFlushing] = useState(false); | ||
| 30 | + const silenceTimeoutRef = useRef(null); // 静默超时定时器 | ||
| 26 | 31 | ||
| 27 | const messagesEndRef = useRef(null); | 32 | const messagesEndRef = useRef(null); |
| 28 | const inputRef = useRef(null); | 33 | const inputRef = useRef(null); |
| @@ -87,15 +92,30 @@ const ChatInterface = () => { | @@ -87,15 +92,30 @@ const ChatInterface = () => { | ||
| 87 | ws.onmessage = (event) => { | 92 | ws.onmessage = (event) => { |
| 88 | try { | 93 | try { |
| 89 | const res = JSON.parse(event.data); | 94 | const res = JSON.parse(event.data); |
| 90 | - if (res.code === 0 && (res.msg === "success" || res.msg === "flush_success")) { | ||
| 91 | - if (res.text && res.text.trim()) { | 95 | + if (res.code === 0) { |
| 96 | + // 处理普通识别结果 | ||
| 97 | + if ((res.msg === "success" || res.msg === "partial") && res.text?.trim()) { | ||
| 98 | + if (wsRef.current) { | ||
| 99 | + wsRef.current.hasReceivedSpeech = true; | ||
| 100 | + } | ||
| 92 | setInputValue(prev => { | 101 | setInputValue(prev => { |
| 93 | const separator = prev && !prev.endsWith(' ') ? ' ' : ''; | 102 | const separator = prev && !prev.endsWith(' ') ? ' ' : ''; |
| 94 | - const newValue = prev ? `${prev}${separator}${res.text}` : res.text; | ||
| 95 | - console.log('语音识别结果:', res.text, '更新后:', newValue); | ||
| 96 | - return newValue; | 103 | + return prev ? `${prev}${separator}${res.text}` : res.text; |
| 97 | }); | 104 | }); |
| 98 | } | 105 | } |
| 106 | + | ||
| 107 | + // 👇 新增:处理 flush 完成 | ||
| 108 | + if (res.msg === "flush_success") { | ||
| 109 | + console.log("Flush 完成,语音识别结束"); | ||
| 110 | + // 延迟一点确保所有消息处理完毕 | ||
| 111 | + setTimeout(() => { | ||
| 112 | + setIsFlushing(false); | ||
| 113 | + // 只有在语音模式下才清空(避免干扰手动输入) | ||
| 114 | + if (isVoiceMode) { | ||
| 115 | + setInputValue(''); | ||
| 116 | + } | ||
| 117 | + }, 100); | ||
| 118 | + } | ||
| 99 | } | 119 | } |
| 100 | } catch (e) { | 120 | } catch (e) { |
| 101 | console.error("WebSocket消息解析失败:", e); | 121 | console.error("WebSocket消息解析失败:", e); |
| @@ -161,20 +181,18 @@ const ChatInterface = () => { | @@ -161,20 +181,18 @@ const ChatInterface = () => { | ||
| 161 | // 开始录音 | 181 | // 开始录音 |
| 162 | const startRecording = async () => { | 182 | const startRecording = async () => { |
| 163 | if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { | 183 | if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { |
| 164 | - alert("浏览器不支持麦克风采集"); | 184 | + Toast.show('浏览器不支持麦克风'); |
| 165 | return; | 185 | return; |
| 166 | } | 186 | } |
| 167 | 187 | ||
| 168 | try { | 188 | try { |
| 169 | - // 先连接WebSocket | ||
| 170 | if (!isWsConnected) { | 189 | if (!isWsConnected) { |
| 171 | connectWebSocket(); | 190 | connectWebSocket(); |
| 172 | await new Promise(resolve => setTimeout(resolve, 1000)); | 191 | await new Promise(resolve => setTimeout(resolve, 1000)); |
| 173 | } | 192 | } |
| 174 | 193 | ||
| 175 | - // 检查 WebSocket 是否已连接 | ||
| 176 | if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) { | 194 | if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) { |
| 177 | - alert("语音识别服务未连接,请重试"); | 195 | + Toast.show('语音服务未连接'); |
| 178 | return; | 196 | return; |
| 179 | } | 197 | } |
| 180 | 198 | ||
| @@ -183,7 +201,6 @@ const ChatInterface = () => { | @@ -183,7 +201,6 @@ const ChatInterface = () => { | ||
| 183 | inputNodeRef.current = audioContextRef.current.createMediaStreamSource(stream); | 201 | inputNodeRef.current = audioContextRef.current.createMediaStreamSource(stream); |
| 184 | scriptProcessorRef.current = audioContextRef.current.createScriptProcessor(2048, 1, 1); | 202 | scriptProcessorRef.current = audioContextRef.current.createScriptProcessor(2048, 1, 1); |
| 185 | 203 | ||
| 186 | - // 使用 ref 来检查录音状态,避免闭包问题 | ||
| 187 | scriptProcessorRef.current.onaudioprocess = (event) => { | 204 | scriptProcessorRef.current.onaudioprocess = (event) => { |
| 188 | if (!isRecordingRef.current) return; | 205 | if (!isRecordingRef.current) return; |
| 189 | const inputData = event.inputBuffer.getChannelData(0); | 206 | const inputData = event.inputBuffer.getChannelData(0); |
| @@ -197,19 +214,34 @@ const ChatInterface = () => { | @@ -197,19 +214,34 @@ const ChatInterface = () => { | ||
| 197 | inputNodeRef.current.connect(scriptProcessorRef.current); | 214 | inputNodeRef.current.connect(scriptProcessorRef.current); |
| 198 | scriptProcessorRef.current.connect(audioContextRef.current.destination); | 215 | scriptProcessorRef.current.connect(audioContextRef.current.destination); |
| 199 | 216 | ||
| 200 | - // 关键:先设置 ref,再设置 state | 217 | + // 👇 关键:重置标志 + 启动静默检测 |
| 218 | + let hasReceivedSpeech = false; // 闭包变量,记录是否收到语音 | ||
| 219 | + | ||
| 220 | + // 保存到 ref,供 onmessage 使用 | ||
| 221 | + wsRef.current.hasReceivedSpeech = false; | ||
| 222 | + | ||
| 223 | + // 设置 3 秒静默超时 | ||
| 224 | + silenceTimeoutRef.current = setTimeout(() => { | ||
| 225 | + if (!wsRef.current?.hasReceivedSpeech) { | ||
| 226 | + console.log('3秒内未检测到语音,自动停止录音'); | ||
| 227 | + Toast.show('未检测到语音,请重新尝试'); | ||
| 228 | + handleSendMessage() | ||
| 229 | + } | ||
| 230 | + }, 3000); | ||
| 231 | + | ||
| 232 | + // 更新录音状态 | ||
| 201 | isRecordingRef.current = true; | 233 | isRecordingRef.current = true; |
| 202 | setIsRecording(true); | 234 | setIsRecording(true); |
| 203 | setIsVoiceMode(true); | 235 | setIsVoiceMode(true); |
| 204 | setRecordingDuration(0); | 236 | setRecordingDuration(0); |
| 205 | 237 | ||
| 206 | - // 开始计时 | ||
| 207 | recordingTimerRef.current = setInterval(() => { | 238 | recordingTimerRef.current = setInterval(() => { |
| 208 | setRecordingDuration(prev => prev + 1); | 239 | setRecordingDuration(prev => prev + 1); |
| 209 | }, 1000); | 240 | }, 1000); |
| 241 | + | ||
| 210 | } catch (e) { | 242 | } catch (e) { |
| 211 | console.error("录音启动失败:", e); | 243 | console.error("录音启动失败:", e); |
| 212 | - alert("录音启动失败:" + e.message); | 244 | + Toast.show('录音启动失败:' + (e.message || '未知错误')); |
| 213 | isRecordingRef.current = false; | 245 | isRecordingRef.current = false; |
| 214 | setIsRecording(false); | 246 | setIsRecording(false); |
| 215 | } | 247 | } |
| @@ -218,10 +250,15 @@ const ChatInterface = () => { | @@ -218,10 +250,15 @@ const ChatInterface = () => { | ||
| 218 | // 停止录音 | 250 | // 停止录音 |
| 219 | const stopRecording = useCallback(() => { | 251 | const stopRecording = useCallback(() => { |
| 220 | console.log("停止录音"); | 252 | console.log("停止录音"); |
| 253 | + // 👇 清理静默超时 | ||
| 254 | + if (silenceTimeoutRef.current) { | ||
| 255 | + clearTimeout(silenceTimeoutRef.current); | ||
| 256 | + silenceTimeoutRef.current = null; | ||
| 257 | + } | ||
| 221 | isRecordingRef.current = false; | 258 | isRecordingRef.current = false; |
| 222 | setIsRecording(false); | 259 | setIsRecording(false); |
| 223 | setIsVoiceMode(false); | 260 | setIsVoiceMode(false); |
| 224 | - | 261 | + setIsFlushing(true); |
| 225 | if (recordingTimerRef.current) { | 262 | if (recordingTimerRef.current) { |
| 226 | clearInterval(recordingTimerRef.current); | 263 | clearInterval(recordingTimerRef.current); |
| 227 | recordingTimerRef.current = null; | 264 | recordingTimerRef.current = null; |
| @@ -242,6 +279,9 @@ const ChatInterface = () => { | @@ -242,6 +279,9 @@ const ChatInterface = () => { | ||
| 242 | 279 | ||
| 243 | // 发送刷新指令获取最终结果 | 280 | // 发送刷新指令获取最终结果 |
| 244 | sendCommand("flush"); | 281 | sendCommand("flush"); |
| 282 | + setTimeout(() => { | ||
| 283 | + setInputValue('') | ||
| 284 | + }, 500); | ||
| 245 | }, [sendCommand]); | 285 | }, [sendCommand]); |
| 246 | 286 | ||
| 247 | // 切换录音状态(点击按钮) | 287 | // 切换录音状态(点击按钮) |
| @@ -406,17 +446,17 @@ const ChatInterface = () => { | @@ -406,17 +446,17 @@ const ChatInterface = () => { | ||
| 406 | } catch (error) { | 446 | } catch (error) { |
| 407 | console.error('请求失败:', error); | 447 | console.error('请求失败:', error); |
| 408 | const errorMessage = ` | 448 | const errorMessage = ` |
| 409 | - 抱歉,请求出现错误:${error.message} | 449 | +抱歉,请求出现错误:${error.message} |
| 410 | 450 | ||
| 411 | - **可能的原因:** | ||
| 412 | - 1. Spring Boot 后端服务未启动 | ||
| 413 | - 2. API 接口路径不正确 | ||
| 414 | - 3. 网络连接问题 | 451 | +**可能的原因:** |
| 452 | +1. Spring Boot 后端服务未启动 | ||
| 453 | +2. API 接口路径不正确 | ||
| 454 | +3. 网络连接问题 | ||
| 415 | 455 | ||
| 416 | - **检查步骤:** | ||
| 417 | - 1. 确保后端服务在端口 8099 运行 | ||
| 418 | - 2. 检查浏览器控制台查看详细错误 | ||
| 419 | - 3. 刷新页面重试 | 456 | +**检查步骤:** |
| 457 | +1. 确保后端服务在端口 8099 运行 | ||
| 458 | +2. 检查浏览器控制台查看详细错误 | ||
| 459 | +3. 刷新页面重试 | ||
| 420 | `; | 460 | `; |
| 421 | addMessage(errorMessage, 'ai', true); | 461 | addMessage(errorMessage, 'ai', true); |
| 422 | } finally { | 462 | } finally { |
| @@ -465,15 +505,32 @@ const ChatInterface = () => { | @@ -465,15 +505,32 @@ const ChatInterface = () => { | ||
| 465 | const handleModelChange = (e) => { | 505 | const handleModelChange = (e) => { |
| 466 | setCurrentModel(e.target.value); | 506 | setCurrentModel(e.target.value); |
| 467 | }; | 507 | }; |
| 468 | - // 录音弹窗 | ||
| 469 | - const handlePhone = () => { | ||
| 470 | - setIsVoiceModel(true) | ||
| 471 | - startRecording(); | ||
| 472 | - } | ||
| 473 | - | ||
| 474 | // ==================== 渲染 ==================== | 508 | // ==================== 渲染 ==================== |
| 475 | return ( | 509 | return ( |
| 476 | <div className="ai-chat-container"> | 510 | <div className="ai-chat-container"> |
| 511 | + {/* 头部 */} | ||
| 512 | + {/* <div className="chat-header"> | ||
| 513 | + <div className="header-left"> | ||
| 514 | + <h1>小羚羊Ai-agent智能体</h1> | ||
| 515 | + <p>AI 印刷助手</p> | ||
| 516 | + </div> | ||
| 517 | + <div className="header-right"> | ||
| 518 | + <select | ||
| 519 | + className="model-selector" | ||
| 520 | + value={currentModel} | ||
| 521 | + onChange={handleModelChange} | ||
| 522 | + > | ||
| 523 | + <option value="process">小羚羊印刷行业大模型</option> | ||
| 524 | + <option value="general">qwen2.5:14b</option> | ||
| 525 | + </select> | ||
| 526 | + <button | ||
| 527 | + className="model-selectors" | ||
| 528 | + onClick={handleClearChat} | ||
| 529 | + > | ||
| 530 | + 清空对话 | ||
| 531 | + </button> | ||
| 532 | + </div> | ||
| 533 | + </div> */} | ||
| 477 | <Button | 534 | <Button |
| 478 | className="model-Button" | 535 | className="model-Button" |
| 479 | onClick={handleClearChat} | 536 | onClick={handleClearChat} |
| @@ -557,7 +614,7 @@ const ChatInterface = () => { | @@ -557,7 +614,7 @@ const ChatInterface = () => { | ||
| 557 | {/* 输入区域 */} | 614 | {/* 输入区域 */} |
| 558 | <div className="input-section"> | 615 | <div className="input-section"> |
| 559 | {/* 语音模式提示 - 仅在录音时显示 */} | 616 | {/* 语音模式提示 - 仅在录音时显示 */} |
| 560 | - {/* {isRecording && ( | 617 | + {isRecording && ( |
| 561 | <div className="voice-mode-indicator"> | 618 | <div className="voice-mode-indicator"> |
| 562 | <div className="voice-wave"> | 619 | <div className="voice-wave"> |
| 563 | <span></span> | 620 | <span></span> |
| @@ -576,7 +633,7 @@ const ChatInterface = () => { | @@ -576,7 +633,7 @@ const ChatInterface = () => { | ||
| 576 | 取消 | 633 | 取消 |
| 577 | </button> | 634 | </button> |
| 578 | </div> | 635 | </div> |
| 579 | - )} */} | 636 | + )} |
| 580 | 637 | ||
| 581 | <div className="input-wrapper"> | 638 | <div className="input-wrapper"> |
| 582 | <input | 639 | <input |
| @@ -599,8 +656,10 @@ const ChatInterface = () => { | @@ -599,8 +656,10 @@ const ChatInterface = () => { | ||
| 599 | disabled={isLoading} | 656 | disabled={isLoading} |
| 600 | readOnly={isRecording} | 657 | readOnly={isRecording} |
| 601 | /> | 658 | /> |
| 602 | - <PhoneFill className='input-icon' onClick={handlePhone} /> | ||
| 603 | - | 659 | + <PhoneFill className='input-icon' onClick={() => { |
| 660 | + setIsRecordingModel(true) | ||
| 661 | + startRecording() | ||
| 662 | + }} /> | ||
| 604 | <LocationOutline className='input-icon' onClick={handleSendMessage} | 663 | <LocationOutline className='input-icon' onClick={handleSendMessage} |
| 605 | disabled={isLoading || isRecording} /> | 664 | disabled={isLoading || isRecording} /> |
| 606 | {/* 语音按钮 - 点击切换录音状态 */} | 665 | {/* 语音按钮 - 点击切换录音状态 */} |
| @@ -618,9 +677,9 @@ const ChatInterface = () => { | @@ -618,9 +677,9 @@ const ChatInterface = () => { | ||
| 618 | <span className="voice-text">点击录音</span> | 677 | <span className="voice-text">点击录音</span> |
| 619 | </> | 678 | </> |
| 620 | )} | 679 | )} |
| 621 | - </button> */} | 680 | + </button> |
| 622 | 681 | ||
| 623 | - {/* <button | 682 | + <button |
| 624 | className={`send-button ${isLoading ? 'disabled' : ''}`} | 683 | className={`send-button ${isLoading ? 'disabled' : ''}`} |
| 625 | onClick={handleSendMessage} | 684 | onClick={handleSendMessage} |
| 626 | disabled={isLoading || isRecording} | 685 | disabled={isLoading || isRecording} |
| @@ -631,44 +690,33 @@ const ChatInterface = () => { | @@ -631,44 +690,33 @@ const ChatInterface = () => { | ||
| 631 | </div> | 690 | </div> |
| 632 | </div> | 691 | </div> |
| 633 | </div> | 692 | </div> |
| 693 | + | ||
| 634 | { | 694 | { |
| 635 | - isVoiceModel ? | ||
| 636 | - <div className='phone-model phone-zhezhao'> | 695 | + isRecordingModel ? |
| 696 | + <div className='phone-model'> | ||
| 637 | <div className='phone-zhezhao'></div> | 697 | <div className='phone-zhezhao'></div> |
| 638 | <div className='phone-content'> | 698 | <div className='phone-content'> |
| 639 | - | ||
| 640 | - </div> | ||
| 641 | - {/* 语音模式提示 - 仅在录音时显示 */} | ||
| 642 | - {isRecording && ( | ||
| 643 | - <div className="voice-mode-indicator"> | ||
| 644 | - <div className="voice-wave"> | ||
| 645 | - <span></span> | ||
| 646 | - <span></span> | ||
| 647 | - <span></span> | ||
| 648 | - <span></span> | ||
| 649 | - <span></span> | 699 | + {inputValue.trim() && ( |
| 700 | + <div className="message user-message"> | ||
| 701 | + <div className="message-bubble user-bubble"> | ||
| 702 | + <div className="message-content"> | ||
| 703 | + {inputValue} | ||
| 704 | + </div> | ||
| 705 | + <div className="message-meta"> | ||
| 706 | + <span className="message-time">{getCurrentTime()}</span> | ||
| 707 | + </div> | ||
| 708 | + </div> | ||
| 650 | </div> | 709 | </div> |
| 651 | - <span className="voice-text"> | ||
| 652 | - 正在录音 {formatDuration(recordingDuration)} | ||
| 653 | - </span> | ||
| 654 | - <button | ||
| 655 | - className="voice-cancel-btn" | ||
| 656 | - onClick={cancelRecording} | ||
| 657 | - > | ||
| 658 | - 取消 | ||
| 659 | - </button> | ||
| 660 | - </div> | ||
| 661 | - )} | ||
| 662 | - <div className='phone-phone' onClick={() => { | ||
| 663 | - stopRecording() | ||
| 664 | - setIsVoiceModel(false) | ||
| 665 | - }}> | ||
| 666 | - <PhoneFill color='red' /> | 710 | + )} |
| 711 | + </div> | ||
| 712 | + <div className='phone-phone'> | ||
| 713 | + <PhoneFill color='red' onClick={() => { | ||
| 714 | + setIsRecordingModel(false) | ||
| 715 | + stopRecording() | ||
| 716 | + }} /> | ||
| 667 | </div> | 717 | </div> |
| 668 | - | ||
| 669 | </div> : '' | 718 | </div> : '' |
| 670 | } | 719 | } |
| 671 | - | ||
| 672 | </div> | 720 | </div> |
| 673 | ); | 721 | ); |
| 674 | }; | 722 | }; |
src/utils/config.js
| @@ -9,7 +9,7 @@ const API = process.env.API; | @@ -9,7 +9,7 @@ const API = process.env.API; | ||
| 9 | const bHttps = false; | 9 | const bHttps = false; |
| 10 | export const webSite = { | 10 | export const webSite = { |
| 11 | faceAddress: isDev ? '//km5cjx.gnway.cc:36867/xlyFace' : '//' + location.host + '/xlyFace', | 11 | faceAddress: isDev ? '//km5cjx.gnway.cc:36867/xlyFace' : '//' + location.host + '/xlyFace', |
| 12 | - ipAddress: localStorage.ipAddress ? localStorage.ipAddress : isDev ? '//118.178.19.35:9198/xlyEntry_saas/' : '//' + location.host + '/xlyEntry/', | 12 | + ipAddress: localStorage.ipAddress ? localStorage.ipAddress : isDev ? '//118.178.19.35:9198/xlyEntry_saas/' : '//118.178.19.35:9198/xlyEntry_saas/', |
| 13 | 13 | ||
| 14 | // ipAddress: localStorage.ipAddress ? localStorage.ipAddress : isDev ? '//118.178.19.35:8088/xlyEntry/' : '//' + location.host + '/xlyEntry/', | 14 | // ipAddress: localStorage.ipAddress ? localStorage.ipAddress : isDev ? '//118.178.19.35:8088/xlyEntry/' : '//' + location.host + '/xlyEntry/', |
| 15 | // ipAddress: localStorage.ipAddress ? localStorage.ipAddress : isDev ? '//km5cjx.gnway.cc:36867/xlyEntry/' : '//' + location.host + '/xlyEntry/', | 15 | // ipAddress: localStorage.ipAddress ? localStorage.ipAddress : isDev ? '//km5cjx.gnway.cc:36867/xlyEntry/' : '//' + location.host + '/xlyEntry/', |