@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__)) {
@@ -5722,6 +5722,7 @@ Expected function or array of functions, received type ${typeof value}.`);
5722
5722
  var defaultConfig = {
5723
5723
  api: {
5724
5724
  baseURL: "https://aox.api.orchiport.asia",
5725
+ resourceBaseURL: "https://resource.api.orchiport.asia",
5725
5726
  prefix: "",
5726
5727
  uploadURL: "https://resource.api.orchiport.asia/system/uploadImage",
5727
5728
  signKey: "Z0XYfLbnDpuVqk41",
@@ -5731,11 +5732,29 @@ Expected function or array of functions, received type ${typeof value}.`);
5731
5732
  defaultSignKey: "your-default-sign-key-here"
5732
5733
  },
5733
5734
  ws: {
5735
+ url: "",
5734
5736
  controller: "",
5735
- platform: ""
5737
+ platform: "",
5738
+ reconnectInterval: 3e3,
5739
+ heartbeatInterval: 3e3,
5740
+ maxReconnectAttempts: 5,
5741
+ connectTimeout: 3e4,
5742
+ traceEnabled: false,
5743
+ protocol: {
5744
+ controller: "",
5745
+ action: {
5746
+ send: "send",
5747
+ msgRead: "msgRead",
5748
+ onConnect: "onConnect",
5749
+ offLine: "offLine",
5750
+ heartbeat: "heartbeat"
5751
+ },
5752
+ heartbeatSignals: ["ping", "pong"]
5753
+ }
5736
5754
  },
5737
5755
  sound: { enabled: true },
5738
5756
  auth: { authorizationPayload: {} },
5757
+ chat: { platformServicePhone: "" },
5739
5758
  runtimeApi: {}
5740
5759
  };
5741
5760
  var currentConfig = defaultConfig;
@@ -5749,19 +5768,28 @@ Expected function or array of functions, received type ${typeof value}.`);
5749
5768
  * 更新配置
5750
5769
  */
5751
5770
  function updateConfig(config) {
5752
- var _ref, _config$sound$enabled, _config$sound, _currentConfig$sound, _config$sound$url, _config$sound2, _currentConfig$sound2, _currentConfig$auth, _config$auth;
5771
+ 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;
5753
5772
  currentConfig = _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig), config), {}, {
5754
5773
  api: _objectSpread2(_objectSpread2({}, currentConfig.api), config.api),
5755
- ws: _objectSpread2(_objectSpread2({}, currentConfig.ws), config.ws),
5774
+ 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), {}, {
5775
+ 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) || {}),
5776
+ 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
5777
+ }) }),
5756
5778
  sound: {
5757
5779
  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,
5758
5780
  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
5759
5781
  },
5760
5782
  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) || {}) }),
5783
+ chat: _objectSpread2(_objectSpread2({}, currentConfig.chat), config.chat),
5761
5784
  runtimeApi: _objectSpread2(_objectSpread2({}, currentConfig.runtimeApi), config.runtimeApi)
5762
5785
  });
5763
5786
  }
5764
5787
  var PREFIX_TRIM_REGEXP = /^\/+|\/+$/g;
5788
+ var URL_TRIM_REGEXP = /\/+$/g;
5789
+ var URL_ORIGIN_REGEXP = /^[a-z][a-z\d+\-.]*:\/\/[^/]+/i;
5790
+ var WS_PROTOCOL_REGEXP = /^wss?:\/\//i;
5791
+ var HTTPS_PROTOCOL_REGEXP = /^https:\/\//i;
5792
+ var HTTP_PROTOCOL_REGEXP = /^http:\/\//i;
5765
5793
  function normalizePrefix(prefix) {
5766
5794
  if (!prefix) return "";
5767
5795
  return `/${prefix.replace(PREFIX_TRIM_REGEXP, "")}`;
@@ -5802,6 +5830,59 @@ Expected function or array of functions, received type ${typeof value}.`);
5802
5830
  return currentConfig.ws.platform || "";
5803
5831
  }
5804
5832
  /**
5833
+ * 是否开启 WebSocket Trace 日志
5834
+ */
5835
+ function isWSTraceEnabled() {
5836
+ return currentConfig.ws.traceEnabled === true;
5837
+ }
5838
+ function normalizeWSAction(value, fallback) {
5839
+ return String(value || "").trim() || fallback;
5840
+ }
5841
+ /**
5842
+ * 获取 WebSocket 协议控制器(优先 protocol.controller)
5843
+ */
5844
+ function getWSProtocolController() {
5845
+ var _currentConfig$ws$pro;
5846
+ return String(((_currentConfig$ws$pro = currentConfig.ws.protocol) === null || _currentConfig$ws$pro === void 0 ? void 0 : _currentConfig$ws$pro.controller) || "").trim() || getWSController();
5847
+ }
5848
+ /**
5849
+ * 获取 WebSocket 协议动作映射
5850
+ */
5851
+ function getWSProtocolAction() {
5852
+ var _currentConfig$ws$pro2;
5853
+ const action = ((_currentConfig$ws$pro2 = currentConfig.ws.protocol) === null || _currentConfig$ws$pro2 === void 0 ? void 0 : _currentConfig$ws$pro2.action) || defaultConfig.ws.protocol.action;
5854
+ return {
5855
+ send: normalizeWSAction(action.send, "send"),
5856
+ msgRead: normalizeWSAction(action.msgRead, "msgRead"),
5857
+ onConnect: normalizeWSAction(action.onConnect, "onConnect"),
5858
+ offLine: normalizeWSAction(action.offLine, "offLine"),
5859
+ heartbeat: normalizeWSAction(action.heartbeat, "heartbeat")
5860
+ };
5861
+ }
5862
+ function normalizeURL(value) {
5863
+ return String(value || "").trim().replace(URL_TRIM_REGEXP, "");
5864
+ }
5865
+ function toWSURLFromHTTP(baseURL, fallback = "") {
5866
+ const normalized = normalizeURL(baseURL);
5867
+ const fallbackURL = normalizeURL(fallback);
5868
+ if (!normalized) return fallbackURL;
5869
+ const originMatch = normalized.match(URL_ORIGIN_REGEXP);
5870
+ const origin = (originMatch === null || originMatch === void 0 ? void 0 : originMatch[0]) || normalized;
5871
+ if (WS_PROTOCOL_REGEXP.test(origin)) return origin;
5872
+ if (HTTPS_PROTOCOL_REGEXP.test(origin)) return origin.replace(HTTPS_PROTOCOL_REGEXP, "wss://");
5873
+ if (HTTP_PROTOCOL_REGEXP.test(origin)) return origin.replace(HTTP_PROTOCOL_REGEXP, "ws://");
5874
+ return fallbackURL;
5875
+ }
5876
+ /**
5877
+ * 获取 WebSocket 基础地址
5878
+ * 优先级:ws.url > api.baseURL 推导 > 默认地址
5879
+ */
5880
+ function getWSBaseURL() {
5881
+ const configured = normalizeURL(currentConfig.ws.url);
5882
+ if (configured) return configured;
5883
+ return toWSURLFromHTTP(currentConfig.api.baseURL, "wss://aox.api.orchiport.asia");
5884
+ }
5885
+ /**
5805
5886
  * 获取鉴权扩展参数(平台默认为空,门店可注入 username/avatar)
5806
5887
  */
5807
5888
  function getAuthorizationExtraPayload() {
@@ -6138,6 +6219,7 @@ Expected function or array of functions, received type ${typeof value}.`);
6138
6219
  var INTEGER_STRING_REGEXP = /^\d+$/;
6139
6220
  var UPLOAD_TIMEOUT_MS = 3e4;
6140
6221
  var MAX_UPLOAD_IMAGE_SIZE_BYTES = 2 * 1024 * 1024;
6222
+ var CUSTOMER_ONLY_TRUE_SET = new Set(["1", "true"]);
6141
6223
  function ensureAuthorized(apiName) {
6142
6224
  if (!httpClient.getAuth()) throw new Error(`未登录,禁止请求 ${apiName},请先完成鉴权`);
6143
6225
  }
@@ -6205,6 +6287,15 @@ Expected function or array of functions, received type ${typeof value}.`);
6205
6287
  if (response.result === void 0 || response.result === null) throw new Error(`${apiName} 接口返回 result 为空`);
6206
6288
  return response.result;
6207
6289
  }
6290
+ function normalizePhone(phone) {
6291
+ return typeof phone === "string" ? phone.trim() : "";
6292
+ }
6293
+ function isCustomerOnlyFlagEnabled(value) {
6294
+ if (typeof value === "boolean") return value;
6295
+ if (typeof value === "number") return value === 1;
6296
+ if (typeof value === "string") return CUSTOMER_ONLY_TRUE_SET.has(value.trim().toLowerCase());
6297
+ return false;
6298
+ }
6208
6299
  /**
6209
6300
  * 获取用户鉴权
6210
6301
  * @param params 鉴权参数
@@ -6335,14 +6426,36 @@ Expected function or array of functions, received type ${typeof value}.`);
6335
6426
  * @param data.session_id - 会话ID
6336
6427
  * @param data.user_type - 用户类型
6337
6428
  * @param data.msg_type - 消息类型
6429
+ * @param data.friend_type - 对话对象类型
6430
+ * @param data.customeronly - 平台客服模式标记(1/true)
6338
6431
  */
6339
6432
  function getChatList(_x7) {
6340
6433
  return _getChatList.apply(this, arguments);
6341
6434
  }
6342
6435
  function _getChatList() {
6343
6436
  _getChatList = _asyncToGenerator(function* (data) {
6437
+ var _data$friend_type, _getConfig$chat;
6344
6438
  ensureAuthorized("getChatList");
6345
- return unwrapResult(yield httpClient.post(buildApiPath("/chat/getList"), data), "getChatList");
6439
+ const friendType = Number((_data$friend_type = data.friend_type) !== null && _data$friend_type !== void 0 ? _data$friend_type : 0);
6440
+ const customerOnlyRaw = data.customeronly;
6441
+ const isCustomerOnly = isCustomerOnlyFlagEnabled(customerOnlyRaw);
6442
+ const isPlatformCustomerMode = isCustomerOnly && friendType === 4;
6443
+ const inputPhone = normalizePhone(data.phone);
6444
+ const servicePhone = normalizePhone((_getConfig$chat = getConfig().chat) === null || _getConfig$chat === void 0 ? void 0 : _getConfig$chat.platformServicePhone);
6445
+ const resolvedPhone = inputPhone || (isPlatformCustomerMode ? servicePhone : "");
6446
+ if (isPlatformCustomerMode && !data.session_id && !resolvedPhone) throw new Error("平台客服会话缺少 phone,请传入 phone 或配置 chat.platformServicePhone");
6447
+ const payload = {
6448
+ page: data.page,
6449
+ limit: data.limit
6450
+ };
6451
+ if (typeof data.username === "string" && data.username.trim()) payload.username = data.username.trim();
6452
+ if (resolvedPhone) payload.phone = resolvedPhone;
6453
+ if (typeof data.session_id === "string" && data.session_id.trim()) payload.session_id = data.session_id.trim();
6454
+ if (typeof data.user_type === "number") payload.user_type = data.user_type;
6455
+ if (typeof data.msg_type === "number") payload.msg_type = data.msg_type;
6456
+ if (Number.isFinite(friendType) && friendType > 0) payload.friend_type = friendType;
6457
+ if (isCustomerOnly) payload.customeronly = 1;
6458
+ return unwrapResult(yield httpClient.post(buildApiPath("/chat/getList"), payload), "getChatList");
6346
6459
  });
6347
6460
  return _getChatList.apply(this, arguments);
6348
6461
  }
@@ -17167,12 +17280,15 @@ Expected function or array of functions, received type ${typeof value}.`);
17167
17280
  }();
17168
17281
  input.click();
17169
17282
  }
17170
- function resolveUploadedImageUrl(uploadURL, fileUrl) {
17283
+ function resolveUploadedImageUrl(resourceBaseURL, uploadURL, fileUrl) {
17171
17284
  const normalizedFileUrl = typeof fileUrl === "string" ? fileUrl.trim() : "";
17172
17285
  if (!normalizedFileUrl) return "";
17173
17286
  if (HTTP_URL_REGEXP.test(normalizedFileUrl)) return normalizedFileUrl;
17287
+ const normalizedResourceBaseURL = typeof resourceBaseURL === "string" ? resourceBaseURL.trim() : "";
17288
+ const normalizedUploadURL = typeof uploadURL === "string" ? uploadURL.trim() : "";
17289
+ const preferredBaseURL = normalizedResourceBaseURL || normalizedUploadURL;
17174
17290
  try {
17175
- return new URL(normalizedFileUrl, uploadURL).toString();
17291
+ return new URL(normalizedFileUrl, preferredBaseURL).toString();
17176
17292
  } catch (_unused2) {
17177
17293
  return normalizedFileUrl;
17178
17294
  }
@@ -17196,7 +17312,8 @@ Expected function or array of functions, received type ${typeof value}.`);
17196
17312
  isUploading.value = true;
17197
17313
  const response = yield uploadImage(file);
17198
17314
  if (!response.success || !((_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.url)) throw new Error(response.message || "上传失败");
17199
- const imageUrl = resolveUploadedImageUrl(getConfig().api.uploadURL, response.data.url);
17315
+ const config = getConfig();
17316
+ const imageUrl = resolveUploadedImageUrl(config.api.resourceBaseURL, config.api.uploadURL, response.data.url);
17200
17317
  if (!imageUrl) throw new Error("上传返回图片地址为空");
17201
17318
  const tempMessageId = createTempMessageId();
17202
17319
  const messageData = {
@@ -17395,7 +17512,7 @@ Expected function or array of functions, received type ${typeof value}.`);
17395
17512
  class: "tool-btn emoji-btn",
17396
17513
  title: "选择表情",
17397
17514
  onClick: toggleEmojiPicker
17398
- }, [..._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), {
17515
+ }, [..._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), {
17399
17516
  native: true,
17400
17517
  theme: "light",
17401
17518
  "group-names": {
@@ -17481,7 +17598,7 @@ Expected function or array of functions, received type ${typeof value}.`);
17481
17598
  ]);
17482
17599
  };
17483
17600
  }
17484
- }), [["__scopeId", "data-v-cc3cfaa7"]]);
17601
+ }), [["__scopeId", "data-v-1459079f"]]);
17485
17602
  //#endregion
17486
17603
  //#region src/assets/img/list.png?url
17487
17604
  var list_default = "data:image/png;base64,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";
@@ -17893,15 +18010,15 @@ Expected function or array of functions, received type ${typeof value}.`);
17893
18010
  const selectedConversation = /* @__PURE__ */ ref(null);
17894
18011
  const selectedConversationData = /* @__PURE__ */ ref(void 0);
17895
18012
  const userStatusOptions = [{
17896
- id: "online",
18013
+ id: "onConnect",
17897
18014
  label: "在线",
17898
18015
  color: "#52c41a"
17899
18016
  }, {
17900
- id: "offline",
18017
+ id: "offLine",
17901
18018
  label: "离线",
17902
18019
  color: "#d9d9d9"
17903
18020
  }];
17904
- const userStatus = /* @__PURE__ */ ref("online");
18021
+ const userStatus = /* @__PURE__ */ ref(wsClient.getPresenceAction());
17905
18022
  const showStatusDropdown = /* @__PURE__ */ ref(false);
17906
18023
  const userInfo = /* @__PURE__ */ ref(null);
17907
18024
  const menus = [{
@@ -17923,16 +18040,23 @@ Expected function or array of functions, received type ${typeof value}.`);
17923
18040
  return props.unreadCount || 0;
17924
18041
  });
17925
18042
  const { setActiveConversationId } = useUnreadStore();
17926
- function syncPresenceAction(status) {
17927
- const action = status === "online" ? "onConnect" : "offLine";
18043
+ function syncPresenceAction(action) {
17928
18044
  wsClient.sendBusinessMessage(action);
17929
18045
  }
18046
+ function applyPresenceAction(action) {
18047
+ if (userStatus.value !== action) userStatus.value = action;
18048
+ }
18049
+ function handlePresenceChanged(payload) {
18050
+ const data = payload;
18051
+ if ((data === null || data === void 0 ? void 0 : data.action) === "onConnect" || (data === null || data === void 0 ? void 0 : data.action) === "offLine") applyPresenceAction(data.action);
18052
+ }
17930
18053
  function handleStatusSelect(status) {
17931
18054
  userStatus.value = status;
17932
18055
  showStatusDropdown.value = false;
17933
18056
  }
17934
18057
  watch(userStatus, (status, prev) => {
17935
18058
  if (status === prev) return;
18059
+ if (status === wsClient.getPresenceAction()) return;
17936
18060
  syncPresenceAction(status);
17937
18061
  });
17938
18062
  function handleSelectConversation(id) {
@@ -18060,6 +18184,8 @@ Expected function or array of functions, received type ${typeof value}.`);
18060
18184
  }
18061
18185
  onMounted(() => {
18062
18186
  userInfo.value = getUserInfo();
18187
+ applyPresenceAction(wsClient.getPresenceAction());
18188
+ wsClient.on("presenceChange", handlePresenceChanged);
18063
18189
  const width = window.innerWidth;
18064
18190
  const height = window.innerHeight;
18065
18191
  viewportSize.value = {
@@ -18125,6 +18251,7 @@ Expected function or array of functions, received type ${typeof value}.`);
18125
18251
  document.removeEventListener("mousemove", handleMouseMove);
18126
18252
  document.removeEventListener("mouseup", handleMouseUp);
18127
18253
  window.removeEventListener("resize", handleViewportResize);
18254
+ wsClient.off("presenceChange", handlePresenceChanged);
18128
18255
  setActiveConversationId(null);
18129
18256
  });
18130
18257
  return (_ctx, _cache) => {
@@ -18229,7 +18356,7 @@ Expected function or array of functions, received type ${typeof value}.`);
18229
18356
  ], 6);
18230
18357
  };
18231
18358
  }
18232
- }), [["__scopeId", "data-v-d726d76e"]]);
18359
+ }), [["__scopeId", "data-v-00d50ef7"]]);
18233
18360
  //#endregion
18234
18361
  //#region src/assets/img/icon.png?url
18235
18362
  var icon_default = "data:image/png;base64,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";
@@ -18540,28 +18667,96 @@ Expected function or array of functions, received type ${typeof value}.`);
18540
18667
  CLOSING: 2,
18541
18668
  CLOSED: 3
18542
18669
  };
18543
- var HEARTBEAT_INTERVAL = 3e3;
18544
- var RECONNECT_INTERVAL = 3e3;
18545
- var MAX_RECONNECT_COUNT = 5;
18670
+ var DEFAULT_HEARTBEAT_INTERVAL = 3e3;
18671
+ var DEFAULT_RECONNECT_INTERVAL = 3e3;
18672
+ var DEFAULT_MAX_RECONNECT_COUNT = 5;
18673
+ var DEFAULT_CONNECT_TIMEOUT = 3e4;
18546
18674
  var MAX_MESSAGE_QUEUE_SIZE = 200;
18675
+ var PRESENCE_ACTION_STORAGE_KEY = "imsdk:presence-action";
18676
+ var PRESENCE_CHANGE_EVENT = "presenceChange";
18677
+ function normalizePresenceAction(action) {
18678
+ return action === "offLine" ? "offLine" : "onConnect";
18679
+ }
18680
+ function readPresenceActionFromStorage() {
18681
+ if (typeof window === "undefined" || !window.localStorage) return "onConnect";
18682
+ try {
18683
+ return normalizePresenceAction(window.localStorage.getItem(PRESENCE_ACTION_STORAGE_KEY));
18684
+ } catch (error) {
18685
+ console.warn("读取在线状态缓存失败,已使用默认 onConnect:", error);
18686
+ return "onConnect";
18687
+ }
18688
+ }
18689
+ function writePresenceActionToStorage(action) {
18690
+ if (typeof window === "undefined" || !window.localStorage) return;
18691
+ try {
18692
+ window.localStorage.setItem(PRESENCE_ACTION_STORAGE_KEY, action);
18693
+ } catch (error) {
18694
+ console.warn("写入在线状态缓存失败:", error);
18695
+ }
18696
+ }
18547
18697
  var WebSocketClient = class {
18548
18698
  constructor(config = {}) {
18549
18699
  _defineProperty(this, "ws", null);
18550
18700
  _defineProperty(this, "status", WS_STATUS.CLOSED);
18551
18701
  _defineProperty(this, "heartbeatTimer", null);
18552
18702
  _defineProperty(this, "reconnectTimer", null);
18703
+ _defineProperty(this, "connectTimeoutTimer", null);
18553
18704
  _defineProperty(this, "reconnectCount", 0);
18554
18705
  _defineProperty(this, "messageQueue", []);
18555
18706
  _defineProperty(this, "listeners", /* @__PURE__ */ new Map());
18707
+ _defineProperty(this, "lastToken", "");
18708
+ _defineProperty(this, "lastUserId", null);
18709
+ _defineProperty(this, "lastPhone", null);
18556
18710
  _defineProperty(this, "userId", null);
18557
18711
  _defineProperty(this, "phone", null);
18558
18712
  _defineProperty(this, "siteId", "");
18559
18713
  _defineProperty(this, "presenceAction", "onConnect");
18560
18714
  _defineProperty(this, "isConnected", false);
18561
- _defineProperty(this, "wsUrl", "");
18715
+ _defineProperty(this, "wsUrlOverride", "");
18562
18716
  _defineProperty(this, "logPrefix", "[WebSocket]");
18563
- this.wsUrl = config.wsUrl || "";
18717
+ this.wsUrlOverride = config.wsUrl || "";
18564
18718
  this.siteId = config.siteId || "";
18719
+ this.presenceAction = readPresenceActionFromStorage();
18720
+ }
18721
+ toPositiveInt(value, fallback) {
18722
+ const next = Number(value);
18723
+ if (!Number.isFinite(next) || next <= 0) return fallback;
18724
+ return Math.floor(next);
18725
+ }
18726
+ getHeartbeatInterval() {
18727
+ return this.toPositiveInt(getConfig().ws.heartbeatInterval, DEFAULT_HEARTBEAT_INTERVAL);
18728
+ }
18729
+ getReconnectInterval() {
18730
+ return this.toPositiveInt(getConfig().ws.reconnectInterval, DEFAULT_RECONNECT_INTERVAL);
18731
+ }
18732
+ getMaxReconnectCount() {
18733
+ return this.toPositiveInt(getConfig().ws.maxReconnectAttempts, DEFAULT_MAX_RECONNECT_COUNT);
18734
+ }
18735
+ getConnectTimeout() {
18736
+ return this.toPositiveInt(getConfig().ws.connectTimeout, DEFAULT_CONNECT_TIMEOUT);
18737
+ }
18738
+ trace(tag, payload) {
18739
+ if (!isWSTraceEnabled()) return;
18740
+ if (payload) {
18741
+ console.debug(`${this.logPrefix} [TRACE] ${tag}`, payload);
18742
+ return;
18743
+ }
18744
+ console.debug(`${this.logPrefix} [TRACE] ${tag}`);
18745
+ }
18746
+ resolveProtocolAction(action) {
18747
+ const actions = getWSProtocolAction();
18748
+ if (action === "send") return actions.send;
18749
+ if (action === "msgRead") return actions.msgRead;
18750
+ if (action === "onConnect") return actions.onConnect;
18751
+ if (action === "offLine") return actions.offLine;
18752
+ if (action === "heartbeat") return actions.heartbeat;
18753
+ return action;
18754
+ }
18755
+ stopConnectTimeout() {
18756
+ if (this.connectTimeoutTimer) {
18757
+ clearTimeout(this.connectTimeoutTimer);
18758
+ this.connectTimeoutTimer = null;
18759
+ }
18565
18760
  }
18566
18761
  /**
18567
18762
  * 连接 WebSocket
@@ -18574,7 +18769,15 @@ Expected function or array of functions, received type ${typeof value}.`);
18574
18769
  return new Promise((resolve, reject) => {
18575
18770
  try {
18576
18771
  this.destroyConnection();
18577
- const url = `${this.wsUrl || "wss://aox.api.orchiport.asia"}?platform=${encodeURIComponent(getWSPlatform())}${token ? `&token=${encodeURIComponent(token)}` : ""}`;
18772
+ const url = `${this.wsUrlOverride || getWSBaseURL()}?platform=${encodeURIComponent(getWSPlatform())}${token ? `&token=${encodeURIComponent(token)}` : ""}`;
18773
+ this.trace("connect:prepare", {
18774
+ url,
18775
+ platform: getWSPlatform()
18776
+ });
18777
+ const connectTimeout = this.getConnectTimeout();
18778
+ this.lastToken = token;
18779
+ this.lastUserId = userId;
18780
+ this.lastPhone = phone;
18578
18781
  this.userId = userId;
18579
18782
  this.phone = phone;
18580
18783
  this.siteId = siteId || this.siteId;
@@ -18585,15 +18788,34 @@ Expected function or array of functions, received type ${typeof value}.`);
18585
18788
  });
18586
18789
  this.ws = new WebSocket(url);
18587
18790
  this.status = WS_STATUS.CONNECTING;
18791
+ this.stopConnectTimeout();
18792
+ this.connectTimeoutTimer = setTimeout(() => {
18793
+ if (!this.ws || this.status !== WS_STATUS.CONNECTING) return;
18794
+ console.warn(`${this.logPrefix} 连接超时,已主动关闭`, {
18795
+ timeoutMs: connectTimeout,
18796
+ platform: getWSPlatform(),
18797
+ siteId: this.siteId
18798
+ });
18799
+ try {
18800
+ this.ws.close();
18801
+ } catch (error) {
18802
+ console.error(`${this.logPrefix} 连接超时关闭失败`, error);
18803
+ }
18804
+ this.status = WS_STATUS.CLOSED;
18805
+ this.stopConnectTimeout();
18806
+ reject(/* @__PURE__ */ new Error(`WebSocket 连接超时(${connectTimeout}ms)`));
18807
+ }, connectTimeout);
18588
18808
  this.ws.onopen = (event) => {
18589
18809
  this.status = WS_STATUS.OPEN;
18590
18810
  this.reconnectCount = 0;
18811
+ this.stopConnectTimeout();
18591
18812
  console.info(`${this.logPrefix} 连接已建立`, {
18592
18813
  platform: getWSPlatform(),
18593
18814
  siteId: this.siteId,
18594
18815
  userId: this.userId
18595
18816
  });
18596
18817
  if (!this.isConnected) {
18818
+ this.setPresenceAction("onConnect", "connect");
18597
18819
  this.sendConnectMessage();
18598
18820
  this.isConnected = true;
18599
18821
  }
@@ -18607,6 +18829,10 @@ Expected function or array of functions, received type ${typeof value}.`);
18607
18829
  if (!rawData || rawData === "null") return;
18608
18830
  try {
18609
18831
  const data = JSON.parse(rawData);
18832
+ this.trace("message:receive", {
18833
+ controller: data === null || data === void 0 ? void 0 : data.controller,
18834
+ action: data === null || data === void 0 ? void 0 : data.action
18835
+ });
18610
18836
  this.emit("message", data);
18611
18837
  } catch (_unused) {
18612
18838
  console.warn("收到非 JSON WebSocket 消息,已忽略:", rawData);
@@ -18614,24 +18840,29 @@ Expected function or array of functions, received type ${typeof value}.`);
18614
18840
  };
18615
18841
  this.ws.onerror = (error) => {
18616
18842
  this.status = WS_STATUS.CLOSED;
18843
+ this.stopConnectTimeout();
18617
18844
  console.error(`${this.logPrefix} 连接异常`, error);
18618
18845
  this.emit("error", error);
18619
18846
  reject(error);
18620
18847
  };
18621
18848
  this.ws.onclose = (event) => {
18622
18849
  this.status = WS_STATUS.CLOSED;
18850
+ this.stopConnectTimeout();
18623
18851
  this.stopHeartbeat();
18624
18852
  this.emit("close", event);
18625
- const canReconnect = this.reconnectCount < MAX_RECONNECT_COUNT;
18853
+ const maxReconnectCount = this.getMaxReconnectCount();
18854
+ const canReconnect = this.presenceAction === "onConnect" && this.reconnectCount < maxReconnectCount;
18626
18855
  console.warn(`${this.logPrefix} 连接关闭`, {
18627
18856
  code: event.code,
18628
18857
  reason: event.reason,
18629
18858
  wasClean: event.wasClean,
18859
+ presenceAction: this.presenceAction,
18630
18860
  reconnectAttempt: this.reconnectCount,
18631
18861
  willReconnect: canReconnect
18632
18862
  });
18633
18863
  if (canReconnect) this.scheduleReconnect(token, this.userId, this.phone);
18634
- else console.error(`${this.logPrefix} 重连次数超过最大限制,停止重连`, { maxReconnectCount: MAX_RECONNECT_COUNT });
18864
+ else if (this.presenceAction === "offLine") console.info(`${this.logPrefix} 当前为 offLine 状态,已停止自动重连`);
18865
+ else console.error(`${this.logPrefix} 重连次数超过最大限制,停止重连`, { maxReconnectCount });
18635
18866
  };
18636
18867
  } catch (error) {
18637
18868
  reject(error);
@@ -18654,6 +18885,10 @@ Expected function or array of functions, received type ${typeof value}.`);
18654
18885
  }
18655
18886
  try {
18656
18887
  this.ws.send(message);
18888
+ if (typeof data !== "string") this.trace("message:send", {
18889
+ controller: data.controller,
18890
+ action: data.action
18891
+ });
18657
18892
  return true;
18658
18893
  } catch (error) {
18659
18894
  console.error("WebSocket发送消息失败:", error);
@@ -18664,7 +18899,7 @@ Expected function or array of functions, received type ${typeof value}.`);
18664
18899
  * 发送控制器动作消息(使用当前配置的 controller)
18665
18900
  */
18666
18901
  sendControllerMessage(action, param = {}) {
18667
- const controller = getWSController();
18902
+ const controller = getWSProtocolController();
18668
18903
  return this.send({
18669
18904
  controller,
18670
18905
  action,
@@ -18682,10 +18917,47 @@ Expected function or array of functions, received type ${typeof value}.`);
18682
18917
  */
18683
18918
  sendBusinessMessage(action, param = {}) {
18684
18919
  if (action === "onConnect" || action === "offLine") {
18685
- this.presenceAction = action;
18686
- if (!this.checkConnected()) return false;
18920
+ this.setPresenceAction(action, "manual");
18921
+ if (!this.checkConnected()) {
18922
+ if (action === "onConnect") this.tryReconnectFromManualOnline();
18923
+ return false;
18924
+ }
18687
18925
  }
18688
- return this.sendControllerMessage(action, param);
18926
+ const runtimeAction = this.resolveProtocolAction(action);
18927
+ return this.sendControllerMessage(runtimeAction, param);
18928
+ }
18929
+ tryReconnectFromManualOnline() {
18930
+ if (this.status === WS_STATUS.CONNECTING) {
18931
+ console.info(`${this.logPrefix} 当前正在连接中,跳过重复连接`);
18932
+ return;
18933
+ }
18934
+ if (!this.lastToken) {
18935
+ console.warn(`${this.logPrefix} 缺少连接凭证,无法在 onConnect 后主动重连`);
18936
+ return;
18937
+ }
18938
+ if (this.reconnectTimer) {
18939
+ clearTimeout(this.reconnectTimer);
18940
+ this.reconnectTimer = null;
18941
+ }
18942
+ console.info(`${this.logPrefix} 检测到手动切换 onConnect,发起主动重连`);
18943
+ this.connect(this.lastToken, this.lastUserId, this.lastPhone, this.siteId).catch((error) => {
18944
+ console.error(`${this.logPrefix} onConnect 主动重连失败`, error);
18945
+ });
18946
+ }
18947
+ setPresenceAction(action, source) {
18948
+ const normalizedAction = normalizePresenceAction(action);
18949
+ const changed = this.presenceAction !== normalizedAction;
18950
+ this.presenceAction = normalizedAction;
18951
+ writePresenceActionToStorage(normalizedAction);
18952
+ if (normalizedAction === "offLine" && this.reconnectTimer) {
18953
+ clearTimeout(this.reconnectTimer);
18954
+ this.reconnectTimer = null;
18955
+ console.info(`${this.logPrefix} 已切换为 offLine,取消待执行的自动重连`);
18956
+ }
18957
+ if (changed) this.emit(PRESENCE_CHANGE_EVENT, {
18958
+ action: normalizedAction,
18959
+ source
18960
+ });
18689
18961
  }
18690
18962
  /**
18691
18963
  * 启动心跳
@@ -18695,8 +18967,8 @@ Expected function or array of functions, received type ${typeof value}.`);
18695
18967
  this.heartbeatTimer = setInterval(() => {
18696
18968
  if (this.status === WS_STATUS.OPEN && this.ws) {
18697
18969
  const heartbeatData = {
18698
- controller: getWSController(),
18699
- action: "heartbeat",
18970
+ controller: getWSProtocolController(),
18971
+ action: this.resolveProtocolAction("heartbeat"),
18700
18972
  param: {
18701
18973
  userId: this.userId,
18702
18974
  platform: getWSPlatform(),
@@ -18706,15 +18978,15 @@ Expected function or array of functions, received type ${typeof value}.`);
18706
18978
  };
18707
18979
  this.send(heartbeatData);
18708
18980
  }
18709
- }, HEARTBEAT_INTERVAL);
18981
+ }, this.getHeartbeatInterval());
18710
18982
  }
18711
18983
  /**
18712
18984
  * 发送连接/状态消息
18713
18985
  */
18714
18986
  sendConnectMessage() {
18715
18987
  const connectData = {
18716
- controller: getWSController(),
18717
- action: this.presenceAction,
18988
+ controller: getWSProtocolController(),
18989
+ action: this.resolveProtocolAction(this.presenceAction),
18718
18990
  param: {
18719
18991
  userId: this.userId,
18720
18992
  platform: getWSPlatform(),
@@ -18746,12 +19018,23 @@ Expected function or array of functions, received type ${typeof value}.`);
18746
19018
  }
18747
19019
  this.reconnectCount++;
18748
19020
  const attempt = this.reconnectCount;
19021
+ const maxReconnectCount = this.getMaxReconnectCount();
19022
+ const reconnectInterval = this.getReconnectInterval();
18749
19023
  console.info(`${this.logPrefix} 准备重连`, {
18750
19024
  attempt,
18751
- maxReconnectCount: MAX_RECONNECT_COUNT,
18752
- retryInMs: RECONNECT_INTERVAL
19025
+ maxReconnectCount,
19026
+ retryInMs: reconnectInterval
18753
19027
  });
18754
19028
  this.reconnectTimer = setTimeout(() => {
19029
+ if (this.presenceAction === "offLine") {
19030
+ console.info(`${this.logPrefix} 当前为 offLine 状态,跳过本次自动重连`);
19031
+ if (this.reconnectTimer) {
19032
+ clearTimeout(this.reconnectTimer);
19033
+ this.reconnectTimer = null;
19034
+ }
19035
+ return;
19036
+ }
19037
+ if (this.presenceAction !== "onConnect") this.setPresenceAction("onConnect", "connect");
18755
19038
  this.stopHeartbeat();
18756
19039
  if (this.reconnectTimer) {
18757
19040
  clearTimeout(this.reconnectTimer);
@@ -18759,7 +19042,7 @@ Expected function or array of functions, received type ${typeof value}.`);
18759
19042
  }
18760
19043
  console.info(`${this.logPrefix} 发起重连`, {
18761
19044
  attempt,
18762
- maxReconnectCount: MAX_RECONNECT_COUNT
19045
+ maxReconnectCount
18763
19046
  });
18764
19047
  this.connect(token, userId, phone, this.siteId).catch((error) => {
18765
19048
  console.error(`${this.logPrefix} 重连失败`, {
@@ -18767,7 +19050,7 @@ Expected function or array of functions, received type ${typeof value}.`);
18767
19050
  error
18768
19051
  });
18769
19052
  });
18770
- }, RECONNECT_INTERVAL);
19053
+ }, reconnectInterval);
18771
19054
  }
18772
19055
  /**
18773
19056
  * 发送消息队列中的消息
@@ -18791,6 +19074,7 @@ Expected function or array of functions, received type ${typeof value}.`);
18791
19074
  clearTimeout(this.reconnectTimer);
18792
19075
  this.reconnectTimer = null;
18793
19076
  }
19077
+ this.stopConnectTimeout();
18794
19078
  if (this.ws) {
18795
19079
  this.ws.onopen = null;
18796
19080
  this.ws.onmessage = null;
@@ -18814,7 +19098,7 @@ Expected function or array of functions, received type ${typeof value}.`);
18814
19098
  disconnect() {
18815
19099
  console.info(`${this.logPrefix} 主动断开连接`);
18816
19100
  this.destroyConnection();
18817
- this.reconnectCount = MAX_RECONNECT_COUNT;
19101
+ this.reconnectCount = this.getMaxReconnectCount();
18818
19102
  this.messageQueue = [];
18819
19103
  }
18820
19104
  /**
@@ -18867,6 +19151,9 @@ Expected function or array of functions, received type ${typeof value}.`);
18867
19151
  var _this$ws;
18868
19152
  return this.status === WS_STATUS.OPEN && ((_this$ws = this.ws) === null || _this$ws === void 0 ? void 0 : _this$ws.readyState) === WS_STATUS.OPEN;
18869
19153
  }
19154
+ getPresenceAction() {
19155
+ return this.presenceAction;
19156
+ }
18870
19157
  };
18871
19158
  var wsClient = new WebSocketClient();
18872
19159
  //#endregion
@@ -18899,10 +19186,10 @@ Expected function or array of functions, received type ${typeof value}.`);
18899
19186
  } }).mount(container);
18900
19187
  }
18901
19188
  function validateModeContract() {
18902
- var _config$api$prefix, _config$ws$controller, _config$ws$platform;
19189
+ var _config$api$prefix, _config$ws$protocol, _config$ws$platform;
18903
19190
  const config = getConfig();
18904
19191
  const apiPrefix = (_config$api$prefix = config.api.prefix) === null || _config$api$prefix === void 0 ? void 0 : _config$api$prefix.trim();
18905
- const wsController = (_config$ws$controller = config.ws.controller) === null || _config$ws$controller === void 0 ? void 0 : _config$ws$controller.trim();
19192
+ const wsController = (config.ws.controller || ((_config$ws$protocol = config.ws.protocol) === null || _config$ws$protocol === void 0 ? void 0 : _config$ws$protocol.controller) || "").trim();
18906
19193
  const wsPlatform = (_config$ws$platform = config.ws.platform) === null || _config$ws$platform === void 0 ? void 0 : _config$ws$platform.trim();
18907
19194
  if (!apiPrefix) throw new Error("IMSDK 初始化失败:缺少 api.prefix,请使用 @zjw-jszn/platform-imsdk 或 @zjw-jszn/store-imsdk,或显式配置前缀");
18908
19195
  if (!wsController || !wsPlatform) throw new Error("IMSDK 初始化失败:缺少 ws.controller 或 ws.platform,请按文档约定配置后重试");
@@ -18915,11 +19202,11 @@ Expected function or array of functions, received type ${typeof value}.`);
18915
19202
  function _initIM() {
18916
19203
  _initIM = _asyncToGenerator(function* (config = {}) {
18917
19204
  if (initInFlight) {
18918
- var _config$api, _config$ws, _config$ws2;
19205
+ var _config$api, _config$ws$controller, _config$ws, _config$ws2, _config$ws3;
18919
19206
  const currentConfig = getConfig();
18920
19207
  const nextApiPrefix = (_config$api = config.api) === null || _config$api === void 0 ? void 0 : _config$api.prefix;
18921
- const nextWSController = (_config$ws = config.ws) === null || _config$ws === void 0 ? void 0 : _config$ws.controller;
18922
- const nextWSPlatform = (_config$ws2 = config.ws) === null || _config$ws2 === void 0 ? void 0 : _config$ws2.platform;
19208
+ 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;
19209
+ const nextWSPlatform = (_config$ws3 = config.ws) === null || _config$ws3 === void 0 ? void 0 : _config$ws3.platform;
18923
19210
  if (nextApiPrefix && nextApiPrefix !== currentConfig.api.prefix || nextWSController && nextWSController !== currentConfig.ws.controller || nextWSPlatform && nextWSPlatform !== currentConfig.ws.platform) throw new Error("IMSDK 正在以其他模式初始化,请等待当前初始化完成后重试");
18924
19211
  return initInFlight;
18925
19212
  }
@@ -18932,11 +19219,11 @@ Expected function or array of functions, received type ${typeof value}.`);
18932
19219
  }
18933
19220
  };
18934
19221
  if (isInitialized.value && httpClient.getAuth()) {
18935
- var _config$api2, _config$ws3, _config$ws4;
19222
+ var _config$api2, _config$ws$controller2, _config$ws4, _config$ws5, _config$ws6;
18936
19223
  const currentConfig = getConfig();
18937
19224
  const nextApiPrefix = (_config$api2 = config.api) === null || _config$api2 === void 0 ? void 0 : _config$api2.prefix;
18938
- const nextWSController = (_config$ws3 = config.ws) === null || _config$ws3 === void 0 ? void 0 : _config$ws3.controller;
18939
- const nextWSPlatform = (_config$ws4 = config.ws) === null || _config$ws4 === void 0 ? void 0 : _config$ws4.platform;
19225
+ 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;
19226
+ const nextWSPlatform = (_config$ws6 = config.ws) === null || _config$ws6 === void 0 ? void 0 : _config$ws6.platform;
18940
19227
  if (nextApiPrefix && nextApiPrefix !== currentConfig.api.prefix || nextWSController && nextWSController !== currentConfig.ws.controller || nextWSPlatform && nextWSPlatform !== currentConfig.ws.platform) throw new Error("IMSDK 已初始化为其他模式,请刷新页面后再切换平台/门店");
18941
19228
  mountIMApp();
18942
19229
  console.warn("IMSDK 已初始化且已鉴权,本次调用将复用现有实例");
@@ -18946,13 +19233,30 @@ Expected function or array of functions, received type ${typeof value}.`);
18946
19233
  if (config.api) updateConfig({ api: config.api });
18947
19234
  if (config.sound) updateConfig({ sound: config.sound });
18948
19235
  if (config.auth) updateConfig({ auth: config.auth });
19236
+ if (config.chat) {
19237
+ var _config$chat$platform;
19238
+ const currentChat = getConfig().chat;
19239
+ updateConfig({ chat: { platformServicePhone: (_config$chat$platform = config.chat.platformServicePhone) !== null && _config$chat$platform !== void 0 ? _config$chat$platform : currentChat.platformServicePhone } });
19240
+ }
18949
19241
  if (config.runtimeApi) updateConfig({ runtimeApi: config.runtimeApi });
18950
19242
  if (config.ws) {
18951
- var _config$ws$controller2, _config$ws$platform2;
19243
+ 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;
18952
19244
  const currentWS = getConfig().ws;
19245
+ 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;
18953
19246
  updateConfig({ ws: {
18954
- controller: (_config$ws$controller2 = config.ws.controller) !== null && _config$ws$controller2 !== void 0 ? _config$ws$controller2 : currentWS.controller,
18955
- platform: (_config$ws$platform2 = config.ws.platform) !== null && _config$ws$platform2 !== void 0 ? _config$ws$platform2 : currentWS.platform
19247
+ url: (_config$ws$url = config.ws.url) !== null && _config$ws$url !== void 0 ? _config$ws$url : currentWS.url,
19248
+ controller: nextWSController,
19249
+ platform: (_config$ws$platform2 = config.ws.platform) !== null && _config$ws$platform2 !== void 0 ? _config$ws$platform2 : currentWS.platform,
19250
+ reconnectInterval: (_config$ws$reconnectI = config.ws.reconnectInterval) !== null && _config$ws$reconnectI !== void 0 ? _config$ws$reconnectI : currentWS.reconnectInterval,
19251
+ heartbeatInterval: (_config$ws$heartbeatI = config.ws.heartbeatInterval) !== null && _config$ws$heartbeatI !== void 0 ? _config$ws$heartbeatI : currentWS.heartbeatInterval,
19252
+ maxReconnectAttempts: (_config$ws$maxReconne = config.ws.maxReconnectAttempts) !== null && _config$ws$maxReconne !== void 0 ? _config$ws$maxReconne : currentWS.maxReconnectAttempts,
19253
+ connectTimeout: (_config$ws$connectTim = config.ws.connectTimeout) !== null && _config$ws$connectTim !== void 0 ? _config$ws$connectTim : currentWS.connectTimeout,
19254
+ traceEnabled: (_config$ws$traceEnabl = config.ws.traceEnabled) !== null && _config$ws$traceEnabl !== void 0 ? _config$ws$traceEnabl : currentWS.traceEnabled,
19255
+ protocol: _objectSpread2(_objectSpread2(_objectSpread2({}, currentWS.protocol), config.ws.protocol || {}), {}, {
19256
+ 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,
19257
+ action: _objectSpread2(_objectSpread2({}, currentWS.protocol.action), ((_config$ws$protocol4 = config.ws.protocol) === null || _config$ws$protocol4 === void 0 ? void 0 : _config$ws$protocol4.action) || {}),
19258
+ 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
19259
+ })
18956
19260
  } });
18957
19261
  }
18958
19262
  httpClient.setBaseURL(getConfig().api.baseURL);
@@ -18992,17 +19296,21 @@ Expected function or array of functions, received type ${typeof value}.`);
18992
19296
  //#endregion
18993
19297
  //#region src/mode.ts
18994
19298
  function warnModeOverrides(scope, config, defaults) {
19299
+ var _wsConfig$protocol;
18995
19300
  const apiConfig = config.api;
18996
19301
  const wsConfig = config.ws;
18997
19302
  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}`);
18998
19303
  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}`);
18999
19304
  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}`);
19000
19305
  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}`);
19306
+ const protocolController = wsConfig === null || wsConfig === void 0 || (_wsConfig$protocol = wsConfig.protocol) === null || _wsConfig$protocol === void 0 ? void 0 : _wsConfig$protocol.controller;
19307
+ if (protocolController && protocolController !== defaults.ws.controller) console.warn(`[${scope}] 已忽略 ws.protocol.controller=${protocolController},当前模式固定为 ${defaults.ws.controller}`);
19001
19308
  }
19002
19309
  function applyModeDefaults(config, defaults) {
19310
+ var _config$ws;
19003
19311
  return _objectSpread2(_objectSpread2({}, config), {}, {
19004
19312
  api: _objectSpread2(_objectSpread2({}, config.api || {}), defaults.api),
19005
- ws: _objectSpread2(_objectSpread2({}, config.ws || {}), defaults.ws)
19313
+ 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 }) })
19006
19314
  });
19007
19315
  }
19008
19316
  //#endregion