Compare commits

...
19 Commits
Author SHA1 Message Date
fengshao1227 cc3ea27b1d feat(gameRecords): 会员游戏记录增加洗码量显示 2026-05-29 11:58:31 +08:00
黎小北 b36f75599e 手机端项目整体UI调整修改 2026-05-14 16:45:12 +08:00
testadmin 31996b716f fix: 退出登录清空浏览器历史栈,防止返回键回到游戏页面 2026-05-13 13:49:47 +08:00
testadmin e8f0e2efbe feat: AlinPay 充值改为 iframe 内嵌弹窗,不再跳转外链 2026-04-26 20:37:50 +08:00
testadmin fcda0e1f0d feat: 充值页新增 CCpay 银行QR 第三通道
- recharge.vue: 新增 Ngân hàng QR tab + 银行QR弹窗 + 轮询到账
- api.js: 新增 ccpayDeposit / ccpayOrderStatus 接口
2026-04-20 11:15:47 +08:00
testadmin a81b39aef0 feat(recharge): USDT 提示语明确输入货币为 VND + 新汇率 27100 2026-04-16 23:33:46 +08:00
testadmin 301af6d91c feat(recharge): USDT 通道改为内嵌二维码弹窗,替代跳转 pay.g7g7.top
- 复用 qr-image 库生成 TRC20 地址二维码(YBF 分支已在用,无需新依赖)
- u-popup 内嵌展示:地址/精确金额/QR/倒计时,可一键复制
- 每 3s 轮询 /epay_order_status,成功后刷新用户信息并自动关闭
- 新增 api.epayOrderStatus
- 后端未返回 qrcode 时回退跳转式(向后兼容)
2026-04-16 23:31:52 +08:00
li 99e4265e01 fix(portal): 越南双 tab 按 area_id=3 判断,与 PC 统一
之前只认 pay_channel=='ALIN_VN'(只有 2 个账号),
现在所有 area_id=3 的越南用户都能看到 银行卡/USDT 双 tab。
BC/YBF 分支加 area_id != 3 条件避免重复。
2026-04-15 23:52:37 +08:00
li 91fa85f4ef feat: 越南充值页加 USDT (TRC20) 通道切换
- recharge.vue: 银行卡 / USDT 两个 tab,共用 amount 输入
- api.js: 新增 epayDeposit 调 /epay_online_order

USDT 请求体多传 pay_type='usdt',下单响应同 AlinPay 走 Data.url 跳转
2026-04-15 23:19:16 +08:00
b67b11c181 chore: 杂项更新(gitignore/登录/注册/首页微调)
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-22 12:56:08 +08:00
18a4d03c3a feat: 对接越南AlinPay支付(充值+提现)
- recharge.vue: 新增ALIN_VN充值模板,最低1,000,000 VND
- withdraw.vue: 新增银行卡提现模板,银行列表API加载,最低1,000,000 VND
- api.js: 新增alinDeposit/applyWithdrawBank/getBankListVn接口

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-22 12:55:52 +08:00
li be597042c8 fix: 大厅余额K格式化 + 货币符号改为越南盾₫
- 左上角余额用 $fk() 包裹,≥1000显示为K格式
- 货币符号从 ¥ 改为 ₫(越南盾)
2026-02-11 16:41:43 +08:00
li 27cdc9a568 fix: 大厅限红动态显示+K格式化,在线人数动态计算
- 限红从 item.limit_money 动态拆分显示(上限/下限),不再硬编码
- 上限值≥1000自动显示为K格式(如50000→50K)
- 在线人数改为动态计算(基础800+时段浮动+随机数)
- 注入全局 $fk 方法用于金额K格式化
2026-02-11 16:29:34 +08:00
li 124cbf36ce fix: 牛牛路单改白底+限制最多显示7列,对齐游戏内UI风格 2026-02-11 01:54:05 +08:00
li 87c12ed6c2 style: 优化牛牛路单表格样式,对齐百家乐UI风格 2026-02-11 01:47:55 +08:00
li d0ff375ba7 feat: 牛牛/三卡大厅路单改为表格样式,显示牛型文字和WIN标记 2026-02-11 01:43:15 +08:00
li 88b9e49108 fix: 修复牛牛/三卡路单在大厅不显示的问题,适配nn_waybill数据结构 2026-02-11 01:37:02 +08:00
li 322cc24208 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.
2026-01-29 03:04:52 +08:00
li 14c8cbffcc add 2026-01-26 23:21:30 +08:00
39 changed files with 4829 additions and 787 deletions
+1
View File
@@ -32,3 +32,4 @@ pnpm-debug.log*
*.log
*.tmp
*.temp
.ace-tool/
+119 -28
View File
@@ -5,19 +5,26 @@
['Recharge', 'Withdraw', 'Index', 'User', 'Transfer'].includes(routeName)
"
>
<view
class="item"
:class="{ active: routeName == item.name }"
v-for="(item, index) in list"
:key="index"
@click="goTab(item)"
>
<image
class="icon"
:src="routeName == item.name ? item.selectedIconPath : item.iconPath"
alt=""
></image>
<view class="text">{{ item.text }}</view>
<view class="tab-bar__shell">
<view
class="item"
:class="{ active: routeName == item.name }"
v-for="(item, index) in list"
:key="index"
@click="goTab(item)"
>
<view class="item-inner">
<view class="item-indicator"></view>
<view class="icon-box">
<image
class="icon"
:src="routeName == item.name ? item.selectedIconPath : item.iconPath"
alt=""
></image>
</view>
<view class="text">{{ item.text }}</view>
</view>
</view>
</view>
</view>
</template>
@@ -122,27 +129,111 @@ export default {
left: 0;
right: 0;
bottom: 0;
display: flex;
background: #000;
justify-content: space-between;
height: 50px;
z-index: 99;
padding: 0 8px 4px;
background: linear-gradient(
180deg,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 0.12) 26%,
rgba(0, 0, 0, 0.32) 100%
);
.tab-bar__shell {
display: flex;
justify-content: space-between;
align-items: stretch;
min-height: 56px;
padding: 4px 5px calc(4px + env(safe-area-inset-bottom));
background: linear-gradient(
180deg,
rgba(9, 8, 7, 0.98) 0%,
rgba(2, 2, 2, 0.99) 100%
);
border: 1px solid rgba(226, 193, 117, 0.22);
border-bottom: none;
border-radius: 16px 16px 0 0;
box-shadow: 0 -8px 22px rgba(0, 0, 0, 0.18),
inset 0 1px 0 rgba(255, 243, 212, 0.04);
}
.item {
flex: 1;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
color: #fff;
&.active {
color: #deb366;
min-width: 0;
color: rgba(255, 255, 255, 0.84);
.item-inner {
position: relative;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
min-height: 46px;
margin: 0 1px;
padding: 5px 5px 2px;
border-radius: 14px;
transition: all 0.2s ease;
}
.item-indicator {
position: absolute;
top: -1px;
left: 50%;
width: 20px;
height: 2px;
border-radius: 999px;
background: transparent;
transform: translateX(-50%);
}
.icon-box {
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
transition: all 0.2s ease;
}
.icon {
width: 25px;
height: 25px;
width: 22px;
height: 22px;
}
.text {
font-size: 12px;
padding-top: 2px;
margin-top: 2px;
font-size: 11px;
line-height: 1.2;
letter-spacing: 0.2px;
white-space: nowrap;
transition: all 0.2s ease;
}
&.active {
color: #e8c26f;
.item-inner {
background: linear-gradient(
180deg,
rgba(63, 46, 20, 0.24) 0%,
rgba(30, 22, 13, 0.08) 100%
);
box-shadow: inset 0 1px 0 rgba(255, 236, 192, 0.08);
}
.item-indicator {
background: linear-gradient(90deg, #f4ddb0 0%, #d9ae55 100%);
}
.icon-box {
background: rgba(225, 191, 116, 0.08);
box-shadow: inset 0 1px 0 rgba(255, 244, 219, 0.06);
}
.text {
font-weight: 600;
text-shadow: 0 0 10px rgba(217, 174, 85, 0.1);
}
}
}
}
+23
View File
@@ -72,6 +72,12 @@ var cn = {
commission: "手续费",
amountCannotBe0: "金额不能为0",
submittingApplication: "提交申请中...",
bankName: "银行名称",
accountName: "账户姓名",
accountNumber: "银行卡号",
enterAccountName: "请输入账户姓名",
enterAccountNumber: "请输入银行卡号",
insufficientBalance: "余额不足",
transfer: "划转",
accountBalance: "账户余额",
@@ -86,6 +92,7 @@ var cn = {
user: "我的",
userBalance: "余额",
customerService: "在线客服",
logout: "退出登录",
tip: "提示",
logoutTip: "确认退出登录?",
@@ -150,6 +157,7 @@ var cn = {
tableNumber: "桌台号",
playingMethod: "玩法",
maliang: "码粮",
ximaliang: "洗码量",
result: "结果",
totalBetting: "总投注",
totalWin: "总输赢",
@@ -174,6 +182,21 @@ var cn = {
chooseCoin: "请选择币种",
flagshipHall: "旗舰厅",
liveHall: "现场厅",
// 在线客服
csConnected: "已连接",
csConnecting: "连接中...",
csWelcome: "欢迎使用在线客服",
csBusy: "客服繁忙,请稍候...",
csInputTip: "请输入您的问题",
csInputPlaceholder: "输入消息,点击发送...",
csSend: "发送",
csMe: "我",
csAgent: "客服",
csSessionEnded: "会话已结束",
csAgentServing: "客服为您服务",
csAgentJoined: "已接入",
csConnectFailed: "连接失败",
};
export { cn };
+24 -1
View File
@@ -29,7 +29,7 @@ var en = {
baccarat: "Baccarat",
niuniu: "Bull Bull",
longhu: "D-Tiger",
longhu: "Dragon-Tiger",
lunpan: "Roulette",
threecard: "3-Card",
zhajinghua: "Sedie",
@@ -72,6 +72,12 @@ var en = {
commission: "Commission",
amountCannotBe0: "Amount cannot be 0",
submittingApplication: "Submitting Application...",
bankName: "Bank Name",
accountName: "Account Name",
accountNumber: "Bank Account Number",
enterAccountName: "Please enter account name",
enterAccountNumber: "Please enter bank account number",
insufficientBalance: "Insufficient balance",
transfer: "Transfer",
accountBalance: "Account Balance",
@@ -86,6 +92,7 @@ var en = {
user: "User",
userBalance: "Balance",
customerService: "Customer Service",
logout: "Logout",
tip: "Tip",
logoutTip: "Are you sure to logout?",
@@ -154,6 +161,7 @@ var en = {
tableNumber: "Table Number",
playingMethod: "Playing Method",
maliang: "Rebate",
ximaliang: "Turnover",
result: "Result",
totalBetting: "Total Betting",
totalWin: "Total Win or Lose",
@@ -178,6 +186,21 @@ var en = {
chooseCoin: "Currency",
flagshipHall: "Flagship 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 };
+25 -2
View File
@@ -27,10 +27,10 @@ var In = {
goLogin: "Sudah memiliki akun? Login",
submit: "Kirim",
baccarat: "Baccarat",
baccarat: "Bakarat",
niuniu: "Sapi Sapi",
longhu: "Naga Harimau",
lunpan: "Roulette",
lunpan: "Rolet",
threecard: "3 Kartu",
zhajinghua: "Three Card Poker Nyata",
sedie: "Color Plate Nyata",
@@ -72,6 +72,12 @@ var In = {
commission: "Biaya Administrasi",
amountCannotBe0: "Jumlah tidak boleh 0",
submittingApplication: "Mengirimkan permintaan...",
bankName: "Nama Bank",
accountName: "Nama Rekening",
accountNumber: "Nomor Rekening Bank",
enterAccountName: "Masukkan nama rekening",
enterAccountNumber: "Masukkan nomor rekening bank",
insufficientBalance: "Saldo tidak cukup",
transfer: "Transfer",
accountBalance: "Saldo",
@@ -86,6 +92,7 @@ var In = {
user: "Saya",
userBalance: "Saldo",
customerService: "Layanan Pelanggan",
logout: "Keluar",
tip: "Tips",
logoutTip: "Konfirmasi keluar?",
@@ -150,6 +157,7 @@ var In = {
tableNumber: "Nomor Meja",
playingMethod: "Gameplay",
maliang: "Rabat Komisi",
ximaliang: "Turnover",
result: "Hasil",
totalBetting: "Total Taruhan",
totalWin: "Total Menang/Kalah",
@@ -173,6 +181,21 @@ var In = {
chooseCoin: "Currency",
flagshipHall: "Flagship 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 };
+23
View File
@@ -72,6 +72,12 @@ var kr = {
commission: "수수료",
amountCannotBe0: "금액은 0일 수 없습니다.",
submittingApplication: "신청 제출 중...",
bankName: "은행명",
accountName: "예금주명",
accountNumber: "은행 계좌번호",
enterAccountName: "예금주명을 입력해 주세요",
enterAccountNumber: "은행 계좌번호를 입력해 주세요",
insufficientBalance: "잔액이 부족합니다",
transfer: "전송",
accountBalance: "계정 잔액",
@@ -86,6 +92,7 @@ var kr = {
user: "나의 계정",
userBalance: "잔액",
customerService: "고객 서비스",
logout: "로그아웃",
tip: "알림",
logoutTip: "로그아웃하시겠습니까?",
@@ -150,6 +157,7 @@ var kr = {
tableNumber: "테이블 번호",
playingMethod: "플레이 방법",
maliang: "커미션 반환",
ximaliang: "롤링",
result: "결과",
totalBetting: "총 베팅",
totalWin: "총 승패",
@@ -174,6 +182,21 @@ var kr = {
chooseCoin: "통화를 선택하세요",
flagshipHall: "플래그십 홀",
liveHall: "라이브홀",
// 고객 서비스
csConnected: "연결됨",
csConnecting: "연결 중...",
csWelcome: "고객 서비스에 오신 것을 환영합니다",
csBusy: "상담원이 바빠요. 잠시만 기다려 주세요...",
csInputTip: "질문을 입력해 주세요",
csInputPlaceholder: "메시지를 입력하고 보내세요...",
csSend: "보내기",
csMe: "나",
csAgent: "상담원",
csSessionEnded: "세션 종료",
csAgentServing: "님이 도와드립니다",
csAgentJoined: "님이 참여했습니다",
csConnectFailed: "연결 실패",
};
export { kr };
+24 -1
View File
@@ -30,7 +30,7 @@ var tl = {
baccarat: "บาคาร่า",
niuniu: "วัวกระทิง",
longhu: "มังกรเสือ",
lunpan: "รูเล็ต",
lunpan: "วงล้อ",
threecard: "3 ใบ",
zhajinghua: "ไฮโลออนไลน์ Live",
sedie: "Sedie Live",
@@ -71,6 +71,12 @@ var tl = {
commission: "คอมมิชชัน",
amountCannotBe0: "ยอดไม่สามารถเป็น 0",
submittingApplication: "ยื่นถอนเงิน",
bankName: "ชื่อธนาคาร",
accountName: "ชื่อบัญชี",
accountNumber: "เลขที่บัญชีธนาคาร",
enterAccountName: "กรุณากรอกชื่อบัญชี",
enterAccountNumber: "กรุณากรอกเลขที่บัญชีธนาคาร",
insufficientBalance: "ยอดเงินคงเหลือไม่เพียงพอ",
transfer: "โอน",
accountBalance: "ยอดเงินในบัญชี",
@@ -85,6 +91,7 @@ var tl = {
user: "ผู้ใช้",
userBalance: "ยอด",
customerService: "บริการลูกค้า",
logout: "ออกจากระบบ",
tip: "คำแนะนำ",
logoutTip: "คุณต้องการออกจากระบบหรือไม่",
@@ -149,6 +156,7 @@ var tl = {
tableNumber: "หมายเลขโต๊ะ",
playingMethod: "วิธีเล่น",
maliang: "รับเงินคืน",
ximaliang: "ยอดเทิร์นโอเวอร์",
result: "ผล",
totalBetting: "ยอดเดิมพัน",
totalWin: "ยอดชนะหรือแพ้",
@@ -173,6 +181,21 @@ var tl = {
chooseCoin: "โปรดเลือกสกุลเงิน",
flagshipHall: "แฟล็กชิปฮอลล์",
liveHall: "ฮอลล์สด",
// บริการลูกค้า
csConnected: "เชื่อมต่อแล้ว",
csConnecting: "กำลังเชื่อมต่อ...",
csWelcome: "ยินดีต้อนรับสู่บริการลูกค้า",
csBusy: "เจ้าหน้าที่กำลังยุ่ง กรุณารอสักครู่...",
csInputTip: "กรุณาใส่คำถามของคุณ",
csInputPlaceholder: "พิมพ์ข้อความและส่ง...",
csSend: "ส่ง",
csMe: "ฉัน",
csAgent: "เจ้าหน้าที่",
csSessionEnded: "เซสชันสิ้นสุด",
csAgentServing: "กำลังให้บริการคุณ",
csAgentJoined: "ได้เข้าร่วม",
csConnectFailed: "เชื่อมต่อไม่สำเร็จ",
};
export { tl };
+23
View File
@@ -72,6 +72,12 @@ var tw = {
commission: "手續費",
amountCannotBe0: "金額不能為0",
submittingApplication: "提交申請中...",
bankName: "銀行名稱",
accountName: "賬戶姓名",
accountNumber: "銀行卡號",
enterAccountName: "請輸入賬戶姓名",
enterAccountNumber: "請輸入銀行卡號",
insufficientBalance: "餘額不足",
transfer: "劃轉",
accountBalance: "賬戶餘額",
@@ -86,6 +92,7 @@ var tw = {
user: "我的",
userBalance: "餘額",
customerService: "在線客服",
logout: "退出登錄",
tip: "提示",
logoutTip: "確認退出登錄?",
@@ -150,6 +157,7 @@ var tw = {
tableNumber: "桌台號",
playingMethod: "玩法",
maliang: "碼糧",
ximaliang: "洗碼量",
result: "結果",
totalBetting: "總投注",
totalWin: "總輸贏",
@@ -174,6 +182,21 @@ var tw = {
chooseCoin: "請選擇幣種",
flagshipHall: "旗艦廳",
liveHall: "現場廳",
// 在線客服
csConnected: "已連接",
csConnecting: "連接中...",
csWelcome: "歡迎使用在線客服",
csBusy: "客服繁忙,請稍候...",
csInputTip: "請輸入您的問題",
csInputPlaceholder: "輸入消息,點擊發送...",
csSend: "發送",
csMe: "我",
csAgent: "客服",
csSessionEnded: "會話已結束",
csAgentServing: "客服為您服務",
csAgentJoined: "已接入",
csConnectFailed: "連接失敗",
};
export { tw };
+24 -1
View File
@@ -27,7 +27,7 @@ var yn = {
goLogin: "Đã có tài khoản? Đến đăng nhập",
submit: "Gửi",
baccarat: "Baccarat",
baccarat: "Bài Bạc",
niuniu: "Bò Bò",
longhu: "Rồng Hổ",
lunpan: "Roulette",
@@ -72,6 +72,12 @@ var yn = {
commission: "Phí thủ tục",
amountCannotBe0: "Số tiền không thể bằng 0",
submittingApplication: "Đang gửi yêu cầu...",
bankName: "Tên ngân hàng",
accountName: "Tên tài khoản",
accountNumber: "Số tài khoản ngân hàng",
enterAccountName: "Vui lòng nhập tên tài khoản",
enterAccountNumber: "Vui lòng nhập số tài khoản ngân hàng",
insufficientBalance: "Số dư không đủ",
transfer: "Chuyển khoản",
accountBalance: "Số dư tài khoản",
@@ -86,6 +92,7 @@ var yn = {
user: "Của tôi",
userBalance: "Số dư",
customerService: "Hỗ trợ trực tuyến",
logout: "Đăng xuất",
tip: "Gợi ý",
logoutTip: "Xác nhận đăng xuất?",
@@ -154,6 +161,7 @@ var yn = {
tableNumber: "ID bàn",
playingMethod: "Lối chơi",
maliang: "Phỉnh boa",
ximaliang: "Doanh số cược",
result: "Kết quả",
totalBetting: "Tổng cược",
totalWin: "Tổng thắng thua",
@@ -178,6 +186,21 @@ var yn = {
chooseCoin: "Vui lòng chọn loại tiền tệ",
flagshipHall: "Hội trường hàng đầu",
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 };
+14
View File
@@ -12,6 +12,20 @@ import {
Vue.config.productionTip = false;
Vue.prototype.$api = api;
const formatK = (val) => {
if (val === null || val === undefined || val === '') return val
if (typeof val === 'string' && val.includes('-')) {
return val.split('-').map(s => formatK(isNaN(s) ? s : Number(s))).join('-')
}
const n = Number(val)
if (isNaN(n)) return val
if (n >= 1000 || n <= -1000) {
const k = n / 1000
return (k % 1 === 0 ? k.toFixed(0) : k) + 'K'
}
return val
}
Vue.prototype.$fk = formatK
Vue.use(uView);
Vue.use(router);
App.mpType = "app";
+519
View File
@@ -3,12 +3,210 @@
"lockfileVersion": 3,
"requires": true,
"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": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==",
"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": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
@@ -18,6 +216,31 @@
"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": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
@@ -27,12 +250,106 @@
"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": {
"version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==",
"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": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
@@ -46,18 +363,157 @@
"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": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
"integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==",
"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": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz",
"integrity": "sha512-rXKDS5Sx3YipVsqmlMJsJsk6jXylEpiHRC2+nJy66fxA5ExYyGa4PqwteW69SaVmAb2OQ18HbYriT7cGQMbduw==",
"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": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
@@ -67,6 +523,11 @@
"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": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz",
@@ -97,6 +558,29 @@
"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": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz",
@@ -108,6 +592,41 @@
"peerDependencies": {
"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": {
"": {
"dependencies": {
"socket.io-client": "^2.5.0",
"uview-ui": "^2.0.36"
},
"devDependencies": {
@@ -17,12 +18,210 @@
"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": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==",
"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": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
@@ -32,6 +231,31 @@
"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": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
@@ -41,12 +265,106 @@
"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": {
"version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==",
"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": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
@@ -60,18 +378,157 @@
"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": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
"integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==",
"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": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz",
"integrity": "sha512-rXKDS5Sx3YipVsqmlMJsJsk6jXylEpiHRC2+nJy66fxA5ExYyGa4PqwteW69SaVmAb2OQ18HbYriT7cGQMbduw==",
"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": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
@@ -81,6 +538,11 @@
"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": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/uni-read-pages/-/uni-read-pages-1.0.5.tgz",
@@ -111,6 +573,29 @@
"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": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz",
@@ -122,6 +607,41 @@
"peerDependencies": {
"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": {
"socket.io-client": "^2.5.0",
"uview-ui": "^2.0.36"
},
"devDependencies": {
+653 -245
View File
File diff suppressed because it is too large Load Diff
+171 -76
View File
@@ -1,11 +1,11 @@
<template>
<view class="login">
<div class="langview">
<div class="select" @click="showLangselect(true)">
<view class="langview">
<view class="select" @click="showLangselect(true)">
{{ langList[language] }}
</div>
<div class="select-box" v-show="langselect">
<div
</view>
<view class="select-box" v-show="langselect">
<view
class="option"
v-for="item in Object.keys(langList)"
:key="item"
@@ -13,42 +13,56 @@
@click="choseLang(item)"
>
{{ langList[item] }}
</div>
</div>
</div>
</view>
</view>
</view>
<view class="content">
<view class="logo">
<u--image
:showLoading="false"
:src="loginLogo"
width="125px"
height="119px"
mode="scaleToFill"
></u--image>
<view class="logo-shell">
<view class="logo">
<u--image
:showLoading="false"
:src="loginLogo"
width="125px"
height="119px"
mode="scaleToFill"
></u--image>
</view>
</view>
<u-input
class="input"
v-model="phone"
type="number"
clearable
:placeholder="$lang.enterAccount"
><!--
<view class="phone-code" slot="prefix" @click="countryShow = true">{{
countryData.country_code
}}</view>-->
</u-input>
<u-input
class="input"
v-model="password"
:password="true"
:placeholder="$lang.enterPassword"
>
</u-input>
<view class="btn-box">
<view class="btn" @tap="login('login')">{{ $lang.login }}</view>
<view class="btn" @tap="login('dome')">{{ $lang.dome }}</view>
<view class="panel">
<u-input
class="input"
v-model="phone"
type="text"
clearable
border="none"
color="#f7ecd2"
:placeholder="$lang.enterAccount"
placeholderStyle="color: rgba(245, 228, 184, 0.38); font-size: 14px;"
><!--
<view class="phone-code" slot="prefix" @click="countryShow = true">{{
countryData.country_code
}}</view>-->
</u-input>
<u-input
class="input"
v-model="password"
:password="true"
border="none"
color="#f7ecd2"
:placeholder="$lang.enterPassword"
placeholderStyle="color: rgba(245, 228, 184, 0.38); font-size: 14px;"
>
</u-input>
<view class="btn-box">
<view class="btn btn-primary" @tap="login('login')">{{
$lang.login
}}</view>
<view class="btn btn-secondary" @tap="login('dome')">{{
$lang.dome
}}</view>
</view>
<view class="tip" @tap="goRegister">{{ $lang.goRegister }}</view>
</view>
<view class="tip" @tap="goRegister">{{ $lang.goRegister }}</view>
</view>
<!-- 提示 -->
<u-toast ref="uToast" />
@@ -202,65 +216,126 @@ export default {
overflow-y: auto;
.langview {
position: absolute;
top: 15px;
right: 15px;
top: 16px;
right: 16px;
z-index: 20;
.select {
border-radius: 4px;
width: 90px;
display: inline-block;
font-size: 14px;
color: #cfc189;
line-height: 35px;
background: #212121;
min-width: 96px;
padding: 0 14px;
font-size: 13px;
color: #e8d39b;
line-height: 34px;
background: rgba(15, 12, 10, 0.74);
border: 1px solid rgba(213, 181, 103, 0.18);
border-radius: 10px;
text-align: center;
&:active {
opacity: 0.6;
opacity: 0.82;
}
}
.select-box {
position: absolute;
right: 0;
top: 45px;
width: 90px;
line-height: 30px;
background: #212121;
border-radius: 4px;
top: 40px;
width: 108px;
padding: 4px 0;
line-height: 32px;
background: rgba(15, 12, 10, 0.92);
border: 1px solid rgba(213, 181, 103, 0.18);
border-radius: 10px;
text-align: center;
color: #fff;
font-size: 14px;
color: rgba(255, 246, 226, 0.88);
font-size: 13px;
z-index: 9;
.option {
padding: 0 8px;
}
.option:active {
opacity: 0.6;
}
.active {
color: #cfc189;
color: #e8d39b;
font-weight: bold;
}
}
}
.content {
width: 280px;
padding-bottom: 50px;
width: 86%;
max-width: 326px;
margin: 0 auto;
padding: 94px 0 48px;
.logo-shell {
margin-bottom: 20px;
}
.logo {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
margin-top: 20%;
width: 125px;
height: 119px;
margin: 0 auto;
}
.panel {
position: relative;
padding: 20px 18px 22px;
border-radius: 24px;
background: linear-gradient(
180deg,
rgba(14, 11, 9, 0.9) 0%,
rgba(10, 8, 7, 0.8) 100%
);
border: 1px solid rgba(213, 181, 103, 0.22);
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.24),
inset 0 1px 0 rgba(255, 255, 255, 0.03);
overflow: hidden;
&::before {
content: "";
position: absolute;
top: 0;
left: 18px;
right: 18px;
height: 1px;
background: linear-gradient(
90deg,
rgba(213, 181, 103, 0),
rgba(244, 221, 169, 0.82),
rgba(213, 181, 103, 0)
);
}
}
.input {
height: 30px;
line-height: 30px;
margin-bottom: 15px;
background: #fff;
border-radius: 8px;
height: 50px;
line-height: 50px;
margin-bottom: 14px;
background: rgba(24, 20, 17, 0.96);
border: 1px solid rgba(213, 181, 103, 0.14);
border-radius: 15px;
overflow: hidden;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03),
inset 0 -1px 0 rgba(0, 0, 0, 0.16);
&:last-of-type {
margin-bottom: 0;
}
::v-deep .u-input__content {
min-height: 100%;
padding: 0 15px;
}
::v-deep .u-input__content__field-wrapper {
width: 100%;
}
::v-deep input {
color: #f7ecd2 !important;
font-size: 15px !important;
letter-spacing: 0.2px;
}
::v-deep input::placeholder {
color: rgba(245, 228, 184, 0.42) !important;
}
}
.phone-code {
min-width: 50px;
text-align: center;
border-right: 1px solid #ddd;
border-right: 1px solid rgba(213, 181, 103, 0.18);
}
.btn-box {
margin-top: 20px;
@@ -269,15 +344,33 @@ export default {
height: 48px;
line-height: 48px;
text-align: center;
font-size: 16px;
background: url("~@/static/images/btn_bg.png") no-repeat;
background-size: 100% 100%;
font-weight: 600;
margin-top: 15px;
font-size: 14px;
font-weight: 700;
letter-spacing: 0.5px;
border-radius: 15px;
margin-top: 12px;
&:active {
opacity: 0.8;
opacity: 0.86;
}
}
.btn-primary {
margin-top: 0;
color: #241804;
background: linear-gradient(
180deg,
#f2dfb6 0%,
#dfbd78 52%,
#bd8d39 100%
);
box-shadow: 0 12px 24px rgba(125, 84, 22, 0.24),
inset 0 1px 0 rgba(255, 255, 255, 0.42);
}
.btn-secondary {
color: #ead6a0;
background: rgba(18, 15, 12, 0.92);
border: 1px solid rgba(213, 181, 103, 0.2);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
}
}
}
.country {
@@ -287,12 +380,14 @@ export default {
}
.tip {
font-size: 12px;
color: #b38f3c;
margin-top: 20px;
color: rgba(234, 214, 160, 0.92);
margin-top: 16px;
padding-top: 14px;
border-top: 1px solid rgba(213, 181, 103, 0.1);
text-align: center;
margin-bottom: 20px;
letter-spacing: 0.2px;
&:active {
opacity: 0.6;
opacity: 0.7;
}
}
}
+852 -47
View File
File diff suppressed because it is too large Load Diff
+257 -106
View File
@@ -1,39 +1,103 @@
<template>
<view class="register">
<view class="content">
<view class="logo">
<u--image :showLoading="false" :src="loginLogo" width="125px" height="119px" mode="scaleToFill"></u--image>
</view>
<u-input class="input" :focus='focusUsername' v-model="username" type="number" clearable :placeholder="$lang.enterAccount">
<text class="text" slot="prefix">{{ $lang.account }}</text>
</u-input>
<u-input class="input" :focus='focusPassword' v-model="password" :password="true" :placeholder="$lang.enterPassword" autocomplete="new-password">
<text class="text" slot="prefix">{{ $lang.password }}</text>
</u-input>
<u-input class="input" :focus='focusRepass' v-model="repass" :password="true" :placeholder="$lang.enterPasswordAgain">
<text class="text" slot="prefix">{{ $lang.confirmPassword }}</text>
</u-input>
<u-input class="input" :focus='focusPhone' v-model="phone" type="number" clearable
:placeholder="`${$lang.enterPhone}`">
<view class="phone-code" slot="prefix" @click="countryShow = true">
{{ countryData.country_code }}
</view>
</u-input>
<u-input class="input" v-model="referral_code" placeholder="TC176852" :disabled="referral_disabled">
<text class="text" slot="prefix">{{ $lang.invitationCode }}</text>
</u-input>
<view class="btn-box">
<view class="btn" @tap="register()">{{ $lang.register }}</view>
</view>
<view class="tip" @tap="goLogin">{{ $lang.goLogin }}</view>
</view>
<!-- 提示 -->
<u-toast ref="uToast" />
<!-- 区号 -->
<country-code class="country" :show="countryShow" :anchor="countryData.anchor_index"
:country="countryData.country_en" @select="selectCountryTap" @close="countryShow = false"></country-code>
<view class="mb60"></view>
</view>
<view class="register">
<view class="content">
<view class="logo-shell">
<view class="logo">
<u--image
:showLoading="false"
:src="loginLogo"
width="125px"
height="119px"
mode="scaleToFill"
></u--image>
</view>
</view>
<view class="panel">
<u-input
class="input"
:focus="focusUsername"
v-model="username"
type="text"
clearable
border="none"
color="#f7ecd2"
:placeholder="$lang.enterAccount"
placeholderStyle="color: rgba(245, 228, 184, 0.42); font-size: 14px;"
>
<text class="text" slot="prefix">{{ $lang.account }}</text>
</u-input>
<u-input
class="input"
:focus="focusPassword"
v-model="password"
:password="true"
border="none"
color="#f7ecd2"
:placeholder="$lang.enterPassword"
autocomplete="new-password"
placeholderStyle="color: rgba(245, 228, 184, 0.42); font-size: 14px;"
>
<text class="text" slot="prefix">{{ $lang.password }}</text>
</u-input>
<u-input
class="input"
:focus="focusRepass"
v-model="repass"
:password="true"
border="none"
color="#f7ecd2"
:placeholder="$lang.enterPasswordAgain"
placeholderStyle="color: rgba(245, 228, 184, 0.42); font-size: 14px;"
>
<text class="text" slot="prefix">{{ $lang.confirmPassword }}</text>
</u-input>
<u-input
class="input"
:focus="focusPhone"
v-model="phone"
type="number"
clearable
border="none"
color="#f7ecd2"
:placeholder="`${$lang.enterPhone}`"
placeholderStyle="color: rgba(245, 228, 184, 0.42); font-size: 14px;"
>
<view class="phone-code" slot="prefix" @click="countryShow = true">
{{ countryData.country_code }}
</view>
</u-input>
<u-input
class="input"
v-model="referral_code"
border="none"
color="#f7ecd2"
placeholder="TC176852"
placeholderStyle="color: rgba(245, 228, 184, 0.42); font-size: 14px;"
:disabled="referral_disabled"
>
<text class="text" slot="prefix">{{ $lang.invitationCode }}</text>
</u-input>
<view class="btn-box">
<view class="btn btn-primary" @tap="register()">{{
$lang.register
}}</view>
</view>
<view class="tip" @tap="goLogin">{{ $lang.goLogin }}</view>
</view>
</view>
<!-- 提示 -->
<u-toast ref="uToast" />
<!-- 区号 -->
<country-code
class="country"
:show="countryShow"
:anchor="countryData.anchor_index"
:country="countryData.country_en"
@select="selectCountryTap"
@close="countryShow = false"
></country-code>
<view class="mb60"></view>
</view>
</template>
<script>
@@ -165,86 +229,173 @@
</script>
<style lang="scss" scoped>
.register {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
background: url("~@/static/images/login_bg.png") no-repeat;
background-size: 100% auto;
background-position: bottom left;
overflow-y: auto;
.register {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
background: url("~@/static/images/login_bg.png") no-repeat;
background-size: 100% auto;
background-position: bottom left;
overflow-y: auto;
.content {
width: 280px;
padding-bottom: 50px;
margin: 0 auto;
.content {
width: 86%;
max-width: 326px;
margin: 0 auto;
padding: 94px 0 48px;
.logo {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
margin-top: 20%;
}
.logo-shell {
margin-bottom: 20px;
}
.input {
height: 30px;
line-height: 30px;
margin-bottom: 15px;
background: #fff;
border-radius: 8px;
overflow: hidden;
}
.logo {
display: flex;
align-items: center;
justify-content: center;
width: 125px;
height: 119px;
margin: 0 auto;
}
.phone-code {
min-width: 50px;
text-align: center;
border-right: 1px solid #ddd;
}
.panel {
position: relative;
padding: 20px 18px 22px;
border-radius: 24px;
background: linear-gradient(
180deg,
rgba(14, 11, 9, 0.9) 0%,
rgba(10, 8, 7, 0.8) 100%
);
border: 1px solid rgba(213, 181, 103, 0.22);
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.24),
inset 0 1px 0 rgba(255, 255, 255, 0.03);
overflow: hidden;
.text {
padding-right: 5px;
}
&::before {
content: "";
position: absolute;
top: 0;
left: 18px;
right: 18px;
height: 1px;
background: linear-gradient(
90deg,
rgba(213, 181, 103, 0),
rgba(244, 221, 169, 0.82),
rgba(213, 181, 103, 0)
);
}
}
.btn-box {
margin-top: 20px;
.input {
height: 50px;
line-height: 50px;
margin-bottom: 14px;
background: rgba(24, 20, 17, 0.96);
border: 1px solid rgba(213, 181, 103, 0.14);
border-radius: 15px;
overflow: hidden;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03),
inset 0 -1px 0 rgba(0, 0, 0, 0.16);
.btn {
width: 100%;
height: 48px;
line-height: 48px;
text-align: center;
font-size: 16px;
background: url("~@/static/images/btn_bg.png") no-repeat;
background-size: 100% 100%;
font-weight: 600;
margin-top: 15px;
&:last-of-type {
margin-bottom: 0;
}
&:active {
opacity: 0.8;
}
}
}
}
::v-deep .u-input__content {
min-height: 100%;
padding: 0 15px;
}
.country {
position: fixed;
bottom: 0;
left: 0;
}
::v-deep .u-input__content__field-wrapper {
width: 100%;
}
.tip {
font-size: 12px;
color: #b38f3c;
margin-top: 20px;
text-align: center;
margin-bottom: 20px;
::v-deep input {
color: #f7ecd2 !important;
font-size: 15px !important;
letter-spacing: 0.2px;
}
&:active {
opacity: 0.6;
}
}
}
::v-deep input::placeholder {
color: rgba(245, 228, 184, 0.42) !important;
}
::v-deep .u-input__content__prefix-icon,
::v-deep .u-input__content__subfix-icon {
color: #e8d39b !important;
}
}
.phone-code {
min-width: 58px;
margin-right: 12px;
padding-right: 12px;
text-align: center;
font-size: 13px;
color: #e8d39b;
border-right: 1px solid rgba(213, 181, 103, 0.18);
}
.text {
min-width: 74px;
margin-right: 12px;
font-size: 13px;
color: rgba(232, 211, 155, 0.92);
}
.btn-box {
margin-top: 20px;
.btn {
width: 100%;
height: 48px;
line-height: 48px;
text-align: center;
font-size: 14px;
font-weight: 700;
letter-spacing: 0.5px;
border-radius: 15px;
&:active {
opacity: 0.86;
}
}
.btn-primary {
color: #241804;
background: linear-gradient(
180deg,
#f2dfb6 0%,
#dfbd78 52%,
#bd8d39 100%
);
box-shadow: 0 12px 24px rgba(125, 84, 22, 0.24),
inset 0 1px 0 rgba(255, 255, 255, 0.42);
}
}
}
.country {
position: fixed;
bottom: 0;
left: 0;
}
.tip {
font-size: 12px;
color: rgba(234, 214, 160, 0.92);
margin-top: 16px;
padding-top: 14px;
border-top: 1px solid rgba(213, 181, 103, 0.1);
text-align: center;
letter-spacing: 0.2px;
&:active {
opacity: 0.7;
}
}
}
</style>
+473 -69
View File
@@ -1,51 +1,81 @@
<template>
<view class="customservice">
<u-navbar
leftIconColor="#eee"
bgColor="#0c0c0d"
leftIconColor="#d9ac6b"
bgColor="#1f120e"
:placeholder="true"
:fixed="true"
height="60"
height="50"
@leftClick="back"
:title="$lang.customerService || '在线客服'"
titleStyle="color: #d9ac6b; font-weight: bold;"
></u-navbar>
<view class="cellBox">
<view class="cell">
<u--image
:showLoading="false"
:src="require('static/images/customservice.png')"
width="100%"
height="auto"
mode="widthFix"
class="icon"
></u--image>
<u-link
target="_blank"
:href="customServiceUrl"
text="Online service"
class="lable"
></u-link>
<!-- 聊天窗口 -->
<view class="chat-container">
<!-- 聊天头部状态 -->
<view class="chat-header">
<view class="chat-status" :class="{'online': sessionId}">
{{ sessionId ? ($lang.csConnected || '已连接') : ($lang.csConnecting || '连接中...') }}
</view>
</view>
<view class="cell">
<u--image
:showLoading="false"
:src="require('static/images/line.png')"
width="100%"
height="auto"
mode="widthFix"
class="icon"
></u--image>
<u-link target="_blank" :href="telegramUrl" text="Telegram" class="lable"></u-link>
</view>
<view class="cell">
<u--image
:showLoading="false"
:src="require('static/images/telegram.png')"
width="100%"
height="auto"
mode="widthFix"
class="icon"
></u--image>
<u-link target="_blank" :href="lineUrl" text="Line" class="lable"></u-link>
<!-- 消息列表 -->
<scroll-view class="chat-messages" scroll-y :scroll-top="scrollTop" scroll-with-animation>
<!-- 欢迎信息 -->
<view v-if="!sessionId" class="chat-welcome">
<text class="welcome-icon">💬</text>
<text class="welcome-title">{{ $lang.csWelcome || '欢迎使用在线客服' }}</text>
<text v-if="!isConnected" class="welcome-tip">{{ $lang.csConnecting || '正在连接...' }}</text>
<text v-else-if="sessionStatus === 0" class="welcome-tip warning">{{ $lang.csBusy || '客服繁忙请稍候...' }}</text>
<text v-else class="welcome-tip">{{ $lang.csInputTip || '请输入您的问题' }}</text>
</view>
<!-- 消息列表 -->
<view v-for="(msg, index) in messages" :key="index"
class="chat-message"
:class="{
'chat-message-own': msg.senderType === 1,
'chat-message-system': msg.senderType === 0
}">
<!-- 系统消息 -->
<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>
@@ -53,21 +83,210 @@
<script>
import { mapState } from "vuex";
import io from 'socket.io-client';
export default {
data() {
return {};
return {
socket: null,
isConnected: false,
sessionId: null,
sessionStatus: null,
messages: [],
inputMessage: '',
scrollTop: 0,
heartbeatTimer: null
};
},
computed: {
...mapState({
customServiceUrl: state => state.app.customServiceUrl,
telegramUrl: state => state.app.telegramUrl,
lineUrl: state => state.app.lineUrl
userInfo: state => state.app.userInfo,
sockUrl: state => state.app.sockUrl,
$lang: state => state.app.lang[state.app.language]
})
},
onLoad() {},
onLoad() {
this.connectWebSocket();
},
onUnload() {
this.disconnect();
},
methods: {
back() {
this.disconnect();
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;
width: 100%;
min-height: 100vh;
::v-deep .u-navbar__content__title {
color: #eee;
color: #d9ac6b;
font-weight: 600;
}
.cellBox {
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
}
.cell {
/* 聊天容器 */
.chat-container {
position: fixed;
top: 50px;
left: 0;
right: 0;
bottom: 0;
display: flex;
padding: 15px;
flex-direction: column;
background: #3d2c22;
}
/* 聊天头部 */
.chat-header {
flex-shrink: 0;
display: flex;
justify-content: center;
align-items: center;
// background: #151617;
color: #deb366;
.icon {
width: 35px;
margin-right: 15px;
padding: 10px 15px;
background: #1f120e;
}
.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;
color: #deb366 !important;
font-size: 30px !important;
line-height: 30px !important;
::v-deep span {
border-bottom: 1px solid;
padding-bottom: 4px;
}
.welcome-title {
font-size: 18px;
font-weight: bold;
color: #d9ac6b;
}
.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>
+3
View File
@@ -44,6 +44,9 @@
{{ $lang.tableNumber }} {{ item.table_name }}
</view>
<view class="box">{{ $lang.playingMethod }} {{ item.user_bet }}</view>
<view class="box" v-if="item.ximaliang"
>{{ $lang.ximaliang }} {{ item.ximaliang }}</view
>
<view class="box" v-if="item.maliang"
>{{ $lang.maliang }} {{ item.maliang }}</view
>
+485 -99
View File
@@ -1,70 +1,105 @@
<template>
<view class="user">
<view class="card">
<view class="uid">ID:{{ userInfo.username }}</view>
<u--image
class="logo"
:showLoading="true"
:src="loginLogo"
width="50px"
height="auto"
mode="widthFix"
></u--image>
<view class="box">
<view class="text">{{ $lang.userBalance }}</view>
<view class="money">{{ money }}</view>
<view class="hero">
<view class="card">
<view class="card-sheen"></view>
<view class="card-orb"></view>
<view class="card-grid"></view>
<view class="card-head">
<view class="uid">ID:{{ userInfo.username }}</view>
<view class="logo-shell">
<u--image
class="logo"
:showLoading="true"
:src="loginLogo"
width="42px"
height="42px"
mode="scaleToFill"
></u--image>
</view>
</view>
<view class="box">
<view class="text">{{ $lang.userBalance }}</view>
<view class="money-row">
<view class="money-icon"></view>
<view class="money">{{ money }}</view>
</view>
</view>
</view>
<u--image
:showLoading="false"
:src="require('static/images/card_bg.png')"
width="100%"
height="auto"
mode="widthFix"
></u--image>
</view>
<view class="content">
<view
class="cell"
v-for="(item, index) in userMenu"
:key="index"
@click="goPath(item)"
>
<view class="lab">{{ item.name }}</view>
<u-icon
class="icon"
name="arrow-right"
color="#757272"
size="16"
></u-icon>
<view class="section-title">{{ $lang.tip }}</view>
<view class="menu-panel">
<view
class="cell"
v-for="(item, index) in userMenu"
:key="index"
@click="goPath(item)"
>
<view class="cell-left">
<view class="cell-dot"></view>
<view class="lab">{{ item.name }}</view>
</view>
<u-icon
class="icon"
name="arrow-right"
color="#b9aa84"
size="16"
></u-icon>
</view>
</view>
<view class="logout" @tap="modalShow = true">{{ $lang.logout }}</view>
</view>
<u-picker
:title="$lang.languageSettings"
closeOnClickOverlay
:defaultIndex="defaultIndex"
<u-popup
:show="show"
:columns="langList"
:cancelText="$lang.cancel"
:confirmText="$lang.confirm"
keyName="name"
@close="show = false"
@cancel="show = false"
@confirm="confirm"
></u-picker>
<u-modal
:show="modalShow"
:title="$lang.tip"
:confirmText="$lang.confirm"
:cancelText="$lang.cancel"
@confirm="confirmLogout"
@cancel="modalShow = false"
:showCancelButton="true"
ref="uModal"
:asyncClose="true"
mode="bottom"
round="20"
closeOnClickOverlay
@close="closeLangPopup"
>
<view style="text-align: center">{{ $lang.logoutTip }}</view>
</u-modal>
<view class="lang-popup">
<view class="popup-header">
<view class="popup-action cancel" @click="closeLangPopup">{{
$lang.cancel
}}</view>
<view class="popup-title">{{ $lang.languageSettings }}</view>
<view class="popup-action confirm" @click="confirmLanguageSelection">{{
$lang.confirm
}}</view>
</view>
<scroll-view scroll-y class="popup-list">
<view
class="popup-item"
:class="{ active: tempLanguageKey === item.key }"
v-for="item in langList[0]"
:key="item.key"
@click="tempLanguageKey = item.key"
>
<text>{{ item.name }}</text>
<u-icon
v-if="tempLanguageKey === item.key"
name="checkmark"
color="#231705"
size="16"
></u-icon>
</view>
</scroll-view>
</view>
</u-popup>
<u-popup :show="modalShow" mode="center" round="20" @close="closeLogoutModal">
<view class="logout-modal">
<view class="logout-title">{{ $lang.tip }}</view>
<view class="logout-text">{{ $lang.logoutTip }}</view>
<view class="logout-actions">
<view class="logout-btn logout-btn-cancel" @click="closeLogoutModal">{{
$lang.cancel
}}</view>
<view class="logout-btn logout-btn-confirm" @click="confirmLogout">{{
$lang.confirm
}}</view>
</view>
</view>
</u-popup>
<view class="mb60"></view>
</view>
</template>
@@ -78,6 +113,7 @@ export default {
modalShow: false,
defaultIndex: [0],
tempLanguageKey: "cn",
langList: [
[
{ key: "en", name: "English" },
@@ -121,6 +157,7 @@ export default {
this.defaultIndex = [i];
}
});
this.tempLanguageKey = this.language;
this.getUserMoneyData()
},
methods: {
@@ -128,8 +165,22 @@ export default {
this.$store.commit("app/updateLanguage", item.value[0].key);
this.show = false;
},
closeLangPopup() {
this.tempLanguageKey = this.language;
this.show = false;
},
confirmLanguageSelection() {
if (this.tempLanguageKey) {
this.$store.commit("app/updateLanguage", this.tempLanguageKey);
}
this.show = false;
},
closeLogoutModal() {
this.modalShow = false;
},
goPath(item) {
if (item.id == 0) {
this.tempLanguageKey = this.language;
this.show = true;
} else if (item.id == 4 || item.id == 5 || item.id == 6) {
uni.switchTab({
@@ -149,8 +200,13 @@ export default {
}
},
confirmLogout() {
this.modalShow = false;
localStorage.removeItem("userInfo");
this.$router.replace({ path: "/" });
localStorage.removeItem("uni_id_token");
sessionStorage.clear();
const backSteps = window.history.length - 1;
window.history.go(-backSteps);
setTimeout(() => { window.location.replace("/"); }, 200);
},
getUserMoneyData() {
var that = this
@@ -179,83 +235,413 @@ export default {
<style lang="scss" scoped>
.user {
background: #0b1520;
width: 100%;
min-height: 100vh;
background: linear-gradient(180deg, #060505 0%, #0d0b09 100%);
color: #f7ecd0;
.hero {
padding: 14px 12px 0;
}
.card {
width: 100%;
padding: 10px;
box-sizing: border-box;
position: relative;
overflow: hidden;
border-radius: 28px;
min-height: 188px;
border: 1px solid rgba(226, 193, 117, 0.22);
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.24),
inset 0 1px 0 rgba(255, 245, 223, 0.08);
background: linear-gradient(
180deg,
#f1d488 0%,
#ddaf4e 42%,
#c78f28 100%
);
&::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.2) 0%,
rgba(255, 255, 255, 0.04) 26%,
rgba(133, 88, 16, 0.08) 60%,
rgba(78, 50, 8, 0.18) 100%
);
pointer-events: none;
}
.card-sheen {
position: absolute;
top: -22px;
right: -36px;
width: 180px;
height: 180px;
border-radius: 50%;
background: radial-gradient(
circle,
rgba(255, 247, 218, 0.34) 0%,
rgba(255, 247, 218, 0.06) 46%,
rgba(255, 247, 218, 0) 74%
);
pointer-events: none;
}
.card-orb {
position: absolute;
left: -34px;
bottom: -48px;
width: 150px;
height: 150px;
border-radius: 50%;
background: radial-gradient(
circle,
rgba(169, 107, 20, 0.24) 0%,
rgba(169, 107, 20, 0.08) 45%,
rgba(169, 107, 20, 0) 76%
);
pointer-events: none;
}
.card-grid {
position: absolute;
inset: 0;
background-image: linear-gradient(
135deg,
rgba(255, 241, 204, 0.14) 12%,
transparent 12%,
transparent 50%,
rgba(160, 107, 22, 0.08) 50%,
rgba(160, 107, 22, 0.08) 62%,
transparent 62%
),
linear-gradient(
28deg,
rgba(255, 247, 228, 0.08) 14%,
transparent 14%,
transparent 56%,
rgba(149, 98, 21, 0.08) 56%,
rgba(149, 98, 21, 0.08) 70%,
transparent 70%
);
background-size: 180px 180px, 220px 220px;
opacity: 0.7;
pointer-events: none;
}
.card-head {
position: absolute;
top: 16px;
left: 16px;
right: 16px;
z-index: 3;
display: flex;
align-items: center;
justify-content: space-between;
}
.uid {
position: absolute;
left: 30px;
top: 25px;
z-index: 3;
font-size: 14px;
color: #573d14;
max-width: calc(100% - 82px);
padding: 8px 14px;
border-radius: 999px;
background: rgba(84, 64, 25, 0.38);
border: 1px solid rgba(113, 82, 24, 0.12);
color: rgba(92, 61, 12, 0.92);
font-size: 13px;
font-weight: 700;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.logo-shell {
width: 52px;
height: 52px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 16px;
background: rgba(255, 247, 224, 0.12);
border: 1px solid rgba(115, 81, 18, 0.1);
backdrop-filter: blur(2px);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.logo {
position: absolute;
right: 25px;
top: 20px;
z-index: 3;
opacity: 0.96;
border-radius: 14px;
}
.box {
position: absolute;
left: 50%;
top: 50%;
top: 55%;
z-index: 3;
transform: translate(-50%, -50%);
font-size: 18px;
font-weight: 600;
color: #573d14;
width: calc(100% - 52px);
text-align: center;
.money {
padding-left: 38px;
padding-right: 36px;
padding-top: 10px;
padding-bottom: 4px;
color: #5d4312;
.text {
font-size: 16px;
font-weight: 600;
letter-spacing: 0.2px;
}
.money-row {
width: fit-content;
max-width: 100%;
margin: 10px auto 0;
display: flex;
align-items: center;
gap: 8px;
}
.money-icon {
width: 28px;
height: 28px;
flex-shrink: 0;
background: url("/static/images/balance_icon.png") no-repeat;
background-size: 33px auto;
background-position: left top;
background-size: 28px auto;
background-position: center;
}
.money {
padding: 0;
font-size: 30px;
font-weight: 700;
line-height: 1.1;
white-space: nowrap;
letter-spacing: 0.3px;
}
}
}
.content {
margin: 20px 15px;
border-radius: 5px;
overflow: hidden;
margin: 18px 12px 0;
.section-title {
margin: 0 2px 12px;
font-size: 13px;
color: #a9956d;
letter-spacing: 0.3px;
}
.menu-panel {
border-radius: 24px;
overflow: hidden;
background: linear-gradient(
180deg,
rgba(16, 13, 11, 0.96) 0%,
rgba(10, 8, 7, 0.96) 100%
);
border: 1px solid rgba(223, 189, 120, 0.12);
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.18),
inset 0 1px 0 rgba(255, 245, 223, 0.03);
}
.cell {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 16px;
padding: 15px 10px;
color: #deb366;
border-bottom: 1px solid #594522;
background: #151617;
min-height: 58px;
padding: 0 16px;
color: #e1c483;
border-bottom: 1px solid rgba(223, 189, 120, 0.08);
background: rgba(19, 17, 15, 0.82);
&:active {
opacity: 0.8;
opacity: 0.82;
}
&:last-child {
border-bottom: none;
}
.cell-left {
display: flex;
align-items: center;
gap: 12px;
min-width: 0;
}
.cell-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: linear-gradient(180deg, #f2dfb6 0%, #dfbd78 52%, #bd8d39 100%);
box-shadow: 0 0 0 4px rgba(223, 189, 120, 0.06);
}
.lab {
font-size: 15px;
font-weight: 600;
color: #e0c283;
}
.icon {
flex-shrink: 0;
}
}
.logout {
width: 100%;
height: 48px;
line-height: 48px;
height: 50px;
line-height: 50px;
text-align: center;
font-size: 16px;
background: #e5b932;
font-weight: 600;
margin: 20px auto;
border-radius: 5px;
font-size: 15px;
color: #231705;
background: linear-gradient(180deg, #f2dfb6 0%, #dfbd78 52%, #bd8d39 100%);
font-weight: 700;
letter-spacing: 0.3px;
margin: 18px auto 0;
border-radius: 16px;
box-shadow: 0 12px 24px rgba(125, 84, 22, 0.18),
inset 0 1px 0 rgba(255, 255, 255, 0.36);
&:active {
opacity: 0.8;
opacity: 0.86;
}
}
}
.lang-popup {
background: linear-gradient(180deg, #17130f 0%, #0d0b09 100%);
border-top: 1px solid rgba(223, 189, 120, 0.14);
border-radius: 20px 20px 0 0;
overflow: hidden;
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 54px;
padding: 0 16px;
border-bottom: 1px solid rgba(223, 189, 120, 0.1);
background: rgba(21, 18, 15, 0.96);
}
.popup-title {
font-size: 16px;
font-weight: 700;
color: #f4dfae;
}
.popup-action {
min-width: 52px;
font-size: 14px;
line-height: 1;
&.cancel {
color: #a9956d;
text-align: left;
}
&.confirm {
color: #dfbd78;
text-align: right;
}
}
.popup-list {
max-height: 50vh;
padding: 10px 12px calc(18px + env(safe-area-inset-bottom));
box-sizing: border-box;
}
.popup-item {
min-height: 48px;
padding: 0 14px;
margin-bottom: 10px;
border-radius: 14px;
display: flex;
align-items: center;
justify-content: space-between;
color: #d9c6a0;
font-size: 15px;
font-weight: 600;
background: linear-gradient(
180deg,
rgba(25, 21, 18, 0.96) 0%,
rgba(17, 14, 12, 0.96) 100%
);
border: 1px solid rgba(223, 189, 120, 0.12);
box-shadow: inset 0 1px 0 rgba(255, 244, 220, 0.03);
&:last-child {
margin-bottom: 0;
}
&.active {
color: #231705;
background: linear-gradient(180deg, #f2dfb6 0%, #dfbd78 52%, #bd8d39 100%);
border-color: rgba(242, 223, 182, 0.45);
box-shadow: 0 10px 20px rgba(125, 84, 22, 0.16),
inset 0 1px 0 rgba(255, 255, 255, 0.28);
}
}
.logout-modal {
width: 620rpx;
padding: 34rpx 34rpx 28rpx;
background: linear-gradient(
180deg,
rgba(20, 16, 12, 0.98) 0%,
rgba(11, 9, 7, 0.98) 100%
);
border: 1rpx solid rgba(223, 189, 120, 0.18);
border-radius: 20rpx;
box-sizing: border-box;
box-shadow: 0 24rpx 60rpx rgba(0, 0, 0, 0.3);
}
.logout-title {
text-align: center;
font-size: 30rpx;
font-weight: 700;
color: #f4dfae;
}
.logout-text {
margin-top: 18rpx;
color: #d9c6a0;
font-size: 24rpx;
line-height: 1.7;
text-align: center;
}
.logout-actions {
display: flex;
gap: 16rpx;
margin-top: 28rpx;
}
.logout-btn {
flex: 1;
height: 78rpx;
border-radius: 14rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
font-weight: 700;
&.logout-btn-cancel {
color: #d9c6a0;
background: rgba(255, 255, 255, 0.03);
border: 1rpx solid rgba(223, 189, 120, 0.12);
}
&.logout-btn-confirm {
color: #231705;
background: linear-gradient(180deg, #f2dfb6 0%, #dfbd78 52%, #bd8d39 100%);
box-shadow: 0 10rpx 20rpx rgba(125, 84, 22, 0.16),
inset 0 1px 0 rgba(255, 255, 255, 0.28);
}
}
}
</style>
+567 -112
View File
@@ -2,7 +2,7 @@
<view class="withdraw">
<u-navbar
title=""
bgColor="#000"
bgColor="transparent"
:placeholder="true"
:fixed="true"
leftIcon=""
@@ -18,77 +18,186 @@
>{{ $lang.balance }}{{ userInfo.money }}</view
>
</view>
<view class="picker-view" @click="show = true">
<u-input
readonly
:placeholder="$lang.pleaseChoose"
color="#93979b"
v-model="type"
border="none"
<!-- USDT 提现 -->
<template v-if="userInfo.pay_channel != 'ALIN_VN'">
<view class="picker-view" @click="show = true">
<u-input
readonly
:placeholder="$lang.pleaseChoose"
color="#f7ecd0"
v-model="type"
border="none"
>
<u--text
:text="$lang.chooseWithdraw"
slot="prefix"
margin="0 3px 0 0"
type="tips"
></u--text>
<u-icon
slot="suffix"
name="arrow-down-fill"
color="#b9aa84"
size="16"
></u-icon>
</u-input>
</view>
<u-picker
:title="$lang.pleaseChooseWithdraw"
closeOnClickOverlay
:show="show"
:columns="columns"
:cancelText="$lang.cancel"
:confirmText="$lang.confirm"
@cancel="close"
@close="close"
@confirm="confirm"
></u-picker>
<view class="list">
<view class="lable">{{ $lang.walletAddress }}</view>
<u-input
class="input"
color="#f7ecd0"
clearable
:placeholder="$lang.enterWithdrawalAddress"
border="none"
v-model="address"
></u-input>
</view>
<view class="list">
<view class="lable">{{ $lang.amount }}</view>
<u-input
class="input"
color="#f7ecd0"
clearable
:placeholder="$lang.enterWithdrawalamount"
border="none"
v-model="money"
></u-input>
</view>
<view class="list">
<view class="lab">{{ $lang.rechargeWithdrawNetwork }}</view>
<view class="type">TRC20</view>
</view>
<view class="list">
<u-button
@tap="applyWithdraw"
class="button"
color="#e5b932"
:text="$lang.submit"
></u-button>
</view>
<view class="list">
<view class="tip">{{ $lang.withdrawTip }}</view>
<view class="tip">{{ $lang.commission }}:1 USDT</view>
</view>
</template>
<!-- 越南银行卡提现 -->
<template v-if="userInfo.pay_channel == 'ALIN_VN'">
<view class="picker-view" @click="openBankPicker">
<u-input
readonly
:placeholder="$lang.pleaseChoose"
color="#f7ecd0"
v-model="bankName"
border="none"
>
<u--text
:text="$lang.bankName"
slot="prefix"
margin="0 3px 0 0"
type="tips"
></u--text>
<u-icon
slot="suffix"
name="arrow-down-fill"
color="#b9aa84"
size="16"
></u-icon>
</u-input>
</view>
<u-popup
:show="showBankPicker"
mode="bottom"
round="20"
closeOnClickOverlay
@close="closeBankPicker"
>
<u--text
:text="$lang.chooseWithdraw"
slot="prefix"
margin="0 3px 0 0"
type="tips"
></u--text>
<u-icon
slot="suffix"
name="arrow-down-fill"
color="#757272"
size="16"
></u-icon>
</u-input>
</view>
<u-picker
:title="$lang.pleaseChooseWithdraw"
closeOnClickOverlay
:show="show"
:columns="columns"
:cancelText="$lang.cancel"
:confirmText="$lang.confirm"
@cancel="close"
@close="close"
@confirm="confirm"
></u-picker>
<view class="list">
<view class="lable">{{ $lang.walletAddress }}</view>
<u-input
class="input"
color="#947b2b"
clearable
:placeholder="$lang.enterWithdrawalAddress"
border="surround"
v-model="address"
></u-input>
</view>
<view class="list">
<view class="lable">{{ $lang.amount }}</view>
<u-input
class="input"
color="#947b2b"
clearable
:placeholder="$lang.enterWithdrawalamount"
border="surround"
v-model="money"
></u-input>
</view>
<view class="list">
<view class="lab">{{ $lang.rechargeWithdrawNetwork }}</view>
<view class="type">TRC20</view>
</view>
<view class="list">
<u-button
@tap="applyWithdraw"
class="button"
color="#e5b932"
:text="$lang.submit"
></u-button>
</view>
<view class="list">
<view class="tip">{{ $lang.withdrawTip }}</view>
<view class="tip">{{ $lang.commission }}:1 USDT</view>
</view>
<view class="bank-picker-popup">
<view class="bank-picker-header">
<view class="bank-picker-action cancel" @click="closeBankPicker">{{
$lang.cancel
}}</view>
<view class="bank-picker-title">{{ $lang.bankName }}</view>
<view class="bank-picker-action confirm" @click="confirmBankSelection">{{
$lang.confirm
}}</view>
</view>
<scroll-view scroll-y class="bank-picker-list">
<view
class="bank-picker-item"
:class="{ active: tempBankName === item.name }"
v-for="(item, index) in bankList"
:key="index"
@click="selectBankOption(item)"
>
<text>{{ item.name }}</text>
<u-icon
v-if="tempBankName === item.name"
name="checkmark"
color="#231705"
size="16"
></u-icon>
</view>
</scroll-view>
</view>
</u-popup>
<view class="list">
<view class="lable">{{ $lang.accountName }}</view>
<u-input
class="input"
color="#f7ecd0"
clearable
:placeholder="$lang.enterAccountName"
border="none"
v-model="accountName"
></u-input>
</view>
<view class="list">
<view class="lable">{{ $lang.accountNumber }}</view>
<u-input
class="input"
color="#f7ecd0"
clearable
:placeholder="$lang.enterAccountNumber"
border="none"
v-model="accountNumber"
></u-input>
</view>
<view class="list">
<view class="lable">{{ $lang.amount }}</view>
<u-input
class="input"
color="#f7ecd0"
clearable
type="number"
:placeholder="'Tối thiểu 1,000,000 VND'"
border="none"
v-model="money"
></u-input>
</view>
<view class="list">
<u-button
@tap="applyWithdrawBank"
class="button"
color="#e5b932"
:text="$lang.submit"
></u-button>
</view>
<view class="list">
<view class="tip">{{ $lang.withdrawTip }}</view>
</view>
</template>
</view>
<view class="mb60"></view>
</view>
@@ -104,6 +213,15 @@ export default {
type: "USDT",
show: false,
columns: [["USDT"]],
// 越南银行卡提现
bankName: "",
bankCode: "",
tempBankName: "",
accountName: "",
accountNumber: "",
showBankPicker: false,
bankColumns: [[]],
bankList: [],
};
},
computed: {
@@ -112,7 +230,12 @@ export default {
$lang: (state) => state.app.lang[state.app.language],
}),
},
onLoad() {},
onLoad() {
// 越南渠道加载银行列表
if (this.userInfo && this.userInfo.pay_channel === 'ALIN_VN') {
this.loadBankList();
}
},
methods: {
confirm(chose) {
this.type = chose.value[0];
@@ -169,86 +292,418 @@ export default {
});
}
},
// 加载越南银行列表
loadBankList() {
this.$api
.getBankListVn({ user_id: this.userInfo.id })
.then((res) => {
if (res.Data && res.Data.data) {
this.bankList = res.Data.data;
this.bankColumns = [res.Data.data.map((item) => item.name)];
}
})
.catch((err) => {
console.log(err);
});
},
openBankPicker() {
this.tempBankName = this.bankName;
this.showBankPicker = true;
},
closeBankPicker() {
this.showBankPicker = false;
},
selectBankOption(item) {
this.tempBankName = item.name;
},
// 选择银行
confirmBankSelection() {
if (!this.tempBankName) {
this.showBankPicker = false;
return;
}
this.bankName = this.tempBankName;
this.bankCode = this.tempBankName;
this.showBankPicker = false;
},
// 越南银行卡提现
applyWithdrawBank() {
if (!this.bankName) {
this.$toast({
message: this.$lang.bankName,
duration: 2000,
});
return;
}
if (!this.accountName) {
this.$toast({
message: this.$lang.enterAccountName,
duration: 2000,
});
return;
}
if (!this.accountNumber) {
this.$toast({
message: this.$lang.enterAccountNumber,
duration: 2000,
});
return;
}
if (!this.money || this.money <= 0) {
this.$toast({
message: this.$lang.amountCannotBe0,
duration: 2000,
});
return;
}
if (Number(this.money) < 1000000) {
this.$toast({
message: 'Số tiền rút tối thiểu là 1,000,000 VND',
duration: 2000,
});
return;
}
if (Number(this.money) > Number(this.userInfo.money)) {
this.$toast({
message: this.$lang.insufficientBalance,
duration: 2000,
});
return;
}
const params = {
user_id: this.userInfo.id,
account_name: this.accountName,
account_number: this.accountNumber,
bank_code: this.bankCode,
bank_name: this.bankName,
amount: this.money,
};
this.$toast({
type: "loading",
message: this.$lang.submittingApplication,
duration: 200000,
});
this.$api
.applyWithdrawBank(params)
.then((res) => {
if (res.Success) {
this.$toast({
type: "success",
message: res.Msg,
duration: 2000,
});
this.bankName = "";
this.bankCode = "";
this.accountName = "";
this.accountNumber = "";
this.money = "";
} else {
this.$toast({
message: res.Msg,
duration: 2000,
});
}
})
.catch((err) => {
console.log(err);
})
.finally(() => {
this.$toastHide();
});
},
},
};
</script>
<style lang="scss" scoped>
.withdraw {
background: #0b1520;
width: 100%;
min-height: 100vh;
background: linear-gradient(180deg, #060505 0%, #0d0b09 100%);
color: #f7ecd0;
::v-deep .u-navbar {
background: rgba(0, 0, 0, 0.72) !important;
}
::v-deep .u-navbar__content {
background: transparent !important;
}
::v-deep .u-picker__view__column__item {
color: #f3e3b8 !important;
font-size: 16px !important;
font-weight: 600;
}
::v-deep .u-toolbar {
background: #15120f !important;
border-bottom-color: rgba(223, 189, 120, 0.12) !important;
}
::v-deep .u-toolbar__title {
color: #f4dfae !important;
}
::v-deep .u-toolbar__wrapper__cancel {
color: #a9956d !important;
}
::v-deep .u-toolbar__wrapper__confirm {
color: #dfbd78 !important;
}
.navbar-lab {
color: #fff;
font-weight: 500;
font-size: 18px;
color: #fbf2de;
font-weight: 700;
font-size: 19px;
letter-spacing: 0.3px;
}
.content {
margin: 5px 5px;
border: 2px solid #947b2b;
background: #222222;
width: calc(100% - 24px);
max-width: 760px;
margin: 10px auto 0;
padding: 18px 16px 22px;
box-sizing: border-box;
padding: 15px;
border-radius: 24px;
background: linear-gradient(
180deg,
rgba(16, 13, 11, 0.96) 0%,
rgba(10, 8, 7, 0.96) 100%
);
border: 1px solid rgba(223, 189, 120, 0.18);
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.24),
inset 0 1px 0 rgba(255, 245, 223, 0.03);
min-height: 400px;
.picker-view {
border: 2px solid #947b2b;
padding: 8px;
border-radius: 5px;
min-height: 56px;
margin-bottom: 14px;
padding: 0 14px;
display: flex;
align-items: center;
background: linear-gradient(
180deg,
rgba(25, 21, 18, 0.96) 0%,
rgba(17, 14, 12, 0.96) 100%
);
border: 1px solid rgba(223, 189, 120, 0.14);
border-radius: 16px;
box-shadow: inset 0 1px 0 rgba(255, 244, 220, 0.03),
inset 0 -1px 0 rgba(0, 0, 0, 0.12);
::v-deep .u-input {
flex: 1;
}
::v-deep .u-input__content {
min-height: 54px;
padding: 0;
}
::v-deep .u-input__content__field-wrapper {
width: 100%;
}
::v-deep input {
color: #f7ecd0 !important;
font-size: 15px !important;
letter-spacing: 0.2px;
}
::v-deep input::placeholder {
color: rgba(245, 228, 184, 0.4) !important;
}
::v-deep .u-text__value {
color: #baa67f !important;
font-size: 13px !important;
}
}
.list {
margin-bottom: 14px;
padding: 14px;
border-radius: 16px;
background: linear-gradient(
180deg,
rgba(23, 19, 16, 0.92) 0%,
rgba(14, 12, 10, 0.92) 100%
);
border: 1px solid rgba(223, 189, 120, 0.1);
font-size: 14px;
text-align: center;
.lab {
color: #757272;
margin: 10px 0;
color: #b9aa84;
margin: 0 0 10px;
text-align: left;
font-size: 13px;
}
.lable {
text-align: left;
color: #ddd;
margin-top: 20px;
font-size: 16px;
color: #d9c6a0;
margin-top: 0;
font-size: 15px;
margin-bottom: 10px;
font-weight: 600;
}
.money {
font-size: 16px;
min-height: 52px;
padding: 0 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 17px;
margin-top: 0;
padding: 15px 0;
color: #e5b932;
}
.btn {
height: 30px;
font-weight: 600;
color: #0b1520 !important;
color: #f1d392;
font-weight: 700;
border-radius: 16px;
background: linear-gradient(
180deg,
rgba(27, 22, 18, 0.96) 0%,
rgba(17, 14, 12, 0.96) 100%
);
border: 1px solid rgba(223, 189, 120, 0.14);
box-shadow: inset 0 1px 0 rgba(255, 244, 220, 0.04);
}
.type {
width: 70px;
height: 35px;
background: #e5b932;
border-radius: 40px;
min-width: 86px;
height: 36px;
padding: 0 16px;
display: inline-flex;
align-items: center;
justify-content: center;
background: linear-gradient(180deg, #f2dfb6 0%, #dfbd78 52%, #bd8d39 100%);
border-radius: 999px;
text-align: center;
line-height: 35px;
font-weight: 600;
margin: 10px auto;
line-height: 36px;
font-weight: 700;
color: #231705;
box-shadow: 0 8px 18px rgba(125, 84, 22, 0.16),
inset 0 1px 0 rgba(255, 255, 255, 0.28);
margin: 0 auto;
}
.input {
line-height: 30px;
height: 30px;
min-height: 48px;
padding: 0 12px;
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(223, 189, 120, 0.12);
border-radius: 14px;
::v-deep .u-input__content {
min-height: 48px;
padding: 0;
}
::v-deep .u-input__content__field-wrapper {
width: 100%;
}
::v-deep input {
color: #f7ecd0 !important;
font-size: 15px !important;
letter-spacing: 0.2px;
}
::v-deep input::placeholder {
color: rgba(245, 228, 184, 0.4) !important;
}
}
.button {
line-height: 45px;
height: 45px;
color: #0b1520 !important;
font-weight: bold;
margin-top: 30px;
margin-bottom: 10px;
height: 50px !important;
margin-top: 8px;
margin-bottom: 2px;
border: none !important;
border-radius: 16px !important;
color: #231705 !important;
font-weight: 700;
letter-spacing: 0.3px;
box-shadow: 0 12px 24px rgba(125, 84, 22, 0.18),
inset 0 1px 0 rgba(255, 255, 255, 0.36);
}
.tip {
color: #cc4c0e;
color: #bca47a;
font-size: 13px;
text-align: justify;
line-height: 1.6;
}
}
}
.bank-picker-popup {
background: linear-gradient(180deg, #17130f 0%, #0d0b09 100%);
border-top: 1px solid rgba(223, 189, 120, 0.14);
border-radius: 20px 20px 0 0;
overflow: hidden;
}
.bank-picker-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 54px;
padding: 0 16px;
border-bottom: 1px solid rgba(223, 189, 120, 0.1);
background: rgba(21, 18, 15, 0.96);
}
.bank-picker-title {
font-size: 16px;
font-weight: 700;
color: #f4dfae;
}
.bank-picker-action {
min-width: 52px;
font-size: 14px;
line-height: 1;
&.cancel {
color: #a9956d;
text-align: left;
}
&.confirm {
color: #dfbd78;
text-align: right;
}
}
.bank-picker-list {
max-height: 52vh;
padding: 10px 12px calc(18px + env(safe-area-inset-bottom));
box-sizing: border-box;
}
.bank-picker-item {
min-height: 48px;
padding: 0 14px;
margin-bottom: 10px;
border-radius: 14px;
display: flex;
align-items: center;
justify-content: space-between;
color: #d9c6a0;
font-size: 15px;
font-weight: 600;
background: linear-gradient(
180deg,
rgba(25, 21, 18, 0.96) 0%,
rgba(17, 14, 12, 0.96) 100%
);
border: 1px solid rgba(223, 189, 120, 0.12);
box-shadow: inset 0 1px 0 rgba(255, 244, 220, 0.03);
&:last-child {
margin-bottom: 0;
}
&.active {
color: #231705;
background: linear-gradient(180deg, #f2dfb6 0%, #dfbd78 52%, #bd8d39 100%);
border-color: rgba(242, 223, 182, 0.45);
box-shadow: 0 10px 20px rgba(125, 84, 22, 0.16),
inset 0 1px 0 rgba(255, 255, 255, 0.28);
}
}
}
</style>
+28
View File
@@ -53,6 +53,34 @@ let api = {
ybfDeposit: async (params) => {
return await ajax.post("/deposit", params);
},
// 越南AlinPay充值
alinDeposit: async (params) => {
return await ajax.post("/alin_online_order", params);
},
// 彩虹易支付充值(USDT TRC20 / 支付宝 / 微信 等,默认 usdt)
epayDeposit: async (params) => {
return await ajax.post("/epay_online_order", params);
},
// 易支付订单状态轮询(内嵌二维码支付用)
epayOrderStatus: async (params) => {
return await ajax.post("/epay_order_status", params);
},
// CCpay越南银行QR充值
ccpayDeposit: async (params) => {
return await ajax.post("/ccpay_online_order", params);
},
// CCpay订单状态轮询
ccpayOrderStatus: async (params) => {
return await ajax.post("/ccpay_order_status", params);
},
// 越南银行卡提现
applyWithdrawBank: async (params) => {
return await ajax.post("/apply_withdraw_bank", params);
},
// 获取越南银行列表
getBankListVn: async (params) => {
return await ajax.post("/get_bank_list_vn", params);
},
// 获取用户信息
getUserInfo: async (params) => {
return await ajax.post("/get_user_info", params);
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 21 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 21 KiB