@zjw-jszn/shared-imsdk 1.0.9 → 1.0.12
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.
- package/README.md +19 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/config/index.d.ts +44 -0
- package/dist/shared-imsdk.css +148 -120
- package/dist/shared-imsdk.es.js +369 -77
- package/dist/shared-imsdk.umd.cjs +369 -77
- package/dist/types/index.d.ts +21 -0
- package/dist/utils/websocket.d.ts +10 -1
- package/package.json +1 -1
package/dist/shared-imsdk.es.js
CHANGED
|
@@ -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-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*/"
|
|
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-66bc5469] {\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-66bc5469]::-webkit-scrollbar {\n width: 6px;\n}\n.conversation-list[data-v-66bc5469]::-webkit-scrollbar-track {\n background: transparent;\n}\n.conversation-list[data-v-66bc5469]::-webkit-scrollbar-thumb {\n border-radius: 3px;\n background: #d9d9d9;\n}\n.conversation-list[data-v-66bc5469]::-webkit-scrollbar-thumb:hover {\n background: #bfbfbf;\n}\n.unread-header[data-v-66bc5469] {\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-66bc5469] {\n font-size: 15px;\n font-weight: 600;\n color: #262626;\n letter-spacing: 0.3px;\n}\n.search-header[data-v-66bc5469] {\n padding: 10px 16px;\n border-bottom: 1px solid #f0f0f0;\n background: #fff;\n}\n.search-input[data-v-66bc5469] {\n box-sizing: border-box;\n width: 100%;\n height: 36px;\n padding: 0 12px;\n border: 1px solid #d9d9d9;\n border-radius: 8px;\n\n font-size: 13px;\n color: #262626;\n\n background: #fff;\n outline: none;\n\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n}\n.search-input[data-v-66bc5469]::placeholder {\n color: #bfbfbf;\n}\n.search-input[data-v-66bc5469]:focus {\n border-color: #0e77cc;\n box-shadow: 0 0 0 2px rgb(14 119 204 / 12%);\n}\n.loading-state[data-v-66bc5469] {\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-66bc5469] {\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-66bc5469 0.8s linear infinite;\n}\n@keyframes spin-66bc5469 {\n0% { transform: rotate(0deg);\n}\n100% { transform: rotate(360deg);\n}\n}\n.empty-state[data-v-66bc5469] {\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-66bc5469] {\n width: 64px;\n height: 64px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n.empty-state p[data-v-66bc5469] {\n margin: 0;\n font-size: 14px;\n font-weight: 400;\n}\n.conversation-item[data-v-66bc5469] {\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-66bc5469]:hover {\n background-color: #f5f7fa;\n}\n.conversation-item.active[data-v-66bc5469] {\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-66bc5469]:last-child {\n border-bottom: none;\n}\n\n/* 会话项内容布局 */\n.conversation-item-content[data-v-66bc5469] {\n display: flex;\n gap: 12px;\n align-items: center;\n width: 100%;\n}\n.avatar-wrapper[data-v-66bc5469] {\n position: relative;\n flex-shrink: 0;\n width: 44px;\n height: 44px;\n}\n.avatar-img[data-v-66bc5469] {\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-66bc5469] {\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-66bc5469] {\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-66bc5469] {\n font-size: 14px;\n font-weight: 600;\n color: #262626;\n letter-spacing: 0.2px;\n}\n.content-text[data-v-66bc5469] {\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-66bc5469] {\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-66bc5469] {\n font-size: 12px;\n font-weight: 400;\n color: #8c8c8c;\n}\n.unread-badge[data-v-66bc5469] {\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-66bc5469 2s ease-in-out infinite;\n}\n@keyframes pulse-66bc5469 {\n0%, 100% {\n transform: scale(1);\n}\n50% {\n transform: scale(1.05);\n}\n}\n\n.chat-window[data-v-00d50ef7] {\n position: fixed;\n z-index: 9998;\n\n overflow: hidden;\n display: flex;\n flex-direction: column;\n\n min-width: 380px;\n min-height: 360px;\n border: 1px solid rgba(9, 62, 105, 0.14);\n border-radius: 18px;\n\n background: linear-gradient(180deg, #fff 0%, #f9fcff 100%);\n backdrop-filter: blur(6px);\n box-shadow: 0 24px 80px rgba(11, 58, 106, 0.24);\n\n animation: window-enter-00d50ef7 0.22s ease-out;\n}\n.chat-window.is-dragging[data-v-00d50ef7] {\n cursor: move;\n box-shadow: 0 28px 88px rgba(11, 58, 106, 0.28);\n}\n.chat-window.is-resizing[data-v-00d50ef7] {\n cursor: nwse-resize;\n}\n.chat-header[data-v-00d50ef7] {\n cursor: move;\n user-select: none;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: space-between;\n\n padding: 10px 20px;\n\n color: white;\n\n background: linear-gradient(135deg, #0f83df 0%, #0e6fbe 62%, #0c5fa5 100%);\n box-shadow: 0 2px 12px rgba(14, 119, 204, 0.26);\n}\n\n/* 用户信息区域 */\n.user-info-section[data-v-00d50ef7] {\n display: flex;\n flex: 1;\n gap: 12px;\n align-items: center;\n}\n.user-avatar-wrapper[data-v-00d50ef7] {\n position: relative;\n flex-shrink: 0;\n width: 40px;\n height: 40px;\n}\n.user-avatar[data-v-00d50ef7] {\n width: 100%;\n height: 100%;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 50%;\n\n object-fit: cover;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n.user-avatar-default[data-v-00d50ef7] {\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 40px;\n height: 40px;\n border: 2px solid rgba(255, 255, 255, 0.3);\n border-radius: 50%;\n\n font-size: 16px;\n font-weight: 600;\n color: white;\n\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n.status-indicator[data-v-00d50ef7] {\n cursor: pointer;\n\n position: absolute;\n right: -2px;\n bottom: -2px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 14px;\n height: 14px;\n border: 2px solid white;\n border-radius: 50%;\n\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n\n transition: transform 0.2s;\n}\n.status-indicator[data-v-00d50ef7]:hover {\n transform: scale(1.15);\n}\n.status-indicator svg[data-v-00d50ef7] {\n width: 8px;\n height: 8px;\n}\n\n/* 状态下拉菜单 */\n.status-dropdown[data-v-00d50ef7] {\n position: absolute;\n z-index: 100;\n top: 100%;\n left: 0;\n\n min-width: 120px;\n margin-top: 8px;\n padding: 6px;\n border: 1px solid #dbe7f5;\n border-radius: 10px;\n\n background: white;\n box-shadow: 0 12px 30px rgba(11, 58, 106, 0.18);\n}\n.status-option[data-v-00d50ef7] {\n cursor: pointer;\n\n display: flex;\n gap: 8px;\n align-items: center;\n\n padding: 8px 10px;\n border-radius: 6px;\n\n color: #262626;\n\n transition: all 0.2s;\n}\n.status-option[data-v-00d50ef7]:hover {\n background: #f5f5f5;\n}\n.status-option.active[data-v-00d50ef7] {\n color: #0e77cc;\n background: #e6f7ff;\n}\n.status-dot[data-v-00d50ef7] {\n flex-shrink: 0;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n}\n.status-option span[data-v-00d50ef7] {\n flex: 1;\n font-size: 13px;\n}\n.check-icon[data-v-00d50ef7] {\n width: 16px;\n height: 16px;\n opacity: 0.8;\n}\n.user-details[data-v-00d50ef7] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.user-name[data-v-00d50ef7] {\n font-size: 14px;\n font-weight: 600;\n letter-spacing: 0.2px;\n}\n.user-status[data-v-00d50ef7] {\n font-size: 12px;\n font-weight: 400;\n opacity: 0.9;\n}\n.close-btn[data-v-00d50ef7] {\n cursor: pointer;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n\n font-size: 28px;\n line-height: 1;\n color: white;\n\n opacity: 0.8;\n background: none;\n\n transition: all 0.2s;\n}\n.close-btn[data-v-00d50ef7]:hover {\n transform: rotate(90deg);\n opacity: 1;\n background: rgba(255, 255, 255, 0.15);\n}\n.close-btn[data-v-00d50ef7]:active {\n transform: rotate(90deg) scale(0.95);\n}\n.chat-body[data-v-00d50ef7] {\n overflow: hidden;\n display: flex;\n flex: 1;\n\n min-height: 0;\n\n background: linear-gradient(180deg, #fbfdff 0%, #f4f8fc 100%);\n}\n\n/* 第一栏:一级菜单 */\n.first-sidebar[data-v-00d50ef7] {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n\n width: 76px;\n padding: 0;\n border-right: 1px solid #dce8f3;\n\n background: linear-gradient(180deg, #f5f9ff 0%, #f0f6fd 100%);\n}\n.menu-items-container[data-v-00d50ef7] {\n display: flex;\n flex: 1;\n flex-direction: column;\n align-items: center;\n\n padding: 18px 0;\n}\n.menu-item[data-v-00d50ef7] {\n cursor: pointer;\n\n position: relative;\n\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 50px;\n height: 50px;\n margin-bottom: 12px;\n border: 1px solid transparent;\n border-radius: 12px;\n\n font-weight: 400;\n color: #7d8fa3;\n\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.menu-item[data-v-00d50ef7]:last-child {\n margin-bottom: 0;\n}\n.menu-item[data-v-00d50ef7]:hover {\n transform: translateY(-1px);\n border-color: #d2e3f3;\n color: #0e77cc;\n background: #f7fbff;\n}\n.menu-item.active[data-v-00d50ef7] {\n border-color: #0e77cc;\n color: white;\n background: linear-gradient(135deg, #0f83df 0%, #0d6db8 100%);\n box-shadow: 0 8px 20px rgba(14, 119, 204, 0.35);\n}\n.menu-item.active[data-v-00d50ef7]::before {\n content: '';\n\n position: absolute;\n top: 50%;\n left: -11px;\n transform: translateY(-50%);\n\n width: 3px;\n height: 24px;\n border-radius: 2px;\n\n background: #0e77cc;\n}\n.menu-item .icon[data-v-00d50ef7] {\n width: 23px;\n height: 23px;\n}\n.menu-item .label[data-v-00d50ef7] {\n display: none;\n}\n.menu-item .menu-badge[data-v-00d50ef7] {\n position: absolute;\n top: 6px;\n right: 6px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-width: 16px;\n height: 16px;\n padding: 0 5px;\n border: 2px solid white;\n border-radius: 8px;\n\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n color: white;\n\n background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);\n box-shadow: 0 2px 6px rgba(255, 77, 79, 0.4);\n}\n.menu-item.active .menu-badge[data-v-00d50ef7] {\n border-color: #0e77cc;\n color: #ff4d4f;\n background: linear-gradient(135deg, #fff 0%, #f0f0f0 100%);\n}\n\n/* 第二栏:二级侧边栏 */\n.second-sidebar[data-v-00d50ef7] {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n\n width: 250px;\n border-right: 1px solid #dce8f3;\n\n background: linear-gradient(180deg, #fff 0%, #fbfdff 100%);\n}\n\n/* 第三栏:聊天区域 */\n.chat-area[data-v-00d50ef7] {\n overflow: hidden;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-width: 0;\n\n background: radial-gradient(circle at top right, rgba(14, 119, 204, 0.08) 0%, rgba(255, 255, 255, 0) 42%), #fff;\n}\n.empty-chat[data-v-00d50ef7] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n\n height: 100%;\n\n color: #8ca1b8;\n\n background: linear-gradient(180deg, #f7fbff 0%, #fff 100%);\n}\n.empty-chat .empty-icon[data-v-00d50ef7] {\n width: 72px;\n height: 72px;\n margin-bottom: 18px;\n\n opacity: 0.5;\n filter: drop-shadow(0 8px 20px rgba(11, 58, 106, 0.16));\n}\n.empty-chat p[data-v-00d50ef7] {\n margin: 0;\n font-size: 15px;\n font-weight: 500;\n letter-spacing: 0.3px;\n}\n\n/* 拉伸手柄 */\n.resize-handle[data-v-00d50ef7] {\n cursor: nwse-resize;\n\n position: absolute;\n z-index: 9999;\n right: 0;\n bottom: 0;\n\n width: 24px;\n height: 24px;\n\n opacity: 0.5;\n\n transition: opacity 0.2s;\n}\n.resize-handle[data-v-00d50ef7]:hover {\n opacity: 1;\n}\n.resize-handle[data-v-00d50ef7]::after {\n content: '';\n\n position: absolute;\n right: 6px;\n bottom: 6px;\n\n width: 0;\n height: 0;\n border-top: 10px solid transparent;\n border-right: 10px solid #0e77cc;\n border-bottom: 10px solid #0e77cc;\n border-left: 10px solid transparent;\n\n opacity: 0.6;\n filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));\n}\n@keyframes window-enter-00d50ef7 {\nfrom {\n transform: translate3d(0, 16px, 0) scale(0.98);\n opacity: 0;\n}\nto {\n transform: translate3d(0, 0, 0) scale(1);\n opacity: 1;\n}\n}\n@media (width <= 960px) {\n.second-sidebar[data-v-00d50ef7] {\n width: 220px;\n}\n}\n\n.float-button[data-v-a60f9c33] {\n touch-action: none;\n cursor: grab;\n user-select: none;\n\n position: fixed;\n z-index: 9999;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 64px;\n height: 64px;\n border: 1px solid #0e77cc;\n border-radius: 50%;\n\n background: #fff;\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3);\n\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.float-button.is-hidden[data-v-a60f9c33] {\n pointer-events: none;\n transform: scale(0.88);\n opacity: 0;\n}\n.float-button[data-v-a60f9c33]:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 30px rgba(14, 119, 204, 0.4);\n}\n.float-button[data-v-a60f9c33]:active {\n transform: translateY(0) scale(0.95);\n}\n.float-button.is-dragging[data-v-a60f9c33] {\n cursor: grabbing;\n transform: scale(1.08);\n box-shadow: 0 8px 35px rgba(14, 119, 204, 0.35);\n}\n.float-button .icon[data-v-a60f9c33] {\n pointer-events: none;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 32px;\n height: 32px;\n\n filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));\n}\n.float-button .icon img[data-v-a60f9c33] {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.float-button .badge[data-v-a60f9c33] {\n pointer-events: none;\n\n position: absolute;\n top: 4px;\n right: 4px;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n border: 2.5px solid white;\n border-radius: 10px;\n\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n color: white;\n\n background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);\n box-shadow: 0 2px 8px rgba(255, 77, 79, 0.4);\n}\n.float-button.has-unread[data-v-a60f9c33] {\n animation: pulse-a60f9c33 2s ease-in-out infinite;\n}\n@keyframes pulse-a60f9c33 {\n0%, 100% {\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3),\n 0 0 0 0 rgba(255, 77, 79, 0.4);\n}\n50% {\n box-shadow: 0 4px 20px rgba(14, 119, 204, 0.3),\n 0 0 0 12px rgba(255, 77, 79, 0);\n}\n}\n/*$vite$:1*/"
|
|
2
2
|
if (typeof document !== 'undefined' && __SHARED_IMSDK_CSS__) {
|
|
3
3
|
const __SHARED_IMSDK_STYLE_ID__ = 'zjw-jszn-shared-imsdk-style'
|
|
4
4
|
if (!document.getElementById(__SHARED_IMSDK_STYLE_ID__)) {
|
|
@@ -5693,6 +5693,7 @@ function _objectSpread2(e) {
|
|
|
5693
5693
|
var defaultConfig = {
|
|
5694
5694
|
api: {
|
|
5695
5695
|
baseURL: "https://aox.api.orchiport.asia",
|
|
5696
|
+
resourceBaseURL: "https://resource.api.orchiport.asia",
|
|
5696
5697
|
prefix: "",
|
|
5697
5698
|
uploadURL: "https://resource.api.orchiport.asia/system/uploadImage",
|
|
5698
5699
|
signKey: "Z0XYfLbnDpuVqk41",
|
|
@@ -5702,11 +5703,29 @@ var defaultConfig = {
|
|
|
5702
5703
|
defaultSignKey: "your-default-sign-key-here"
|
|
5703
5704
|
},
|
|
5704
5705
|
ws: {
|
|
5706
|
+
url: "",
|
|
5705
5707
|
controller: "",
|
|
5706
|
-
platform: ""
|
|
5708
|
+
platform: "",
|
|
5709
|
+
reconnectInterval: 3e3,
|
|
5710
|
+
heartbeatInterval: 3e3,
|
|
5711
|
+
maxReconnectAttempts: 5,
|
|
5712
|
+
connectTimeout: 3e4,
|
|
5713
|
+
traceEnabled: false,
|
|
5714
|
+
protocol: {
|
|
5715
|
+
controller: "",
|
|
5716
|
+
action: {
|
|
5717
|
+
send: "send",
|
|
5718
|
+
msgRead: "msgRead",
|
|
5719
|
+
onConnect: "onConnect",
|
|
5720
|
+
offLine: "offLine",
|
|
5721
|
+
heartbeat: "heartbeat"
|
|
5722
|
+
},
|
|
5723
|
+
heartbeatSignals: ["ping", "pong"]
|
|
5724
|
+
}
|
|
5707
5725
|
},
|
|
5708
5726
|
sound: { enabled: true },
|
|
5709
5727
|
auth: { authorizationPayload: {} },
|
|
5728
|
+
chat: { platformServicePhone: "" },
|
|
5710
5729
|
runtimeApi: {}
|
|
5711
5730
|
};
|
|
5712
5731
|
var currentConfig = defaultConfig;
|
|
@@ -5720,28 +5739,37 @@ function getConfig() {
|
|
|
5720
5739
|
* 更新配置
|
|
5721
5740
|
*/
|
|
5722
5741
|
function updateConfig(config) {
|
|
5723
|
-
var _ref, _config$sound$enabled, _config$sound, _currentConfig$sound, _config$sound$url, _config$sound2, _currentConfig$sound2, _currentConfig$auth, _config$auth;
|
|
5742
|
+
var _config$ws, _config$ws2, _config$ws$protocol$h, _config$ws3, _ref, _config$sound$enabled, _config$sound, _currentConfig$sound, _config$sound$url, _config$sound2, _currentConfig$sound2, _currentConfig$auth, _config$auth;
|
|
5724
5743
|
currentConfig = _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig), config), {}, {
|
|
5725
5744
|
api: _objectSpread2(_objectSpread2({}, currentConfig.api), config.api),
|
|
5726
|
-
ws: _objectSpread2(_objectSpread2({}, currentConfig.ws), config.ws),
|
|
5745
|
+
ws: _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig.ws), config.ws), {}, { protocol: _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig.ws.protocol), (_config$ws = config.ws) === null || _config$ws === void 0 ? void 0 : _config$ws.protocol), {}, {
|
|
5746
|
+
action: _objectSpread2(_objectSpread2({}, currentConfig.ws.protocol.action), ((_config$ws2 = config.ws) === null || _config$ws2 === void 0 || (_config$ws2 = _config$ws2.protocol) === null || _config$ws2 === void 0 ? void 0 : _config$ws2.action) || {}),
|
|
5747
|
+
heartbeatSignals: (_config$ws$protocol$h = (_config$ws3 = config.ws) === null || _config$ws3 === void 0 || (_config$ws3 = _config$ws3.protocol) === null || _config$ws3 === void 0 ? void 0 : _config$ws3.heartbeatSignals) !== null && _config$ws$protocol$h !== void 0 ? _config$ws$protocol$h : currentConfig.ws.protocol.heartbeatSignals
|
|
5748
|
+
}) }),
|
|
5727
5749
|
sound: {
|
|
5728
5750
|
enabled: (_ref = (_config$sound$enabled = (_config$sound = config.sound) === null || _config$sound === void 0 ? void 0 : _config$sound.enabled) !== null && _config$sound$enabled !== void 0 ? _config$sound$enabled : (_currentConfig$sound = currentConfig.sound) === null || _currentConfig$sound === void 0 ? void 0 : _currentConfig$sound.enabled) !== null && _ref !== void 0 ? _ref : true,
|
|
5729
5751
|
url: (_config$sound$url = (_config$sound2 = config.sound) === null || _config$sound2 === void 0 ? void 0 : _config$sound2.url) !== null && _config$sound$url !== void 0 ? _config$sound$url : (_currentConfig$sound2 = currentConfig.sound) === null || _currentConfig$sound2 === void 0 ? void 0 : _currentConfig$sound2.url
|
|
5730
5752
|
},
|
|
5731
5753
|
auth: _objectSpread2(_objectSpread2(_objectSpread2({}, currentConfig.auth), config.auth), {}, { authorizationPayload: _objectSpread2(_objectSpread2({}, ((_currentConfig$auth = currentConfig.auth) === null || _currentConfig$auth === void 0 ? void 0 : _currentConfig$auth.authorizationPayload) || {}), ((_config$auth = config.auth) === null || _config$auth === void 0 ? void 0 : _config$auth.authorizationPayload) || {}) }),
|
|
5754
|
+
chat: _objectSpread2(_objectSpread2({}, currentConfig.chat), config.chat),
|
|
5732
5755
|
runtimeApi: _objectSpread2(_objectSpread2({}, currentConfig.runtimeApi), config.runtimeApi)
|
|
5733
5756
|
});
|
|
5734
5757
|
}
|
|
5735
5758
|
var PREFIX_TRIM_REGEXP = /^\/+|\/+$/g;
|
|
5759
|
+
var URL_TRIM_REGEXP = /\/+$/g;
|
|
5760
|
+
var URL_ORIGIN_REGEXP = /^[a-z][a-z\d+\-.]*:\/\/[^/]+/i;
|
|
5761
|
+
var WS_PROTOCOL_REGEXP = /^wss?:\/\//i;
|
|
5762
|
+
var HTTPS_PROTOCOL_REGEXP = /^https:\/\//i;
|
|
5763
|
+
var HTTP_PROTOCOL_REGEXP = /^http:\/\//i;
|
|
5736
5764
|
function normalizePrefix(prefix) {
|
|
5737
5765
|
if (!prefix) return "";
|
|
5738
5766
|
return `/${prefix.replace(PREFIX_TRIM_REGEXP, "")}`;
|
|
5739
5767
|
}
|
|
5740
|
-
var STORE_API_PREFIX = "/cashier/IM";
|
|
5768
|
+
var STORE_API_PREFIX$1 = "/cashier/IM";
|
|
5741
5769
|
var PLATFORM_API_PREFIX = "/site/IM";
|
|
5742
5770
|
function isStorePrefix(prefix) {
|
|
5743
5771
|
const normalized = normalizePrefix(prefix);
|
|
5744
|
-
return normalized === STORE_API_PREFIX || normalized.startsWith(`${STORE_API_PREFIX}/`);
|
|
5772
|
+
return normalized === STORE_API_PREFIX$1 || normalized.startsWith(`${STORE_API_PREFIX$1}/`);
|
|
5745
5773
|
}
|
|
5746
5774
|
function isPlatformPrefix(prefix) {
|
|
5747
5775
|
const normalized = normalizePrefix(prefix);
|
|
@@ -5773,6 +5801,59 @@ function getWSPlatform() {
|
|
|
5773
5801
|
return currentConfig.ws.platform || "";
|
|
5774
5802
|
}
|
|
5775
5803
|
/**
|
|
5804
|
+
* 是否开启 WebSocket Trace 日志
|
|
5805
|
+
*/
|
|
5806
|
+
function isWSTraceEnabled() {
|
|
5807
|
+
return currentConfig.ws.traceEnabled === true;
|
|
5808
|
+
}
|
|
5809
|
+
function normalizeWSAction(value, fallback) {
|
|
5810
|
+
return String(value || "").trim() || fallback;
|
|
5811
|
+
}
|
|
5812
|
+
/**
|
|
5813
|
+
* 获取 WebSocket 协议控制器(优先 protocol.controller)
|
|
5814
|
+
*/
|
|
5815
|
+
function getWSProtocolController() {
|
|
5816
|
+
var _currentConfig$ws$pro;
|
|
5817
|
+
return String(((_currentConfig$ws$pro = currentConfig.ws.protocol) === null || _currentConfig$ws$pro === void 0 ? void 0 : _currentConfig$ws$pro.controller) || "").trim() || getWSController();
|
|
5818
|
+
}
|
|
5819
|
+
/**
|
|
5820
|
+
* 获取 WebSocket 协议动作映射
|
|
5821
|
+
*/
|
|
5822
|
+
function getWSProtocolAction() {
|
|
5823
|
+
var _currentConfig$ws$pro2;
|
|
5824
|
+
const action = ((_currentConfig$ws$pro2 = currentConfig.ws.protocol) === null || _currentConfig$ws$pro2 === void 0 ? void 0 : _currentConfig$ws$pro2.action) || defaultConfig.ws.protocol.action;
|
|
5825
|
+
return {
|
|
5826
|
+
send: normalizeWSAction(action.send, "send"),
|
|
5827
|
+
msgRead: normalizeWSAction(action.msgRead, "msgRead"),
|
|
5828
|
+
onConnect: normalizeWSAction(action.onConnect, "onConnect"),
|
|
5829
|
+
offLine: normalizeWSAction(action.offLine, "offLine"),
|
|
5830
|
+
heartbeat: normalizeWSAction(action.heartbeat, "heartbeat")
|
|
5831
|
+
};
|
|
5832
|
+
}
|
|
5833
|
+
function normalizeURL(value) {
|
|
5834
|
+
return String(value || "").trim().replace(URL_TRIM_REGEXP, "");
|
|
5835
|
+
}
|
|
5836
|
+
function toWSURLFromHTTP(baseURL, fallback = "") {
|
|
5837
|
+
const normalized = normalizeURL(baseURL);
|
|
5838
|
+
const fallbackURL = normalizeURL(fallback);
|
|
5839
|
+
if (!normalized) return fallbackURL;
|
|
5840
|
+
const originMatch = normalized.match(URL_ORIGIN_REGEXP);
|
|
5841
|
+
const origin = (originMatch === null || originMatch === void 0 ? void 0 : originMatch[0]) || normalized;
|
|
5842
|
+
if (WS_PROTOCOL_REGEXP.test(origin)) return origin;
|
|
5843
|
+
if (HTTPS_PROTOCOL_REGEXP.test(origin)) return origin.replace(HTTPS_PROTOCOL_REGEXP, "wss://");
|
|
5844
|
+
if (HTTP_PROTOCOL_REGEXP.test(origin)) return origin.replace(HTTP_PROTOCOL_REGEXP, "ws://");
|
|
5845
|
+
return fallbackURL;
|
|
5846
|
+
}
|
|
5847
|
+
/**
|
|
5848
|
+
* 获取 WebSocket 基础地址
|
|
5849
|
+
* 优先级:ws.url > api.baseURL 推导 > 默认地址
|
|
5850
|
+
*/
|
|
5851
|
+
function getWSBaseURL() {
|
|
5852
|
+
const configured = normalizeURL(currentConfig.ws.url);
|
|
5853
|
+
if (configured) return configured;
|
|
5854
|
+
return toWSURLFromHTTP(currentConfig.api.baseURL, "wss://aox.api.orchiport.asia");
|
|
5855
|
+
}
|
|
5856
|
+
/**
|
|
5776
5857
|
* 获取鉴权扩展参数(平台默认为空,门店可注入 username/avatar)
|
|
5777
5858
|
*/
|
|
5778
5859
|
function getAuthorizationExtraPayload() {
|
|
@@ -6109,6 +6190,7 @@ function _asyncToGenerator(n) {
|
|
|
6109
6190
|
var INTEGER_STRING_REGEXP = /^\d+$/;
|
|
6110
6191
|
var UPLOAD_TIMEOUT_MS = 3e4;
|
|
6111
6192
|
var MAX_UPLOAD_IMAGE_SIZE_BYTES = 2 * 1024 * 1024;
|
|
6193
|
+
var CUSTOMER_ONLY_TRUE_SET = new Set(["1", "true"]);
|
|
6112
6194
|
function ensureAuthorized(apiName) {
|
|
6113
6195
|
if (!httpClient.getAuth()) throw new Error(`未登录,禁止请求 ${apiName},请先完成鉴权`);
|
|
6114
6196
|
}
|
|
@@ -6176,6 +6258,15 @@ function unwrapResult(response, apiName) {
|
|
|
6176
6258
|
if (response.result === void 0 || response.result === null) throw new Error(`${apiName} 接口返回 result 为空`);
|
|
6177
6259
|
return response.result;
|
|
6178
6260
|
}
|
|
6261
|
+
function normalizePhone(phone) {
|
|
6262
|
+
return typeof phone === "string" ? phone.trim() : "";
|
|
6263
|
+
}
|
|
6264
|
+
function isCustomerOnlyFlagEnabled(value) {
|
|
6265
|
+
if (typeof value === "boolean") return value;
|
|
6266
|
+
if (typeof value === "number") return value === 1;
|
|
6267
|
+
if (typeof value === "string") return CUSTOMER_ONLY_TRUE_SET.has(value.trim().toLowerCase());
|
|
6268
|
+
return false;
|
|
6269
|
+
}
|
|
6179
6270
|
/**
|
|
6180
6271
|
* 获取用户鉴权
|
|
6181
6272
|
* @param params 鉴权参数
|
|
@@ -6216,6 +6307,7 @@ function _getAuthorization() {
|
|
|
6216
6307
|
* @param data.limit - 每页数量
|
|
6217
6308
|
* @param data.uid - 用户ID
|
|
6218
6309
|
* @param data.user_type - 用户类型
|
|
6310
|
+
* @param data.username - 用户名(可选,门店场景可用于筛选)
|
|
6219
6311
|
*/
|
|
6220
6312
|
function getUserChatList(_x3) {
|
|
6221
6313
|
return _getUserChatList.apply(this, arguments);
|
|
@@ -6223,7 +6315,14 @@ function getUserChatList(_x3) {
|
|
|
6223
6315
|
function _getUserChatList() {
|
|
6224
6316
|
_getUserChatList = _asyncToGenerator(function* (data) {
|
|
6225
6317
|
ensureAuthorized("getUserChatList");
|
|
6226
|
-
|
|
6318
|
+
const payload = {
|
|
6319
|
+
page: data.page,
|
|
6320
|
+
limit: data.limit
|
|
6321
|
+
};
|
|
6322
|
+
if (typeof data.uid === "number") payload.uid = data.uid;
|
|
6323
|
+
if (typeof data.user_type === "number") payload.user_type = data.user_type;
|
|
6324
|
+
if (typeof data.username === "string" && data.username.trim()) payload.username = data.username.trim();
|
|
6325
|
+
return unwrapResult(yield httpClient.post(buildApiPath("/user/getChatList"), payload), "getUserChatList");
|
|
6227
6326
|
});
|
|
6228
6327
|
return _getUserChatList.apply(this, arguments);
|
|
6229
6328
|
}
|
|
@@ -6306,14 +6405,36 @@ function _getChatRewordBySession() {
|
|
|
6306
6405
|
* @param data.session_id - 会话ID
|
|
6307
6406
|
* @param data.user_type - 用户类型
|
|
6308
6407
|
* @param data.msg_type - 消息类型
|
|
6408
|
+
* @param data.friend_type - 对话对象类型
|
|
6409
|
+
* @param data.customeronly - 平台客服模式标记(1/true)
|
|
6309
6410
|
*/
|
|
6310
6411
|
function getChatList(_x7) {
|
|
6311
6412
|
return _getChatList.apply(this, arguments);
|
|
6312
6413
|
}
|
|
6313
6414
|
function _getChatList() {
|
|
6314
6415
|
_getChatList = _asyncToGenerator(function* (data) {
|
|
6416
|
+
var _data$friend_type, _getConfig$chat;
|
|
6315
6417
|
ensureAuthorized("getChatList");
|
|
6316
|
-
|
|
6418
|
+
const friendType = Number((_data$friend_type = data.friend_type) !== null && _data$friend_type !== void 0 ? _data$friend_type : 0);
|
|
6419
|
+
const customerOnlyRaw = data.customeronly;
|
|
6420
|
+
const isCustomerOnly = isCustomerOnlyFlagEnabled(customerOnlyRaw);
|
|
6421
|
+
const isPlatformCustomerMode = isCustomerOnly && friendType === 4;
|
|
6422
|
+
const inputPhone = normalizePhone(data.phone);
|
|
6423
|
+
const servicePhone = normalizePhone((_getConfig$chat = getConfig().chat) === null || _getConfig$chat === void 0 ? void 0 : _getConfig$chat.platformServicePhone);
|
|
6424
|
+
const resolvedPhone = inputPhone || (isPlatformCustomerMode ? servicePhone : "");
|
|
6425
|
+
if (isPlatformCustomerMode && !data.session_id && !resolvedPhone) throw new Error("平台客服会话缺少 phone,请传入 phone 或配置 chat.platformServicePhone");
|
|
6426
|
+
const payload = {
|
|
6427
|
+
page: data.page,
|
|
6428
|
+
limit: data.limit
|
|
6429
|
+
};
|
|
6430
|
+
if (typeof data.username === "string" && data.username.trim()) payload.username = data.username.trim();
|
|
6431
|
+
if (resolvedPhone) payload.phone = resolvedPhone;
|
|
6432
|
+
if (typeof data.session_id === "string" && data.session_id.trim()) payload.session_id = data.session_id.trim();
|
|
6433
|
+
if (typeof data.user_type === "number") payload.user_type = data.user_type;
|
|
6434
|
+
if (typeof data.msg_type === "number") payload.msg_type = data.msg_type;
|
|
6435
|
+
if (Number.isFinite(friendType) && friendType > 0) payload.friend_type = friendType;
|
|
6436
|
+
if (isCustomerOnly) payload.customeronly = 1;
|
|
6437
|
+
return unwrapResult(yield httpClient.post(buildApiPath("/chat/getList"), payload), "getChatList");
|
|
6317
6438
|
});
|
|
6318
6439
|
return _getChatList.apply(this, arguments);
|
|
6319
6440
|
}
|
|
@@ -16615,8 +16736,8 @@ var _hoisted_16$2 = {
|
|
|
16615
16736
|
class: "msg-avatar"
|
|
16616
16737
|
};
|
|
16617
16738
|
var _hoisted_17$2 = { class: "message-content-wrapper" };
|
|
16618
|
-
var _hoisted_18$
|
|
16619
|
-
var _hoisted_19$
|
|
16739
|
+
var _hoisted_18$2 = { class: "message-sender" };
|
|
16740
|
+
var _hoisted_19$2 = { class: "message-content" };
|
|
16620
16741
|
var _hoisted_20$1 = {
|
|
16621
16742
|
key: 0,
|
|
16622
16743
|
class: "message-text"
|
|
@@ -17138,12 +17259,15 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
17138
17259
|
}();
|
|
17139
17260
|
input.click();
|
|
17140
17261
|
}
|
|
17141
|
-
function resolveUploadedImageUrl(uploadURL, fileUrl) {
|
|
17262
|
+
function resolveUploadedImageUrl(resourceBaseURL, uploadURL, fileUrl) {
|
|
17142
17263
|
const normalizedFileUrl = typeof fileUrl === "string" ? fileUrl.trim() : "";
|
|
17143
17264
|
if (!normalizedFileUrl) return "";
|
|
17144
17265
|
if (HTTP_URL_REGEXP.test(normalizedFileUrl)) return normalizedFileUrl;
|
|
17266
|
+
const normalizedResourceBaseURL = typeof resourceBaseURL === "string" ? resourceBaseURL.trim() : "";
|
|
17267
|
+
const normalizedUploadURL = typeof uploadURL === "string" ? uploadURL.trim() : "";
|
|
17268
|
+
const preferredBaseURL = normalizedResourceBaseURL || normalizedUploadURL;
|
|
17145
17269
|
try {
|
|
17146
|
-
return new URL(normalizedFileUrl,
|
|
17270
|
+
return new URL(normalizedFileUrl, preferredBaseURL).toString();
|
|
17147
17271
|
} catch (_unused2) {
|
|
17148
17272
|
return normalizedFileUrl;
|
|
17149
17273
|
}
|
|
@@ -17167,7 +17291,8 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
17167
17291
|
isUploading.value = true;
|
|
17168
17292
|
const response = yield uploadImage(file);
|
|
17169
17293
|
if (!response.success || !((_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.url)) throw new Error(response.message || "上传失败");
|
|
17170
|
-
const
|
|
17294
|
+
const config = getConfig();
|
|
17295
|
+
const imageUrl = resolveUploadedImageUrl(config.api.resourceBaseURL, config.api.uploadURL, response.data.url);
|
|
17171
17296
|
if (!imageUrl) throw new Error("上传返回图片地址为空");
|
|
17172
17297
|
const tempMessageId = createTempMessageId();
|
|
17173
17298
|
const messageData = {
|
|
@@ -17316,7 +17441,7 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
17316
17441
|
alt: msg.sender,
|
|
17317
17442
|
class: "msg-avatar-img",
|
|
17318
17443
|
onError: handleImageError
|
|
17319
|
-
}, null, 40, _hoisted_15$2)) : (openBlock(), createElementBlock("div", _hoisted_16$2, toDisplayString(((_msg$sender = msg.sender) === null || _msg$sender === void 0 ? void 0 : _msg$sender.charAt(0)) || "?"), 1))]), createBaseVNode("div", _hoisted_17$2, [createBaseVNode("div", _hoisted_18$
|
|
17444
|
+
}, null, 40, _hoisted_15$2)) : (openBlock(), createElementBlock("div", _hoisted_16$2, toDisplayString(((_msg$sender = msg.sender) === null || _msg$sender === void 0 ? void 0 : _msg$sender.charAt(0)) || "?"), 1))]), createBaseVNode("div", _hoisted_17$2, [createBaseVNode("div", _hoisted_18$2, toDisplayString(msg.sender), 1), createBaseVNode("div", _hoisted_19$2, [msg.msgType === 1 ? (openBlock(), createElementBlock("div", _hoisted_20$1, toDisplayString(msg.content), 1)) : msg.msgType === 2 ? (openBlock(), createElementBlock("div", _hoisted_21, [createBaseVNode("img", {
|
|
17320
17445
|
src: msg.content,
|
|
17321
17446
|
alt: "图片",
|
|
17322
17447
|
onLoad: ($event) => handleMessageImageLoad(msg.id),
|
|
@@ -17366,7 +17491,7 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
17366
17491
|
class: "tool-btn emoji-btn",
|
|
17367
17492
|
title: "选择表情",
|
|
17368
17493
|
onClick: toggleEmojiPicker
|
|
17369
|
-
}, [..._cache[7] || (_cache[7] = [createStaticVNode("<span class=\"tool-btn-icon\" aria-hidden=\"true\" data-v-
|
|
17494
|
+
}, [..._cache[7] || (_cache[7] = [createStaticVNode("<span class=\"tool-btn-icon\" aria-hidden=\"true\" data-v-1459079f><svg class=\"tool-btn-svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" data-v-1459079f><circle cx=\"12\" cy=\"12\" r=\"10\" data-v-1459079f></circle><path d=\"M8 14s1.5 2 4 2 4-2 4-2\" data-v-1459079f></path><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\" data-v-1459079f></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\" data-v-1459079f></line></svg></span><span class=\"tool-btn-text\" data-v-1459079f>表情</span>", 2)])]), showEmojiPicker.value ? (openBlock(), createElementBlock("div", _hoisted_55, [createVNode(unref(Picker), {
|
|
17370
17495
|
native: true,
|
|
17371
17496
|
theme: "light",
|
|
17372
17497
|
"group-names": {
|
|
@@ -17452,7 +17577,7 @@ var ChatRoom_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__P
|
|
|
17452
17577
|
]);
|
|
17453
17578
|
};
|
|
17454
17579
|
}
|
|
17455
|
-
}), [["__scopeId", "data-v-
|
|
17580
|
+
}), [["__scopeId", "data-v-1459079f"]]);
|
|
17456
17581
|
//#endregion
|
|
17457
17582
|
//#region src/assets/img/list.png?url
|
|
17458
17583
|
var list_default = "data:image/png;base64,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";
|
|
@@ -17484,31 +17609,37 @@ var _hoisted_2$2 = {
|
|
|
17484
17609
|
var _hoisted_3$2 = { class: "unread-count" };
|
|
17485
17610
|
var _hoisted_4$1 = {
|
|
17486
17611
|
key: 1,
|
|
17487
|
-
class: "
|
|
17612
|
+
class: "search-header"
|
|
17488
17613
|
};
|
|
17489
|
-
var _hoisted_5$1 =
|
|
17614
|
+
var _hoisted_5$1 = ["onKeydown"];
|
|
17615
|
+
var _hoisted_6$1 = {
|
|
17490
17616
|
key: 2,
|
|
17617
|
+
class: "loading-state"
|
|
17618
|
+
};
|
|
17619
|
+
var _hoisted_7$1 = {
|
|
17620
|
+
key: 3,
|
|
17491
17621
|
class: "empty-state"
|
|
17492
17622
|
};
|
|
17493
|
-
var
|
|
17494
|
-
var
|
|
17495
|
-
var
|
|
17496
|
-
var
|
|
17497
|
-
var
|
|
17498
|
-
var
|
|
17623
|
+
var _hoisted_8$1 = ["src"];
|
|
17624
|
+
var _hoisted_9$1 = ["onClick"];
|
|
17625
|
+
var _hoisted_10$1 = { class: "conversation-item-content" };
|
|
17626
|
+
var _hoisted_11$1 = { class: "avatar-wrapper" };
|
|
17627
|
+
var _hoisted_12$1 = ["src", "alt"];
|
|
17628
|
+
var _hoisted_13$1 = {
|
|
17499
17629
|
key: 1,
|
|
17500
17630
|
class: "avatar-text"
|
|
17501
17631
|
};
|
|
17502
|
-
var
|
|
17503
|
-
var
|
|
17504
|
-
var
|
|
17505
|
-
var
|
|
17506
|
-
var
|
|
17507
|
-
var
|
|
17632
|
+
var _hoisted_14$1 = { class: "session-info" };
|
|
17633
|
+
var _hoisted_15$1 = { class: "session-name" };
|
|
17634
|
+
var _hoisted_16$1 = { class: "content-text" };
|
|
17635
|
+
var _hoisted_17$1 = { class: "session-meta" };
|
|
17636
|
+
var _hoisted_18$1 = { class: "session-time" };
|
|
17637
|
+
var _hoisted_19$1 = {
|
|
17508
17638
|
key: 0,
|
|
17509
17639
|
class: "unread-badge"
|
|
17510
17640
|
};
|
|
17511
17641
|
var WS_RELOAD_DEBOUNCE_MS = 200;
|
|
17642
|
+
var STORE_API_PREFIX = "/cashier/IM";
|
|
17512
17643
|
//#endregion
|
|
17513
17644
|
//#region src/components/ConversationList.vue
|
|
17514
17645
|
var ConversationList_default = /* @__PURE__ */ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
@@ -17527,8 +17658,11 @@ var ConversationList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
17527
17658
|
const emit = __emit;
|
|
17528
17659
|
const conversations = /* @__PURE__ */ ref([]);
|
|
17529
17660
|
const loading = /* @__PURE__ */ ref(false);
|
|
17661
|
+
const searchInputUsername = /* @__PURE__ */ ref("");
|
|
17662
|
+
const searchUsername = /* @__PURE__ */ ref("");
|
|
17530
17663
|
let latestLoadRequestId = 0;
|
|
17531
17664
|
let wsReloadTimer = null;
|
|
17665
|
+
const TRAILING_SLASH_REGEXP = /\/+$/;
|
|
17532
17666
|
const stableMessageDedupe = createStableMessageDedupe();
|
|
17533
17667
|
const { unreadCount } = useUnreadStore();
|
|
17534
17668
|
function getUserType() {
|
|
@@ -17536,6 +17670,17 @@ var ConversationList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
17536
17670
|
const userType = Number(config.api.userType);
|
|
17537
17671
|
return Number.isFinite(userType) ? userType : void 0;
|
|
17538
17672
|
}
|
|
17673
|
+
function isStoreMode() {
|
|
17674
|
+
const prefix = String(getConfig().api.prefix || "").trim().replace(TRAILING_SLASH_REGEXP, "");
|
|
17675
|
+
return prefix === STORE_API_PREFIX || prefix.startsWith(`${STORE_API_PREFIX}/`);
|
|
17676
|
+
}
|
|
17677
|
+
const showStoreUsernameSearch = computed(() => {
|
|
17678
|
+
return isStoreMode() && props.type === "conversation";
|
|
17679
|
+
});
|
|
17680
|
+
const emptyStateText = computed(() => {
|
|
17681
|
+
if (showStoreUsernameSearch.value && searchUsername.value) return "未找到匹配用户";
|
|
17682
|
+
return "暂无消息";
|
|
17683
|
+
});
|
|
17539
17684
|
const MsgType = {
|
|
17540
17685
|
TEXT: 1,
|
|
17541
17686
|
IMAGE: 2,
|
|
@@ -17617,11 +17762,14 @@ var ConversationList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
17617
17762
|
if (!userInfo) return;
|
|
17618
17763
|
try {
|
|
17619
17764
|
loading.value = true;
|
|
17765
|
+
const keyword = searchUsername.value.trim();
|
|
17766
|
+
const shouldSearchByUsername = showStoreUsernameSearch.value && !!keyword;
|
|
17620
17767
|
const result = yield getUserChatList({
|
|
17621
17768
|
page: 1,
|
|
17622
17769
|
limit: 50,
|
|
17623
17770
|
uid: userInfo.id,
|
|
17624
|
-
user_type: getUserType()
|
|
17771
|
+
user_type: getUserType(),
|
|
17772
|
+
username: shouldSearchByUsername ? keyword : void 0
|
|
17625
17773
|
});
|
|
17626
17774
|
if (requestId !== latestLoadRequestId) return;
|
|
17627
17775
|
conversations.value = result.list.map((session) => transformSession(session));
|
|
@@ -17739,6 +17887,13 @@ var ConversationList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
17739
17887
|
loadData();
|
|
17740
17888
|
}, WS_RELOAD_DEBOUNCE_MS);
|
|
17741
17889
|
}
|
|
17890
|
+
function handleSearchEnter() {
|
|
17891
|
+
if (!showStoreUsernameSearch.value) return;
|
|
17892
|
+
const nextKeyword = searchInputUsername.value.trim();
|
|
17893
|
+
const changed = nextKeyword !== searchUsername.value;
|
|
17894
|
+
if (changed) searchUsername.value = nextKeyword;
|
|
17895
|
+
if (changed || nextKeyword) loadData();
|
|
17896
|
+
}
|
|
17742
17897
|
function handleWebSocketMessage(data) {
|
|
17743
17898
|
const message = normalizeWSMessage(data);
|
|
17744
17899
|
if (!message) return;
|
|
@@ -17764,7 +17919,13 @@ var ConversationList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
17764
17919
|
}
|
|
17765
17920
|
}
|
|
17766
17921
|
__expose({ reload });
|
|
17767
|
-
watch(() => props.type,
|
|
17922
|
+
watch(() => props.type, (nextType, prevType) => {
|
|
17923
|
+
if (prevType === "conversation" && nextType !== "conversation" && (searchInputUsername.value || searchUsername.value)) {
|
|
17924
|
+
searchInputUsername.value = "";
|
|
17925
|
+
searchUsername.value = "";
|
|
17926
|
+
}
|
|
17927
|
+
loadData();
|
|
17928
|
+
});
|
|
17768
17929
|
onMounted(() => {
|
|
17769
17930
|
loadData();
|
|
17770
17931
|
wsClient.on("message", handleWebSocketMessage);
|
|
@@ -17779,32 +17940,40 @@ var ConversationList_default = /* @__PURE__ */ _plugin_vue_export_helper_default
|
|
|
17779
17940
|
return (_ctx, _cache) => {
|
|
17780
17941
|
return openBlock(), createElementBlock("div", _hoisted_1$3, [
|
|
17781
17942
|
props.type === "unread" ? (openBlock(), createElementBlock("div", _hoisted_2$2, [createBaseVNode("span", _hoisted_3$2, "未读消息 (" + toDisplayString(unref(unreadCount)) + ")", 1)])) : createCommentVNode("", true),
|
|
17782
|
-
|
|
17943
|
+
showStoreUsernameSearch.value ? (openBlock(), createElementBlock("div", _hoisted_4$1, [withDirectives(createBaseVNode("input", {
|
|
17944
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchInputUsername.value = $event),
|
|
17945
|
+
class: "search-input",
|
|
17946
|
+
type: "text",
|
|
17947
|
+
placeholder: "输入用户名后回车搜索",
|
|
17948
|
+
maxlength: "32",
|
|
17949
|
+
onKeydown: withKeys(withModifiers(handleSearchEnter, ["prevent"]), ["enter"])
|
|
17950
|
+
}, null, 40, _hoisted_5$1), [[vModelText, searchInputUsername.value]])])) : createCommentVNode("", true),
|
|
17951
|
+
loading.value ? (openBlock(), createElementBlock("div", _hoisted_6$1, [..._cache[1] || (_cache[1] = [createBaseVNode("div", { class: "loading-spinner" }, null, -1), createBaseVNode("p", null, "加载中...", -1)])])) : filteredConversations.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_7$1, [createBaseVNode("img", {
|
|
17783
17952
|
class: "empty-icon",
|
|
17784
17953
|
src: unref(list_default),
|
|
17785
17954
|
alt: "暂无消息"
|
|
17786
|
-
}, null, 8,
|
|
17955
|
+
}, null, 8, _hoisted_8$1), createBaseVNode("p", null, toDisplayString(emptyStateText.value), 1)])) : createCommentVNode("", true),
|
|
17787
17956
|
(openBlock(true), createElementBlock(Fragment, null, renderList(filteredConversations.value, (conversation) => {
|
|
17788
17957
|
return openBlock(), createElementBlock("div", {
|
|
17789
17958
|
key: conversation.id,
|
|
17790
17959
|
class: normalizeClass(["conversation-item", { active: conversation.id === props.selectedId }]),
|
|
17791
17960
|
onClick: ($event) => handleSelect(conversation.id)
|
|
17792
|
-
}, [createBaseVNode("div",
|
|
17793
|
-
createBaseVNode("div",
|
|
17961
|
+
}, [createBaseVNode("div", _hoisted_10$1, [
|
|
17962
|
+
createBaseVNode("div", _hoisted_11$1, [conversation.avatar ? (openBlock(), createElementBlock("img", {
|
|
17794
17963
|
key: 0,
|
|
17795
17964
|
src: conversation.avatar,
|
|
17796
17965
|
alt: conversation.name,
|
|
17797
17966
|
class: "avatar-img",
|
|
17798
17967
|
onError: handleImageError
|
|
17799
|
-
}, null, 40,
|
|
17800
|
-
createBaseVNode("div",
|
|
17801
|
-
createBaseVNode("div",
|
|
17802
|
-
])], 10,
|
|
17968
|
+
}, null, 40, _hoisted_12$1)) : (openBlock(), createElementBlock("div", _hoisted_13$1, toDisplayString(conversation.avatarText), 1))]),
|
|
17969
|
+
createBaseVNode("div", _hoisted_14$1, [createBaseVNode("div", _hoisted_15$1, toDisplayString(conversation.name), 1), createBaseVNode("span", _hoisted_16$1, toDisplayString(conversation.lastMessage), 1)]),
|
|
17970
|
+
createBaseVNode("div", _hoisted_17$1, [createBaseVNode("div", _hoisted_18$1, toDisplayString(formatTime(conversation.lastTime)), 1), conversation.unreadCount > 0 ? (openBlock(), createElementBlock("span", _hoisted_19$1, toDisplayString(conversation.unreadCount > 99 ? "99+" : conversation.unreadCount), 1)) : createCommentVNode("", true)])
|
|
17971
|
+
])], 10, _hoisted_9$1);
|
|
17803
17972
|
}), 128))
|
|
17804
17973
|
]);
|
|
17805
17974
|
};
|
|
17806
17975
|
}
|
|
17807
|
-
}), [["__scopeId", "data-v-
|
|
17976
|
+
}), [["__scopeId", "data-v-66bc5469"]]);
|
|
17808
17977
|
//#endregion
|
|
17809
17978
|
//#region src/components/ChatWindow.vue?vue&type=script&setup=true&lang.ts
|
|
17810
17979
|
var _hoisted_1$2 = { class: "user-info-section" };
|
|
@@ -18521,9 +18690,10 @@ var WS_STATUS = {
|
|
|
18521
18690
|
CLOSING: 2,
|
|
18522
18691
|
CLOSED: 3
|
|
18523
18692
|
};
|
|
18524
|
-
var
|
|
18525
|
-
var
|
|
18526
|
-
var
|
|
18693
|
+
var DEFAULT_HEARTBEAT_INTERVAL = 3e3;
|
|
18694
|
+
var DEFAULT_RECONNECT_INTERVAL = 3e3;
|
|
18695
|
+
var DEFAULT_MAX_RECONNECT_COUNT = 5;
|
|
18696
|
+
var DEFAULT_CONNECT_TIMEOUT = 3e4;
|
|
18527
18697
|
var MAX_MESSAGE_QUEUE_SIZE = 200;
|
|
18528
18698
|
var PRESENCE_ACTION_STORAGE_KEY = "imsdk:presence-action";
|
|
18529
18699
|
var PRESENCE_CHANGE_EVENT = "presenceChange";
|
|
@@ -18553,6 +18723,7 @@ var WebSocketClient = class {
|
|
|
18553
18723
|
_defineProperty(this, "status", WS_STATUS.CLOSED);
|
|
18554
18724
|
_defineProperty(this, "heartbeatTimer", null);
|
|
18555
18725
|
_defineProperty(this, "reconnectTimer", null);
|
|
18726
|
+
_defineProperty(this, "connectTimeoutTimer", null);
|
|
18556
18727
|
_defineProperty(this, "reconnectCount", 0);
|
|
18557
18728
|
_defineProperty(this, "messageQueue", []);
|
|
18558
18729
|
_defineProperty(this, "listeners", /* @__PURE__ */ new Map());
|
|
@@ -18564,12 +18735,52 @@ var WebSocketClient = class {
|
|
|
18564
18735
|
_defineProperty(this, "siteId", "");
|
|
18565
18736
|
_defineProperty(this, "presenceAction", "onConnect");
|
|
18566
18737
|
_defineProperty(this, "isConnected", false);
|
|
18567
|
-
_defineProperty(this, "
|
|
18738
|
+
_defineProperty(this, "wsUrlOverride", "");
|
|
18568
18739
|
_defineProperty(this, "logPrefix", "[WebSocket]");
|
|
18569
|
-
this.
|
|
18740
|
+
this.wsUrlOverride = config.wsUrl || "";
|
|
18570
18741
|
this.siteId = config.siteId || "";
|
|
18571
18742
|
this.presenceAction = readPresenceActionFromStorage();
|
|
18572
18743
|
}
|
|
18744
|
+
toPositiveInt(value, fallback) {
|
|
18745
|
+
const next = Number(value);
|
|
18746
|
+
if (!Number.isFinite(next) || next <= 0) return fallback;
|
|
18747
|
+
return Math.floor(next);
|
|
18748
|
+
}
|
|
18749
|
+
getHeartbeatInterval() {
|
|
18750
|
+
return this.toPositiveInt(getConfig().ws.heartbeatInterval, DEFAULT_HEARTBEAT_INTERVAL);
|
|
18751
|
+
}
|
|
18752
|
+
getReconnectInterval() {
|
|
18753
|
+
return this.toPositiveInt(getConfig().ws.reconnectInterval, DEFAULT_RECONNECT_INTERVAL);
|
|
18754
|
+
}
|
|
18755
|
+
getMaxReconnectCount() {
|
|
18756
|
+
return this.toPositiveInt(getConfig().ws.maxReconnectAttempts, DEFAULT_MAX_RECONNECT_COUNT);
|
|
18757
|
+
}
|
|
18758
|
+
getConnectTimeout() {
|
|
18759
|
+
return this.toPositiveInt(getConfig().ws.connectTimeout, DEFAULT_CONNECT_TIMEOUT);
|
|
18760
|
+
}
|
|
18761
|
+
trace(tag, payload) {
|
|
18762
|
+
if (!isWSTraceEnabled()) return;
|
|
18763
|
+
if (payload) {
|
|
18764
|
+
console.debug(`${this.logPrefix} [TRACE] ${tag}`, payload);
|
|
18765
|
+
return;
|
|
18766
|
+
}
|
|
18767
|
+
console.debug(`${this.logPrefix} [TRACE] ${tag}`);
|
|
18768
|
+
}
|
|
18769
|
+
resolveProtocolAction(action) {
|
|
18770
|
+
const actions = getWSProtocolAction();
|
|
18771
|
+
if (action === "send") return actions.send;
|
|
18772
|
+
if (action === "msgRead") return actions.msgRead;
|
|
18773
|
+
if (action === "onConnect") return actions.onConnect;
|
|
18774
|
+
if (action === "offLine") return actions.offLine;
|
|
18775
|
+
if (action === "heartbeat") return actions.heartbeat;
|
|
18776
|
+
return action;
|
|
18777
|
+
}
|
|
18778
|
+
stopConnectTimeout() {
|
|
18779
|
+
if (this.connectTimeoutTimer) {
|
|
18780
|
+
clearTimeout(this.connectTimeoutTimer);
|
|
18781
|
+
this.connectTimeoutTimer = null;
|
|
18782
|
+
}
|
|
18783
|
+
}
|
|
18573
18784
|
/**
|
|
18574
18785
|
* 连接 WebSocket
|
|
18575
18786
|
* @param {string} token - 用户token
|
|
@@ -18581,7 +18792,12 @@ var WebSocketClient = class {
|
|
|
18581
18792
|
return new Promise((resolve, reject) => {
|
|
18582
18793
|
try {
|
|
18583
18794
|
this.destroyConnection();
|
|
18584
|
-
const url = `${this.
|
|
18795
|
+
const url = `${this.wsUrlOverride || getWSBaseURL()}?platform=${encodeURIComponent(getWSPlatform())}${token ? `&token=${encodeURIComponent(token)}` : ""}`;
|
|
18796
|
+
this.trace("connect:prepare", {
|
|
18797
|
+
url,
|
|
18798
|
+
platform: getWSPlatform()
|
|
18799
|
+
});
|
|
18800
|
+
const connectTimeout = this.getConnectTimeout();
|
|
18585
18801
|
this.lastToken = token;
|
|
18586
18802
|
this.lastUserId = userId;
|
|
18587
18803
|
this.lastPhone = phone;
|
|
@@ -18595,9 +18811,27 @@ var WebSocketClient = class {
|
|
|
18595
18811
|
});
|
|
18596
18812
|
this.ws = new WebSocket(url);
|
|
18597
18813
|
this.status = WS_STATUS.CONNECTING;
|
|
18814
|
+
this.stopConnectTimeout();
|
|
18815
|
+
this.connectTimeoutTimer = setTimeout(() => {
|
|
18816
|
+
if (!this.ws || this.status !== WS_STATUS.CONNECTING) return;
|
|
18817
|
+
console.warn(`${this.logPrefix} 连接超时,已主动关闭`, {
|
|
18818
|
+
timeoutMs: connectTimeout,
|
|
18819
|
+
platform: getWSPlatform(),
|
|
18820
|
+
siteId: this.siteId
|
|
18821
|
+
});
|
|
18822
|
+
try {
|
|
18823
|
+
this.ws.close();
|
|
18824
|
+
} catch (error) {
|
|
18825
|
+
console.error(`${this.logPrefix} 连接超时关闭失败`, error);
|
|
18826
|
+
}
|
|
18827
|
+
this.status = WS_STATUS.CLOSED;
|
|
18828
|
+
this.stopConnectTimeout();
|
|
18829
|
+
reject(/* @__PURE__ */ new Error(`WebSocket 连接超时(${connectTimeout}ms)`));
|
|
18830
|
+
}, connectTimeout);
|
|
18598
18831
|
this.ws.onopen = (event) => {
|
|
18599
18832
|
this.status = WS_STATUS.OPEN;
|
|
18600
18833
|
this.reconnectCount = 0;
|
|
18834
|
+
this.stopConnectTimeout();
|
|
18601
18835
|
console.info(`${this.logPrefix} 连接已建立`, {
|
|
18602
18836
|
platform: getWSPlatform(),
|
|
18603
18837
|
siteId: this.siteId,
|
|
@@ -18618,6 +18852,10 @@ var WebSocketClient = class {
|
|
|
18618
18852
|
if (!rawData || rawData === "null") return;
|
|
18619
18853
|
try {
|
|
18620
18854
|
const data = JSON.parse(rawData);
|
|
18855
|
+
this.trace("message:receive", {
|
|
18856
|
+
controller: data === null || data === void 0 ? void 0 : data.controller,
|
|
18857
|
+
action: data === null || data === void 0 ? void 0 : data.action
|
|
18858
|
+
});
|
|
18621
18859
|
this.emit("message", data);
|
|
18622
18860
|
} catch (_unused) {
|
|
18623
18861
|
console.warn("收到非 JSON WebSocket 消息,已忽略:", rawData);
|
|
@@ -18625,15 +18863,18 @@ var WebSocketClient = class {
|
|
|
18625
18863
|
};
|
|
18626
18864
|
this.ws.onerror = (error) => {
|
|
18627
18865
|
this.status = WS_STATUS.CLOSED;
|
|
18866
|
+
this.stopConnectTimeout();
|
|
18628
18867
|
console.error(`${this.logPrefix} 连接异常`, error);
|
|
18629
18868
|
this.emit("error", error);
|
|
18630
18869
|
reject(error);
|
|
18631
18870
|
};
|
|
18632
18871
|
this.ws.onclose = (event) => {
|
|
18633
18872
|
this.status = WS_STATUS.CLOSED;
|
|
18873
|
+
this.stopConnectTimeout();
|
|
18634
18874
|
this.stopHeartbeat();
|
|
18635
18875
|
this.emit("close", event);
|
|
18636
|
-
const
|
|
18876
|
+
const maxReconnectCount = this.getMaxReconnectCount();
|
|
18877
|
+
const canReconnect = this.presenceAction === "onConnect" && this.reconnectCount < maxReconnectCount;
|
|
18637
18878
|
console.warn(`${this.logPrefix} 连接关闭`, {
|
|
18638
18879
|
code: event.code,
|
|
18639
18880
|
reason: event.reason,
|
|
@@ -18644,7 +18885,7 @@ var WebSocketClient = class {
|
|
|
18644
18885
|
});
|
|
18645
18886
|
if (canReconnect) this.scheduleReconnect(token, this.userId, this.phone);
|
|
18646
18887
|
else if (this.presenceAction === "offLine") console.info(`${this.logPrefix} 当前为 offLine 状态,已停止自动重连`);
|
|
18647
|
-
else console.error(`${this.logPrefix} 重连次数超过最大限制,停止重连`, { maxReconnectCount
|
|
18888
|
+
else console.error(`${this.logPrefix} 重连次数超过最大限制,停止重连`, { maxReconnectCount });
|
|
18648
18889
|
};
|
|
18649
18890
|
} catch (error) {
|
|
18650
18891
|
reject(error);
|
|
@@ -18667,6 +18908,10 @@ var WebSocketClient = class {
|
|
|
18667
18908
|
}
|
|
18668
18909
|
try {
|
|
18669
18910
|
this.ws.send(message);
|
|
18911
|
+
if (typeof data !== "string") this.trace("message:send", {
|
|
18912
|
+
controller: data.controller,
|
|
18913
|
+
action: data.action
|
|
18914
|
+
});
|
|
18670
18915
|
return true;
|
|
18671
18916
|
} catch (error) {
|
|
18672
18917
|
console.error("WebSocket发送消息失败:", error);
|
|
@@ -18677,7 +18922,7 @@ var WebSocketClient = class {
|
|
|
18677
18922
|
* 发送控制器动作消息(使用当前配置的 controller)
|
|
18678
18923
|
*/
|
|
18679
18924
|
sendControllerMessage(action, param = {}) {
|
|
18680
|
-
const controller =
|
|
18925
|
+
const controller = getWSProtocolController();
|
|
18681
18926
|
return this.send({
|
|
18682
18927
|
controller,
|
|
18683
18928
|
action,
|
|
@@ -18701,7 +18946,8 @@ var WebSocketClient = class {
|
|
|
18701
18946
|
return false;
|
|
18702
18947
|
}
|
|
18703
18948
|
}
|
|
18704
|
-
|
|
18949
|
+
const runtimeAction = this.resolveProtocolAction(action);
|
|
18950
|
+
return this.sendControllerMessage(runtimeAction, param);
|
|
18705
18951
|
}
|
|
18706
18952
|
tryReconnectFromManualOnline() {
|
|
18707
18953
|
if (this.status === WS_STATUS.CONNECTING) {
|
|
@@ -18744,8 +18990,8 @@ var WebSocketClient = class {
|
|
|
18744
18990
|
this.heartbeatTimer = setInterval(() => {
|
|
18745
18991
|
if (this.status === WS_STATUS.OPEN && this.ws) {
|
|
18746
18992
|
const heartbeatData = {
|
|
18747
|
-
controller:
|
|
18748
|
-
action: "heartbeat",
|
|
18993
|
+
controller: getWSProtocolController(),
|
|
18994
|
+
action: this.resolveProtocolAction("heartbeat"),
|
|
18749
18995
|
param: {
|
|
18750
18996
|
userId: this.userId,
|
|
18751
18997
|
platform: getWSPlatform(),
|
|
@@ -18755,15 +19001,15 @@ var WebSocketClient = class {
|
|
|
18755
19001
|
};
|
|
18756
19002
|
this.send(heartbeatData);
|
|
18757
19003
|
}
|
|
18758
|
-
},
|
|
19004
|
+
}, this.getHeartbeatInterval());
|
|
18759
19005
|
}
|
|
18760
19006
|
/**
|
|
18761
19007
|
* 发送连接/状态消息
|
|
18762
19008
|
*/
|
|
18763
19009
|
sendConnectMessage() {
|
|
18764
19010
|
const connectData = {
|
|
18765
|
-
controller:
|
|
18766
|
-
action: this.presenceAction,
|
|
19011
|
+
controller: getWSProtocolController(),
|
|
19012
|
+
action: this.resolveProtocolAction(this.presenceAction),
|
|
18767
19013
|
param: {
|
|
18768
19014
|
userId: this.userId,
|
|
18769
19015
|
platform: getWSPlatform(),
|
|
@@ -18795,10 +19041,12 @@ var WebSocketClient = class {
|
|
|
18795
19041
|
}
|
|
18796
19042
|
this.reconnectCount++;
|
|
18797
19043
|
const attempt = this.reconnectCount;
|
|
19044
|
+
const maxReconnectCount = this.getMaxReconnectCount();
|
|
19045
|
+
const reconnectInterval = this.getReconnectInterval();
|
|
18798
19046
|
console.info(`${this.logPrefix} 准备重连`, {
|
|
18799
19047
|
attempt,
|
|
18800
|
-
maxReconnectCount
|
|
18801
|
-
retryInMs:
|
|
19048
|
+
maxReconnectCount,
|
|
19049
|
+
retryInMs: reconnectInterval
|
|
18802
19050
|
});
|
|
18803
19051
|
this.reconnectTimer = setTimeout(() => {
|
|
18804
19052
|
if (this.presenceAction === "offLine") {
|
|
@@ -18817,7 +19065,7 @@ var WebSocketClient = class {
|
|
|
18817
19065
|
}
|
|
18818
19066
|
console.info(`${this.logPrefix} 发起重连`, {
|
|
18819
19067
|
attempt,
|
|
18820
|
-
maxReconnectCount
|
|
19068
|
+
maxReconnectCount
|
|
18821
19069
|
});
|
|
18822
19070
|
this.connect(token, userId, phone, this.siteId).catch((error) => {
|
|
18823
19071
|
console.error(`${this.logPrefix} 重连失败`, {
|
|
@@ -18825,7 +19073,7 @@ var WebSocketClient = class {
|
|
|
18825
19073
|
error
|
|
18826
19074
|
});
|
|
18827
19075
|
});
|
|
18828
|
-
},
|
|
19076
|
+
}, reconnectInterval);
|
|
18829
19077
|
}
|
|
18830
19078
|
/**
|
|
18831
19079
|
* 发送消息队列中的消息
|
|
@@ -18849,6 +19097,7 @@ var WebSocketClient = class {
|
|
|
18849
19097
|
clearTimeout(this.reconnectTimer);
|
|
18850
19098
|
this.reconnectTimer = null;
|
|
18851
19099
|
}
|
|
19100
|
+
this.stopConnectTimeout();
|
|
18852
19101
|
if (this.ws) {
|
|
18853
19102
|
this.ws.onopen = null;
|
|
18854
19103
|
this.ws.onmessage = null;
|
|
@@ -18872,7 +19121,7 @@ var WebSocketClient = class {
|
|
|
18872
19121
|
disconnect() {
|
|
18873
19122
|
console.info(`${this.logPrefix} 主动断开连接`);
|
|
18874
19123
|
this.destroyConnection();
|
|
18875
|
-
this.reconnectCount =
|
|
19124
|
+
this.reconnectCount = this.getMaxReconnectCount();
|
|
18876
19125
|
this.messageQueue = [];
|
|
18877
19126
|
}
|
|
18878
19127
|
/**
|
|
@@ -18960,27 +19209,46 @@ function mountIMApp() {
|
|
|
18960
19209
|
} }).mount(container);
|
|
18961
19210
|
}
|
|
18962
19211
|
function validateModeContract() {
|
|
18963
|
-
var _config$api$prefix, _config$ws$
|
|
19212
|
+
var _config$api$prefix, _config$ws$protocol, _config$ws$platform;
|
|
18964
19213
|
const config = getConfig();
|
|
18965
19214
|
const apiPrefix = (_config$api$prefix = config.api.prefix) === null || _config$api$prefix === void 0 ? void 0 : _config$api$prefix.trim();
|
|
18966
|
-
const wsController = (_config$ws$
|
|
19215
|
+
const wsController = (config.ws.controller || ((_config$ws$protocol = config.ws.protocol) === null || _config$ws$protocol === void 0 ? void 0 : _config$ws$protocol.controller) || "").trim();
|
|
18967
19216
|
const wsPlatform = (_config$ws$platform = config.ws.platform) === null || _config$ws$platform === void 0 ? void 0 : _config$ws$platform.trim();
|
|
18968
19217
|
if (!apiPrefix) throw new Error("IMSDK 初始化失败:缺少 api.prefix,请使用 @zjw-jszn/platform-imsdk 或 @zjw-jszn/store-imsdk,或显式配置前缀");
|
|
18969
19218
|
if (!wsController || !wsPlatform) throw new Error("IMSDK 初始化失败:缺少 ws.controller 或 ws.platform,请按文档约定配置后重试");
|
|
18970
19219
|
if (wsPlatform !== wsPlatform.toLowerCase()) throw new Error(`IMSDK 初始化失败:ws.platform 必须为小写,当前为 ${wsPlatform}`);
|
|
18971
19220
|
if (wsController.toLowerCase() !== wsPlatform) throw new Error(`IMSDK 初始化失败:ws.controller (${wsController}) 与 ws.platform (${wsPlatform}) 不匹配`);
|
|
18972
19221
|
}
|
|
19222
|
+
function normalizeText(value) {
|
|
19223
|
+
return typeof value === "string" ? value.trim() : "";
|
|
19224
|
+
}
|
|
19225
|
+
function mergeAuthorizedUserInfo(authData, inputPhone) {
|
|
19226
|
+
var _config$auth;
|
|
19227
|
+
const authorizationPayload = ((_config$auth = getConfig().auth) === null || _config$auth === void 0 ? void 0 : _config$auth.authorizationPayload) || {};
|
|
19228
|
+
const payloadUsername = normalizeText(authorizationPayload.username);
|
|
19229
|
+
const payloadAvatar = normalizeText(authorizationPayload.avatar);
|
|
19230
|
+
const resolvedPhone = normalizeText(authData.phone) || inputPhone;
|
|
19231
|
+
const resolvedUsername = normalizeText(authData.username) || payloadUsername;
|
|
19232
|
+
const resolvedName = normalizeText(authData.name) || resolvedUsername;
|
|
19233
|
+
const resolvedAvatar = normalizeText(authData.avatar) || normalizeText(authData.cover) || payloadAvatar;
|
|
19234
|
+
return _objectSpread2(_objectSpread2({}, authData), {}, {
|
|
19235
|
+
phone: resolvedPhone,
|
|
19236
|
+
username: resolvedUsername,
|
|
19237
|
+
name: resolvedName,
|
|
19238
|
+
avatar: resolvedAvatar
|
|
19239
|
+
});
|
|
19240
|
+
}
|
|
18973
19241
|
function initIM() {
|
|
18974
19242
|
return _initIM.apply(this, arguments);
|
|
18975
19243
|
}
|
|
18976
19244
|
function _initIM() {
|
|
18977
19245
|
_initIM = _asyncToGenerator(function* (config = {}) {
|
|
18978
19246
|
if (initInFlight) {
|
|
18979
|
-
var _config$api, _config$ws, _config$ws2;
|
|
19247
|
+
var _config$api, _config$ws$controller, _config$ws, _config$ws2, _config$ws3;
|
|
18980
19248
|
const currentConfig = getConfig();
|
|
18981
19249
|
const nextApiPrefix = (_config$api = config.api) === null || _config$api === void 0 ? void 0 : _config$api.prefix;
|
|
18982
|
-
const nextWSController = (_config$ws = config.ws) === null || _config$ws === void 0 ? void 0 : _config$ws.controller;
|
|
18983
|
-
const nextWSPlatform = (_config$
|
|
19250
|
+
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;
|
|
19251
|
+
const nextWSPlatform = (_config$ws3 = config.ws) === null || _config$ws3 === void 0 ? void 0 : _config$ws3.platform;
|
|
18984
19252
|
if (nextApiPrefix && nextApiPrefix !== currentConfig.api.prefix || nextWSController && nextWSController !== currentConfig.ws.controller || nextWSPlatform && nextWSPlatform !== currentConfig.ws.platform) throw new Error("IMSDK 正在以其他模式初始化,请等待当前初始化完成后重试");
|
|
18985
19253
|
return initInFlight;
|
|
18986
19254
|
}
|
|
@@ -18993,11 +19261,11 @@ function _initIM() {
|
|
|
18993
19261
|
}
|
|
18994
19262
|
};
|
|
18995
19263
|
if (isInitialized.value && httpClient.getAuth()) {
|
|
18996
|
-
var _config$api2, _config$
|
|
19264
|
+
var _config$api2, _config$ws$controller2, _config$ws4, _config$ws5, _config$ws6;
|
|
18997
19265
|
const currentConfig = getConfig();
|
|
18998
19266
|
const nextApiPrefix = (_config$api2 = config.api) === null || _config$api2 === void 0 ? void 0 : _config$api2.prefix;
|
|
18999
|
-
const nextWSController = (_config$
|
|
19000
|
-
const nextWSPlatform = (_config$
|
|
19267
|
+
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;
|
|
19268
|
+
const nextWSPlatform = (_config$ws6 = config.ws) === null || _config$ws6 === void 0 ? void 0 : _config$ws6.platform;
|
|
19001
19269
|
if (nextApiPrefix && nextApiPrefix !== currentConfig.api.prefix || nextWSController && nextWSController !== currentConfig.ws.controller || nextWSPlatform && nextWSPlatform !== currentConfig.ws.platform) throw new Error("IMSDK 已初始化为其他模式,请刷新页面后再切换平台/门店");
|
|
19002
19270
|
mountIMApp();
|
|
19003
19271
|
console.warn("IMSDK 已初始化且已鉴权,本次调用将复用现有实例");
|
|
@@ -19007,13 +19275,30 @@ function _initIM() {
|
|
|
19007
19275
|
if (config.api) updateConfig({ api: config.api });
|
|
19008
19276
|
if (config.sound) updateConfig({ sound: config.sound });
|
|
19009
19277
|
if (config.auth) updateConfig({ auth: config.auth });
|
|
19278
|
+
if (config.chat) {
|
|
19279
|
+
var _config$chat$platform;
|
|
19280
|
+
const currentChat = getConfig().chat;
|
|
19281
|
+
updateConfig({ chat: { platformServicePhone: (_config$chat$platform = config.chat.platformServicePhone) !== null && _config$chat$platform !== void 0 ? _config$chat$platform : currentChat.platformServicePhone } });
|
|
19282
|
+
}
|
|
19010
19283
|
if (config.runtimeApi) updateConfig({ runtimeApi: config.runtimeApi });
|
|
19011
19284
|
if (config.ws) {
|
|
19012
|
-
var _config$ws$
|
|
19285
|
+
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;
|
|
19013
19286
|
const currentWS = getConfig().ws;
|
|
19287
|
+
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;
|
|
19014
19288
|
updateConfig({ ws: {
|
|
19015
|
-
|
|
19016
|
-
|
|
19289
|
+
url: (_config$ws$url = config.ws.url) !== null && _config$ws$url !== void 0 ? _config$ws$url : currentWS.url,
|
|
19290
|
+
controller: nextWSController,
|
|
19291
|
+
platform: (_config$ws$platform2 = config.ws.platform) !== null && _config$ws$platform2 !== void 0 ? _config$ws$platform2 : currentWS.platform,
|
|
19292
|
+
reconnectInterval: (_config$ws$reconnectI = config.ws.reconnectInterval) !== null && _config$ws$reconnectI !== void 0 ? _config$ws$reconnectI : currentWS.reconnectInterval,
|
|
19293
|
+
heartbeatInterval: (_config$ws$heartbeatI = config.ws.heartbeatInterval) !== null && _config$ws$heartbeatI !== void 0 ? _config$ws$heartbeatI : currentWS.heartbeatInterval,
|
|
19294
|
+
maxReconnectAttempts: (_config$ws$maxReconne = config.ws.maxReconnectAttempts) !== null && _config$ws$maxReconne !== void 0 ? _config$ws$maxReconne : currentWS.maxReconnectAttempts,
|
|
19295
|
+
connectTimeout: (_config$ws$connectTim = config.ws.connectTimeout) !== null && _config$ws$connectTim !== void 0 ? _config$ws$connectTim : currentWS.connectTimeout,
|
|
19296
|
+
traceEnabled: (_config$ws$traceEnabl = config.ws.traceEnabled) !== null && _config$ws$traceEnabl !== void 0 ? _config$ws$traceEnabl : currentWS.traceEnabled,
|
|
19297
|
+
protocol: _objectSpread2(_objectSpread2(_objectSpread2({}, currentWS.protocol), config.ws.protocol || {}), {}, {
|
|
19298
|
+
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,
|
|
19299
|
+
action: _objectSpread2(_objectSpread2({}, currentWS.protocol.action), ((_config$ws$protocol4 = config.ws.protocol) === null || _config$ws$protocol4 === void 0 ? void 0 : _config$ws$protocol4.action) || {}),
|
|
19300
|
+
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
|
|
19301
|
+
})
|
|
19017
19302
|
} });
|
|
19018
19303
|
}
|
|
19019
19304
|
httpClient.setBaseURL(getConfig().api.baseURL);
|
|
@@ -19023,11 +19308,14 @@ function _initIM() {
|
|
|
19023
19308
|
if (!normalizedPhone) throw new Error("IMSDK 初始化失败:缺少鉴权参数 phone");
|
|
19024
19309
|
try {
|
|
19025
19310
|
const authData = yield getAuthorization({ phone: normalizedPhone });
|
|
19026
|
-
|
|
19027
|
-
if (!
|
|
19028
|
-
|
|
19311
|
+
const normalizedToken = normalizeText(authData.token);
|
|
19312
|
+
if (!normalizedToken) throw new Error("鉴权返回 token 为空");
|
|
19313
|
+
const mergedAuthData = mergeAuthorizedUserInfo(authData, normalizedPhone);
|
|
19314
|
+
mergedAuthData.token = normalizedToken;
|
|
19315
|
+
userInfo.value = mergedAuthData;
|
|
19316
|
+
httpClient.setAuth(normalizedToken, "");
|
|
19029
19317
|
const sdkConfig = getConfig();
|
|
19030
|
-
wsClient.connect(
|
|
19318
|
+
wsClient.connect(normalizedToken, mergedAuthData.id, mergedAuthData.phone, sdkConfig.api.siteId).catch((error) => {
|
|
19031
19319
|
console.error("WebSocket连接失败:", error);
|
|
19032
19320
|
});
|
|
19033
19321
|
} catch (error) {
|
|
@@ -19053,17 +19341,21 @@ function getUserInfo() {
|
|
|
19053
19341
|
//#endregion
|
|
19054
19342
|
//#region src/mode.ts
|
|
19055
19343
|
function warnModeOverrides(scope, config, defaults) {
|
|
19344
|
+
var _wsConfig$protocol;
|
|
19056
19345
|
const apiConfig = config.api;
|
|
19057
19346
|
const wsConfig = config.ws;
|
|
19058
19347
|
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}`);
|
|
19059
19348
|
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}`);
|
|
19060
19349
|
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}`);
|
|
19061
19350
|
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}`);
|
|
19351
|
+
const protocolController = wsConfig === null || wsConfig === void 0 || (_wsConfig$protocol = wsConfig.protocol) === null || _wsConfig$protocol === void 0 ? void 0 : _wsConfig$protocol.controller;
|
|
19352
|
+
if (protocolController && protocolController !== defaults.ws.controller) console.warn(`[${scope}] 已忽略 ws.protocol.controller=${protocolController},当前模式固定为 ${defaults.ws.controller}`);
|
|
19062
19353
|
}
|
|
19063
19354
|
function applyModeDefaults(config, defaults) {
|
|
19355
|
+
var _config$ws;
|
|
19064
19356
|
return _objectSpread2(_objectSpread2({}, config), {}, {
|
|
19065
19357
|
api: _objectSpread2(_objectSpread2({}, config.api || {}), defaults.api),
|
|
19066
|
-
ws: _objectSpread2(_objectSpread2({}, config.ws || {}), defaults.ws)
|
|
19358
|
+
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 }) })
|
|
19067
19359
|
});
|
|
19068
19360
|
}
|
|
19069
19361
|
//#endregion
|