feat: integrate customer service chat functionality and add socket.io-client dependency

- Implemented a customer service chat interface in the application.
- Added socket.io-client for real-time communication.
- Updated language files to include customer service related translations.
- Modified navigation to direct users to the customer service page.
- Enhanced UI elements for better user experience in chat interactions.
This commit is contained in:
li
2026-01-29 03:04:52 +08:00
parent 14c8cbffcc
commit 322cc24208
12 changed files with 1629 additions and 72 deletions
+16
View File
@@ -86,6 +86,7 @@ var cn = {
user: "我的", user: "我的",
userBalance: "余额", userBalance: "余额",
customerService: "在线客服",
logout: "退出登录", logout: "退出登录",
tip: "提示", tip: "提示",
logoutTip: "确认退出登录?", logoutTip: "确认退出登录?",
@@ -174,6 +175,21 @@ var cn = {
chooseCoin: "请选择币种", chooseCoin: "请选择币种",
flagshipHall: "旗舰厅", flagshipHall: "旗舰厅",
liveHall: "现场厅", liveHall: "现场厅",
// 在线客服
csConnected: "已连接",
csConnecting: "连接中...",
csWelcome: "欢迎使用在线客服",
csBusy: "客服繁忙,请稍候...",
csInputTip: "请输入您的问题",
csInputPlaceholder: "输入消息,点击发送...",
csSend: "发送",
csMe: "我",
csAgent: "客服",
csSessionEnded: "会话已结束",
csAgentServing: "客服为您服务",
csAgentJoined: "已接入",
csConnectFailed: "连接失败",
}; };
export { cn }; export { cn };
+16
View File
@@ -86,6 +86,7 @@ var en = {
user: "User", user: "User",
userBalance: "Balance", userBalance: "Balance",
customerService: "Customer Service",
logout: "Logout", logout: "Logout",
tip: "Tip", tip: "Tip",
logoutTip: "Are you sure to logout?", logoutTip: "Are you sure to logout?",
@@ -178,6 +179,21 @@ var en = {
chooseCoin: "Currency", chooseCoin: "Currency",
flagshipHall: "Flagship Hall", flagshipHall: "Flagship Hall",
liveHall: "Live hall", liveHall: "Live hall",
// Customer Service
csConnected: "Connected",
csConnecting: "Connecting...",
csWelcome: "Welcome to Customer Service",
csBusy: "Agents are busy, please wait...",
csInputTip: "Please enter your question",
csInputPlaceholder: "Type a message and send...",
csSend: "Send",
csMe: "Me",
csAgent: "Agent",
csSessionEnded: "Session ended",
csAgentServing: "is serving you",
csAgentJoined: "has joined",
csConnectFailed: "Connection failed",
}; };
export { en }; export { en };
+16
View File
@@ -86,6 +86,7 @@ var In = {
user: "Saya", user: "Saya",
userBalance: "Saldo", userBalance: "Saldo",
customerService: "Layanan Pelanggan",
logout: "Keluar", logout: "Keluar",
tip: "Tips", tip: "Tips",
logoutTip: "Konfirmasi keluar?", logoutTip: "Konfirmasi keluar?",
@@ -173,6 +174,21 @@ var In = {
chooseCoin: "Currency", chooseCoin: "Currency",
flagshipHall: "Flagship Hall", flagshipHall: "Flagship Hall",
liveHall: "Live hall", liveHall: "Live hall",
// Layanan Pelanggan
csConnected: "Terhubung",
csConnecting: "Menghubungkan...",
csWelcome: "Selamat datang di Layanan Pelanggan",
csBusy: "Agen sedang sibuk, harap tunggu...",
csInputTip: "Silakan masukkan pertanyaan Anda",
csInputPlaceholder: "Ketik pesan dan kirim...",
csSend: "Kirim",
csMe: "Saya",
csAgent: "Agen",
csSessionEnded: "Sesi berakhir",
csAgentServing: "melayani Anda",
csAgentJoined: "telah bergabung",
csConnectFailed: "Koneksi gagal",
}; };
export { In }; export { In };
+16
View File
@@ -86,6 +86,7 @@ var kr = {
user: "나의 계정", user: "나의 계정",
userBalance: "잔액", userBalance: "잔액",
customerService: "고객 서비스",
logout: "로그아웃", logout: "로그아웃",
tip: "알림", tip: "알림",
logoutTip: "로그아웃하시겠습니까?", logoutTip: "로그아웃하시겠습니까?",
@@ -174,6 +175,21 @@ var kr = {
chooseCoin: "통화를 선택하세요", chooseCoin: "통화를 선택하세요",
flagshipHall: "플래그십 홀", flagshipHall: "플래그십 홀",
liveHall: "라이브홀", liveHall: "라이브홀",
// 고객 서비스
csConnected: "연결됨",
csConnecting: "연결 중...",
csWelcome: "고객 서비스에 오신 것을 환영합니다",
csBusy: "상담원이 바빠요. 잠시만 기다려 주세요...",
csInputTip: "질문을 입력해 주세요",
csInputPlaceholder: "메시지를 입력하고 보내세요...",
csSend: "보내기",
csMe: "나",
csAgent: "상담원",
csSessionEnded: "세션 종료",
csAgentServing: "님이 도와드립니다",
csAgentJoined: "님이 참여했습니다",
csConnectFailed: "연결 실패",
}; };
export { kr }; export { kr };
+16
View File
@@ -85,6 +85,7 @@ var tl = {
user: "ผู้ใช้", user: "ผู้ใช้",
userBalance: "ยอด", userBalance: "ยอด",
customerService: "บริการลูกค้า",
logout: "ออกจากระบบ", logout: "ออกจากระบบ",
tip: "คำแนะนำ", tip: "คำแนะนำ",
logoutTip: "คุณต้องการออกจากระบบหรือไม่", logoutTip: "คุณต้องการออกจากระบบหรือไม่",
@@ -173,6 +174,21 @@ var tl = {
chooseCoin: "โปรดเลือกสกุลเงิน", chooseCoin: "โปรดเลือกสกุลเงิน",
flagshipHall: "แฟล็กชิปฮอลล์", flagshipHall: "แฟล็กชิปฮอลล์",
liveHall: "ฮอลล์สด", liveHall: "ฮอลล์สด",
// บริการลูกค้า
csConnected: "เชื่อมต่อแล้ว",
csConnecting: "กำลังเชื่อมต่อ...",
csWelcome: "ยินดีต้อนรับสู่บริการลูกค้า",
csBusy: "เจ้าหน้าที่กำลังยุ่ง กรุณารอสักครู่...",
csInputTip: "กรุณาใส่คำถามของคุณ",
csInputPlaceholder: "พิมพ์ข้อความและส่ง...",
csSend: "ส่ง",
csMe: "ฉัน",
csAgent: "เจ้าหน้าที่",
csSessionEnded: "เซสชันสิ้นสุด",
csAgentServing: "กำลังให้บริการคุณ",
csAgentJoined: "ได้เข้าร่วม",
csConnectFailed: "เชื่อมต่อไม่สำเร็จ",
}; };
export { tl }; export { tl };
+16
View File
@@ -86,6 +86,7 @@ var tw = {
user: "我的", user: "我的",
userBalance: "餘額", userBalance: "餘額",
customerService: "在線客服",
logout: "退出登錄", logout: "退出登錄",
tip: "提示", tip: "提示",
logoutTip: "確認退出登錄?", logoutTip: "確認退出登錄?",
@@ -174,6 +175,21 @@ var tw = {
chooseCoin: "請選擇幣種", chooseCoin: "請選擇幣種",
flagshipHall: "旗艦廳", flagshipHall: "旗艦廳",
liveHall: "現場廳", liveHall: "現場廳",
// 在線客服
csConnected: "已連接",
csConnecting: "連接中...",
csWelcome: "歡迎使用在線客服",
csBusy: "客服繁忙,請稍候...",
csInputTip: "請輸入您的問題",
csInputPlaceholder: "輸入消息,點擊發送...",
csSend: "發送",
csMe: "我",
csAgent: "客服",
csSessionEnded: "會話已結束",
csAgentServing: "客服為您服務",
csAgentJoined: "已接入",
csConnectFailed: "連接失敗",
}; };
export { tw }; export { tw };
+16
View File
@@ -86,6 +86,7 @@ var yn = {
user: "Của tôi", user: "Của tôi",
userBalance: "Số dư", userBalance: "Số dư",
customerService: "Hỗ trợ trực tuyến",
logout: "Đăng xuất", logout: "Đăng xuất",
tip: "Gợi ý", tip: "Gợi ý",
logoutTip: "Xác nhận đăng xuất?", logoutTip: "Xác nhận đăng xuất?",
@@ -178,6 +179,21 @@ var yn = {
chooseCoin: "Vui lòng chọn loại tiền tệ", chooseCoin: "Vui lòng chọn loại tiền tệ",
flagshipHall: "Hội trường hàng đầu", flagshipHall: "Hội trường hàng đầu",
liveHall: "Hội trường trực tiếp", liveHall: "Hội trường trực tiếp",
// Hỗ trợ trực tuyến
csConnected: "Đã kết nối",
csConnecting: "Đang kết nối...",
csWelcome: "Chào mừng đến với hỗ trợ trực tuyến",
csBusy: "Nhân viên đang bận, vui lòng chờ...",
csInputTip: "Hãy nhập câu hỏi của bạn",
csInputPlaceholder: "Nhập tin nhắn và gửi...",
csSend: "Gửi",
csMe: "Tôi",
csAgent: "CSKH",
csSessionEnded: "Phiên đã kết thúc",
csAgentServing: "đang phục vụ bạn",
csAgentJoined: "đã tham gia",
csConnectFailed: "Kết nối thất bại",
}; };
export { yn }; export { yn };
+519
View File
@@ -3,12 +3,210 @@
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz",
"integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/types": "^7.28.6"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/types": {
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz",
"integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.28.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/@vue/compiler-core": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz",
"integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/shared": "3.5.26",
"entities": "^7.0.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz",
"integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-core": "3.5.26",
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz",
"integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/compiler-core": "3.5.26",
"@vue/compiler-dom": "3.5.26",
"@vue/compiler-ssr": "3.5.26",
"@vue/shared": "3.5.26",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
"postcss": "^8.5.6",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz",
"integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.26",
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/devtools-api": { "node_modules/@vue/devtools-api": {
"version": "6.5.0", "version": "6.5.0",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==", "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==",
"dev": true "dev": true
}, },
"node_modules/@vue/reactivity": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.26.tgz",
"integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.26.tgz",
"integrity": "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.5.26",
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.26.tgz",
"integrity": "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.5.26",
"@vue/runtime-core": "3.5.26",
"@vue/shared": "3.5.26",
"csstype": "^3.2.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.26.tgz",
"integrity": "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-ssr": "3.5.26",
"@vue/shared": "3.5.26"
},
"peerDependencies": {
"vue": "3.5.26"
}
},
"node_modules/@vue/shared": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz",
"integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/after": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
"integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==",
"license": "MIT"
},
"node_modules/arraybuffer.slice": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
"integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==",
"license": "MIT"
},
"node_modules/backo2": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
"integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==",
"license": "MIT"
},
"node_modules/base64-arraybuffer": { "node_modules/base64-arraybuffer": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
@@ -18,6 +216,31 @@
"node": ">= 0.6.0" "node": ">= 0.6.0"
} }
}, },
"node_modules/blob": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
"integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==",
"license": "MIT"
},
"node_modules/component-bind": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
"integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw=="
},
"node_modules/component-emitter": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
"integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/component-inherit": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
"integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA=="
},
"node_modules/css-line-break": { "node_modules/css-line-break": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
@@ -27,12 +250,106 @@
"utrie": "^1.0.2" "utrie": "^1.0.2"
} }
}, },
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/dayjs": { "node_modules/dayjs": {
"version": "1.11.7", "version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==", "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==",
"dev": true "dev": true
}, },
"node_modules/debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/engine.io-client": {
"version": "3.5.6",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.6.tgz",
"integrity": "sha512-2fDMKiXSU7bGRDCWEw9cHEdRNfoU8cpP6lt+nwJhv72tSJpO7YBsqMqYZ63eVvwX3l9prPl2k/mxhfVhY+SDWg==",
"license": "MIT",
"dependencies": {
"component-emitter": "~1.3.0",
"component-inherit": "0.0.3",
"debug": "~3.1.0",
"engine.io-parser": "~2.2.0",
"has-cors": "1.1.0",
"indexof": "0.0.1",
"parseqs": "0.0.6",
"parseuri": "0.0.6",
"ws": "~7.5.10",
"xmlhttprequest-ssl": "~1.6.2",
"yeast": "0.1.2"
}
},
"node_modules/engine.io-parser": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz",
"integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==",
"license": "MIT",
"dependencies": {
"after": "0.8.2",
"arraybuffer.slice": "~0.0.7",
"base64-arraybuffer": "0.1.4",
"blob": "0.0.5",
"has-binary2": "~1.0.2"
}
},
"node_modules/engine.io-parser/node_modules/base64-arraybuffer": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
"integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/entities": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz",
"integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/has-binary2": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
"integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
"license": "MIT",
"dependencies": {
"isarray": "2.0.1"
}
},
"node_modules/has-cors": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
"integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==",
"license": "MIT"
},
"node_modules/html2canvas": { "node_modules/html2canvas": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
@@ -46,18 +363,157 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/indexof": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
"integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg=="
},
"node_modules/isarray": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
"integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
"license": "MIT"
},
"node_modules/js-md5": { "node_modules/js-md5": {
"version": "0.7.3", "version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
"integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==", "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==",
"dev": true "dev": true
}, },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/parseqs": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
"integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==",
"license": "MIT"
},
"node_modules/parseuri": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
"integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC",
"peer": true
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/qr-image": { "node_modules/qr-image": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz", "resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz",
"integrity": "sha512-rXKDS5Sx3YipVsqmlMJsJsk6jXylEpiHRC2+nJy66fxA5ExYyGa4PqwteW69SaVmAb2OQ18HbYriT7cGQMbduw==", "integrity": "sha512-rXKDS5Sx3YipVsqmlMJsJsk6jXylEpiHRC2+nJy66fxA5ExYyGa4PqwteW69SaVmAb2OQ18HbYriT7cGQMbduw==",
"dev": true "dev": true
}, },
"node_modules/socket.io-client": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz",
"integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==",
"license": "MIT",
"dependencies": {
"backo2": "1.0.2",
"component-bind": "1.0.0",
"component-emitter": "~1.3.0",
"debug": "~3.1.0",
"engine.io-client": "~3.5.0",
"has-binary2": "~1.0.2",
"indexof": "0.0.1",
"parseqs": "0.0.6",
"parseuri": "0.0.6",
"socket.io-parser": "~3.3.0",
"to-array": "0.1.4"
}
},
"node_modules/socket.io-parser": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.4.tgz",
"integrity": "sha512-z/pFQB3x+EZldRRzORYW1vwVO8m/3ILkswtnpoeU6Ve3cbMWkmHEWDAVJn4QJtchiiFTo5j7UG2QvwxvaA9vow==",
"license": "MIT",
"dependencies": {
"component-emitter": "~1.3.0",
"debug": "~3.1.0",
"isarray": "2.0.1"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/text-segmentation": { "node_modules/text-segmentation": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
@@ -67,6 +523,11 @@
"utrie": "^1.0.2" "utrie": "^1.0.2"
} }
}, },
"node_modules/to-array": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
"integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A=="
},
"node_modules/uni-read-pages": { "node_modules/uni-read-pages": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz", "resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz",
@@ -97,6 +558,29 @@
"HBuilderX": "^3.1.0" "HBuilderX": "^3.1.0"
} }
}, },
"node_modules/vue": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz",
"integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.26",
"@vue/compiler-sfc": "3.5.26",
"@vue/runtime-dom": "3.5.26",
"@vue/server-renderer": "3.5.26",
"@vue/shared": "3.5.26"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/vuex": { "node_modules/vuex": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz",
@@ -108,6 +592,41 @@
"peerDependencies": { "peerDependencies": {
"vue": "^3.2.0" "vue": "^3.2.0"
} }
},
"node_modules/ws": {
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"license": "MIT",
"engines": {
"node": ">=8.3.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xmlhttprequest-ssl": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
"integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/yeast": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
"integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==",
"license": "MIT"
} }
} }
} }
+520
View File
@@ -5,6 +5,7 @@
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"socket.io-client": "^2.5.0",
"uview-ui": "^2.0.36" "uview-ui": "^2.0.36"
}, },
"devDependencies": { "devDependencies": {
@@ -17,12 +18,210 @@
"vuex": "^4.1.0" "vuex": "^4.1.0"
} }
}, },
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz",
"integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/types": "^7.28.6"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/types": {
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz",
"integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.28.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/@vue/compiler-core": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz",
"integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/shared": "3.5.26",
"entities": "^7.0.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz",
"integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-core": "3.5.26",
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz",
"integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/compiler-core": "3.5.26",
"@vue/compiler-dom": "3.5.26",
"@vue/compiler-ssr": "3.5.26",
"@vue/shared": "3.5.26",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
"postcss": "^8.5.6",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz",
"integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.26",
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/devtools-api": { "node_modules/@vue/devtools-api": {
"version": "6.5.0", "version": "6.5.0",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==", "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==",
"dev": true "dev": true
}, },
"node_modules/@vue/reactivity": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.26.tgz",
"integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.26.tgz",
"integrity": "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.5.26",
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.26.tgz",
"integrity": "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.5.26",
"@vue/runtime-core": "3.5.26",
"@vue/shared": "3.5.26",
"csstype": "^3.2.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.26.tgz",
"integrity": "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-ssr": "3.5.26",
"@vue/shared": "3.5.26"
},
"peerDependencies": {
"vue": "3.5.26"
}
},
"node_modules/@vue/shared": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz",
"integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/after": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
"integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==",
"license": "MIT"
},
"node_modules/arraybuffer.slice": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
"integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==",
"license": "MIT"
},
"node_modules/backo2": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
"integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==",
"license": "MIT"
},
"node_modules/base64-arraybuffer": { "node_modules/base64-arraybuffer": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
@@ -32,6 +231,31 @@
"node": ">= 0.6.0" "node": ">= 0.6.0"
} }
}, },
"node_modules/blob": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
"integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==",
"license": "MIT"
},
"node_modules/component-bind": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
"integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw=="
},
"node_modules/component-emitter": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
"integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/component-inherit": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
"integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA=="
},
"node_modules/css-line-break": { "node_modules/css-line-break": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
@@ -41,12 +265,106 @@
"utrie": "^1.0.2" "utrie": "^1.0.2"
} }
}, },
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/dayjs": { "node_modules/dayjs": {
"version": "1.11.7", "version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==", "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==",
"dev": true "dev": true
}, },
"node_modules/debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/engine.io-client": {
"version": "3.5.6",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.6.tgz",
"integrity": "sha512-2fDMKiXSU7bGRDCWEw9cHEdRNfoU8cpP6lt+nwJhv72tSJpO7YBsqMqYZ63eVvwX3l9prPl2k/mxhfVhY+SDWg==",
"license": "MIT",
"dependencies": {
"component-emitter": "~1.3.0",
"component-inherit": "0.0.3",
"debug": "~3.1.0",
"engine.io-parser": "~2.2.0",
"has-cors": "1.1.0",
"indexof": "0.0.1",
"parseqs": "0.0.6",
"parseuri": "0.0.6",
"ws": "~7.5.10",
"xmlhttprequest-ssl": "~1.6.2",
"yeast": "0.1.2"
}
},
"node_modules/engine.io-parser": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz",
"integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==",
"license": "MIT",
"dependencies": {
"after": "0.8.2",
"arraybuffer.slice": "~0.0.7",
"base64-arraybuffer": "0.1.4",
"blob": "0.0.5",
"has-binary2": "~1.0.2"
}
},
"node_modules/engine.io-parser/node_modules/base64-arraybuffer": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
"integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/entities": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz",
"integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/has-binary2": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
"integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
"license": "MIT",
"dependencies": {
"isarray": "2.0.1"
}
},
"node_modules/has-cors": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
"integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==",
"license": "MIT"
},
"node_modules/html2canvas": { "node_modules/html2canvas": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
@@ -60,18 +378,157 @@
"node": ">=8.0.0" "node": ">=8.0.0"
} }
}, },
"node_modules/indexof": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
"integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg=="
},
"node_modules/isarray": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
"integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==",
"license": "MIT"
},
"node_modules/js-md5": { "node_modules/js-md5": {
"version": "0.7.3", "version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz", "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
"integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==", "integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==",
"dev": true "dev": true
}, },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/parseqs": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
"integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==",
"license": "MIT"
},
"node_modules/parseuri": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
"integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC",
"peer": true
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/qr-image": { "node_modules/qr-image": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz", "resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz",
"integrity": "sha512-rXKDS5Sx3YipVsqmlMJsJsk6jXylEpiHRC2+nJy66fxA5ExYyGa4PqwteW69SaVmAb2OQ18HbYriT7cGQMbduw==", "integrity": "sha512-rXKDS5Sx3YipVsqmlMJsJsk6jXylEpiHRC2+nJy66fxA5ExYyGa4PqwteW69SaVmAb2OQ18HbYriT7cGQMbduw==",
"dev": true "dev": true
}, },
"node_modules/socket.io-client": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz",
"integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==",
"license": "MIT",
"dependencies": {
"backo2": "1.0.2",
"component-bind": "1.0.0",
"component-emitter": "~1.3.0",
"debug": "~3.1.0",
"engine.io-client": "~3.5.0",
"has-binary2": "~1.0.2",
"indexof": "0.0.1",
"parseqs": "0.0.6",
"parseuri": "0.0.6",
"socket.io-parser": "~3.3.0",
"to-array": "0.1.4"
}
},
"node_modules/socket.io-parser": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.4.tgz",
"integrity": "sha512-z/pFQB3x+EZldRRzORYW1vwVO8m/3ILkswtnpoeU6Ve3cbMWkmHEWDAVJn4QJtchiiFTo5j7UG2QvwxvaA9vow==",
"license": "MIT",
"dependencies": {
"component-emitter": "~1.3.0",
"debug": "~3.1.0",
"isarray": "2.0.1"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/text-segmentation": { "node_modules/text-segmentation": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
@@ -81,6 +538,11 @@
"utrie": "^1.0.2" "utrie": "^1.0.2"
} }
}, },
"node_modules/to-array": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
"integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A=="
},
"node_modules/uni-read-pages": { "node_modules/uni-read-pages": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz", "resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz",
@@ -111,6 +573,29 @@
"HBuilderX": "^3.1.0" "HBuilderX": "^3.1.0"
} }
}, },
"node_modules/vue": {
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz",
"integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.26",
"@vue/compiler-sfc": "3.5.26",
"@vue/runtime-dom": "3.5.26",
"@vue/server-renderer": "3.5.26",
"@vue/shared": "3.5.26"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/vuex": { "node_modules/vuex": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz",
@@ -122,6 +607,41 @@
"peerDependencies": { "peerDependencies": {
"vue": "^3.2.0" "vue": "^3.2.0"
} }
},
"node_modules/ws": {
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"license": "MIT",
"engines": {
"node": ">=8.3.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xmlhttprequest-ssl": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
"integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/yeast": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
"integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==",
"license": "MIT"
} }
} }
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"dependencies": { "dependencies": {
"socket.io-client": "^2.5.0",
"uview-ui": "^2.0.36" "uview-ui": "^2.0.36"
}, },
"devDependencies": { "devDependencies": {
+4 -3
View File
@@ -179,9 +179,10 @@ export default {
uni.navigateTo({ url }); uni.navigateTo({ url });
}, },
goService() { goService() {
// Mock service // 跳转到客服页面
const url = this.$store.state.app.customServiceUrl; uni.navigateTo({
if(url) window.open(url, '_blank'); url: '/pages/user/customservice'
});
}, },
switchCategory(id) { switchCategory(id) {
this.currentCategory = id; this.currentCategory = id;
+473 -69
View File
@@ -1,51 +1,81 @@
<template> <template>
<view class="customservice"> <view class="customservice">
<u-navbar <u-navbar
leftIconColor="#eee" leftIconColor="#d9ac6b"
bgColor="#0c0c0d" bgColor="#1f120e"
:placeholder="true" :placeholder="true"
:fixed="true" :fixed="true"
height="60" height="50"
@leftClick="back" @leftClick="back"
:title="$lang.customerService || '在线客服'"
titleStyle="color: #d9ac6b; font-weight: bold;"
></u-navbar> ></u-navbar>
<view class="cellBox">
<view class="cell"> <!-- 聊天窗口 -->
<u--image <view class="chat-container">
:showLoading="false" <!-- 聊天头部状态 -->
:src="require('static/images/customservice.png')" <view class="chat-header">
width="100%" <view class="chat-status" :class="{'online': sessionId}">
height="auto" {{ sessionId ? ($lang.csConnected || '已连接') : ($lang.csConnecting || '连接中...') }}
mode="widthFix" </view>
class="icon"
></u--image>
<u-link
target="_blank"
:href="customServiceUrl"
text="Online service"
class="lable"
></u-link>
</view> </view>
<view class="cell">
<u--image <!-- 消息列表 -->
:showLoading="false" <scroll-view class="chat-messages" scroll-y :scroll-top="scrollTop" scroll-with-animation>
:src="require('static/images/line.png')" <!-- 欢迎信息 -->
width="100%" <view v-if="!sessionId" class="chat-welcome">
height="auto" <text class="welcome-icon">💬</text>
mode="widthFix" <text class="welcome-title">{{ $lang.csWelcome || '欢迎使用在线客服' }}</text>
class="icon" <text v-if="!isConnected" class="welcome-tip">{{ $lang.csConnecting || '正在连接...' }}</text>
></u--image> <text v-else-if="sessionStatus === 0" class="welcome-tip warning">{{ $lang.csBusy || '客服繁忙请稍候...' }}</text>
<u-link target="_blank" :href="telegramUrl" text="Telegram" class="lable"></u-link> <text v-else class="welcome-tip">{{ $lang.csInputTip || '请输入您的问题' }}</text>
</view> </view>
<view class="cell">
<u--image <!-- 消息列表 -->
:showLoading="false" <view v-for="(msg, index) in messages" :key="index"
:src="require('static/images/telegram.png')" class="chat-message"
width="100%" :class="{
height="auto" 'chat-message-own': msg.senderType === 1,
mode="widthFix" 'chat-message-system': msg.senderType === 0
class="icon" }">
></u--image> <!-- 系统消息 -->
<u-link target="_blank" :href="lineUrl" text="Line" class="lable"></u-link> <view v-if="msg.senderType === 0" class="system-msg">
<text>{{ msg.content }}</text>
</view>
<!-- 普通消息 -->
<view v-else class="message-content">
<view class="message-avatar">
<text v-if="msg.senderType === 1">{{ $lang.csMe || '' }}</text>
<text v-else>{{ $lang.csAgent || '客服' }}</text>
</view>
<view class="message-bubble">
<text class="message-text">{{ msg.content }}</text>
<text class="message-time">{{ formatTime(msg.createTime) }}</text>
</view>
</view>
</view>
<!-- 底部占位 -->
<view style="height: 20px;"></view>
</scroll-view>
<!-- 输入区域 -->
<view class="chat-input-area">
<textarea
v-model="inputMessage"
:placeholder="$lang.csInputPlaceholder || '输入消息,点击发送...'"
:disabled="!isConnected || !sessionId"
class="chat-input"
:maxlength="500"
@confirm="sendMessage"
></textarea>
<view class="chat-actions">
<button
class="chat-btn-send"
@click="sendMessage"
:disabled="!isConnected || !sessionId || !inputMessage.trim()"
>{{ $lang.csSend || '发送' }}</button>
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -53,21 +83,210 @@
<script> <script>
import { mapState } from "vuex"; import { mapState } from "vuex";
import io from 'socket.io-client';
export default { export default {
data() { data() {
return {}; return {
socket: null,
isConnected: false,
sessionId: null,
sessionStatus: null,
messages: [],
inputMessage: '',
scrollTop: 0,
heartbeatTimer: null
};
}, },
computed: { computed: {
...mapState({ ...mapState({
customServiceUrl: state => state.app.customServiceUrl, userInfo: state => state.app.userInfo,
telegramUrl: state => state.app.telegramUrl, sockUrl: state => state.app.sockUrl,
lineUrl: state => state.app.lineUrl $lang: state => state.app.lang[state.app.language]
}) })
}, },
onLoad() {}, onLoad() {
this.connectWebSocket();
},
onUnload() {
this.disconnect();
},
methods: { methods: {
back() { back() {
this.disconnect();
uni.navigateBack(); uni.navigateBack();
},
disconnect() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
}
if (this.socket) {
this.socket.disconnect();
this.socket = null;
}
},
connectWebSocket() {
// 使用 store 中的 sockUrl
const sockUrl = this.sockUrl || 'wss://wss.g7g7.top';
const loginToken = this.userInfo.online_token || this.userInfo.login_token || '';
console.log('[CustomerService] 连接 WebSocket:', sockUrl);
console.log('[CustomerService] loginToken:', loginToken);
console.log('[CustomerService] userInfo:', JSON.stringify(this.userInfo));
// 客服连接:不带 connect=user 参数,避免触发游戏连接逻辑
// 连接成功后通过 chat.connect 事件进行客服认证
this.socket = io(sockUrl, {
transports: ['websocket'],
reconnection: true,
reconnectionDelay: 1000,
reconnectionAttempts: 5
});
this.socket.on('connect', () => {
console.log('[CustomerService] WebSocket 已连接, socket.id:', this.socket.id);
this.isConnected = true;
// 发送客服连接请求,后端通过 chat.connect 事件验证用户
const chatConnectData = {
token: loginToken,
role: 'user',
source: 3 // Portal端
};
console.log('[CustomerService] 发送 chat.connect:', JSON.stringify(chatConnectData));
this.socket.emit('chat.connect', chatConnectData);
// 启动心跳
this.startHeartbeat();
});
this.socket.on('disconnect', (reason) => {
console.log('[CustomerService] WebSocket 已断开, 原因:', reason);
this.isConnected = false;
});
this.socket.on('connect_error', (error) => {
console.log('[CustomerService] 连接错误:', error.message);
this.isConnected = false;
});
this.socket.on('error', (error) => {
console.log('[CustomerService] Socket错误:', error);
});
// 后端 ChatConnect.php 使用下划线格式的事件名
this.socket.on('chat_connected', (data) => {
console.log('[CustomerService] chat_connected:', data);
if (data.success) {
this.sessionId = data.sessionId;
this.sessionStatus = data.status;
if (data.agentInfo) {
this.addSystemMessage((this.$lang.csAgent || '客服') + ' ' + data.agentInfo.nickname + ' ' + (this.$lang.csAgentServing || '为您服务'));
}
} else {
uni.showToast({ title: (this.$lang.csConnectFailed || '连接失败') + ': ' + (data.error || '未知错误'), icon: 'none' });
}
});
this.socket.on('chat.session.assigned', (data) => {
console.log('[CustomerService] chat.session.assigned:', data);
this.sessionStatus = 1;
this.addSystemMessage((this.$lang.csAgent || '客服') + ' ' + data.agentInfo.nickname + ' ' + (this.$lang.csAgentJoined || '已接入'));
});
this.socket.on('chat_message_new', (data) => {
console.log('[CustomerService] chat_message_new:', data);
const msg = data.data || data;
this.messages.push({
msgId: msg.msgId,
senderType: msg.senderType,
msgType: msg.msgType,
content: msg.content,
createTime: msg.createTime || msg.time
});
this.scrollToBottom();
// 发送已读回执
if (msg.msgId) {
this.socket.emit('chat.message.ack', { msgId: msg.msgId });
}
});
this.socket.on('chat.session.ended', () => {
console.log('[CustomerService] chat.session.ended');
this.addSystemMessage(this.$lang.csSessionEnded || '会话已结束');
this.sessionStatus = 2;
});
// 后端使用下划线格式
this.socket.on('chat_offline_notice', (data) => {
console.log('[CustomerService] chat_offline_notice:', data);
this.addSystemMessage(data.message);
});
// 后端使用下划线格式
this.socket.on('chat_pong', () => {
// 心跳响应
});
},
startHeartbeat() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
}
this.heartbeatTimer = setInterval(() => {
if (this.socket && this.socket.connected) {
this.socket.emit('chat.ping', {});
}
}, 25000);
},
sendMessage() {
const content = this.inputMessage.trim();
if (!content || !this.sessionId) return;
const clientMsgId = Date.now();
this.socket.emit('chat.message.send', {
sessionId: this.sessionId,
msgType: 1,
content: content,
clientMsgId: clientMsgId
});
// 乐观更新 UI
this.messages.push({
msgId: clientMsgId,
senderType: 1, // 用户发送
msgType: 1,
content: content,
createTime: Date.now()
});
this.inputMessage = '';
this.scrollToBottom();
},
addSystemMessage(text) {
this.messages.push({
msgId: Date.now(),
senderType: 0,
msgType: 1,
content: text,
createTime: Date.now()
});
this.scrollToBottom();
},
scrollToBottom() {
// 先重置为0,再设置大值,确保Vue检测到变化
this.scrollTop = 0;
this.$nextTick(() => {
this.scrollTop = 999999;
});
},
formatTime(timestamp) {
if (!timestamp) return '';
// 如果是毫秒时间戳
const ts = timestamp > 9999999999 ? timestamp : timestamp * 1000;
const date = new Date(ts);
return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
} }
} }
}; };
@@ -78,37 +297,222 @@ export default {
background: #0b1520; background: #0b1520;
width: 100%; width: 100%;
min-height: 100vh; min-height: 100vh;
::v-deep .u-navbar__content__title { ::v-deep .u-navbar__content__title {
color: #eee; color: #d9ac6b;
font-weight: 600; font-weight: 600;
} }
.cellBox {
position: absolute; /* 聊天容器 */
top: 30%; .chat-container {
left: 50%; position: fixed;
transform: translate(-50%, -50%); top: 50px;
width: 300px; left: 0;
} right: 0;
.cell { bottom: 0;
display: flex; display: flex;
padding: 15px; flex-direction: column;
background: #3d2c22;
}
/* 聊天头部 */
.chat-header {
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center; align-items: center;
// background: #151617; padding: 10px 15px;
color: #deb366; background: #1f120e;
.icon { }
width: 35px;
margin-right: 15px; .chat-status {
padding: 4px 16px;
background: rgba(255, 255, 255, 0.1);
border-radius: 12px;
font-size: 12px;
color: #999;
}
.chat-status.online {
background: rgba(76, 175, 80, 0.3);
color: #4caf50;
}
/* 消息区域 */
.chat-messages {
flex: 1;
padding: 15px;
background: #3d2c22;
overflow: hidden;
height: 0; /* 配合flex:1让scroll-view正常工作 */
}
/* 欢迎信息 */
.chat-welcome {
text-align: center;
padding: 60px 20px;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
.welcome-icon {
font-size: 48px;
} }
.lable {
// border-bottom: 1px solid; .welcome-title {
color: #deb366 !important; font-size: 18px;
font-size: 30px !important; font-weight: bold;
line-height: 30px !important; color: #d9ac6b;
::v-deep span {
border-bottom: 1px solid;
padding-bottom: 4px;
}
} }
.welcome-tip {
font-size: 14px;
color: #999;
}
.welcome-tip.warning {
color: #ff9800;
}
}
/* 消息项 */
.chat-message {
margin-bottom: 15px;
display: flex;
}
.chat-message-own {
justify-content: flex-end;
}
.chat-message-system {
justify-content: center;
}
/* 系统消息 */
.system-msg {
background: rgba(0, 0, 0, 0.3);
color: #999;
font-size: 12px;
padding: 5px 15px;
border-radius: 12px;
}
/* 消息内容 */
.message-content {
display: flex;
align-items: flex-start;
max-width: 80%;
}
.chat-message-own .message-content {
flex-direction: row-reverse;
}
/* 头像 */
.message-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
background: #1f120e;
color: #d9ac6b;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
flex-shrink: 0;
margin: 0 10px;
}
.chat-message-own .message-avatar {
background: linear-gradient(135deg, #d9ac6b 0%, #a67c3d 100%);
color: #1f120e;
}
/* 消息气泡 */
.message-bubble {
background: #2a1f18;
border-radius: 8px;
padding: 10px 12px;
}
.chat-message-own .message-bubble {
background: linear-gradient(135deg, #d9ac6b 0%, #a67c3d 100%);
}
.message-text {
color: #e0e0e0;
font-size: 14px;
line-height: 1.5;
word-break: break-word;
}
.chat-message-own .message-text {
color: #1f120e;
}
.message-time {
font-size: 11px;
color: #777;
margin-top: 5px;
display: block;
text-align: right;
}
.chat-message-own .message-time {
color: rgba(31, 18, 14, 0.6);
}
/* 输入区域 */
.chat-input-area {
flex-shrink: 0;
border-top: 1px solid #2a1f18;
padding: 12px;
background: #1f120e;
padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
.chat-input {
width: 100%;
min-height: 60px;
max-height: 100px;
background: #3d2c22;
border: 1px solid #553e31;
border-radius: 6px;
padding: 10px;
font-size: 14px;
color: #e0e0e0;
box-sizing: border-box;
}
.chat-input[disabled] {
opacity: 0.5;
}
.chat-actions {
display: flex;
justify-content: flex-end;
margin-top: 10px;
}
.chat-btn-send {
padding: 10px 30px;
border: none;
border-radius: 20px;
font-size: 14px;
font-weight: bold;
background: linear-gradient(180deg, #f7ee99 0%, #78681c 50%, #c0b141 100%);
color: #1f120e;
}
.chat-btn-send:active {
opacity: 0.8;
}
.chat-btn-send[disabled] {
opacity: 0.5;
} }
} }
</style> </style>