@zjw-jszn/shared-imsdk 1.0.8 → 1.0.10

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.
@@ -1,4 +1,4 @@
1
- const __SHARED_IMSDK_CSS__ = ".confirm-dialog-mask[data-v-69eaf313] {\n position: fixed;\n z-index: 12000;\n inset: 0;\n\n background: rgba(15, 23, 42, 0.35);\n backdrop-filter: blur(2px);\n}\n.confirm-dialog[data-v-69eaf313] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n width: min(420px, calc(100vw - 32px));\n border: 1px solid #e8edf4;\n border-radius: 12px;\n\n background: #fff;\n box-shadow: 0 18px 48px rgba(15, 23, 42, 0.22);\n}\n.confirm-dialog-header[data-v-69eaf313] {\n padding: 16px 18px 8px;\n}\n.confirm-dialog-title[data-v-69eaf313] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1f2937;\n}\n.confirm-dialog-body[data-v-69eaf313] {\n padding: 0 18px 10px;\n}\n.confirm-dialog-message[data-v-69eaf313] {\n margin: 0;\n font-size: 14px;\n line-height: 1.55;\n color: #4b5563;\n}\n.confirm-dialog-error[data-v-69eaf313] {\n margin: 10px 0 0;\n font-size: 13px;\n line-height: 1.45;\n color: #cf1322;\n}\n.confirm-dialog-footer[data-v-69eaf313] {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n padding: 14px 18px 18px;\n}\n.dialog-btn[data-v-69eaf313] {\n cursor: pointer;\n\n min-width: 80px;\n height: 34px;\n padding: 0 14px;\n border: 1px solid transparent;\n border-radius: 8px;\n\n font-size: 14px;\n\n transition: all 0.2s ease;\n}\n.dialog-btn[data-v-69eaf313]:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n.cancel-btn[data-v-69eaf313] {\n border-color: #d9d9d9;\n color: #595959;\n background: #fff;\n}\n.cancel-btn[data-v-69eaf313]:hover:not(:disabled) {\n border-color: #bfbfbf;\n color: #262626;\n background: #fafafa;\n}\n.confirm-btn[data-v-69eaf313] {\n border-color: #0e77cc;\n color: #fff;\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n}\n.confirm-btn[data-v-69eaf313]:hover:not(:disabled) {\n border-color: #0d6db8;\n filter: brightness(1.03);\n}\n.v3-body-inner{scroll-behavior:smooth;scrollbar-color:#393d3f rgba(0,0,0,.1);scrollbar-width:thin}.v3-body-inner::-webkit-scrollbar{width:8px}.v3-body-inner::-webkit-scrollbar-track{background-color:transparent}.v3-body-inner::-webkit-scrollbar-thumb{display:none;background:rgba(0,0,0,.3);border-radius:5px}.v3-body-inner:hover::-webkit-scrollbar-thumb{display:block}.v3-emoji-picker{height:320px;width:280px;box-shadow:0 2px 10px #0003;border-radius:10px;margin:0 auto;box-sizing:border-box;display:flex;flex-direction:column;text-align:left}.v3-emoji-picker *{box-sizing:border-box}.v3-emoji-picker .v3-header{padding:15px 15px 13px;border-bottom:1px solid}.v3-emoji-picker .v3-header .v3-groups{display:flex}.v3-emoji-picker .v3-header .v3-groups .v3-group{flex-grow:1;padding:0;margin:0;border:none;background:none;font-size:23px;cursor:pointer;position:relative;display:block;opacity:.7;transition:.2s}.v3-emoji-picker .v3-header .v3-groups .v3-group.v3-is-hidden{display:none}.v3-emoji-picker .v3-header .v3-groups .v3-group:first-child,.v3-emoji-picker .v3-header .v3-groups .v3-group:last-child{flex-grow:0}.v3-emoji-picker .v3-header .v3-groups .v3-group:hover{opacity:1}.v3-emoji-picker .v3-header .v3-groups .v3-group span{display:flex;align-items:center;justify-content:center}.v3-emoji-picker .v3-header .v3-groups .v3-group span img{display:block;width:1em;height:auto}.v3-emoji-picker .v3-spacing{height:11px}.v3-emoji-picker .v3-search input{width:100%;display:block;height:26px;padding:0 10px;border:1px solid;border-radius:3px;font-size:12px;transition:.2s}.v3-emoji-picker .v3-search input:focus{outline:none}.v3-emoji-picker .v3-body{padding:0 0 15px 11px;min-height:0;flex-grow:1}.v3-emoji-picker .v3-body .v3-body-inner{flex-grow:1;min-height:0;overflow-y:auto;overflow-x:hidden;height:100%;padding-right:11px}.v3-emoji-picker .v3-body .v3-body-inner .v3-group h5{margin:0;top:0;padding:7px 0 3px 4px;z-index:2}.v3-emoji-picker .v3-body .v3-body-inner .v3-group h5.v3-sticky{position:sticky}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis{display:flex;font-size:18px;flex-wrap:wrap}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button{cursor:pointer;border:none;background:none;margin:0;text-align:center;display:flex;align-items:center;justify-content:center;flex-basis:12.5%;max-width:12.5%;flex-grow:1;padding:0;font-size:22px;position:relative}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button:after{content:\"\";width:100%;padding-bottom:100%}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button span{display:flex;align-items:center;justify-content:center}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button img{max-width:100%;padding:4px}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button span,.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button img{position:absolute;top:0;left:0;width:100%;height:100%}.v3-emoji-picker .v3-body .v3-body-inner.is-mac .v3-emojis button{font-family:\"Apple Color Emoji\"}.v3-emoji-picker .v3-footer{font-size:14px;border-top:1px solid #dddddd;padding:15px;display:flex;align-items:center;justify-content:space-between;position:relative}.v3-emoji-picker .v3-footer .v3-tone,.v3-emoji-picker .v3-footer .v3-foot-left{display:flex;align-items:center}.v3-emoji-picker .v3-footer .v3-tone img,.v3-emoji-picker .v3-footer .v3-foot-left img{width:20px;display:block}.v3-emoji-picker .v3-footer .v3-tone>span:first-child,.v3-emoji-picker .v3-footer .v3-foot-left>span:first-child{margin-right:6px}.v3-emoji-picker .v3-footer .v3-foot-left>span.v3-text{max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.v3-emoji-picker .v3-footer .v3-tone{border:none;padding:0;background:none;cursor:pointer;display:inline-flex;align-items:center}.v3-emoji-picker .v3-footer .v3-tone>span{display:inline-flex;vertical-align:top}.v3-emoji-picker .v3-footer .v3-tone .v3-text{font-size:13px}.v3-emoji-picker .v3-footer .v3-tone .v3-icon{display:inline-flex;height:15px;width:15px;vertical-align:middle;align-self:center;border:2px solid rgba(0,0,0,.2)}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-neutral{background-color:#ffd225}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3fb{background-color:#ffdfbd}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3fc{background-color:#e9c197}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3fd{background-color:#c88e62}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3fe{background-color:#a86637}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3ff{background-color:#60463a}.v3-emoji-picker .v3-footer .v3-tone .is-mac span{font-family:\"Apple Color Emoji\"}.v3-skin-tones{position:absolute;height:100%;width:60%;top:0;left:0;display:flex;align-items:center;justify-content:flex-end;padding:0 15px;opacity:0;visibility:hidden;transition:.2s;border-radius:0 0 10px 10px}.v3-skin-tones.v3-is-open{opacity:1;visibility:visible}.v3-skin-tones .v3-skin-tone{display:inline-block;height:15px;width:25px;border:none;padding:0;cursor:pointer;transition:0ms}.v3-skin-tones .v3-skin-tone:hover{transform:scale(1.1);transition:.2s}.v3-skin-tones .v3-skin-tone-neutral{color:#ffd225;background-color:#ffd225}.v3-skin-tones .v3-skin-tone-1f3fb{color:#ffdfbd;background-color:#ffdfbd}.v3-skin-tones .v3-skin-tone-1f3fc{color:#e9c197;background-color:#e9c197}.v3-skin-tones .v3-skin-tone-1f3fd{color:#c88e62;background-color:#c88e62}.v3-skin-tones .v3-skin-tone-1f3fe{color:#a86637;background-color:#a86637}.v3-skin-tones .v3-skin-tone-1f3ff{color:#60463a;background-color:#60463a}.v3-input-emoji-picker *{box-sizing:border-box}.v3-input-emoji-picker .v3-input-picker-root{position:relative}.v3-input-emoji-picker .v3-input-picker-root .v3-emoji-picker-input,.v3-input-emoji-picker .v3-input-picker-root .v3-emoji-picker-textarea{width:100%;height:40px;border:1px solid #999;padding-left:15px}.v3-input-emoji-picker .v3-input-picker-root .v3-emoji-picker-textarea{min-height:80px;resize:vertical}.v3-input-emoji-picker .v3-input-picker-root .v3-emoji-picker-textarea+.v3-input-picker-wrap .v3-input-picker-icon{top:auto;bottom:5px}.v3-input-emoji-picker .v3-input-picker-root .v3-input-picker-wrap .v3-input-picker-icon{display:inline-flex;position:absolute;right:5px;top:50%;transform:translateY(-50%);font-size:24px;border:none;background:none;padding:0 5px;cursor:pointer}.v3-input-emoji-picker .v3-input-picker-root .v3-input-picker-wrap .v3-input-picker-icon img{display:block;width:1em;height:1em}.v3-input-emoji-picker .v3-input-picker-root .v3-input-picker-wrap .v3-emoji-picker{opacity:0;visibility:hidden;transition:.2s}.v3-input-emoji-picker .v3-input-picker-root .v3-input-picker-wrap.v3-picker-is-open .v3-emoji-picker{opacity:1;visibility:visible;z-index:999}.v3-emoji-picker{--v3-picker-bg: #ffffff;--v3-picker-fg: #000000;--v3-picker-border: #dddddd;--v3-picker-input-bg: var(--v3-picker-bg);--v3-picker-input-border: #cccccc;--v3-picker-input-focus-border: #000000;--v3-group-image-filter: none;--v3-picker-emoji-hover: #f7f7f7;background:var(--v3-picker-bg);color:var(--v3-picker-fg)}.v3-emoji-picker .v3-footer,.v3-emoji-picker .v3-header{border-color:var(--v3-picker-border)}.v3-emoji-picker .v3-groups{filter:var(--v3-group-image-filter)}.v3-emoji-picker .v3-tone{color:var(--v3-picker-fg)}.v3-emoji-picker .v3-search input{background:var(--v3-picker-input-bg);border-color:var(--v3-picker-input-border);color:inherit}.v3-emoji-picker .v3-search input:focus{border-color:var(--v3-picker-input-focus-border)}.v3-emoji-picker .v3-body .v3-body-inner .v3-group h5,.v3-emoji-picker .v3-skin-tones{background:var(--v3-picker-bg)}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button:hover{background:var(--v3-picker-emoji-hover, #f7f7f7)}@media (prefers-color-scheme: dark){.v3-emoji-picker.v3-color-theme-auto{--v3-picker-bg: #000000;--v3-picker-fg: #ffffff;--v3-picker-border: #333333;--v3-picker-input-bg: #222222;--v3-picker-input-border: #444444;--v3-picker-input-focus-border: #555555;--v3-group-image-filter: invert(1);--v3-picker-emoji-hover: #222222}}.v3-emoji-picker.v3-color-theme-dark{--v3-picker-bg: #000000;--v3-picker-fg: #ffffff;--v3-picker-border: #333333;--v3-picker-input-bg: #222222;--v3-picker-input-border: #444444;--v3-picker-input-focus-border: #555555;--v3-group-image-filter: invert(1);--v3-picker-emoji-hover: #222222}\n\n.chat-room[data-v-cc3cfaa7] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #fff;\n}\n.chat-room-header[data-v-cc3cfaa7] {\n display: flex;\n gap: 12px;\n align-items: center;\n\n padding: 8px 20px;\n border-bottom: 1px solid #e8e8e8;\n\n background: linear-gradient(180deg, #fff 0%, #fafafa 100%);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n.back-btn[data-v-cc3cfaa7] {\n cursor: pointer;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 50%;\n\n font-size: 16px;\n color: #595959;\n\n background: #f0f0f0;\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.back-btn[data-v-cc3cfaa7]:hover {\n transform: scale(1.05);\n color: #0e77cc;\n background: #e8e8e8;\n}\n.back-btn[data-v-cc3cfaa7]:active {\n transform: scale(0.95);\n}\n.title[data-v-cc3cfaa7] {\n display: flex;\n flex: 1;\n gap: 12px;\n align-items: center;\n}\n.header-actions[data-v-cc3cfaa7] {\n display: flex;\n flex-shrink: 0;\n align-items: flex-end;\n}\n.end-session-btn[data-v-cc3cfaa7] {\n cursor: pointer;\n\n min-width: 90px;\n height: 32px;\n padding: 0 12px;\n border: 1px solid #ffd6d6;\n border-radius: 16px;\n\n font-size: 13px;\n font-weight: 500;\n color: #d4380d;\n\n background: #fff2f0;\n\n transition: all 0.2s ease;\n}\n.end-session-btn[data-v-cc3cfaa7]:hover:not(:disabled) {\n border-color: #ffb3ad;\n background: #ffe7e2;\n}\n.end-session-btn[data-v-cc3cfaa7]:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n.avatar-wrapper[data-v-cc3cfaa7] {\n position: relative;\n flex-shrink: 0;\n width: 42px;\n height: 42px;\n}\n.avatar-img[data-v-cc3cfaa7] {\n width: 100%;\n height: 100%;\n border: 2px solid white;\n border-radius: 50%;\n\n object-fit: cover;\n background: linear-gradient(135deg, #f0f0f0 0%, #e8e8e8 100%);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n.avatar-text[data-v-cc3cfaa7] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 42px;\n height: 42px;\n border: 2px solid white;\n border-radius: 50%;\n\n font-size: 16px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 8px rgba(14, 119, 204, 0.3);\n}\n.user-info[data-v-cc3cfaa7] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.name[data-v-cc3cfaa7] {\n font-size: 15px;\n font-weight: 600;\n color: #262626;\n letter-spacing: 0.2px;\n}\n.messages[data-v-cc3cfaa7] {\n position: relative;\n\n overflow-y: auto;\n flex: 1;\n\n padding: 24px 20px;\n\n background: linear-gradient(180deg, #f5f5f5 0%, #fafafa 100%);\n}\n\n/* 自定义滚动条 */\n.messages[data-v-cc3cfaa7]::-webkit-scrollbar {\n width: 6px;\n}\n.messages[data-v-cc3cfaa7]::-webkit-scrollbar-track {\n background: transparent;\n}\n.messages[data-v-cc3cfaa7]::-webkit-scrollbar-thumb {\n border-radius: 3px;\n background: #d9d9d9;\n}\n.messages[data-v-cc3cfaa7]::-webkit-scrollbar-thumb:hover {\n background: #bfbfbf;\n}\n.loading-more[data-v-cc3cfaa7] {\n display: flex;\n gap: 8px;\n align-items: center;\n justify-content: center;\n\n padding: 16px;\n\n font-size: 13px;\n color: #8c8c8c;\n}\n.loading-spinner-small[data-v-cc3cfaa7] {\n width: 20px;\n height: 20px;\n border: 2px solid #f0f0f0;\n border-top: 2px solid #0e77cc;\n border-radius: 50%;\n\n animation: spin-cc3cfaa7 0.8s linear infinite;\n}\n.no-more[data-v-cc3cfaa7] {\n padding: 12px;\n font-size: 12px;\n color: #bfbfbf;\n text-align: center;\n}\n.loading-state[data-v-cc3cfaa7] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n padding: 60px 20px;\n\n color: #bfbfbf;\n}\n.loading-spinner[data-v-cc3cfaa7] {\n width: 40px;\n height: 40px;\n margin-bottom: 16px;\n border: 3px solid #f0f0f0;\n border-top: 3px solid #0e77cc;\n border-radius: 50%;\n\n animation: spin-cc3cfaa7 0.8s linear infinite;\n}\n@keyframes spin-cc3cfaa7 {\n0% { transform: rotate(0deg);\n}\n100% { transform: rotate(360deg);\n}\n}\n.empty-messages[data-v-cc3cfaa7] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n height: 100%;\n\n color: #bfbfbf;\n}\n.empty-messages .icon[data-v-cc3cfaa7] {\n margin-bottom: 16px;\n font-size: 64px;\n opacity: 0.5;\n}\n.empty-messages p[data-v-cc3cfaa7] {\n margin: 0;\n font-size: 14px;\n font-weight: 400;\n}\n.message-item[data-v-cc3cfaa7] {\n display: flex;\n gap: 12px;\n margin-bottom: 24px;\n animation: slide-in-cc3cfaa7 0.3s ease-out;\n}\n@keyframes slide-in-cc3cfaa7 {\nfrom {\n transform: translateY(10px);\n opacity: 0;\n}\nto {\n transform: translateY(0);\n opacity: 1;\n}\n}\n.message-item.is-self[data-v-cc3cfaa7] {\n justify-content: flex-end;\n}\n.msg-avatar-wrapper[data-v-cc3cfaa7] {\n position: relative;\n flex-shrink: 0;\n width: 40px;\n height: 40px;\n}\n.msg-avatar-img[data-v-cc3cfaa7] {\n width: 100%;\n height: 100%;\n border: 2px solid white;\n border-radius: 50%;\n\n object-fit: cover;\n background: linear-gradient(135deg, #f0f0f0 0%, #e8e8e8 100%);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);\n}\n.msg-avatar[data-v-cc3cfaa7] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 40px;\n height: 40px;\n border: 2px solid white;\n border-radius: 50%;\n\n font-size: 15px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 6px rgba(14, 119, 204, 0.3);\n}\n.message-content-wrapper[data-v-cc3cfaa7] {\n display: flex;\n flex-direction: column;\n max-width: 65%;\n}\n.is-self .message-content-wrapper[data-v-cc3cfaa7] {\n align-items: flex-end;\n}\n.message-sender[data-v-cc3cfaa7] {\n margin-bottom: 6px;\n font-size: 12px;\n font-weight: 400;\n color: #8c8c8c;\n}\n.message-content[data-v-cc3cfaa7] {\n padding: 12px 16px;\n border-radius: 12px;\n\n background-color: white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n\n transition: all 0.2s;\n}\n.message-item.is-self .message-content[data-v-cc3cfaa7] {\n color: white;\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 8px rgba(14, 119, 204, 0.25);\n}\n.message-text[data-v-cc3cfaa7] {\n margin-bottom: 6px;\n\n font-size: 14px;\n line-height: 1.6;\n color: #262626;\n overflow-wrap: break-word;\n}\n.message-item.is-self .message-text[data-v-cc3cfaa7] {\n color: white;\n}\n\n/* 图片消息 */\n.message-image[data-v-cc3cfaa7] {\n margin-bottom: 6px;\n}\n.message-image img[data-v-cc3cfaa7] {\n cursor: pointer;\n\n max-width: 300px;\n max-height: 300px;\n border-radius: 8px;\n\n object-fit: cover;\n\n transition: transform 0.2s;\n}\n.message-image img[data-v-cc3cfaa7]:hover {\n transform: scale(1.02);\n}\n\n/* 表情消息 */\n.message-emoji[data-v-cc3cfaa7] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-height: 60px;\n margin-bottom: 6px;\n\n font-size: 48px;\n line-height: 1;\n}\n\n/* 文件消息 */\n.message-file[data-v-cc3cfaa7] {\n margin-bottom: 6px;\n}\n.file-link[data-v-cc3cfaa7] {\n display: inline-flex;\n gap: 8px;\n align-items: center;\n\n padding: 12px 16px;\n border-radius: 8px;\n\n font-size: 14px;\n font-weight: 500;\n color: #262626;\n text-decoration: none;\n\n background-color: #f5f5f5;\n\n transition: all 0.2s;\n}\n.file-link[data-v-cc3cfaa7]:hover {\n color: #0e77cc;\n background-color: #e8e8e8;\n}\n.is-self .file-link[data-v-cc3cfaa7] {\n color: white;\n background-color: rgba(255, 255, 255, 0.2);\n}\n.is-self .file-link[data-v-cc3cfaa7]:hover {\n background-color: rgba(255, 255, 255, 0.3);\n}\n\n/* 系统通知 */\n.message-system[data-v-cc3cfaa7] {\n margin-bottom: 6px;\n padding: 8px 12px;\n border-left: 3px solid #0e77cc;\n border-radius: 6px;\n\n font-size: 13px;\n color: #8c8c8c;\n text-align: center;\n\n background-color: #f5f5f5;\n}\n.is-self .message-system[data-v-cc3cfaa7] {\n border-left-color: white;\n color: rgba(255, 255, 255, 0.9);\n background-color: rgba(255, 255, 255, 0.2);\n}\n\n/* 卡片消息 */\n.message-card[data-v-cc3cfaa7] {\n margin-bottom: 6px;\n padding: 12px;\n border: 1px solid #bae6fd;\n border-radius: 8px;\n\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n}\n.is-self .message-card[data-v-cc3cfaa7] {\n border-color: rgba(255, 255, 255, 0.3);\n background: rgba(255, 255, 255, 0.2);\n}\n.message-time[data-v-cc3cfaa7] {\n font-size: 11px;\n color: #8c8c8c;\n}\n.message-item.is-self .message-time[data-v-cc3cfaa7] {\n color: rgba(255, 255, 255, 0.75);\n}\n.input-area[data-v-cc3cfaa7] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n padding: 16px 20px;\n border-top: 1px solid #e8e8e8;\n\n background: white;\n box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.04);\n}\n\n/* 工具栏 */\n.input-toolbar[data-v-cc3cfaa7] {\n display: flex;\n gap: 8px;\n padding: 4px 0;\n}\n.tool-btn[data-v-cc3cfaa7] {\n cursor: pointer;\n\n display: inline-flex;\n gap: 6px;\n align-items: center;\n\n padding: 8px 14px;\n border: 1.5px solid #e8e8e8;\n border-radius: 8px;\n\n font-size: 13px;\n font-weight: 500;\n color: #595959;\n\n background: white;\n outline: none;\n\n transition: all 0.2s;\n}\n.tool-btn[data-v-cc3cfaa7]:hover:not(:disabled) {\n border-color: #0e77cc;\n color: #0e77cc;\n background: #f0f9ff;\n}\n.tool-btn[data-v-cc3cfaa7]:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n background: #f5f5f5;\n}\n.tool-btn-text[data-v-cc3cfaa7] {\n font-size: 13px;\n}\n.tool-btn-icon[data-v-cc3cfaa7] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n width: 18px;\n height: 18px;\n}\n.tool-btn-svg[data-v-cc3cfaa7] {\n width: 18px;\n height: 18px;\n}\n.image-btn[data-v-cc3cfaa7] {\n border-color: #d9d9d9;\n}\n.emoji-container[data-v-cc3cfaa7] {\n position: relative;\n}\n.quick-reply-container[data-v-cc3cfaa7] {\n position: relative;\n}\n.quick-reply-trigger[data-v-cc3cfaa7] {\n border-color: #d9d9d9;\n}\n.quick-reply-trigger.active[data-v-cc3cfaa7] {\n border-color: #0e77cc;\n color: #0e77cc;\n background: #f0f9ff;\n}\n.quick-reply-panel[data-v-cc3cfaa7] {\n position: absolute;\n z-index: 1001;\n bottom: calc(100% + 8px);\n left: 0;\n\n overflow: hidden;\n\n width: 320px;\n max-width: min(320px, calc(100vw - 80px));\n border: 1px solid #e8e8e8;\n border-radius: 10px;\n\n background: #fff;\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);\n}\n.quick-reply-search[data-v-cc3cfaa7] {\n padding: 10px;\n border-bottom: 1px solid #f0f0f0;\n}\n.quick-reply-search input[data-v-cc3cfaa7] {\n width: 100%;\n height: 34px;\n padding: 0 10px;\n border: 1px solid #d9d9d9;\n border-radius: 8px;\n\n font-size: 13px;\n color: #595959;\n\n background: #fff;\n outline: none;\n}\n.quick-reply-search input[data-v-cc3cfaa7]:focus {\n border-color: #0e77cc;\n box-shadow: 0 0 0 2px rgba(14, 119, 204, 0.08);\n}\n.quick-reply-list[data-v-cc3cfaa7] {\n overflow-y: auto;\n max-height: 220px;\n padding: 8px;\n}\n.quick-reply-item[data-v-cc3cfaa7] {\n cursor: pointer;\n\n width: 100%;\n margin-bottom: 6px;\n padding: 8px 10px;\n border: 1px solid transparent;\n border-radius: 8px;\n\n font-size: 13px;\n line-height: 1.45;\n color: #595959;\n text-align: left;\n\n background: #f7f8fa;\n}\n.quick-reply-item[data-v-cc3cfaa7]:last-child {\n margin-bottom: 0;\n}\n.quick-reply-item[data-v-cc3cfaa7]:hover {\n border-color: #b6dcfa;\n color: #0e77cc;\n background: #f0f9ff;\n}\n.quick-reply-empty[data-v-cc3cfaa7] {\n padding: 18px 10px;\n font-size: 12px;\n color: #bfbfbf;\n text-align: center;\n}\n.emoji-picker-wrapper[data-v-cc3cfaa7] {\n position: absolute;\n z-index: 1000;\n bottom: 100%;\n left: 0;\n\n overflow: hidden;\n\n margin-bottom: 8px;\n border-radius: 8px;\n\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);\n}\n.input-area textarea[data-v-cc3cfaa7] {\n resize: none;\n\n width: 100%;\n padding: 12px 14px;\n border: 1.5px solid #e8e8e8;\n border-radius: 8px;\n\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n\n background: #fafafa;\n outline: none;\n\n transition: all 0.2s;\n}\n.input-area textarea[data-v-cc3cfaa7]:focus {\n border-color: #0e77cc;\n background: white;\n box-shadow: 0 0 0 3px rgba(14, 119, 204, 0.08);\n}\n.input-area textarea[data-v-cc3cfaa7]::placeholder {\n color: #bfbfbf;\n}\n.input-actions[data-v-cc3cfaa7] {\n display: flex;\n justify-content: flex-end;\n}\n.send-btn[data-v-cc3cfaa7] {\n cursor: pointer;\n\n padding: 10px 28px;\n border: none;\n border-radius: 8px;\n\n font-size: 14px;\n font-weight: 500;\n color: white;\n letter-spacing: 0.3px;\n\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 6px rgba(14, 119, 204, 0.25);\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.send-btn[data-v-cc3cfaa7]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(14, 119, 204, 0.35);\n}\n.send-btn[data-v-cc3cfaa7]:active {\n transform: translateY(0);\n box-shadow: 0 2px 6px rgba(14, 119, 204, 0.25);\n}\n\n.conversation-list[data-v-d070a051] {\n overflow-y: auto;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n background: #fff;\n}\n\n/* 自定义滚动条 */\n.conversation-list[data-v-d070a051]::-webkit-scrollbar {\n width: 6px;\n}\n.conversation-list[data-v-d070a051]::-webkit-scrollbar-track {\n background: transparent;\n}\n.conversation-list[data-v-d070a051]::-webkit-scrollbar-thumb {\n border-radius: 3px;\n background: #d9d9d9;\n}\n.conversation-list[data-v-d070a051]::-webkit-scrollbar-thumb:hover {\n background: #bfbfbf;\n}\n.unread-header[data-v-d070a051] {\n padding: 8px 20px;\n border-bottom: 1px solid #e8e8e8;\n background: linear-gradient(180deg, #fafafa 0%, #fff 100%);\n}\n.unread-count[data-v-d070a051] {\n font-size: 15px;\n font-weight: 600;\n color: #262626;\n letter-spacing: 0.3px;\n}\n.loading-state[data-v-d070a051] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n padding: 60px 20px;\n\n color: #bfbfbf;\n}\n.loading-spinner[data-v-d070a051] {\n width: 40px;\n height: 40px;\n margin-bottom: 16px;\n border: 3px solid #f0f0f0;\n border-top: 3px solid #0e77cc;\n border-radius: 50%;\n\n animation: spin-d070a051 0.8s linear infinite;\n}\n@keyframes spin-d070a051 {\n0% { transform: rotate(0deg);\n}\n100% { transform: rotate(360deg);\n}\n}\n.empty-state[data-v-d070a051] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n height: 100%;\n padding: 40px 20px;\n\n color: #bfbfbf;\n}\n.empty-icon[data-v-d070a051] {\n width: 64px;\n height: 64px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n.empty-state p[data-v-d070a051] {\n margin: 0;\n font-size: 14px;\n font-weight: 400;\n}\n.conversation-item[data-v-d070a051] {\n cursor: pointer;\n\n position: relative;\n\n padding: 12px 16px;\n border-bottom: 1px solid #f0f0f0;\n\n background: white;\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.conversation-item[data-v-d070a051]:hover {\n background-color: #f5f7fa;\n}\n.conversation-item.active[data-v-d070a051] {\n padding-left: 13px;\n border-left: 3px solid #0e77cc;\n background: linear-gradient(90deg, #ecf5ff 0%, #fff 100%);\n}\n.conversation-item[data-v-d070a051]:last-child {\n border-bottom: none;\n}\n\n/* 会话项内容布局 */\n.conversation-item-content[data-v-d070a051] {\n display: flex;\n gap: 12px;\n align-items: center;\n width: 100%;\n}\n.avatar-wrapper[data-v-d070a051] {\n position: relative;\n flex-shrink: 0;\n width: 44px;\n height: 44px;\n}\n.avatar-img[data-v-d070a051] {\n width: 100%;\n height: 100%;\n border: 2px solid white;\n border-radius: 50%;\n\n object-fit: cover;\n background: linear-gradient(135deg, #f0f0f0 0%, #e8e8e8 100%);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n.avatar-text[data-v-d070a051] {\n position: absolute;\n top: 0;\n left: 0;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 44px;\n height: 44px;\n border: 2px solid white;\n border-radius: 50%;\n\n font-size: 16px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 8px rgba(14, 119, 204, 0.3);\n}\n.session-info[data-v-d070a051] {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n justify-content: center;\n\n min-width: 0;\n}\n.session-name[data-v-d070a051] {\n font-size: 14px;\n font-weight: 600;\n color: #262626;\n letter-spacing: 0.2px;\n}\n.content-text[data-v-d070a051] {\n overflow: hidden;\n display: block;\n\n font-size: 13px;\n line-height: 1.4;\n color: #595959;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.session-meta[data-v-d070a051] {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n gap: 6px;\n align-items: flex-end;\n}\n.session-time[data-v-d070a051] {\n font-size: 12px;\n font-weight: 400;\n color: #8c8c8c;\n}\n.unread-badge[data-v-d070a051] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-width: 20px;\n height: 20px;\n margin-left: 8px;\n padding: 0 7px;\n border-radius: 10px;\n\n font-size: 12px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);\n box-shadow: 0 2px 6px rgba(255, 77, 79, 0.3);\n\n animation: pulse-d070a051 2s ease-in-out infinite;\n}\n@keyframes pulse-d070a051 {\n0%, 100% {\n transform: scale(1);\n}\n50% {\n transform: scale(1.05);\n}\n}\n\n.chat-window[data-v-d726d76e] {\n position: fixed;\n z-index: 9998;\n\n overflow: hidden;\n display: flex;\n flex-direction: column;\n\n min-width: 380px;\n min-height: 360px;\n border: 1px solid rgba(9, 62, 105, 0.14);\n border-radius: 18px;\n\n background: linear-gradient(180deg, #fff 0%, #f9fcff 100%);\n backdrop-filter: blur(6px);\n box-shadow: 0 24px 80px rgba(11, 58, 106, 0.24);\n\n animation: window-enter-d726d76e 0.22s ease-out;\n}\n.chat-window.is-dragging[data-v-d726d76e] {\n cursor: move;\n box-shadow: 0 28px 88px rgba(11, 58, 106, 0.28);\n}\n.chat-window.is-resizing[data-v-d726d76e] {\n cursor: nwse-resize;\n}\n.chat-header[data-v-d726d76e] {\n cursor: move;\n user-select: none;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: space-between;\n\n padding: 10px 20px;\n\n color: white;\n\n background: linear-gradient(135deg, #0f83df 0%, #0e6fbe 62%, #0c5fa5 100%);\n box-shadow: 0 2px 12px rgba(14, 119, 204, 0.26);\n}\n\n/* 用户信息区域 */\n.user-info-section[data-v-d726d76e] {\n display: flex;\n flex: 1;\n gap: 12px;\n align-items: center;\n}\n.user-avatar-wrapper[data-v-d726d76e] {\n position: relative;\n flex-shrink: 0;\n width: 40px;\n height: 40px;\n}\n.user-avatar[data-v-d726d76e] {\n width: 100%;\n height: 100%;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 50%;\n\n object-fit: cover;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n.user-avatar-default[data-v-d726d76e] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 40px;\n height: 40px;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 50%;\n\n font-size: 16px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n.status-indicator[data-v-d726d76e] {\n cursor: pointer;\n\n position: absolute;\n right: -2px;\n bottom: -2px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 14px;\n height: 14px;\n border: 2px solid white;\n border-radius: 50%;\n\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n\n transition: transform 0.2s;\n}\n.status-indicator[data-v-d726d76e]:hover {\n transform: scale(1.15);\n}\n.status-indicator svg[data-v-d726d76e] {\n width: 8px;\n height: 8px;\n}\n\n/* 状态下拉菜单 */\n.status-dropdown[data-v-d726d76e] {\n position: absolute;\n z-index: 100;\n top: 100%;\n left: 0;\n\n min-width: 120px;\n margin-top: 8px;\n padding: 6px;\n border: 1px solid #dbe7f5;\n border-radius: 10px;\n\n background: white;\n box-shadow: 0 12px 30px rgba(11, 58, 106, 0.18);\n}\n.status-option[data-v-d726d76e] {\n cursor: pointer;\n\n display: flex;\n gap: 8px;\n align-items: center;\n\n padding: 8px 10px;\n border-radius: 6px;\n\n color: #262626;\n\n transition: all 0.2s;\n}\n.status-option[data-v-d726d76e]:hover {\n background: #f5f5f5;\n}\n.status-option.active[data-v-d726d76e] {\n color: #0e77cc;\n background: #e6f7ff;\n}\n.status-dot[data-v-d726d76e] {\n flex-shrink: 0;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n}\n.status-option span[data-v-d726d76e] {\n flex: 1;\n font-size: 13px;\n}\n.check-icon[data-v-d726d76e] {\n width: 16px;\n height: 16px;\n opacity: 0.8;\n}\n.user-details[data-v-d726d76e] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.user-name[data-v-d726d76e] {\n font-size: 14px;\n font-weight: 600;\n letter-spacing: 0.2px;\n}\n.user-status[data-v-d726d76e] {\n font-size: 12px;\n font-weight: 400;\n opacity: 0.9;\n}\n.close-btn[data-v-d726d76e] {\n cursor: pointer;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n\n font-size: 28px;\n line-height: 1;\n color: white;\n\n opacity: 0.8;\n background: none;\n\n transition: all 0.2s;\n}\n.close-btn[data-v-d726d76e]:hover {\n transform: rotate(90deg);\n opacity: 1;\n background: rgba(255, 255, 255, 0.15);\n}\n.close-btn[data-v-d726d76e]:active {\n transform: rotate(90deg) scale(0.95);\n}\n.chat-body[data-v-d726d76e] {\n overflow: hidden;\n display: flex;\n flex: 1;\n\n min-height: 0;\n\n background: linear-gradient(180deg, #fbfdff 0%, #f4f8fc 100%);\n}\n\n/* 第一栏:一级菜单 */\n.first-sidebar[data-v-d726d76e] {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n\n width: 76px;\n padding: 0;\n border-right: 1px solid #dce8f3;\n\n background: linear-gradient(180deg, #f5f9ff 0%, #f0f6fd 100%);\n}\n.menu-items-container[data-v-d726d76e] {\n display: flex;\n flex: 1;\n flex-direction: column;\n align-items: center;\n\n padding: 18px 0;\n}\n.menu-item[data-v-d726d76e] {\n cursor: pointer;\n\n position: relative;\n\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 50px;\n height: 50px;\n margin-bottom: 12px;\n border: 1px solid transparent;\n border-radius: 12px;\n\n font-weight: 400;\n color: #7d8fa3;\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.menu-item[data-v-d726d76e]:last-child {\n margin-bottom: 0;\n}\n.menu-item[data-v-d726d76e]:hover {\n transform: translateY(-1px);\n border-color: #d2e3f3;\n color: #0e77cc;\n background: #f7fbff;\n}\n.menu-item.active[data-v-d726d76e] {\n border-color: #0e77cc;\n color: white;\n background: linear-gradient(135deg, #0f83df 0%, #0d6db8 100%);\n box-shadow: 0 8px 20px rgba(14, 119, 204, 0.35);\n}\n.menu-item.active[data-v-d726d76e]::before {\n content: '';\n\n position: absolute;\n top: 50%;\n left: -11px;\n transform: translateY(-50%);\n\n width: 3px;\n height: 24px;\n border-radius: 2px;\n\n background: #0e77cc;\n}\n.menu-item .icon[data-v-d726d76e] {\n width: 23px;\n height: 23px;\n}\n.menu-item .label[data-v-d726d76e] {\n display: none;\n}\n.menu-item .menu-badge[data-v-d726d76e] {\n position: absolute;\n top: 6px;\n right: 6px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-width: 16px;\n height: 16px;\n padding: 0 5px;\n border: 2px solid white;\n border-radius: 8px;\n\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n color: white;\n\n background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);\n box-shadow: 0 2px 6px rgba(255, 77, 79, 0.4);\n}\n.menu-item.active .menu-badge[data-v-d726d76e] {\n border-color: #0e77cc;\n color: #ff4d4f;\n background: linear-gradient(135deg, #fff 0%, #f0f0f0 100%);\n}\n\n/* 第二栏:二级侧边栏 */\n.second-sidebar[data-v-d726d76e] {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n\n width: 250px;\n border-right: 1px solid #dce8f3;\n\n background: linear-gradient(180deg, #fff 0%, #fbfdff 100%);\n}\n\n/* 第三栏:聊天区域 */\n.chat-area[data-v-d726d76e] {\n overflow: hidden;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-width: 0;\n\n background: radial-gradient(circle at top right, rgba(14, 119, 204, 0.08) 0%, rgba(255, 255, 255, 0) 42%), #fff;\n}\n.empty-chat[data-v-d726d76e] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n height: 100%;\n\n color: #8ca1b8;\n\n background: linear-gradient(180deg, #f7fbff 0%, #fff 100%);\n}\n.empty-chat .empty-icon[data-v-d726d76e] {\n width: 72px;\n height: 72px;\n margin-bottom: 18px;\n\n opacity: 0.5;\n filter: drop-shadow(0 8px 20px rgba(11, 58, 106, 0.16));\n}\n.empty-chat p[data-v-d726d76e] {\n margin: 0;\n font-size: 15px;\n font-weight: 500;\n letter-spacing: 0.3px;\n}\n\n/* 拉伸手柄 */\n.resize-handle[data-v-d726d76e] {\n cursor: nwse-resize;\n\n position: absolute;\n z-index: 9999;\n right: 0;\n bottom: 0;\n\n width: 24px;\n height: 24px;\n\n opacity: 0.5;\n\n transition: opacity 0.2s;\n}\n.resize-handle[data-v-d726d76e]:hover {\n opacity: 1;\n}\n.resize-handle[data-v-d726d76e]::after {\n content: '';\n\n position: absolute;\n right: 6px;\n bottom: 6px;\n\n width: 0;\n height: 0;\n border-top: 10px solid transparent;\n border-right: 10px solid #0e77cc;\n border-bottom: 10px solid #0e77cc;\n border-left: 10px solid transparent;\n\n opacity: 0.6;\n filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));\n}\n@keyframes window-enter-d726d76e {\nfrom {\n transform: translate3d(0, 16px, 0) scale(0.98);\n opacity: 0;\n}\nto {\n transform: translate3d(0, 0, 0) scale(1);\n opacity: 1;\n}\n}\n@media (width <= 960px) {\n.second-sidebar[data-v-d726d76e] {\n width: 220px;\n}\n}\n\n.float-button[data-v-a60f9c33] {\n touch-action: none;\n cursor: grab;\n user-select: none;\n\n position: fixed;\n z-index: 9999;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 64px;\n height: 64px;\n border: 1px solid #0e77cc;\n border-radius: 50%;\n\n background: #fff;\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3);\n\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.float-button.is-hidden[data-v-a60f9c33] {\n pointer-events: none;\n transform: scale(0.88);\n opacity: 0;\n}\n.float-button[data-v-a60f9c33]:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 30px rgba(14, 119, 204, 0.4);\n}\n.float-button[data-v-a60f9c33]:active {\n transform: translateY(0) scale(0.95);\n}\n.float-button.is-dragging[data-v-a60f9c33] {\n cursor: grabbing;\n transform: scale(1.08);\n box-shadow: 0 8px 35px rgba(14, 119, 204, 0.35);\n}\n.float-button .icon[data-v-a60f9c33] {\n pointer-events: none;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n\n filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));\n}\n.float-button .icon img[data-v-a60f9c33] {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.float-button .badge[data-v-a60f9c33] {\n pointer-events: none;\n\n position: absolute;\n top: 4px;\n right: 4px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border: 2.5px solid white;\n border-radius: 10px;\n\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n color: white;\n\n background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);\n box-shadow: 0 2px 8px rgba(255, 77, 79, 0.4);\n}\n.float-button.has-unread[data-v-a60f9c33] {\n animation: pulse-a60f9c33 2s ease-in-out infinite;\n}\n@keyframes pulse-a60f9c33 {\n0%, 100% {\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3),\n 0 0 0 0 rgba(255, 77, 79, 0.4);\n}\n50% {\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3),\n 0 0 0 12px rgba(255, 77, 79, 0);\n}\n}\n/*$vite$:1*/"
1
+ const __SHARED_IMSDK_CSS__ = ".confirm-dialog-mask[data-v-69eaf313] {\n position: fixed;\n z-index: 12000;\n inset: 0;\n\n background: rgba(15, 23, 42, 0.35);\n backdrop-filter: blur(2px);\n}\n.confirm-dialog[data-v-69eaf313] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n width: min(420px, calc(100vw - 32px));\n border: 1px solid #e8edf4;\n border-radius: 12px;\n\n background: #fff;\n box-shadow: 0 18px 48px rgba(15, 23, 42, 0.22);\n}\n.confirm-dialog-header[data-v-69eaf313] {\n padding: 16px 18px 8px;\n}\n.confirm-dialog-title[data-v-69eaf313] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #1f2937;\n}\n.confirm-dialog-body[data-v-69eaf313] {\n padding: 0 18px 10px;\n}\n.confirm-dialog-message[data-v-69eaf313] {\n margin: 0;\n font-size: 14px;\n line-height: 1.55;\n color: #4b5563;\n}\n.confirm-dialog-error[data-v-69eaf313] {\n margin: 10px 0 0;\n font-size: 13px;\n line-height: 1.45;\n color: #cf1322;\n}\n.confirm-dialog-footer[data-v-69eaf313] {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n padding: 14px 18px 18px;\n}\n.dialog-btn[data-v-69eaf313] {\n cursor: pointer;\n\n min-width: 80px;\n height: 34px;\n padding: 0 14px;\n border: 1px solid transparent;\n border-radius: 8px;\n\n font-size: 14px;\n\n transition: all 0.2s ease;\n}\n.dialog-btn[data-v-69eaf313]:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n.cancel-btn[data-v-69eaf313] {\n border-color: #d9d9d9;\n color: #595959;\n background: #fff;\n}\n.cancel-btn[data-v-69eaf313]:hover:not(:disabled) {\n border-color: #bfbfbf;\n color: #262626;\n background: #fafafa;\n}\n.confirm-btn[data-v-69eaf313] {\n border-color: #0e77cc;\n color: #fff;\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n}\n.confirm-btn[data-v-69eaf313]:hover:not(:disabled) {\n border-color: #0d6db8;\n filter: brightness(1.03);\n}\n.v3-body-inner{scroll-behavior:smooth;scrollbar-color:#393d3f rgba(0,0,0,.1);scrollbar-width:thin}.v3-body-inner::-webkit-scrollbar{width:8px}.v3-body-inner::-webkit-scrollbar-track{background-color:transparent}.v3-body-inner::-webkit-scrollbar-thumb{display:none;background:rgba(0,0,0,.3);border-radius:5px}.v3-body-inner:hover::-webkit-scrollbar-thumb{display:block}.v3-emoji-picker{height:320px;width:280px;box-shadow:0 2px 10px #0003;border-radius:10px;margin:0 auto;box-sizing:border-box;display:flex;flex-direction:column;text-align:left}.v3-emoji-picker *{box-sizing:border-box}.v3-emoji-picker .v3-header{padding:15px 15px 13px;border-bottom:1px solid}.v3-emoji-picker .v3-header .v3-groups{display:flex}.v3-emoji-picker .v3-header .v3-groups .v3-group{flex-grow:1;padding:0;margin:0;border:none;background:none;font-size:23px;cursor:pointer;position:relative;display:block;opacity:.7;transition:.2s}.v3-emoji-picker .v3-header .v3-groups .v3-group.v3-is-hidden{display:none}.v3-emoji-picker .v3-header .v3-groups .v3-group:first-child,.v3-emoji-picker .v3-header .v3-groups .v3-group:last-child{flex-grow:0}.v3-emoji-picker .v3-header .v3-groups .v3-group:hover{opacity:1}.v3-emoji-picker .v3-header .v3-groups .v3-group span{display:flex;align-items:center;justify-content:center}.v3-emoji-picker .v3-header .v3-groups .v3-group span img{display:block;width:1em;height:auto}.v3-emoji-picker .v3-spacing{height:11px}.v3-emoji-picker .v3-search input{width:100%;display:block;height:26px;padding:0 10px;border:1px solid;border-radius:3px;font-size:12px;transition:.2s}.v3-emoji-picker .v3-search input:focus{outline:none}.v3-emoji-picker .v3-body{padding:0 0 15px 11px;min-height:0;flex-grow:1}.v3-emoji-picker .v3-body .v3-body-inner{flex-grow:1;min-height:0;overflow-y:auto;overflow-x:hidden;height:100%;padding-right:11px}.v3-emoji-picker .v3-body .v3-body-inner .v3-group h5{margin:0;top:0;padding:7px 0 3px 4px;z-index:2}.v3-emoji-picker .v3-body .v3-body-inner .v3-group h5.v3-sticky{position:sticky}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis{display:flex;font-size:18px;flex-wrap:wrap}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button{cursor:pointer;border:none;background:none;margin:0;text-align:center;display:flex;align-items:center;justify-content:center;flex-basis:12.5%;max-width:12.5%;flex-grow:1;padding:0;font-size:22px;position:relative}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button:after{content:\"\";width:100%;padding-bottom:100%}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button span{display:flex;align-items:center;justify-content:center}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button img{max-width:100%;padding:4px}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button span,.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button img{position:absolute;top:0;left:0;width:100%;height:100%}.v3-emoji-picker .v3-body .v3-body-inner.is-mac .v3-emojis button{font-family:\"Apple Color Emoji\"}.v3-emoji-picker .v3-footer{font-size:14px;border-top:1px solid #dddddd;padding:15px;display:flex;align-items:center;justify-content:space-between;position:relative}.v3-emoji-picker .v3-footer .v3-tone,.v3-emoji-picker .v3-footer .v3-foot-left{display:flex;align-items:center}.v3-emoji-picker .v3-footer .v3-tone img,.v3-emoji-picker .v3-footer .v3-foot-left img{width:20px;display:block}.v3-emoji-picker .v3-footer .v3-tone>span:first-child,.v3-emoji-picker .v3-footer .v3-foot-left>span:first-child{margin-right:6px}.v3-emoji-picker .v3-footer .v3-foot-left>span.v3-text{max-width:100px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.v3-emoji-picker .v3-footer .v3-tone{border:none;padding:0;background:none;cursor:pointer;display:inline-flex;align-items:center}.v3-emoji-picker .v3-footer .v3-tone>span{display:inline-flex;vertical-align:top}.v3-emoji-picker .v3-footer .v3-tone .v3-text{font-size:13px}.v3-emoji-picker .v3-footer .v3-tone .v3-icon{display:inline-flex;height:15px;width:15px;vertical-align:middle;align-self:center;border:2px solid rgba(0,0,0,.2)}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-neutral{background-color:#ffd225}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3fb{background-color:#ffdfbd}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3fc{background-color:#e9c197}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3fd{background-color:#c88e62}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3fe{background-color:#a86637}.v3-emoji-picker .v3-footer .v3-tone .v3-icon.v3-tone-1f3ff{background-color:#60463a}.v3-emoji-picker .v3-footer .v3-tone .is-mac span{font-family:\"Apple Color Emoji\"}.v3-skin-tones{position:absolute;height:100%;width:60%;top:0;left:0;display:flex;align-items:center;justify-content:flex-end;padding:0 15px;opacity:0;visibility:hidden;transition:.2s;border-radius:0 0 10px 10px}.v3-skin-tones.v3-is-open{opacity:1;visibility:visible}.v3-skin-tones .v3-skin-tone{display:inline-block;height:15px;width:25px;border:none;padding:0;cursor:pointer;transition:0ms}.v3-skin-tones .v3-skin-tone:hover{transform:scale(1.1);transition:.2s}.v3-skin-tones .v3-skin-tone-neutral{color:#ffd225;background-color:#ffd225}.v3-skin-tones .v3-skin-tone-1f3fb{color:#ffdfbd;background-color:#ffdfbd}.v3-skin-tones .v3-skin-tone-1f3fc{color:#e9c197;background-color:#e9c197}.v3-skin-tones .v3-skin-tone-1f3fd{color:#c88e62;background-color:#c88e62}.v3-skin-tones .v3-skin-tone-1f3fe{color:#a86637;background-color:#a86637}.v3-skin-tones .v3-skin-tone-1f3ff{color:#60463a;background-color:#60463a}.v3-input-emoji-picker *{box-sizing:border-box}.v3-input-emoji-picker .v3-input-picker-root{position:relative}.v3-input-emoji-picker .v3-input-picker-root .v3-emoji-picker-input,.v3-input-emoji-picker .v3-input-picker-root .v3-emoji-picker-textarea{width:100%;height:40px;border:1px solid #999;padding-left:15px}.v3-input-emoji-picker .v3-input-picker-root .v3-emoji-picker-textarea{min-height:80px;resize:vertical}.v3-input-emoji-picker .v3-input-picker-root .v3-emoji-picker-textarea+.v3-input-picker-wrap .v3-input-picker-icon{top:auto;bottom:5px}.v3-input-emoji-picker .v3-input-picker-root .v3-input-picker-wrap .v3-input-picker-icon{display:inline-flex;position:absolute;right:5px;top:50%;transform:translateY(-50%);font-size:24px;border:none;background:none;padding:0 5px;cursor:pointer}.v3-input-emoji-picker .v3-input-picker-root .v3-input-picker-wrap .v3-input-picker-icon img{display:block;width:1em;height:1em}.v3-input-emoji-picker .v3-input-picker-root .v3-input-picker-wrap .v3-emoji-picker{opacity:0;visibility:hidden;transition:.2s}.v3-input-emoji-picker .v3-input-picker-root .v3-input-picker-wrap.v3-picker-is-open .v3-emoji-picker{opacity:1;visibility:visible;z-index:999}.v3-emoji-picker{--v3-picker-bg: #ffffff;--v3-picker-fg: #000000;--v3-picker-border: #dddddd;--v3-picker-input-bg: var(--v3-picker-bg);--v3-picker-input-border: #cccccc;--v3-picker-input-focus-border: #000000;--v3-group-image-filter: none;--v3-picker-emoji-hover: #f7f7f7;background:var(--v3-picker-bg);color:var(--v3-picker-fg)}.v3-emoji-picker .v3-footer,.v3-emoji-picker .v3-header{border-color:var(--v3-picker-border)}.v3-emoji-picker .v3-groups{filter:var(--v3-group-image-filter)}.v3-emoji-picker .v3-tone{color:var(--v3-picker-fg)}.v3-emoji-picker .v3-search input{background:var(--v3-picker-input-bg);border-color:var(--v3-picker-input-border);color:inherit}.v3-emoji-picker .v3-search input:focus{border-color:var(--v3-picker-input-focus-border)}.v3-emoji-picker .v3-body .v3-body-inner .v3-group h5,.v3-emoji-picker .v3-skin-tones{background:var(--v3-picker-bg)}.v3-emoji-picker .v3-body .v3-body-inner .v3-group .v3-emojis button:hover{background:var(--v3-picker-emoji-hover, #f7f7f7)}@media (prefers-color-scheme: dark){.v3-emoji-picker.v3-color-theme-auto{--v3-picker-bg: #000000;--v3-picker-fg: #ffffff;--v3-picker-border: #333333;--v3-picker-input-bg: #222222;--v3-picker-input-border: #444444;--v3-picker-input-focus-border: #555555;--v3-group-image-filter: invert(1);--v3-picker-emoji-hover: #222222}}.v3-emoji-picker.v3-color-theme-dark{--v3-picker-bg: #000000;--v3-picker-fg: #ffffff;--v3-picker-border: #333333;--v3-picker-input-bg: #222222;--v3-picker-input-border: #444444;--v3-picker-input-focus-border: #555555;--v3-group-image-filter: invert(1);--v3-picker-emoji-hover: #222222}\n\n.chat-room[data-v-1459079f] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #fff;\n}\n.chat-room-header[data-v-1459079f] {\n display: flex;\n gap: 12px;\n align-items: center;\n\n padding: 8px 20px;\n border-bottom: 1px solid #e8e8e8;\n\n background: linear-gradient(180deg, #fff 0%, #fafafa 100%);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n.back-btn[data-v-1459079f] {\n cursor: pointer;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 50%;\n\n font-size: 16px;\n color: #595959;\n\n background: #f0f0f0;\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.back-btn[data-v-1459079f]:hover {\n transform: scale(1.05);\n color: #0e77cc;\n background: #e8e8e8;\n}\n.back-btn[data-v-1459079f]:active {\n transform: scale(0.95);\n}\n.title[data-v-1459079f] {\n display: flex;\n flex: 1;\n gap: 12px;\n align-items: center;\n}\n.header-actions[data-v-1459079f] {\n display: flex;\n flex-shrink: 0;\n align-items: flex-end;\n}\n.end-session-btn[data-v-1459079f] {\n cursor: pointer;\n\n min-width: 90px;\n height: 32px;\n padding: 0 12px;\n border: 1px solid #ffd6d6;\n border-radius: 16px;\n\n font-size: 13px;\n font-weight: 500;\n color: #d4380d;\n\n background: #fff2f0;\n\n transition: all 0.2s ease;\n}\n.end-session-btn[data-v-1459079f]:hover:not(:disabled) {\n border-color: #ffb3ad;\n background: #ffe7e2;\n}\n.end-session-btn[data-v-1459079f]:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n.avatar-wrapper[data-v-1459079f] {\n position: relative;\n flex-shrink: 0;\n width: 42px;\n height: 42px;\n}\n.avatar-img[data-v-1459079f] {\n width: 100%;\n height: 100%;\n border: 2px solid white;\n border-radius: 50%;\n\n object-fit: cover;\n background: linear-gradient(135deg, #f0f0f0 0%, #e8e8e8 100%);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n.avatar-text[data-v-1459079f] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 42px;\n height: 42px;\n border: 2px solid white;\n border-radius: 50%;\n\n font-size: 16px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 8px rgba(14, 119, 204, 0.3);\n}\n.user-info[data-v-1459079f] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.name[data-v-1459079f] {\n font-size: 15px;\n font-weight: 600;\n color: #262626;\n letter-spacing: 0.2px;\n}\n.messages[data-v-1459079f] {\n position: relative;\n\n overflow-y: auto;\n flex: 1;\n\n padding: 24px 20px;\n\n background: linear-gradient(180deg, #f5f5f5 0%, #fafafa 100%);\n}\n\n/* 自定义滚动条 */\n.messages[data-v-1459079f]::-webkit-scrollbar {\n width: 6px;\n}\n.messages[data-v-1459079f]::-webkit-scrollbar-track {\n background: transparent;\n}\n.messages[data-v-1459079f]::-webkit-scrollbar-thumb {\n border-radius: 3px;\n background: #d9d9d9;\n}\n.messages[data-v-1459079f]::-webkit-scrollbar-thumb:hover {\n background: #bfbfbf;\n}\n.loading-more[data-v-1459079f] {\n display: flex;\n gap: 8px;\n align-items: center;\n justify-content: center;\n\n padding: 16px;\n\n font-size: 13px;\n color: #8c8c8c;\n}\n.loading-spinner-small[data-v-1459079f] {\n width: 20px;\n height: 20px;\n border: 2px solid #f0f0f0;\n border-top: 2px solid #0e77cc;\n border-radius: 50%;\n\n animation: spin-1459079f 0.8s linear infinite;\n}\n.no-more[data-v-1459079f] {\n padding: 12px;\n font-size: 12px;\n color: #bfbfbf;\n text-align: center;\n}\n.loading-state[data-v-1459079f] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n padding: 60px 20px;\n\n color: #bfbfbf;\n}\n.loading-spinner[data-v-1459079f] {\n width: 40px;\n height: 40px;\n margin-bottom: 16px;\n border: 3px solid #f0f0f0;\n border-top: 3px solid #0e77cc;\n border-radius: 50%;\n\n animation: spin-1459079f 0.8s linear infinite;\n}\n@keyframes spin-1459079f {\n0% { transform: rotate(0deg);\n}\n100% { transform: rotate(360deg);\n}\n}\n.empty-messages[data-v-1459079f] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n height: 100%;\n\n color: #bfbfbf;\n}\n.empty-messages .icon[data-v-1459079f] {\n margin-bottom: 16px;\n font-size: 64px;\n opacity: 0.5;\n}\n.empty-messages p[data-v-1459079f] {\n margin: 0;\n font-size: 14px;\n font-weight: 400;\n}\n.message-item[data-v-1459079f] {\n display: flex;\n gap: 12px;\n margin-bottom: 24px;\n animation: slide-in-1459079f 0.3s ease-out;\n}\n@keyframes slide-in-1459079f {\nfrom {\n transform: translateY(10px);\n opacity: 0;\n}\nto {\n transform: translateY(0);\n opacity: 1;\n}\n}\n.message-item.is-self[data-v-1459079f] {\n justify-content: flex-end;\n}\n.msg-avatar-wrapper[data-v-1459079f] {\n position: relative;\n flex-shrink: 0;\n width: 40px;\n height: 40px;\n}\n.msg-avatar-img[data-v-1459079f] {\n width: 100%;\n height: 100%;\n border: 2px solid white;\n border-radius: 50%;\n\n object-fit: cover;\n background: linear-gradient(135deg, #f0f0f0 0%, #e8e8e8 100%);\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);\n}\n.msg-avatar[data-v-1459079f] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 40px;\n height: 40px;\n border: 2px solid white;\n border-radius: 50%;\n\n font-size: 15px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 6px rgba(14, 119, 204, 0.3);\n}\n.message-content-wrapper[data-v-1459079f] {\n display: flex;\n flex-direction: column;\n max-width: 65%;\n}\n.is-self .message-content-wrapper[data-v-1459079f] {\n align-items: flex-end;\n}\n.message-sender[data-v-1459079f] {\n margin-bottom: 6px;\n font-size: 12px;\n font-weight: 400;\n color: #8c8c8c;\n}\n.message-content[data-v-1459079f] {\n padding: 12px 16px;\n border-radius: 12px;\n\n background-color: white;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n\n transition: all 0.2s;\n}\n.message-item.is-self .message-content[data-v-1459079f] {\n color: white;\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 8px rgba(14, 119, 204, 0.25);\n}\n.message-text[data-v-1459079f] {\n margin-bottom: 6px;\n\n font-size: 14px;\n line-height: 1.6;\n color: #262626;\n overflow-wrap: break-word;\n}\n.message-item.is-self .message-text[data-v-1459079f] {\n color: white;\n}\n\n/* 图片消息 */\n.message-image[data-v-1459079f] {\n margin-bottom: 6px;\n}\n.message-image img[data-v-1459079f] {\n cursor: pointer;\n\n max-width: 300px;\n max-height: 300px;\n border-radius: 8px;\n\n object-fit: cover;\n\n transition: transform 0.2s;\n}\n.message-image img[data-v-1459079f]:hover {\n transform: scale(1.02);\n}\n\n/* 表情消息 */\n.message-emoji[data-v-1459079f] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-height: 60px;\n margin-bottom: 6px;\n\n font-size: 48px;\n line-height: 1;\n}\n\n/* 文件消息 */\n.message-file[data-v-1459079f] {\n margin-bottom: 6px;\n}\n.file-link[data-v-1459079f] {\n display: inline-flex;\n gap: 8px;\n align-items: center;\n\n padding: 12px 16px;\n border-radius: 8px;\n\n font-size: 14px;\n font-weight: 500;\n color: #262626;\n text-decoration: none;\n\n background-color: #f5f5f5;\n\n transition: all 0.2s;\n}\n.file-link[data-v-1459079f]:hover {\n color: #0e77cc;\n background-color: #e8e8e8;\n}\n.is-self .file-link[data-v-1459079f] {\n color: white;\n background-color: rgba(255, 255, 255, 0.2);\n}\n.is-self .file-link[data-v-1459079f]:hover {\n background-color: rgba(255, 255, 255, 0.3);\n}\n\n/* 系统通知 */\n.message-system[data-v-1459079f] {\n margin-bottom: 6px;\n padding: 8px 12px;\n border-left: 3px solid #0e77cc;\n border-radius: 6px;\n\n font-size: 13px;\n color: #8c8c8c;\n text-align: center;\n\n background-color: #f5f5f5;\n}\n.is-self .message-system[data-v-1459079f] {\n border-left-color: white;\n color: rgba(255, 255, 255, 0.9);\n background-color: rgba(255, 255, 255, 0.2);\n}\n\n/* 卡片消息 */\n.message-card[data-v-1459079f] {\n margin-bottom: 6px;\n padding: 12px;\n border: 1px solid #bae6fd;\n border-radius: 8px;\n\n background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);\n}\n.is-self .message-card[data-v-1459079f] {\n border-color: rgba(255, 255, 255, 0.3);\n background: rgba(255, 255, 255, 0.2);\n}\n.message-time[data-v-1459079f] {\n font-size: 11px;\n color: #8c8c8c;\n}\n.message-item.is-self .message-time[data-v-1459079f] {\n color: rgba(255, 255, 255, 0.75);\n}\n.input-area[data-v-1459079f] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n padding: 16px 20px;\n border-top: 1px solid #e8e8e8;\n\n background: white;\n box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.04);\n}\n\n/* 工具栏 */\n.input-toolbar[data-v-1459079f] {\n display: flex;\n gap: 8px;\n padding: 4px 0;\n}\n.tool-btn[data-v-1459079f] {\n cursor: pointer;\n\n display: inline-flex;\n gap: 6px;\n align-items: center;\n\n padding: 8px 14px;\n border: 1.5px solid #e8e8e8;\n border-radius: 8px;\n\n font-size: 13px;\n font-weight: 500;\n color: #595959;\n\n background: white;\n outline: none;\n\n transition: all 0.2s;\n}\n.tool-btn[data-v-1459079f]:hover:not(:disabled) {\n border-color: #0e77cc;\n color: #0e77cc;\n background: #f0f9ff;\n}\n.tool-btn[data-v-1459079f]:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n background: #f5f5f5;\n}\n.tool-btn-text[data-v-1459079f] {\n font-size: 13px;\n}\n.tool-btn-icon[data-v-1459079f] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n width: 18px;\n height: 18px;\n}\n.tool-btn-svg[data-v-1459079f] {\n width: 18px;\n height: 18px;\n}\n.image-btn[data-v-1459079f] {\n border-color: #d9d9d9;\n}\n.emoji-container[data-v-1459079f] {\n position: relative;\n}\n.quick-reply-container[data-v-1459079f] {\n position: relative;\n}\n.quick-reply-trigger[data-v-1459079f] {\n border-color: #d9d9d9;\n}\n.quick-reply-trigger.active[data-v-1459079f] {\n border-color: #0e77cc;\n color: #0e77cc;\n background: #f0f9ff;\n}\n.quick-reply-panel[data-v-1459079f] {\n position: absolute;\n z-index: 1001;\n bottom: calc(100% + 8px);\n left: 0;\n\n overflow: hidden;\n\n width: 320px;\n max-width: min(320px, calc(100vw - 80px));\n border: 1px solid #e8e8e8;\n border-radius: 10px;\n\n background: #fff;\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);\n}\n.quick-reply-search[data-v-1459079f] {\n padding: 10px;\n border-bottom: 1px solid #f0f0f0;\n}\n.quick-reply-search input[data-v-1459079f] {\n width: 100%;\n height: 34px;\n padding: 0 10px;\n border: 1px solid #d9d9d9;\n border-radius: 8px;\n\n font-size: 13px;\n color: #595959;\n\n background: #fff;\n outline: none;\n}\n.quick-reply-search input[data-v-1459079f]:focus {\n border-color: #0e77cc;\n box-shadow: 0 0 0 2px rgba(14, 119, 204, 0.08);\n}\n.quick-reply-list[data-v-1459079f] {\n overflow-y: auto;\n max-height: 220px;\n padding: 8px;\n}\n.quick-reply-item[data-v-1459079f] {\n cursor: pointer;\n\n width: 100%;\n margin-bottom: 6px;\n padding: 8px 10px;\n border: 1px solid transparent;\n border-radius: 8px;\n\n font-size: 13px;\n line-height: 1.45;\n color: #595959;\n text-align: left;\n\n background: #f7f8fa;\n}\n.quick-reply-item[data-v-1459079f]:last-child {\n margin-bottom: 0;\n}\n.quick-reply-item[data-v-1459079f]:hover {\n border-color: #b6dcfa;\n color: #0e77cc;\n background: #f0f9ff;\n}\n.quick-reply-empty[data-v-1459079f] {\n padding: 18px 10px;\n font-size: 12px;\n color: #bfbfbf;\n text-align: center;\n}\n.emoji-picker-wrapper[data-v-1459079f] {\n position: absolute;\n z-index: 1000;\n bottom: 100%;\n left: 0;\n\n overflow: hidden;\n\n margin-bottom: 8px;\n border-radius: 8px;\n\n box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);\n}\n.input-area textarea[data-v-1459079f] {\n resize: none;\n\n width: 100%;\n padding: 12px 14px;\n border: 1.5px solid #e8e8e8;\n border-radius: 8px;\n\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n\n background: #fafafa;\n outline: none;\n\n transition: all 0.2s;\n}\n.input-area textarea[data-v-1459079f]:focus {\n border-color: #0e77cc;\n background: white;\n box-shadow: 0 0 0 3px rgba(14, 119, 204, 0.08);\n}\n.input-area textarea[data-v-1459079f]::placeholder {\n color: #bfbfbf;\n}\n.input-actions[data-v-1459079f] {\n display: flex;\n justify-content: flex-end;\n}\n.send-btn[data-v-1459079f] {\n cursor: pointer;\n\n padding: 10px 28px;\n border: none;\n border-radius: 8px;\n\n font-size: 14px;\n font-weight: 500;\n color: white;\n letter-spacing: 0.3px;\n\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 6px rgba(14, 119, 204, 0.25);\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.send-btn[data-v-1459079f]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(14, 119, 204, 0.35);\n}\n.send-btn[data-v-1459079f]:active {\n transform: translateY(0);\n box-shadow: 0 2px 6px rgba(14, 119, 204, 0.25);\n}\n\n.conversation-list[data-v-d070a051] {\n overflow-y: auto;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n background: #fff;\n}\n\n/* 自定义滚动条 */\n.conversation-list[data-v-d070a051]::-webkit-scrollbar {\n width: 6px;\n}\n.conversation-list[data-v-d070a051]::-webkit-scrollbar-track {\n background: transparent;\n}\n.conversation-list[data-v-d070a051]::-webkit-scrollbar-thumb {\n border-radius: 3px;\n background: #d9d9d9;\n}\n.conversation-list[data-v-d070a051]::-webkit-scrollbar-thumb:hover {\n background: #bfbfbf;\n}\n.unread-header[data-v-d070a051] {\n padding: 8px 20px;\n border-bottom: 1px solid #e8e8e8;\n background: linear-gradient(180deg, #fafafa 0%, #fff 100%);\n}\n.unread-count[data-v-d070a051] {\n font-size: 15px;\n font-weight: 600;\n color: #262626;\n letter-spacing: 0.3px;\n}\n.loading-state[data-v-d070a051] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n padding: 60px 20px;\n\n color: #bfbfbf;\n}\n.loading-spinner[data-v-d070a051] {\n width: 40px;\n height: 40px;\n margin-bottom: 16px;\n border: 3px solid #f0f0f0;\n border-top: 3px solid #0e77cc;\n border-radius: 50%;\n\n animation: spin-d070a051 0.8s linear infinite;\n}\n@keyframes spin-d070a051 {\n0% { transform: rotate(0deg);\n}\n100% { transform: rotate(360deg);\n}\n}\n.empty-state[data-v-d070a051] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n height: 100%;\n padding: 40px 20px;\n\n color: #bfbfbf;\n}\n.empty-icon[data-v-d070a051] {\n width: 64px;\n height: 64px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n.empty-state p[data-v-d070a051] {\n margin: 0;\n font-size: 14px;\n font-weight: 400;\n}\n.conversation-item[data-v-d070a051] {\n cursor: pointer;\n\n position: relative;\n\n padding: 12px 16px;\n border-bottom: 1px solid #f0f0f0;\n\n background: white;\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.conversation-item[data-v-d070a051]:hover {\n background-color: #f5f7fa;\n}\n.conversation-item.active[data-v-d070a051] {\n padding-left: 13px;\n border-left: 3px solid #0e77cc;\n background: linear-gradient(90deg, #ecf5ff 0%, #fff 100%);\n}\n.conversation-item[data-v-d070a051]:last-child {\n border-bottom: none;\n}\n\n/* 会话项内容布局 */\n.conversation-item-content[data-v-d070a051] {\n display: flex;\n gap: 12px;\n align-items: center;\n width: 100%;\n}\n.avatar-wrapper[data-v-d070a051] {\n position: relative;\n flex-shrink: 0;\n width: 44px;\n height: 44px;\n}\n.avatar-img[data-v-d070a051] {\n width: 100%;\n height: 100%;\n border: 2px solid white;\n border-radius: 50%;\n\n object-fit: cover;\n background: linear-gradient(135deg, #f0f0f0 0%, #e8e8e8 100%);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n.avatar-text[data-v-d070a051] {\n position: absolute;\n top: 0;\n left: 0;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 44px;\n height: 44px;\n border: 2px solid white;\n border-radius: 50%;\n\n font-size: 16px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, #0e77cc 0%, #0d6db8 100%);\n box-shadow: 0 2px 8px rgba(14, 119, 204, 0.3);\n}\n.session-info[data-v-d070a051] {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n justify-content: center;\n\n min-width: 0;\n}\n.session-name[data-v-d070a051] {\n font-size: 14px;\n font-weight: 600;\n color: #262626;\n letter-spacing: 0.2px;\n}\n.content-text[data-v-d070a051] {\n overflow: hidden;\n display: block;\n\n font-size: 13px;\n line-height: 1.4;\n color: #595959;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.session-meta[data-v-d070a051] {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n gap: 6px;\n align-items: flex-end;\n}\n.session-time[data-v-d070a051] {\n font-size: 12px;\n font-weight: 400;\n color: #8c8c8c;\n}\n.unread-badge[data-v-d070a051] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-width: 20px;\n height: 20px;\n margin-left: 8px;\n padding: 0 7px;\n border-radius: 10px;\n\n font-size: 12px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);\n box-shadow: 0 2px 6px rgba(255, 77, 79, 0.3);\n\n animation: pulse-d070a051 2s ease-in-out infinite;\n}\n@keyframes pulse-d070a051 {\n0%, 100% {\n transform: scale(1);\n}\n50% {\n transform: scale(1.05);\n}\n}\n\n.chat-window[data-v-00d50ef7] {\n position: fixed;\n z-index: 9998;\n\n overflow: hidden;\n display: flex;\n flex-direction: column;\n\n min-width: 380px;\n min-height: 360px;\n border: 1px solid rgba(9, 62, 105, 0.14);\n border-radius: 18px;\n\n background: linear-gradient(180deg, #fff 0%, #f9fcff 100%);\n backdrop-filter: blur(6px);\n box-shadow: 0 24px 80px rgba(11, 58, 106, 0.24);\n\n animation: window-enter-00d50ef7 0.22s ease-out;\n}\n.chat-window.is-dragging[data-v-00d50ef7] {\n cursor: move;\n box-shadow: 0 28px 88px rgba(11, 58, 106, 0.28);\n}\n.chat-window.is-resizing[data-v-00d50ef7] {\n cursor: nwse-resize;\n}\n.chat-header[data-v-00d50ef7] {\n cursor: move;\n user-select: none;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: space-between;\n\n padding: 10px 20px;\n\n color: white;\n\n background: linear-gradient(135deg, #0f83df 0%, #0e6fbe 62%, #0c5fa5 100%);\n box-shadow: 0 2px 12px rgba(14, 119, 204, 0.26);\n}\n\n/* 用户信息区域 */\n.user-info-section[data-v-00d50ef7] {\n display: flex;\n flex: 1;\n gap: 12px;\n align-items: center;\n}\n.user-avatar-wrapper[data-v-00d50ef7] {\n position: relative;\n flex-shrink: 0;\n width: 40px;\n height: 40px;\n}\n.user-avatar[data-v-00d50ef7] {\n width: 100%;\n height: 100%;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 50%;\n\n object-fit: cover;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n.user-avatar-default[data-v-00d50ef7] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 40px;\n height: 40px;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 50%;\n\n font-size: 16px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n.status-indicator[data-v-00d50ef7] {\n cursor: pointer;\n\n position: absolute;\n right: -2px;\n bottom: -2px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 14px;\n height: 14px;\n border: 2px solid white;\n border-radius: 50%;\n\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n\n transition: transform 0.2s;\n}\n.status-indicator[data-v-00d50ef7]:hover {\n transform: scale(1.15);\n}\n.status-indicator svg[data-v-00d50ef7] {\n width: 8px;\n height: 8px;\n}\n\n/* 状态下拉菜单 */\n.status-dropdown[data-v-00d50ef7] {\n position: absolute;\n z-index: 100;\n top: 100%;\n left: 0;\n\n min-width: 120px;\n margin-top: 8px;\n padding: 6px;\n border: 1px solid #dbe7f5;\n border-radius: 10px;\n\n background: white;\n box-shadow: 0 12px 30px rgba(11, 58, 106, 0.18);\n}\n.status-option[data-v-00d50ef7] {\n cursor: pointer;\n\n display: flex;\n gap: 8px;\n align-items: center;\n\n padding: 8px 10px;\n border-radius: 6px;\n\n color: #262626;\n\n transition: all 0.2s;\n}\n.status-option[data-v-00d50ef7]:hover {\n background: #f5f5f5;\n}\n.status-option.active[data-v-00d50ef7] {\n color: #0e77cc;\n background: #e6f7ff;\n}\n.status-dot[data-v-00d50ef7] {\n flex-shrink: 0;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n}\n.status-option span[data-v-00d50ef7] {\n flex: 1;\n font-size: 13px;\n}\n.check-icon[data-v-00d50ef7] {\n width: 16px;\n height: 16px;\n opacity: 0.8;\n}\n.user-details[data-v-00d50ef7] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.user-name[data-v-00d50ef7] {\n font-size: 14px;\n font-weight: 600;\n letter-spacing: 0.2px;\n}\n.user-status[data-v-00d50ef7] {\n font-size: 12px;\n font-weight: 400;\n opacity: 0.9;\n}\n.close-btn[data-v-00d50ef7] {\n cursor: pointer;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n\n font-size: 28px;\n line-height: 1;\n color: white;\n\n opacity: 0.8;\n background: none;\n\n transition: all 0.2s;\n}\n.close-btn[data-v-00d50ef7]:hover {\n transform: rotate(90deg);\n opacity: 1;\n background: rgba(255, 255, 255, 0.15);\n}\n.close-btn[data-v-00d50ef7]:active {\n transform: rotate(90deg) scale(0.95);\n}\n.chat-body[data-v-00d50ef7] {\n overflow: hidden;\n display: flex;\n flex: 1;\n\n min-height: 0;\n\n background: linear-gradient(180deg, #fbfdff 0%, #f4f8fc 100%);\n}\n\n/* 第一栏:一级菜单 */\n.first-sidebar[data-v-00d50ef7] {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n\n width: 76px;\n padding: 0;\n border-right: 1px solid #dce8f3;\n\n background: linear-gradient(180deg, #f5f9ff 0%, #f0f6fd 100%);\n}\n.menu-items-container[data-v-00d50ef7] {\n display: flex;\n flex: 1;\n flex-direction: column;\n align-items: center;\n\n padding: 18px 0;\n}\n.menu-item[data-v-00d50ef7] {\n cursor: pointer;\n\n position: relative;\n\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 50px;\n height: 50px;\n margin-bottom: 12px;\n border: 1px solid transparent;\n border-radius: 12px;\n\n font-weight: 400;\n color: #7d8fa3;\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.menu-item[data-v-00d50ef7]:last-child {\n margin-bottom: 0;\n}\n.menu-item[data-v-00d50ef7]:hover {\n transform: translateY(-1px);\n border-color: #d2e3f3;\n color: #0e77cc;\n background: #f7fbff;\n}\n.menu-item.active[data-v-00d50ef7] {\n border-color: #0e77cc;\n color: white;\n background: linear-gradient(135deg, #0f83df 0%, #0d6db8 100%);\n box-shadow: 0 8px 20px rgba(14, 119, 204, 0.35);\n}\n.menu-item.active[data-v-00d50ef7]::before {\n content: '';\n\n position: absolute;\n top: 50%;\n left: -11px;\n transform: translateY(-50%);\n\n width: 3px;\n height: 24px;\n border-radius: 2px;\n\n background: #0e77cc;\n}\n.menu-item .icon[data-v-00d50ef7] {\n width: 23px;\n height: 23px;\n}\n.menu-item .label[data-v-00d50ef7] {\n display: none;\n}\n.menu-item .menu-badge[data-v-00d50ef7] {\n position: absolute;\n top: 6px;\n right: 6px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-width: 16px;\n height: 16px;\n padding: 0 5px;\n border: 2px solid white;\n border-radius: 8px;\n\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n color: white;\n\n background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);\n box-shadow: 0 2px 6px rgba(255, 77, 79, 0.4);\n}\n.menu-item.active .menu-badge[data-v-00d50ef7] {\n border-color: #0e77cc;\n color: #ff4d4f;\n background: linear-gradient(135deg, #fff 0%, #f0f0f0 100%);\n}\n\n/* 第二栏:二级侧边栏 */\n.second-sidebar[data-v-00d50ef7] {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n\n width: 250px;\n border-right: 1px solid #dce8f3;\n\n background: linear-gradient(180deg, #fff 0%, #fbfdff 100%);\n}\n\n/* 第三栏:聊天区域 */\n.chat-area[data-v-00d50ef7] {\n overflow: hidden;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-width: 0;\n\n background: radial-gradient(circle at top right, rgba(14, 119, 204, 0.08) 0%, rgba(255, 255, 255, 0) 42%), #fff;\n}\n.empty-chat[data-v-00d50ef7] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n height: 100%;\n\n color: #8ca1b8;\n\n background: linear-gradient(180deg, #f7fbff 0%, #fff 100%);\n}\n.empty-chat .empty-icon[data-v-00d50ef7] {\n width: 72px;\n height: 72px;\n margin-bottom: 18px;\n\n opacity: 0.5;\n filter: drop-shadow(0 8px 20px rgba(11, 58, 106, 0.16));\n}\n.empty-chat p[data-v-00d50ef7] {\n margin: 0;\n font-size: 15px;\n font-weight: 500;\n letter-spacing: 0.3px;\n}\n\n/* 拉伸手柄 */\n.resize-handle[data-v-00d50ef7] {\n cursor: nwse-resize;\n\n position: absolute;\n z-index: 9999;\n right: 0;\n bottom: 0;\n\n width: 24px;\n height: 24px;\n\n opacity: 0.5;\n\n transition: opacity 0.2s;\n}\n.resize-handle[data-v-00d50ef7]:hover {\n opacity: 1;\n}\n.resize-handle[data-v-00d50ef7]::after {\n content: '';\n\n position: absolute;\n right: 6px;\n bottom: 6px;\n\n width: 0;\n height: 0;\n border-top: 10px solid transparent;\n border-right: 10px solid #0e77cc;\n border-bottom: 10px solid #0e77cc;\n border-left: 10px solid transparent;\n\n opacity: 0.6;\n filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));\n}\n@keyframes window-enter-00d50ef7 {\nfrom {\n transform: translate3d(0, 16px, 0) scale(0.98);\n opacity: 0;\n}\nto {\n transform: translate3d(0, 0, 0) scale(1);\n opacity: 1;\n}\n}\n@media (width <= 960px) {\n.second-sidebar[data-v-00d50ef7] {\n width: 220px;\n}\n}\n\n.float-button[data-v-a60f9c33] {\n touch-action: none;\n cursor: grab;\n user-select: none;\n\n position: fixed;\n z-index: 9999;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 64px;\n height: 64px;\n border: 1px solid #0e77cc;\n border-radius: 50%;\n\n background: #fff;\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3);\n\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.float-button.is-hidden[data-v-a60f9c33] {\n pointer-events: none;\n transform: scale(0.88);\n opacity: 0;\n}\n.float-button[data-v-a60f9c33]:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 30px rgba(14, 119, 204, 0.4);\n}\n.float-button[data-v-a60f9c33]:active {\n transform: translateY(0) scale(0.95);\n}\n.float-button.is-dragging[data-v-a60f9c33] {\n cursor: grabbing;\n transform: scale(1.08);\n box-shadow: 0 8px 35px rgba(14, 119, 204, 0.35);\n}\n.float-button .icon[data-v-a60f9c33] {\n pointer-events: none;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n\n filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));\n}\n.float-button .icon img[data-v-a60f9c33] {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.float-button .badge[data-v-a60f9c33] {\n pointer-events: none;\n\n position: absolute;\n top: 4px;\n right: 4px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border: 2.5px solid white;\n border-radius: 10px;\n\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n color: white;\n\n background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);\n box-shadow: 0 2px 8px rgba(255, 77, 79, 0.4);\n}\n.float-button.has-unread[data-v-a60f9c33] {\n animation: pulse-a60f9c33 2s ease-in-out infinite;\n}\n@keyframes pulse-a60f9c33 {\n0%, 100% {\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3),\n 0 0 0 0 rgba(255, 77, 79, 0.4);\n}\n50% {\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3),\n 0 0 0 12px rgba(255, 77, 79, 0);\n}\n}\n/*$vite$:1*/"
2
2
  if (typeof document !== 'undefined' && __SHARED_IMSDK_CSS__) {
3
3
  const __SHARED_IMSDK_STYLE_ID__ = 'zjw-jszn-shared-imsdk-style'
4
4
  if (!document.getElementById(__SHARED_IMSDK_STYLE_ID__)) {
@@ -5693,6 +5693,7 @@ function _objectSpread2(e) {
5693
5693
  var defaultConfig = {
5694
5694
  api: {
5695
5695
  baseURL: "https://aox.api.orchiport.asia",
5696
+ resourceBaseURL: "https://resource.api.orchiport.asia",
5696
5697
  prefix: "",
5697
5698
  uploadURL: "https://resource.api.orchiport.asia/system/uploadImage",
5698
5699
  signKey: "Z0XYfLbnDpuVqk41",
@@ -5702,11 +5703,29 @@ var defaultConfig = {
5702
5703
  defaultSignKey: "your-default-sign-key-here"
5703
5704
  },
5704
5705
  ws: {
5706
+ url: "",
5705
5707
  controller: "",
5706
- platform: ""
5708
+ platform: "",
5709
+ reconnectInterval: 3e3,
5710
+ heartbeatInterval: 3e3,
5711
+ maxReconnectAttempts: 5,
5712
+ connectTimeout: 3e4,
5713
+ traceEnabled: false,
5714
+ protocol: {
5715
+ controller: "",
5716
+ action: {
5717
+ send: "send",
5718
+ msgRead: "msgRead",
5719
+ onConnect: "onConnect",
5720
+ offLine: "offLine",
5721
+ heartbeat: "heartbeat"
5722
+ },
5723
+ heartbeatSignals: ["ping", "pong"]
5724
+ }
5707
5725
  },
5708
5726
  sound: { enabled: true },
5709
5727
  auth: { authorizationPayload: {} },
5728
+ chat: { platformServicePhone: "" },
5710
5729
  runtimeApi: {}
5711
5730
  };
5712
5731
  var currentConfig = defaultConfig;
@@ -5720,19 +5739,28 @@ function getConfig() {
5720
5739
  * 更新配置
5721
5740
  */
5722
5741
  function updateConfig(config) {
5723
- var _ref, _config$sound$enabled, _config$sound, _currentConfig$sound, _config$sound$url, _config$sound2, _currentConfig$sound2, _currentConfig$auth, _config$auth;
5742
+ var _config$ws, _config$ws2, _config$ws$protocol$h, _config$ws3, _ref, _config$sound$enabled, _config$sound, _currentConfig$sound, _config$sound$url, _config$sound2, _currentConfig$sound2, _currentConfig$auth, _config$auth;
5724
5743
  currentConfig = _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig), config), {}, {
5725
5744
  api: _objectSpread2(_objectSpread2({}, currentConfig.api), config.api),
5726
- ws: _objectSpread2(_objectSpread2({}, currentConfig.ws), config.ws),
5745
+ ws: _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig.ws), config.ws), {}, { protocol: _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig.ws.protocol), (_config$ws = config.ws) === null || _config$ws === void 0 ? void 0 : _config$ws.protocol), {}, {
5746
+ action: _objectSpread2(_objectSpread2({}, currentConfig.ws.protocol.action), ((_config$ws2 = config.ws) === null || _config$ws2 === void 0 || (_config$ws2 = _config$ws2.protocol) === null || _config$ws2 === void 0 ? void 0 : _config$ws2.action) || {}),
5747
+ heartbeatSignals: (_config$ws$protocol$h = (_config$ws3 = config.ws) === null || _config$ws3 === void 0 || (_config$ws3 = _config$ws3.protocol) === null || _config$ws3 === void 0 ? void 0 : _config$ws3.heartbeatSignals) !== null && _config$ws$protocol$h !== void 0 ? _config$ws$protocol$h : currentConfig.ws.protocol.heartbeatSignals
5748
+ }) }),
5727
5749
  sound: {
5728
5750
  enabled: (_ref = (_config$sound$enabled = (_config$sound = config.sound) === null || _config$sound === void 0 ? void 0 : _config$sound.enabled) !== null && _config$sound$enabled !== void 0 ? _config$sound$enabled : (_currentConfig$sound = currentConfig.sound) === null || _currentConfig$sound === void 0 ? void 0 : _currentConfig$sound.enabled) !== null && _ref !== void 0 ? _ref : true,
5729
5751
  url: (_config$sound$url = (_config$sound2 = config.sound) === null || _config$sound2 === void 0 ? void 0 : _config$sound2.url) !== null && _config$sound$url !== void 0 ? _config$sound$url : (_currentConfig$sound2 = currentConfig.sound) === null || _currentConfig$sound2 === void 0 ? void 0 : _currentConfig$sound2.url
5730
5752
  },
5731
5753
  auth: _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig.auth), config.auth), {}, { authorizationPayload: _objectSpread2(_objectSpread2({}, ((_currentConfig$auth = currentConfig.auth) === null || _currentConfig$auth === void 0 ? void 0 : _currentConfig$auth.authorizationPayload) || {}), ((_config$auth = config.auth) === null || _config$auth === void 0 ? void 0 : _config$auth.authorizationPayload) || {}) }),
5754
+ chat: _objectSpread2(_objectSpread2({}, currentConfig.chat), config.chat),
5732
5755
  runtimeApi: _objectSpread2(_objectSpread2({}, currentConfig.runtimeApi), config.runtimeApi)
5733
5756
  });
5734
5757
  }
5735
5758
  var PREFIX_TRIM_REGEXP = /^\/+|\/+$/g;
5759
+ var URL_TRIM_REGEXP = /\/+$/g;
5760
+ var URL_ORIGIN_REGEXP = /^[a-z][a-z\d+\-.]*:\/\/[^/]+/i;
5761
+ var WS_PROTOCOL_REGEXP = /^wss?:\/\//i;
5762
+ var HTTPS_PROTOCOL_REGEXP = /^https:\/\//i;
5763
+ var HTTP_PROTOCOL_REGEXP = /^http:\/\//i;
5736
5764
  function normalizePrefix(prefix) {
5737
5765
  if (!prefix) return "";
5738
5766
  return `/${prefix.replace(PREFIX_TRIM_REGEXP, "")}`;
@@ -5773,6 +5801,59 @@ function getWSPlatform() {
5773
5801
  return currentConfig.ws.platform || "";
5774
5802
  }
5775
5803
  /**
5804
+ * 是否开启 WebSocket Trace 日志
5805
+ */
5806
+ function isWSTraceEnabled() {
5807
+ return currentConfig.ws.traceEnabled === true;
5808
+ }
5809
+ function normalizeWSAction(value, fallback) {
5810
+ return String(value || "").trim() || fallback;
5811
+ }
5812
+ /**
5813
+ * 获取 WebSocket 协议控制器(优先 protocol.controller)
5814
+ */
5815
+ function getWSProtocolController() {
5816
+ var _currentConfig$ws$pro;
5817
+ return String(((_currentConfig$ws$pro = currentConfig.ws.protocol) === null || _currentConfig$ws$pro === void 0 ? void 0 : _currentConfig$ws$pro.controller) || "").trim() || getWSController();
5818
+ }
5819
+ /**
5820
+ * 获取 WebSocket 协议动作映射
5821
+ */
5822
+ function getWSProtocolAction() {
5823
+ var _currentConfig$ws$pro2;
5824
+ const action = ((_currentConfig$ws$pro2 = currentConfig.ws.protocol) === null || _currentConfig$ws$pro2 === void 0 ? void 0 : _currentConfig$ws$pro2.action) || defaultConfig.ws.protocol.action;
5825
+ return {
5826
+ send: normalizeWSAction(action.send, "send"),
5827
+ msgRead: normalizeWSAction(action.msgRead, "msgRead"),
5828
+ onConnect: normalizeWSAction(action.onConnect, "onConnect"),
5829
+ offLine: normalizeWSAction(action.offLine, "offLine"),
5830
+ heartbeat: normalizeWSAction(action.heartbeat, "heartbeat")
5831
+ };
5832
+ }
5833
+ function normalizeURL(value) {
5834
+ return String(value || "").trim().replace(URL_TRIM_REGEXP, "");
5835
+ }
5836
+ function toWSURLFromHTTP(baseURL, fallback = "") {
5837
+ const normalized = normalizeURL(baseURL);
5838
+ const fallbackURL = normalizeURL(fallback);
5839
+ if (!normalized) return fallbackURL;
5840
+ const originMatch = normalized.match(URL_ORIGIN_REGEXP);
5841
+ const origin = (originMatch === null || originMatch === void 0 ? void 0 : originMatch[0]) || normalized;
5842
+ if (WS_PROTOCOL_REGEXP.test(origin)) return origin;
5843
+ if (HTTPS_PROTOCOL_REGEXP.test(origin)) return origin.replace(HTTPS_PROTOCOL_REGEXP, "wss://");
5844
+ if (HTTP_PROTOCOL_REGEXP.test(origin)) return origin.replace(HTTP_PROTOCOL_REGEXP, "ws://");
5845
+ return fallbackURL;
5846
+ }
5847
+ /**
5848
+ * 获取 WebSocket 基础地址
5849
+ * 优先级:ws.url > api.baseURL 推导 > 默认地址
5850
+ */
5851
+ function getWSBaseURL() {
5852
+ const configured = normalizeURL(currentConfig.ws.url);
5853
+ if (configured) return configured;
5854
+ return toWSURLFromHTTP(currentConfig.api.baseURL, "wss://aox.api.orchiport.asia");
5855
+ }
5856
+ /**
5776
5857
  * 获取鉴权扩展参数(平台默认为空,门店可注入 username/avatar)
5777
5858
  */
5778
5859
  function getAuthorizationExtraPayload() {
@@ -6109,6 +6190,7 @@ function _asyncToGenerator(n) {
6109
6190
  var INTEGER_STRING_REGEXP = /^\d+$/;
6110
6191
  var UPLOAD_TIMEOUT_MS = 3e4;
6111
6192
  var MAX_UPLOAD_IMAGE_SIZE_BYTES = 2 * 1024 * 1024;
6193
+ var CUSTOMER_ONLY_TRUE_SET = new Set(["1", "true"]);
6112
6194
  function ensureAuthorized(apiName) {
6113
6195
  if (!httpClient.getAuth()) throw new Error(`未登录,禁止请求 ${apiName},请先完成鉴权`);
6114
6196
  }
@@ -6176,6 +6258,15 @@ function unwrapResult(response, apiName) {
6176
6258
  if (response.result === void 0 || response.result === null) throw new Error(`${apiName} 接口返回 result 为空`);
6177
6259
  return response.result;
6178
6260
  }
6261
+ function normalizePhone(phone) {
6262
+ return typeof phone === "string" ? phone.trim() : "";
6263
+ }
6264
+ function isCustomerOnlyFlagEnabled(value) {
6265
+ if (typeof value === "boolean") return value;
6266
+ if (typeof value === "number") return value === 1;
6267
+ if (typeof value === "string") return CUSTOMER_ONLY_TRUE_SET.has(value.trim().toLowerCase());
6268
+ return false;
6269
+ }
6179
6270
  /**
6180
6271
  * 获取用户鉴权
6181
6272
  * @param params 鉴权参数
@@ -6306,14 +6397,36 @@ function _getChatRewordBySession() {
6306
6397
  * @param data.session_id - 会话ID
6307
6398
  * @param data.user_type - 用户类型
6308
6399
  * @param data.msg_type - 消息类型
6400
+ * @param data.friend_type - 对话对象类型
6401
+ * @param data.customeronly - 平台客服模式标记(1/true)
6309
6402
  */
6310
6403
  function getChatList(_x7) {
6311
6404
  return _getChatList.apply(this, arguments);
6312
6405
  }
6313
6406
  function _getChatList() {
6314
6407
  _getChatList = _asyncToGenerator(function* (data) {
6408
+ var _data$friend_type, _getConfig$chat;
6315
6409
  ensureAuthorized("getChatList");
6316
- return unwrapResult(yield httpClient.post(buildApiPath("/chat/getList"), data), "getChatList");
6410
+ const friendType = Number((_data$friend_type = data.friend_type) !== null && _data$friend_type !== void 0 ? _data$friend_type : 0);
6411
+ const customerOnlyRaw = data.customeronly;
6412
+ const isCustomerOnly = isCustomerOnlyFlagEnabled(customerOnlyRaw);
6413
+ const isPlatformCustomerMode = isCustomerOnly && friendType === 4;
6414
+ const inputPhone = normalizePhone(data.phone);
6415
+ const servicePhone = normalizePhone((_getConfig$chat = getConfig().chat) === null || _getConfig$chat === void 0 ? void 0 : _getConfig$chat.platformServicePhone);
6416
+ const resolvedPhone = inputPhone || (isPlatformCustomerMode ? servicePhone : "");
6417
+ if (isPlatformCustomerMode && !data.session_id && !resolvedPhone) throw new Error("平台客服会话缺少 phone,请传入 phone 或配置 chat.platformServicePhone");
6418
+ const payload = {
6419
+ page: data.page,
6420
+ limit: data.limit
6421
+ };
6422
+ if (typeof data.username === "string" && data.username.trim()) payload.username = data.username.trim();
6423
+ if (resolvedPhone) payload.phone = resolvedPhone;
6424
+ if (typeof data.session_id === "string" && data.session_id.trim()) payload.session_id = data.session_id.trim();
6425
+ if (typeof data.user_type === "number") payload.user_type = data.user_type;
6426
+ if (typeof data.msg_type === "number") payload.msg_type = data.msg_type;
6427
+ if (Number.isFinite(friendType) && friendType > 0) payload.friend_type = friendType;
6428
+ if (isCustomerOnly) payload.customeronly = 1;
6429
+ return unwrapResult(yield httpClient.post(buildApiPath("/chat/getList"), payload), "getChatList");
6317
6430
  });
6318
6431
  return _getChatList.apply(this, arguments);
6319
6432
  }
@@ -17138,12 +17251,15 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
17138
17251
  }();
17139
17252
  input.click();
17140
17253
  }
17141
- function resolveUploadedImageUrl(uploadURL, fileUrl) {
17254
+ function resolveUploadedImageUrl(resourceBaseURL, uploadURL, fileUrl) {
17142
17255
  const normalizedFileUrl = typeof fileUrl === "string" ? fileUrl.trim() : "";
17143
17256
  if (!normalizedFileUrl) return "";
17144
17257
  if (HTTP_URL_REGEXP.test(normalizedFileUrl)) return normalizedFileUrl;
17258
+ const normalizedResourceBaseURL = typeof resourceBaseURL === "string" ? resourceBaseURL.trim() : "";
17259
+ const normalizedUploadURL = typeof uploadURL === "string" ? uploadURL.trim() : "";
17260
+ const preferredBaseURL = normalizedResourceBaseURL || normalizedUploadURL;
17145
17261
  try {
17146
- return new URL(normalizedFileUrl, uploadURL).toString();
17262
+ return new URL(normalizedFileUrl, preferredBaseURL).toString();
17147
17263
  } catch (_unused2) {
17148
17264
  return normalizedFileUrl;
17149
17265
  }
@@ -17167,7 +17283,8 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
17167
17283
  isUploading.value = true;
17168
17284
  const response = yield uploadImage(file);
17169
17285
  if (!response.success || !((_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.url)) throw new Error(response.message || "上传失败");
17170
- const imageUrl = resolveUploadedImageUrl(getConfig().api.uploadURL, response.data.url);
17286
+ const config = getConfig();
17287
+ const imageUrl = resolveUploadedImageUrl(config.api.resourceBaseURL, config.api.uploadURL, response.data.url);
17171
17288
  if (!imageUrl) throw new Error("上传返回图片地址为空");
17172
17289
  const tempMessageId = createTempMessageId();
17173
17290
  const messageData = {
@@ -17366,7 +17483,7 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
17366
17483
  class: "tool-btn emoji-btn",
17367
17484
  title: "选择表情",
17368
17485
  onClick: toggleEmojiPicker
17369
- }, [..._cache[7] || (_cache[7] = [createStaticVNode("<span class=\"tool-btn-icon\" aria-hidden=\"true\" data-v-cc3cfaa7><svg class=\"tool-btn-svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" data-v-cc3cfaa7><circle cx=\"12\" cy=\"12\" r=\"10\" data-v-cc3cfaa7></circle><path d=\"M8 14s1.5 2 4 2 4-2 4-2\" data-v-cc3cfaa7></path><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\" data-v-cc3cfaa7></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\" data-v-cc3cfaa7></line></svg></span><span class=\"tool-btn-text\" data-v-cc3cfaa7>表情</span>", 2)])]), showEmojiPicker.value ? (openBlock(), createElementBlock("div", _hoisted_55, [createVNode(unref(Picker), {
17486
+ }, [..._cache[7] || (_cache[7] = [createStaticVNode("<span class=\"tool-btn-icon\" aria-hidden=\"true\" data-v-1459079f><svg class=\"tool-btn-svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" data-v-1459079f><circle cx=\"12\" cy=\"12\" r=\"10\" data-v-1459079f></circle><path d=\"M8 14s1.5 2 4 2 4-2 4-2\" data-v-1459079f></path><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\" data-v-1459079f></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\" data-v-1459079f></line></svg></span><span class=\"tool-btn-text\" data-v-1459079f>表情</span>", 2)])]), showEmojiPicker.value ? (openBlock(), createElementBlock("div", _hoisted_55, [createVNode(unref(Picker), {
17370
17487
  native: true,
17371
17488
  theme: "light",
17372
17489
  "group-names": {
@@ -17452,7 +17569,7 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
17452
17569
  ]);
17453
17570
  };
17454
17571
  }
17455
- }), [["__scopeId", "data-v-cc3cfaa7"]]);
17572
+ }), [["__scopeId", "data-v-1459079f"]]);
17456
17573
  //#endregion
17457
17574
  //#region src/assets/img/list.png?url
17458
17575
  var list_default = "data:image/png;base64,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";
@@ -17864,15 +17981,15 @@ var ChatWindow_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @_
17864
17981
  const selectedConversation = /* @__PURE__ */ ref(null);
17865
17982
  const selectedConversationData = /* @__PURE__ */ ref(void 0);
17866
17983
  const userStatusOptions = [{
17867
- id: "online",
17984
+ id: "onConnect",
17868
17985
  label: "在线",
17869
17986
  color: "#52c41a"
17870
17987
  }, {
17871
- id: "offline",
17988
+ id: "offLine",
17872
17989
  label: "离线",
17873
17990
  color: "#d9d9d9"
17874
17991
  }];
17875
- const userStatus = /* @__PURE__ */ ref("online");
17992
+ const userStatus = /* @__PURE__ */ ref(wsClient.getPresenceAction());
17876
17993
  const showStatusDropdown = /* @__PURE__ */ ref(false);
17877
17994
  const userInfo = /* @__PURE__ */ ref(null);
17878
17995
  const menus = [{
@@ -17894,16 +18011,23 @@ var ChatWindow_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @_
17894
18011
  return props.unreadCount || 0;
17895
18012
  });
17896
18013
  const { setActiveConversationId } = useUnreadStore();
17897
- function syncPresenceAction(status) {
17898
- const action = status === "online" ? "onConnect" : "offLine";
18014
+ function syncPresenceAction(action) {
17899
18015
  wsClient.sendBusinessMessage(action);
17900
18016
  }
18017
+ function applyPresenceAction(action) {
18018
+ if (userStatus.value !== action) userStatus.value = action;
18019
+ }
18020
+ function handlePresenceChanged(payload) {
18021
+ const data = payload;
18022
+ if ((data === null || data === void 0 ? void 0 : data.action) === "onConnect" || (data === null || data === void 0 ? void 0 : data.action) === "offLine") applyPresenceAction(data.action);
18023
+ }
17901
18024
  function handleStatusSelect(status) {
17902
18025
  userStatus.value = status;
17903
18026
  showStatusDropdown.value = false;
17904
18027
  }
17905
18028
  watch(userStatus, (status, prev) => {
17906
18029
  if (status === prev) return;
18030
+ if (status === wsClient.getPresenceAction()) return;
17907
18031
  syncPresenceAction(status);
17908
18032
  });
17909
18033
  function handleSelectConversation(id) {
@@ -18031,6 +18155,8 @@ var ChatWindow_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @_
18031
18155
  }
18032
18156
  onMounted(() => {
18033
18157
  userInfo.value = getUserInfo();
18158
+ applyPresenceAction(wsClient.getPresenceAction());
18159
+ wsClient.on("presenceChange", handlePresenceChanged);
18034
18160
  const width = window.innerWidth;
18035
18161
  const height = window.innerHeight;
18036
18162
  viewportSize.value = {
@@ -18096,6 +18222,7 @@ var ChatWindow_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @_
18096
18222
  document.removeEventListener("mousemove", handleMouseMove);
18097
18223
  document.removeEventListener("mouseup", handleMouseUp);
18098
18224
  window.removeEventListener("resize", handleViewportResize);
18225
+ wsClient.off("presenceChange", handlePresenceChanged);
18099
18226
  setActiveConversationId(null);
18100
18227
  });
18101
18228
  return (_ctx, _cache) => {
@@ -18200,7 +18327,7 @@ var ChatWindow_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @_
18200
18327
  ], 6);
18201
18328
  };
18202
18329
  }
18203
- }), [["__scopeId", "data-v-d726d76e"]]);
18330
+ }), [["__scopeId", "data-v-00d50ef7"]]);
18204
18331
  //#endregion
18205
18332
  //#region src/assets/img/icon.png?url
18206
18333
  var icon_default = "data:image/png;base64,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";
@@ -18511,28 +18638,96 @@ var WS_STATUS = {
18511
18638
  CLOSING: 2,
18512
18639
  CLOSED: 3
18513
18640
  };
18514
- var HEARTBEAT_INTERVAL = 3e3;
18515
- var RECONNECT_INTERVAL = 3e3;
18516
- var MAX_RECONNECT_COUNT = 5;
18641
+ var DEFAULT_HEARTBEAT_INTERVAL = 3e3;
18642
+ var DEFAULT_RECONNECT_INTERVAL = 3e3;
18643
+ var DEFAULT_MAX_RECONNECT_COUNT = 5;
18644
+ var DEFAULT_CONNECT_TIMEOUT = 3e4;
18517
18645
  var MAX_MESSAGE_QUEUE_SIZE = 200;
18646
+ var PRESENCE_ACTION_STORAGE_KEY = "imsdk:presence-action";
18647
+ var PRESENCE_CHANGE_EVENT = "presenceChange";
18648
+ function normalizePresenceAction(action) {
18649
+ return action === "offLine" ? "offLine" : "onConnect";
18650
+ }
18651
+ function readPresenceActionFromStorage() {
18652
+ if (typeof window === "undefined" || !window.localStorage) return "onConnect";
18653
+ try {
18654
+ return normalizePresenceAction(window.localStorage.getItem(PRESENCE_ACTION_STORAGE_KEY));
18655
+ } catch (error) {
18656
+ console.warn("读取在线状态缓存失败,已使用默认 onConnect:", error);
18657
+ return "onConnect";
18658
+ }
18659
+ }
18660
+ function writePresenceActionToStorage(action) {
18661
+ if (typeof window === "undefined" || !window.localStorage) return;
18662
+ try {
18663
+ window.localStorage.setItem(PRESENCE_ACTION_STORAGE_KEY, action);
18664
+ } catch (error) {
18665
+ console.warn("写入在线状态缓存失败:", error);
18666
+ }
18667
+ }
18518
18668
  var WebSocketClient = class {
18519
18669
  constructor(config = {}) {
18520
18670
  _defineProperty(this, "ws", null);
18521
18671
  _defineProperty(this, "status", WS_STATUS.CLOSED);
18522
18672
  _defineProperty(this, "heartbeatTimer", null);
18523
18673
  _defineProperty(this, "reconnectTimer", null);
18674
+ _defineProperty(this, "connectTimeoutTimer", null);
18524
18675
  _defineProperty(this, "reconnectCount", 0);
18525
18676
  _defineProperty(this, "messageQueue", []);
18526
18677
  _defineProperty(this, "listeners", /* @__PURE__ */ new Map());
18678
+ _defineProperty(this, "lastToken", "");
18679
+ _defineProperty(this, "lastUserId", null);
18680
+ _defineProperty(this, "lastPhone", null);
18527
18681
  _defineProperty(this, "userId", null);
18528
18682
  _defineProperty(this, "phone", null);
18529
18683
  _defineProperty(this, "siteId", "");
18530
18684
  _defineProperty(this, "presenceAction", "onConnect");
18531
18685
  _defineProperty(this, "isConnected", false);
18532
- _defineProperty(this, "wsUrl", "");
18686
+ _defineProperty(this, "wsUrlOverride", "");
18533
18687
  _defineProperty(this, "logPrefix", "[WebSocket]");
18534
- this.wsUrl = config.wsUrl || "";
18688
+ this.wsUrlOverride = config.wsUrl || "";
18535
18689
  this.siteId = config.siteId || "";
18690
+ this.presenceAction = readPresenceActionFromStorage();
18691
+ }
18692
+ toPositiveInt(value, fallback) {
18693
+ const next = Number(value);
18694
+ if (!Number.isFinite(next) || next <= 0) return fallback;
18695
+ return Math.floor(next);
18696
+ }
18697
+ getHeartbeatInterval() {
18698
+ return this.toPositiveInt(getConfig().ws.heartbeatInterval, DEFAULT_HEARTBEAT_INTERVAL);
18699
+ }
18700
+ getReconnectInterval() {
18701
+ return this.toPositiveInt(getConfig().ws.reconnectInterval, DEFAULT_RECONNECT_INTERVAL);
18702
+ }
18703
+ getMaxReconnectCount() {
18704
+ return this.toPositiveInt(getConfig().ws.maxReconnectAttempts, DEFAULT_MAX_RECONNECT_COUNT);
18705
+ }
18706
+ getConnectTimeout() {
18707
+ return this.toPositiveInt(getConfig().ws.connectTimeout, DEFAULT_CONNECT_TIMEOUT);
18708
+ }
18709
+ trace(tag, payload) {
18710
+ if (!isWSTraceEnabled()) return;
18711
+ if (payload) {
18712
+ console.debug(`${this.logPrefix} [TRACE] ${tag}`, payload);
18713
+ return;
18714
+ }
18715
+ console.debug(`${this.logPrefix} [TRACE] ${tag}`);
18716
+ }
18717
+ resolveProtocolAction(action) {
18718
+ const actions = getWSProtocolAction();
18719
+ if (action === "send") return actions.send;
18720
+ if (action === "msgRead") return actions.msgRead;
18721
+ if (action === "onConnect") return actions.onConnect;
18722
+ if (action === "offLine") return actions.offLine;
18723
+ if (action === "heartbeat") return actions.heartbeat;
18724
+ return action;
18725
+ }
18726
+ stopConnectTimeout() {
18727
+ if (this.connectTimeoutTimer) {
18728
+ clearTimeout(this.connectTimeoutTimer);
18729
+ this.connectTimeoutTimer = null;
18730
+ }
18536
18731
  }
18537
18732
  /**
18538
18733
  * 连接 WebSocket
@@ -18545,7 +18740,15 @@ var WebSocketClient = class {
18545
18740
  return new Promise((resolve, reject) => {
18546
18741
  try {
18547
18742
  this.destroyConnection();
18548
- const url = `${this.wsUrl || "wss://aox.api.orchiport.asia"}?platform=${encodeURIComponent(getWSPlatform())}${token ? `&token=${encodeURIComponent(token)}` : ""}`;
18743
+ const url = `${this.wsUrlOverride || getWSBaseURL()}?platform=${encodeURIComponent(getWSPlatform())}${token ? `&token=${encodeURIComponent(token)}` : ""}`;
18744
+ this.trace("connect:prepare", {
18745
+ url,
18746
+ platform: getWSPlatform()
18747
+ });
18748
+ const connectTimeout = this.getConnectTimeout();
18749
+ this.lastToken = token;
18750
+ this.lastUserId = userId;
18751
+ this.lastPhone = phone;
18549
18752
  this.userId = userId;
18550
18753
  this.phone = phone;
18551
18754
  this.siteId = siteId || this.siteId;
@@ -18556,15 +18759,34 @@ var WebSocketClient = class {
18556
18759
  });
18557
18760
  this.ws = new WebSocket(url);
18558
18761
  this.status = WS_STATUS.CONNECTING;
18762
+ this.stopConnectTimeout();
18763
+ this.connectTimeoutTimer = setTimeout(() => {
18764
+ if (!this.ws || this.status !== WS_STATUS.CONNECTING) return;
18765
+ console.warn(`${this.logPrefix} 连接超时,已主动关闭`, {
18766
+ timeoutMs: connectTimeout,
18767
+ platform: getWSPlatform(),
18768
+ siteId: this.siteId
18769
+ });
18770
+ try {
18771
+ this.ws.close();
18772
+ } catch (error) {
18773
+ console.error(`${this.logPrefix} 连接超时关闭失败`, error);
18774
+ }
18775
+ this.status = WS_STATUS.CLOSED;
18776
+ this.stopConnectTimeout();
18777
+ reject(/* @__PURE__ */ new Error(`WebSocket 连接超时(${connectTimeout}ms)`));
18778
+ }, connectTimeout);
18559
18779
  this.ws.onopen = (event) => {
18560
18780
  this.status = WS_STATUS.OPEN;
18561
18781
  this.reconnectCount = 0;
18782
+ this.stopConnectTimeout();
18562
18783
  console.info(`${this.logPrefix} 连接已建立`, {
18563
18784
  platform: getWSPlatform(),
18564
18785
  siteId: this.siteId,
18565
18786
  userId: this.userId
18566
18787
  });
18567
18788
  if (!this.isConnected) {
18789
+ this.setPresenceAction("onConnect", "connect");
18568
18790
  this.sendConnectMessage();
18569
18791
  this.isConnected = true;
18570
18792
  }
@@ -18578,6 +18800,10 @@ var WebSocketClient = class {
18578
18800
  if (!rawData || rawData === "null") return;
18579
18801
  try {
18580
18802
  const data = JSON.parse(rawData);
18803
+ this.trace("message:receive", {
18804
+ controller: data === null || data === void 0 ? void 0 : data.controller,
18805
+ action: data === null || data === void 0 ? void 0 : data.action
18806
+ });
18581
18807
  this.emit("message", data);
18582
18808
  } catch (_unused) {
18583
18809
  console.warn("收到非 JSON WebSocket 消息,已忽略:", rawData);
@@ -18585,24 +18811,29 @@ var WebSocketClient = class {
18585
18811
  };
18586
18812
  this.ws.onerror = (error) => {
18587
18813
  this.status = WS_STATUS.CLOSED;
18814
+ this.stopConnectTimeout();
18588
18815
  console.error(`${this.logPrefix} 连接异常`, error);
18589
18816
  this.emit("error", error);
18590
18817
  reject(error);
18591
18818
  };
18592
18819
  this.ws.onclose = (event) => {
18593
18820
  this.status = WS_STATUS.CLOSED;
18821
+ this.stopConnectTimeout();
18594
18822
  this.stopHeartbeat();
18595
18823
  this.emit("close", event);
18596
- const canReconnect = this.reconnectCount < MAX_RECONNECT_COUNT;
18824
+ const maxReconnectCount = this.getMaxReconnectCount();
18825
+ const canReconnect = this.presenceAction === "onConnect" && this.reconnectCount < maxReconnectCount;
18597
18826
  console.warn(`${this.logPrefix} 连接关闭`, {
18598
18827
  code: event.code,
18599
18828
  reason: event.reason,
18600
18829
  wasClean: event.wasClean,
18830
+ presenceAction: this.presenceAction,
18601
18831
  reconnectAttempt: this.reconnectCount,
18602
18832
  willReconnect: canReconnect
18603
18833
  });
18604
18834
  if (canReconnect) this.scheduleReconnect(token, this.userId, this.phone);
18605
- else console.error(`${this.logPrefix} 重连次数超过最大限制,停止重连`, { maxReconnectCount: MAX_RECONNECT_COUNT });
18835
+ else if (this.presenceAction === "offLine") console.info(`${this.logPrefix} 当前为 offLine 状态,已停止自动重连`);
18836
+ else console.error(`${this.logPrefix} 重连次数超过最大限制,停止重连`, { maxReconnectCount });
18606
18837
  };
18607
18838
  } catch (error) {
18608
18839
  reject(error);
@@ -18625,6 +18856,10 @@ var WebSocketClient = class {
18625
18856
  }
18626
18857
  try {
18627
18858
  this.ws.send(message);
18859
+ if (typeof data !== "string") this.trace("message:send", {
18860
+ controller: data.controller,
18861
+ action: data.action
18862
+ });
18628
18863
  return true;
18629
18864
  } catch (error) {
18630
18865
  console.error("WebSocket发送消息失败:", error);
@@ -18635,7 +18870,7 @@ var WebSocketClient = class {
18635
18870
  * 发送控制器动作消息(使用当前配置的 controller)
18636
18871
  */
18637
18872
  sendControllerMessage(action, param = {}) {
18638
- const controller = getWSController();
18873
+ const controller = getWSProtocolController();
18639
18874
  return this.send({
18640
18875
  controller,
18641
18876
  action,
@@ -18653,10 +18888,47 @@ var WebSocketClient = class {
18653
18888
  */
18654
18889
  sendBusinessMessage(action, param = {}) {
18655
18890
  if (action === "onConnect" || action === "offLine") {
18656
- this.presenceAction = action;
18657
- if (!this.checkConnected()) return false;
18891
+ this.setPresenceAction(action, "manual");
18892
+ if (!this.checkConnected()) {
18893
+ if (action === "onConnect") this.tryReconnectFromManualOnline();
18894
+ return false;
18895
+ }
18658
18896
  }
18659
- return this.sendControllerMessage(action, param);
18897
+ const runtimeAction = this.resolveProtocolAction(action);
18898
+ return this.sendControllerMessage(runtimeAction, param);
18899
+ }
18900
+ tryReconnectFromManualOnline() {
18901
+ if (this.status === WS_STATUS.CONNECTING) {
18902
+ console.info(`${this.logPrefix} 当前正在连接中,跳过重复连接`);
18903
+ return;
18904
+ }
18905
+ if (!this.lastToken) {
18906
+ console.warn(`${this.logPrefix} 缺少连接凭证,无法在 onConnect 后主动重连`);
18907
+ return;
18908
+ }
18909
+ if (this.reconnectTimer) {
18910
+ clearTimeout(this.reconnectTimer);
18911
+ this.reconnectTimer = null;
18912
+ }
18913
+ console.info(`${this.logPrefix} 检测到手动切换 onConnect,发起主动重连`);
18914
+ this.connect(this.lastToken, this.lastUserId, this.lastPhone, this.siteId).catch((error) => {
18915
+ console.error(`${this.logPrefix} onConnect 主动重连失败`, error);
18916
+ });
18917
+ }
18918
+ setPresenceAction(action, source) {
18919
+ const normalizedAction = normalizePresenceAction(action);
18920
+ const changed = this.presenceAction !== normalizedAction;
18921
+ this.presenceAction = normalizedAction;
18922
+ writePresenceActionToStorage(normalizedAction);
18923
+ if (normalizedAction === "offLine" && this.reconnectTimer) {
18924
+ clearTimeout(this.reconnectTimer);
18925
+ this.reconnectTimer = null;
18926
+ console.info(`${this.logPrefix} 已切换为 offLine,取消待执行的自动重连`);
18927
+ }
18928
+ if (changed) this.emit(PRESENCE_CHANGE_EVENT, {
18929
+ action: normalizedAction,
18930
+ source
18931
+ });
18660
18932
  }
18661
18933
  /**
18662
18934
  * 启动心跳
@@ -18666,8 +18938,8 @@ var WebSocketClient = class {
18666
18938
  this.heartbeatTimer = setInterval(() => {
18667
18939
  if (this.status === WS_STATUS.OPEN && this.ws) {
18668
18940
  const heartbeatData = {
18669
- controller: getWSController(),
18670
- action: "heartbeat",
18941
+ controller: getWSProtocolController(),
18942
+ action: this.resolveProtocolAction("heartbeat"),
18671
18943
  param: {
18672
18944
  userId: this.userId,
18673
18945
  platform: getWSPlatform(),
@@ -18677,15 +18949,15 @@ var WebSocketClient = class {
18677
18949
  };
18678
18950
  this.send(heartbeatData);
18679
18951
  }
18680
- }, HEARTBEAT_INTERVAL);
18952
+ }, this.getHeartbeatInterval());
18681
18953
  }
18682
18954
  /**
18683
18955
  * 发送连接/状态消息
18684
18956
  */
18685
18957
  sendConnectMessage() {
18686
18958
  const connectData = {
18687
- controller: getWSController(),
18688
- action: this.presenceAction,
18959
+ controller: getWSProtocolController(),
18960
+ action: this.resolveProtocolAction(this.presenceAction),
18689
18961
  param: {
18690
18962
  userId: this.userId,
18691
18963
  platform: getWSPlatform(),
@@ -18717,12 +18989,23 @@ var WebSocketClient = class {
18717
18989
  }
18718
18990
  this.reconnectCount++;
18719
18991
  const attempt = this.reconnectCount;
18992
+ const maxReconnectCount = this.getMaxReconnectCount();
18993
+ const reconnectInterval = this.getReconnectInterval();
18720
18994
  console.info(`${this.logPrefix} 准备重连`, {
18721
18995
  attempt,
18722
- maxReconnectCount: MAX_RECONNECT_COUNT,
18723
- retryInMs: RECONNECT_INTERVAL
18996
+ maxReconnectCount,
18997
+ retryInMs: reconnectInterval
18724
18998
  });
18725
18999
  this.reconnectTimer = setTimeout(() => {
19000
+ if (this.presenceAction === "offLine") {
19001
+ console.info(`${this.logPrefix} 当前为 offLine 状态,跳过本次自动重连`);
19002
+ if (this.reconnectTimer) {
19003
+ clearTimeout(this.reconnectTimer);
19004
+ this.reconnectTimer = null;
19005
+ }
19006
+ return;
19007
+ }
19008
+ if (this.presenceAction !== "onConnect") this.setPresenceAction("onConnect", "connect");
18726
19009
  this.stopHeartbeat();
18727
19010
  if (this.reconnectTimer) {
18728
19011
  clearTimeout(this.reconnectTimer);
@@ -18730,7 +19013,7 @@ var WebSocketClient = class {
18730
19013
  }
18731
19014
  console.info(`${this.logPrefix} 发起重连`, {
18732
19015
  attempt,
18733
- maxReconnectCount: MAX_RECONNECT_COUNT
19016
+ maxReconnectCount
18734
19017
  });
18735
19018
  this.connect(token, userId, phone, this.siteId).catch((error) => {
18736
19019
  console.error(`${this.logPrefix} 重连失败`, {
@@ -18738,7 +19021,7 @@ var WebSocketClient = class {
18738
19021
  error
18739
19022
  });
18740
19023
  });
18741
- }, RECONNECT_INTERVAL);
19024
+ }, reconnectInterval);
18742
19025
  }
18743
19026
  /**
18744
19027
  * 发送消息队列中的消息
@@ -18762,6 +19045,7 @@ var WebSocketClient = class {
18762
19045
  clearTimeout(this.reconnectTimer);
18763
19046
  this.reconnectTimer = null;
18764
19047
  }
19048
+ this.stopConnectTimeout();
18765
19049
  if (this.ws) {
18766
19050
  this.ws.onopen = null;
18767
19051
  this.ws.onmessage = null;
@@ -18785,7 +19069,7 @@ var WebSocketClient = class {
18785
19069
  disconnect() {
18786
19070
  console.info(`${this.logPrefix} 主动断开连接`);
18787
19071
  this.destroyConnection();
18788
- this.reconnectCount = MAX_RECONNECT_COUNT;
19072
+ this.reconnectCount = this.getMaxReconnectCount();
18789
19073
  this.messageQueue = [];
18790
19074
  }
18791
19075
  /**
@@ -18838,6 +19122,9 @@ var WebSocketClient = class {
18838
19122
  var _this$ws;
18839
19123
  return this.status === WS_STATUS.OPEN && ((_this$ws = this.ws) === null || _this$ws === void 0 ? void 0 : _this$ws.readyState) === WS_STATUS.OPEN;
18840
19124
  }
19125
+ getPresenceAction() {
19126
+ return this.presenceAction;
19127
+ }
18841
19128
  };
18842
19129
  var wsClient = new WebSocketClient();
18843
19130
  //#endregion
@@ -18870,10 +19157,10 @@ function mountIMApp() {
18870
19157
  } }).mount(container);
18871
19158
  }
18872
19159
  function validateModeContract() {
18873
- var _config$api$prefix, _config$ws$controller, _config$ws$platform;
19160
+ var _config$api$prefix, _config$ws$protocol, _config$ws$platform;
18874
19161
  const config = getConfig();
18875
19162
  const apiPrefix = (_config$api$prefix = config.api.prefix) === null || _config$api$prefix === void 0 ? void 0 : _config$api$prefix.trim();
18876
- const wsController = (_config$ws$controller = config.ws.controller) === null || _config$ws$controller === void 0 ? void 0 : _config$ws$controller.trim();
19163
+ const wsController = (config.ws.controller || ((_config$ws$protocol = config.ws.protocol) === null || _config$ws$protocol === void 0 ? void 0 : _config$ws$protocol.controller) || "").trim();
18877
19164
  const wsPlatform = (_config$ws$platform = config.ws.platform) === null || _config$ws$platform === void 0 ? void 0 : _config$ws$platform.trim();
18878
19165
  if (!apiPrefix) throw new Error("IMSDK 初始化失败:缺少 api.prefix,请使用 @zjw-jszn/platform-imsdk 或 @zjw-jszn/store-imsdk,或显式配置前缀");
18879
19166
  if (!wsController || !wsPlatform) throw new Error("IMSDK 初始化失败:缺少 ws.controller 或 ws.platform,请按文档约定配置后重试");
@@ -18886,11 +19173,11 @@ function initIM() {
18886
19173
  function _initIM() {
18887
19174
  _initIM = _asyncToGenerator(function* (config = {}) {
18888
19175
  if (initInFlight) {
18889
- var _config$api, _config$ws, _config$ws2;
19176
+ var _config$api, _config$ws$controller, _config$ws, _config$ws2, _config$ws3;
18890
19177
  const currentConfig = getConfig();
18891
19178
  const nextApiPrefix = (_config$api = config.api) === null || _config$api === void 0 ? void 0 : _config$api.prefix;
18892
- const nextWSController = (_config$ws = config.ws) === null || _config$ws === void 0 ? void 0 : _config$ws.controller;
18893
- const nextWSPlatform = (_config$ws2 = config.ws) === null || _config$ws2 === void 0 ? void 0 : _config$ws2.platform;
19179
+ const nextWSController = (_config$ws$controller = (_config$ws = config.ws) === null || _config$ws === void 0 ? void 0 : _config$ws.controller) !== null && _config$ws$controller !== void 0 ? _config$ws$controller : (_config$ws2 = config.ws) === null || _config$ws2 === void 0 || (_config$ws2 = _config$ws2.protocol) === null || _config$ws2 === void 0 ? void 0 : _config$ws2.controller;
19180
+ const nextWSPlatform = (_config$ws3 = config.ws) === null || _config$ws3 === void 0 ? void 0 : _config$ws3.platform;
18894
19181
  if (nextApiPrefix && nextApiPrefix !== currentConfig.api.prefix || nextWSController && nextWSController !== currentConfig.ws.controller || nextWSPlatform && nextWSPlatform !== currentConfig.ws.platform) throw new Error("IMSDK 正在以其他模式初始化,请等待当前初始化完成后重试");
18895
19182
  return initInFlight;
18896
19183
  }
@@ -18903,11 +19190,11 @@ function _initIM() {
18903
19190
  }
18904
19191
  };
18905
19192
  if (isInitialized.value && httpClient.getAuth()) {
18906
- var _config$api2, _config$ws3, _config$ws4;
19193
+ var _config$api2, _config$ws$controller2, _config$ws4, _config$ws5, _config$ws6;
18907
19194
  const currentConfig = getConfig();
18908
19195
  const nextApiPrefix = (_config$api2 = config.api) === null || _config$api2 === void 0 ? void 0 : _config$api2.prefix;
18909
- const nextWSController = (_config$ws3 = config.ws) === null || _config$ws3 === void 0 ? void 0 : _config$ws3.controller;
18910
- const nextWSPlatform = (_config$ws4 = config.ws) === null || _config$ws4 === void 0 ? void 0 : _config$ws4.platform;
19196
+ const nextWSController = (_config$ws$controller2 = (_config$ws4 = config.ws) === null || _config$ws4 === void 0 ? void 0 : _config$ws4.controller) !== null && _config$ws$controller2 !== void 0 ? _config$ws$controller2 : (_config$ws5 = config.ws) === null || _config$ws5 === void 0 || (_config$ws5 = _config$ws5.protocol) === null || _config$ws5 === void 0 ? void 0 : _config$ws5.controller;
19197
+ const nextWSPlatform = (_config$ws6 = config.ws) === null || _config$ws6 === void 0 ? void 0 : _config$ws6.platform;
18911
19198
  if (nextApiPrefix && nextApiPrefix !== currentConfig.api.prefix || nextWSController && nextWSController !== currentConfig.ws.controller || nextWSPlatform && nextWSPlatform !== currentConfig.ws.platform) throw new Error("IMSDK 已初始化为其他模式,请刷新页面后再切换平台/门店");
18912
19199
  mountIMApp();
18913
19200
  console.warn("IMSDK 已初始化且已鉴权,本次调用将复用现有实例");
@@ -18917,13 +19204,30 @@ function _initIM() {
18917
19204
  if (config.api) updateConfig({ api: config.api });
18918
19205
  if (config.sound) updateConfig({ sound: config.sound });
18919
19206
  if (config.auth) updateConfig({ auth: config.auth });
19207
+ if (config.chat) {
19208
+ var _config$chat$platform;
19209
+ const currentChat = getConfig().chat;
19210
+ updateConfig({ chat: { platformServicePhone: (_config$chat$platform = config.chat.platformServicePhone) !== null && _config$chat$platform !== void 0 ? _config$chat$platform : currentChat.platformServicePhone } });
19211
+ }
18920
19212
  if (config.runtimeApi) updateConfig({ runtimeApi: config.runtimeApi });
18921
19213
  if (config.ws) {
18922
- var _config$ws$controller2, _config$ws$platform2;
19214
+ var _ref, _config$ws$controller3, _config$ws$protocol2, _config$ws$url, _config$ws$platform2, _config$ws$reconnectI, _config$ws$heartbeatI, _config$ws$maxReconne, _config$ws$connectTim, _config$ws$traceEnabl, _config$ws$protocol$c, _config$ws$protocol3, _config$ws$protocol4, _config$ws$protocol$h, _config$ws$protocol5;
18923
19215
  const currentWS = getConfig().ws;
19216
+ const nextWSController = (_ref = (_config$ws$controller3 = config.ws.controller) !== null && _config$ws$controller3 !== void 0 ? _config$ws$controller3 : (_config$ws$protocol2 = config.ws.protocol) === null || _config$ws$protocol2 === void 0 ? void 0 : _config$ws$protocol2.controller) !== null && _ref !== void 0 ? _ref : currentWS.controller;
18924
19217
  updateConfig({ ws: {
18925
- controller: (_config$ws$controller2 = config.ws.controller) !== null && _config$ws$controller2 !== void 0 ? _config$ws$controller2 : currentWS.controller,
18926
- platform: (_config$ws$platform2 = config.ws.platform) !== null && _config$ws$platform2 !== void 0 ? _config$ws$platform2 : currentWS.platform
19218
+ url: (_config$ws$url = config.ws.url) !== null && _config$ws$url !== void 0 ? _config$ws$url : currentWS.url,
19219
+ controller: nextWSController,
19220
+ platform: (_config$ws$platform2 = config.ws.platform) !== null && _config$ws$platform2 !== void 0 ? _config$ws$platform2 : currentWS.platform,
19221
+ reconnectInterval: (_config$ws$reconnectI = config.ws.reconnectInterval) !== null && _config$ws$reconnectI !== void 0 ? _config$ws$reconnectI : currentWS.reconnectInterval,
19222
+ heartbeatInterval: (_config$ws$heartbeatI = config.ws.heartbeatInterval) !== null && _config$ws$heartbeatI !== void 0 ? _config$ws$heartbeatI : currentWS.heartbeatInterval,
19223
+ maxReconnectAttempts: (_config$ws$maxReconne = config.ws.maxReconnectAttempts) !== null && _config$ws$maxReconne !== void 0 ? _config$ws$maxReconne : currentWS.maxReconnectAttempts,
19224
+ connectTimeout: (_config$ws$connectTim = config.ws.connectTimeout) !== null && _config$ws$connectTim !== void 0 ? _config$ws$connectTim : currentWS.connectTimeout,
19225
+ traceEnabled: (_config$ws$traceEnabl = config.ws.traceEnabled) !== null && _config$ws$traceEnabl !== void 0 ? _config$ws$traceEnabl : currentWS.traceEnabled,
19226
+ protocol: _objectSpread2(_objectSpread2(_objectSpread2({}, currentWS.protocol), config.ws.protocol || {}), {}, {
19227
+ controller: (_config$ws$protocol$c = (_config$ws$protocol3 = config.ws.protocol) === null || _config$ws$protocol3 === void 0 ? void 0 : _config$ws$protocol3.controller) !== null && _config$ws$protocol$c !== void 0 ? _config$ws$protocol$c : nextWSController,
19228
+ action: _objectSpread2(_objectSpread2({}, currentWS.protocol.action), ((_config$ws$protocol4 = config.ws.protocol) === null || _config$ws$protocol4 === void 0 ? void 0 : _config$ws$protocol4.action) || {}),
19229
+ heartbeatSignals: (_config$ws$protocol$h = (_config$ws$protocol5 = config.ws.protocol) === null || _config$ws$protocol5 === void 0 ? void 0 : _config$ws$protocol5.heartbeatSignals) !== null && _config$ws$protocol$h !== void 0 ? _config$ws$protocol$h : currentWS.protocol.heartbeatSignals
19230
+ })
18927
19231
  } });
18928
19232
  }
18929
19233
  httpClient.setBaseURL(getConfig().api.baseURL);
@@ -18963,17 +19267,21 @@ function getUserInfo() {
18963
19267
  //#endregion
18964
19268
  //#region src/mode.ts
18965
19269
  function warnModeOverrides(scope, config, defaults) {
19270
+ var _wsConfig$protocol;
18966
19271
  const apiConfig = config.api;
18967
19272
  const wsConfig = config.ws;
18968
19273
  if ((apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.prefix) && apiConfig.prefix !== defaults.api.prefix) console.warn(`[${scope}] 已忽略 api.prefix=${apiConfig.prefix},当前模式固定为 ${defaults.api.prefix}`);
18969
19274
  if ((apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.userType) !== void 0 && apiConfig.userType !== defaults.api.userType) console.warn(`[${scope}] 已忽略 api.userType=${apiConfig.userType},当前模式固定为 ${defaults.api.userType}`);
18970
19275
  if ((wsConfig === null || wsConfig === void 0 ? void 0 : wsConfig.controller) && wsConfig.controller !== defaults.ws.controller) console.warn(`[${scope}] 已忽略 ws.controller=${wsConfig.controller},当前模式固定为 ${defaults.ws.controller}`);
18971
19276
  if ((wsConfig === null || wsConfig === void 0 ? void 0 : wsConfig.platform) && wsConfig.platform !== defaults.ws.platform) console.warn(`[${scope}] 已忽略 ws.platform=${wsConfig.platform},当前模式固定为 ${defaults.ws.platform}`);
19277
+ const protocolController = wsConfig === null || wsConfig === void 0 || (_wsConfig$protocol = wsConfig.protocol) === null || _wsConfig$protocol === void 0 ? void 0 : _wsConfig$protocol.controller;
19278
+ if (protocolController && protocolController !== defaults.ws.controller) console.warn(`[${scope}] 已忽略 ws.protocol.controller=${protocolController},当前模式固定为 ${defaults.ws.controller}`);
18972
19279
  }
18973
19280
  function applyModeDefaults(config, defaults) {
19281
+ var _config$ws;
18974
19282
  return _objectSpread2(_objectSpread2({}, config), {}, {
18975
19283
  api: _objectSpread2(_objectSpread2({}, config.api || {}), defaults.api),
18976
- ws: _objectSpread2(_objectSpread2({}, config.ws || {}), defaults.ws)
19284
+ ws: _objectSpread2(_objectSpread2(_objectSpread2({}, config.ws || {}), defaults.ws), {}, { protocol: _objectSpread2(_objectSpread2({}, ((_config$ws = config.ws) === null || _config$ws === void 0 ? void 0 : _config$ws.protocol) || {}), {}, { controller: defaults.ws.controller }) })
18977
19285
  });
18978
19286
  }
18979
19287
  //#endregion