Compare commits

..
17 Commits
Author SHA1 Message Date
fengshao1227 ccaf2ef200 style: PC余额货币符号₫改为金黄色(深底金字,符合OG主题) 2026-06-01 23:57:32 +08:00
fengshao1227 72934e207a fix: PC端余额货币符号 $ 改为越南盾 ₫(与移动端统一,避免误解为美元) 2026-06-01 23:52:50 +08:00
fengshao1227 959c97c77c feat: 筹码栏默认显示全部13档面值(swiper左右滑动),去掉最多6个上限(保留筹码设置) 2026-05-31 20:34:08 +08:00
fengshao1227 d775482f79 feat(history): 会员注单记录增加洗码量、码粮两列 2026-05-29 11:58:05 +08:00
testadmin 30f3c5939d fix: multi-table countdown freeze + selection not persisted after refresh
1. Countdown freeze: all_table API doesn't return count_down field,
   Vue 2 can't track it reactively. Fixed by initializing count_down=0
   on each table object when data is loaded.

2. Selection persistence: choselist was only in Vuex memory, lost on
   refresh. Now saves selected table IDs to localStorage and restores
   on next load.

3. Added error-report.js for frontend error logging.
2026-05-18 21:22:38 +08:00
testadmin 4ad5e6064b feat: 龙7红圈加粗 2026-05-13 18:42:15 +08:00
testadmin 488f03d872 feat: 龙7路子珠描边改红色圈 2026-05-13 16:11:14 +08:00
testadmin 03f30ae157 refactor: PC端音频引擎重写(Web Audio API) + TTS重新生成音频 2026-05-13 12:53:50 +08:00
testadmin f1ff404ddf fix: 路子珠特殊图标描边色统一调暗
幸运6: #a03030(暗红), 龙7: #c9980a(暗黄), 熊8: #506878(灰蓝)
2026-05-05 23:38:56 +08:00
testadmin 144d76ca43 fix: 路子珠特殊图标颜色调整(暗红6/暗黄7/墨蓝8) 2026-05-05 22:36:47 +08:00
testadmin 0835d7cf95 feat: PC路子珠支持幸运6/龙7/熊8特殊图标 2026-05-01 23:45:35 +08:00
testadmin 0fe4b97c61 chore: PC build 产物更新(CCpay 第三通道) 2026-04-20 11:24:16 +08:00
testadmin 5534c9e551 feat: 充值页新增 CCpay 银行QR 第三通道
- recharge2.vue: 新增 Ngân hàng QR tab + 内嵌银行转账弹窗 + 轮询到账
2026-04-20 11:15:47 +08:00
testadmin b01eb06c25 chore: 更新 PC 端 build 产物
- USDT 内嵌二维码 + VND 提示语构建输出
2026-04-20 10:56:04 +08:00
testadmin e33af3d27d feat(recharge): USDT 提示语明确输入货币为 VND + 新汇率 27100 2026-04-16 23:33:40 +08:00
testadmin b912dcef5e feat(recharge): USDT 通道改为内嵌二维码模式,替代跳转 pay.g7g7.top
- 接入 qrcodejs2 生成 TRC20 地址二维码
- 充值弹窗内嵌:地址/金额/QR/倒计时,一键复制
- 每 3 秒轮询 /epay_order_status,到账自动关闭 + 刷新余额
- 后端返回 qrcode 字段时走内嵌;若无则回退跳转式(兼容)
2026-04-16 23:23:00 +08:00
li d1f69e4bb9 feat: 越南充值页加 USDT (TRC20) 通道切换
- recharge2.vue: 银行卡/USDT 两个 tab
- submitEpay 方法调 /epay_online_order 传 pay_type='usdt'
- 防重复提交:submitting loading 状态
2026-04-15 23:21:03 +08:00
185 changed files with 850 additions and 166 deletions
+1 -1
View File
@@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title></title><link rel="shortcut icon" href=./static/favicon.ico><link href=/static/css/app.79dc6a08f953e0f0024eabba79aa86d6.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.fc2183e86bda37cd12701768032046864.js></script><script type=text/javascript src=/static/js/vendor.9e41d324bb8ddb1839371768032046864.js></script><script type=text/javascript src=/static/js/app.0a99d25499e4b956522e1768032046864.js></script></body></html> <!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title></title><link rel="shortcut icon" href=./static/favicon.ico><link href=/static/css/app.0ab001b70af6476984f762986f6a1d60.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.1a24a879bb69a34cfac01776655235227.js></script><script type=text/javascript src=/static/js/vendor.fdf7e6b387038f39ad6e1776655235227.js></script><script type=text/javascript src=/static/js/app.d4037a1951a5b629b9f61776655235227.js></script></body></html>
+16 -18
View File
@@ -1,36 +1,34 @@
{ {
"ApiUrl":"http://192.168.88.251:85/pcapi", "ApiUrl":"https://api.g7g7.top/pcapi",
"SockUrl":"192.168.88.251:6080", "SockUrl":"wss://api.g7g7.top",
"ServerPort":"6080", "ServerPort":"443",
"HallUrl": "https://v.yourvideo.com/yg/hall.flv", "HallUrl": "https://v1.yourvideo.com/kr/pRzcSz.flv",
"LoginLogo": "http://192.168.88.251:85/static/logo/wb_logo.png", "LoginLogo": "https://api.g7g7.top/static/logo/og_logo_180_180.png",
"LogoPng": "http://192.168.88.251:85/static/logo/wb_logo.png", "LogoPng": "https://api.g7g7.top/static/logo/og_logo_160_143.png",
"TitlePng": "http://192.168.88.251:85/static/logo/wb_200_60.png", "TitlePng": "https://api.g7g7.top/static/logo/og_logo_title_200_60.png",
"entranceQrcode":"http://192.168.88.251:85/static/logo/normal_entranceQrcode.png?v=10", "entranceQrcode":"https://api.g7g7.top/static/logo/og_qrcode.jpg",
"agentUrl":"http://192.168.88.249", "agentUrl":"https://agt.g7g7.top",
"BgMusic": "static/sound/bg.mp3", "BgMusic": "static/sound/bg.mp3",
"IframeUrl": "https://p.abc.com/video.html", "IframeUrl": "https://p.g7g7.top/video.html",
"PayUrl": "", "PayUrl": "",
"AppUrl": "https://www.abc.com/", "AppUrl": "https://og-w.g7g7.top/",
"AppQrcode": "http://192.168.88.251:85/static/logo/app_qrcode.png?v=10", "AppQrcode": "https://api.g7g7.top/static/logo/og_qrcode.png",
"ServerQrcode": "http://192.168.88.251:85/static/logo/cus.jpeg", "ServerQrcode": "https://api.g7g7.top/static/logo/og_service.png",
"customerLink": "https://kf.tvbn018.vip/index/index/home?visiter_id=&visiter_name=&avatar=&groupid=0&business_id=2",
"isCancelBet": "1", "isCancelBet": "1",
"isChipSet": "1", "isChipSet": "1",
"Title": "WINBEST", "Title": "OG ONLINE CASINO",
"baccarat": true, "baccarat": true,
"dt": true, "dt": true,
"flopTime": 1000, "flopTime": 1000,
"videoZoom": false, "nn": true,
"nn": false,
"multiple": true, "multiple": true,
"onlyTel": false, "onlyTel": false,
"sanka": false, "sanka": false,
"isUpdateOnline":true, "isUpdateOnline":true,
"isRegister":false, "isRegister":false,
"isRecharge":false, "isRecharge":true,
"isServerCode":true, "isServerCode":true,
"isSetExpired":true, "isSetExpired":true,
"sound":2, "sound":2,
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

-1
View File
@@ -1 +0,0 @@
webpackJsonp([0],{"+Ngo":function(t,e){},"Fc+r":function(t,e,n){t.exports=n.p+"static/img/agent.6ff686e.jpg"},L682:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n("Dd8w"),r=n.n(i),s=n("NYxO"),c={name:"Entrance",data:function(){return{itemIndex:0}},mounted:function(){},methods:{ItemHover:function(t){this.itemIndex=t},goUrl:function(t,e){1==t?this.$router.push(e):window.location.href=e}},computed:r()({},Object(s.b)(["webconfig","Language"])),watch:{}},a={render:function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"entrance"},[i("div",{staticClass:"title animated slideInLeft"},[i("img",{staticStyle:{width:"12vw"},attrs:{src:t.webconfig.TitlePng}})]),t._v(" "),i("div",{staticClass:"item left",class:{hover:2==t.itemIndex},on:{click:function(e){return t.goUrl(1,"/login")},mouseenter:function(e){return t.ItemHover(2)}}},[i("img",{attrs:{src:n("Wi3H")}}),t._v(" "),i("span",{staticClass:"btn"},[t._v("網投登錄入口")])]),t._v(" "),i("div",{staticClass:"item right",class:{hover:3==t.itemIndex},on:{click:function(e){return t.goUrl(2,t.webconfig.agentUrl)},mouseenter:function(e){return t.ItemHover(3)},mouseleave:function(e){return t.ItemHover(2)}}},[i("img",{attrs:{src:n("Fc+r")}}),t._v(" "),i("span",{staticClass:"btn"},[t._v("代理端登錄入口")])]),t._v(" "),i("img",{staticClass:"qrcode animated slideInUp",attrs:{src:t.webconfig.entranceQrcode}})])},staticRenderFns:[]};var o=n("VU/8")(c,a,!1,function(t){n("+Ngo")},"data-v-5837b354",null);e.default=o.exports},Wi3H:function(t,e,n){t.exports=n.p+"static/img/netthrow.0fda361.jpg"}});
+1
View File
@@ -0,0 +1 @@
webpackJsonp([0],{BEAi:function(t,e){},L682:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n("Dd8w"),a=n.n(i),c=n("NYxO"),s={name:"Entrance",data:function(){return{itemIndex:0}},mounted:function(){},methods:{ItemHover:function(t){this.itemIndex=t},goUrl:function(t,e){1==t?this.$router.push(e):window.location.href=e}},computed:a()({},Object(c.b)(["webconfig","Language"])),watch:{}},r={render:function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"entrance"},[i("div",{staticClass:"title animated slideInLeft"},[i("img",{staticStyle:{width:"12vw"},attrs:{src:t.webconfig.TitlePng}})]),t._v(" "),i("div",{staticClass:"item left",class:{hover:2==t.itemIndex},on:{click:function(e){return t.goUrl(1,"/login")},mouseenter:function(e){return t.ItemHover(2)}}},[i("img",{attrs:{src:n("Wi3H")}}),t._v(" "),i("span",{staticClass:"btn"},[t._v("網投登錄入口")])]),t._v(" "),i("img",{staticClass:"qrcode animated slideInUp",attrs:{src:t.webconfig.entranceQrcode}})])},staticRenderFns:[]};var o=n("VU/8")(s,r,!1,function(t){n("BEAi")},"data-v-207b2fca",null);e.default=o.exports},Wi3H:function(t,e,n){t.exports=n.p+"static/img/netthrow.0fda361.jpg"}});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,a,c){for(var i,u,f,s=0,l=[];s<r.length;s++)u=r[s],t[u]&&l.push(t[u][0]),t[u]=0;for(i in a)Object.prototype.hasOwnProperty.call(a,i)&&(e[i]=a[i]);for(n&&n(r,a,c);l.length;)l.shift()();if(c)for(s=0;s<c.length;s++)f=o(o.s=c[s]);return f};var r={},t={5:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var a=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.timeout=12e4,o.nc&&c.setAttribute("nonce",o.nc),c.src=o.p+"static/js/"+e+"."+{0:"8cf5ff74deafa55520f2",1:"a8feddb563659f366310",2:"6fac4657b1f2b8767dbd"}[e]+"1768032046864.js";var i=setTimeout(u,12e4);function u(){c.onerror=c.onload=null,clearTimeout(i);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return c.onerror=c.onload=u,a.appendChild(c),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="/",o.oe=function(e){throw console.error(e),e}}([]); !function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,a,c){for(var i,u,f,s=0,l=[];s<r.length;s++)u=r[s],t[u]&&l.push(t[u][0]),t[u]=0;for(i in a)Object.prototype.hasOwnProperty.call(a,i)&&(e[i]=a[i]);for(n&&n(r,a,c);l.length;)l.shift()();if(c)for(s=0;s<c.length;s++)f=o(o.s=c[s]);return f};var r={},t={5:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var a=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.timeout=12e4,o.nc&&c.setAttribute("nonce",o.nc),c.src=o.p+"static/js/"+e+"."+{0:"f0e51f931fae6ae15afd",1:"a8feddb563659f366310",2:"49aaa2b746d14fefa698"}[e]+"1776655235227.js";var i=setTimeout(u,12e4);function u(){c.onerror=c.onload=null,clearTimeout(i);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return c.onerror=c.onload=u,a.appendChild(c),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="/",o.oe=function(e){throw console.error(e),e}}([]);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7
View File
@@ -11,6 +11,7 @@
"axios": "^0.18.0", "axios": "^0.18.0",
"babel-preset-es2015": "^6.24.1", "babel-preset-es2015": "^6.24.1",
"px2rem-loader": "^0.1.9", "px2rem-loader": "^0.1.9",
"qrcodejs2": "^0.0.2",
"swiper": "^4.5.0", "swiper": "^4.5.0",
"vue": "^2.5.2", "vue": "^2.5.2",
"vue-js-cookie": "^2.1.0", "vue-js-cookie": "^2.1.0",
@@ -11619,6 +11620,12 @@
"teleport": ">=0.2.0" "teleport": ">=0.2.0"
} }
}, },
"node_modules/qrcodejs2": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/qrcodejs2/-/qrcodejs2-0.0.2.tgz",
"integrity": "sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA==",
"license": "MIT"
},
"node_modules/qs": { "node_modules/qs": {
"version": "6.11.0", "version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+1
View File
@@ -13,6 +13,7 @@
"axios": "^0.18.0", "axios": "^0.18.0",
"babel-preset-es2015": "^6.24.1", "babel-preset-es2015": "^6.24.1",
"px2rem-loader": "^0.1.9", "px2rem-loader": "^0.1.9",
"qrcodejs2": "^0.0.2",
"swiper": "^4.5.0", "swiper": "^4.5.0",
"vue": "^2.5.2", "vue": "^2.5.2",
"vue-js-cookie": "^2.1.0", "vue-js-cookie": "^2.1.0",
+2
View File
@@ -100,6 +100,8 @@ var en={
win_or_lose : 'Win or lose', win_or_lose : 'Win or lose',
xima_liang : 'Turnover',
ma_liang : 'Rebate',
account_tip : 'Please enter the account number', account_tip : 'Please enter the account number',
password_tip : 'Please input a password', password_tip : 'Please input a password',
password_confir_tip : 'Please confirm the password', password_confir_tip : 'Please confirm the password',
+2
View File
@@ -99,6 +99,8 @@ var tv={
end_time_tip : 'Vui lòng chọn thời gian kết thúc', end_time_tip : 'Vui lòng chọn thời gian kết thúc',
win_or_lose : 'Thắng hay thua', win_or_lose : 'Thắng hay thua',
xima_liang : 'Doanh số cược',
ma_liang : 'Phỉnh boa',
account_tip : 'Vui lòng nhập một tài khoản', account_tip : 'Vui lòng nhập một tài khoản',
password_tip : 'Vui lòng nhập mật khẩu', password_tip : 'Vui lòng nhập mật khẩu',
password_confir_tip : 'Vui lòng xác nhận mật khẩu', password_confir_tip : 'Vui lòng xác nhận mật khẩu',
+2
View File
@@ -100,6 +100,8 @@ var cn={
win_or_lose : '输赢', win_or_lose : '输赢',
xima_liang : '洗码量',
ma_liang : '码粮',
account_tip : '请输入账号', account_tip : '请输入账号',
password_tip : '请输入密码', password_tip : '请输入密码',
password_confir_tip : '请确认密码', password_confir_tip : '请确认密码',
+72 -53
View File
@@ -1,60 +1,79 @@
let audioCtx = null
const bufferCache = new Map()
let chainId = 0
var audio = null, function getAudioContext() {
Mp3List=[], if (!audioCtx) {
num=0; audioCtx = new (window.AudioContext || window.webkitAudioContext)()
const resume = () => {
if (audioCtx.state === 'suspended') audioCtx.resume()
}
document.addEventListener('click', resume, { once: true })
document.addEventListener('touchstart', resume, { once: true })
}
if (audioCtx.state === 'suspended') audioCtx.resume()
return audioCtx
}
function getSoundBase() {
try {
const config = JSON.parse(localStorage.getItem('WebConfig') || '{}')
return config.sound && config.sound == 2 ? '/static/sound2/' : '/static/sound/'
} catch (e) {
return '/static/sound/'
}
}
function audioMp3(mp3List,audios){ async function loadBuffer(key) {
var WebConfig=JSON.parse(localStorage.getItem("WebConfig")); if (bufferCache.has(key)) return bufferCache.get(key)
audio=audios; try {
Mp3List=mp3List; const ctx = getAudioContext()
var mp3=new Object(); const url = getSoundBase() + key
mp3.mp3List=mp3List; const response = await fetch(url)
mp3.url="/static/sound/"; if (!response.ok) return null
if(WebConfig.sound&&WebConfig.sound==2){mp3.url="/static/sound2/";} const arrayBuffer = await response.arrayBuffer()
const audioBuffer = await ctx.decodeAudioData(arrayBuffer)
bufferCache.set(key, audioBuffer)
return audioBuffer
} catch (e) {
return null
}
}
mp3.auto_play=false; function playBuffer(buffer) {
mp3.loop=false; return new Promise((resolve) => {
mp3.Play=function(){ const ctx = getAudioContext()
const source = ctx.createBufferSource()
source.buffer = buffer
source.connect(ctx.destination)
source.onended = resolve
source.start(0)
})
}
audio.src=this.url+this.mp3List[0]; function audioMp3(mp3List, _audioEl) {
audio.load(); const myId = ++chainId
audio.play(); const list = mp3List || []
}
mp3.Muted=function(){
audio.muted ? audio.muted = false : audio.muted = true;
}
mp3.volumeAdd=function(){
if(audio.volume.toFixed(1)>=1){
audio.volume=1
}else{
audio.volume = audio.volume + 0.1;
}
}
mp3.volumeMinus=function(){
if(audio.volume.toFixed(1)<=0){
audio.volume=0
}else{
audio.volume = audio.volume - 0.1;
}
}
audio.addEventListener("ended", nextAudio);
return mp3;
}
function nextAudio(){
var WebConfig=JSON.parse(localStorage.getItem("WebConfig"));
num+=1
if(num<Mp3List.length){
audio.src="/static/sound/"+Mp3List[num];
if(WebConfig.sound&&WebConfig.sound==2){audio.src="/static/sound2/"+Mp3List[num];}
audio.play();
}else{
audio.pause();
audio.currentTime = 0.0;
// console.log("播完")
num=0;
}
}
export {audioMp3}; return {
Play() {
;(async () => {
for (let i = 0; i < list.length; i++) {
if (chainId !== myId) return
const buffer = await loadBuffer(list[i])
if (!buffer) continue
if (chainId !== myId) return
await playBuffer(buffer)
}
})()
},
Pause() {
chainId++
},
Muted() {},
volumeAdd() {},
volumeMinus() {}
}
}
export { audioMp3 }
+15 -3
View File
@@ -157,7 +157,7 @@ function cutRoad(billnumber,roadType,ctb,unit,roadData,cols,gameId,ask,askroad){
}else if(roadType=="bigeyeWay"){ }else if(roadType=="bigeyeWay"){
BigeyePath(ctb,unit,start_x,v.show_x-cut,v.show_y,v.result) BigeyePath(ctb,unit,start_x,v.show_x-cut,v.show_y,v.result)
}else if(roadType=="showWay"){ }else if(roadType=="showWay"){
SoloPath(gameId,ctb,unit,v.show_x-cut,v.show_y,v.result,v.pair) SoloPath(gameId,ctb,unit,v.show_x-cut,v.show_y,v.result,v.pair,v.luck_six||0,v.dragon_seven||0,v.panda_eight||0)
}else if(roadType=="bigWay"){ }else if(roadType=="bigWay"){
BigPath(ctb,unit,start_x,v.show_x-cut,v.show_y,v.result,v.tie_num,v.pair,billnumber) BigPath(ctb,unit,start_x,v.show_x-cut,v.show_y,v.result,v.tie_num,v.pair,billnumber)
}else if(roadType=="sanxingWay"){ }else if(roadType=="sanxingWay"){
@@ -257,7 +257,7 @@ function Font_tie(ctb,num,Font_x,Font_y,fontsize,color){
ctb.stroke(); ctb.stroke();
} }
} }
function SoloPath(gameId,ctb,unit,x,y,type,corners){ function SoloPath(gameId,ctb,unit,x,y,type,corners,luck_six,dragon_seven,panda_eight){
ctb.beginPath(); ctb.beginPath();
ctb.lineWidth = unit*0.02; ctb.lineWidth = unit*0.02;
ctb.strokeStyle = "#fff"; ctb.strokeStyle = "#fff";
@@ -273,7 +273,19 @@ function SoloPath(gameId,ctb,unit,x,y,type,corners){
var dragon = isEn ? "D" : "龍"; var dragon = isEn ? "D" : "龍";
var tiger = isEn ? "T" : "虎"; var tiger = isEn ? "T" : "虎";
if(gameId==1){ if(gameId==1 && luck_six > 0){
var color='#8b1a1a', fonts="6";
ctb.strokeStyle = "#a03030";
ctb.lineWidth = unit*0.05;
}else if(gameId==1 && dragon_seven > 0){
var color='#b8860b', fonts="7";
ctb.strokeStyle = "#ff2202";
ctb.lineWidth = unit*0.08;
}else if(gameId==1 && panda_eight > 0){
var color='#34495e', fonts="8";
ctb.strokeStyle = "#506878";
ctb.lineWidth = unit*0.05;
}else if(gameId==1){
if(type==1){ if(type==1){
var color='#b20a00', var color='#b20a00',
fonts= banker; fonts= banker;
@@ -49,6 +49,14 @@
prop="win_total" prop="win_total"
:label="Language.win_or_lose"> :label="Language.win_or_lose">
</el-table-column> </el-table-column>
<el-table-column
prop="ximaliang"
:label="Language.xima_liang">
</el-table-column>
<el-table-column
prop="maliang"
:label="Language.ma_liang">
</el-table-column>
</el-table> </el-table>
+12 -3
View File
@@ -143,9 +143,18 @@ watch:{
background-size:18px auto;; background-size:18px auto;;
} }
.left-box .info .item .icon_money{ .left-box .info .item .icon_money{
background:url(../../common/image/icon/icon_money.png) center center no-repeat; background:#372300;
-webkit-background-size:18px auto; border-radius:50%;
background-size:18px auto;; width:24px;
height:24px;
line-height:24px;
text-align:center;
}
.left-box .info .item .icon_money:before{
content:"\20AB"; /* 越南盾符号 đ(₫),与移动端一致,替换原误导的 $ 图标 */
color:#f5c842;
font-size:15px;
font-weight:bold;
} }
.left-box .info .item .icon_recharge{ .left-box .info .item .icon_recharge{
background:url(../../common/image/icon/icon_recharge.png) center center no-repeat; background:url(../../common/image/icon/icon_recharge.png) center center no-repeat;
+11 -2
View File
@@ -103,8 +103,17 @@ export default {
this.Multipledata=MultipleData; this.Multipledata=MultipleData;
if(this.choselist.length==0){ if(this.choselist.length==0){
var savedIds = this.$store.state._savedChoseIds || [];
this.$store.commit('multipleData',MultipleData.slice(0,4)) if(savedIds.length > 0){
var restored = MultipleData.filter(function(t){ return savedIds.indexOf(t.id) !== -1; });
if(restored.length > 0){
this.$store.commit('multipleData', restored);
} else {
this.$store.commit('multipleData', MultipleData.slice(0,4));
}
} else {
this.$store.commit('multipleData', MultipleData.slice(0,4));
}
} }
} }
}, },
+3 -4
View File
@@ -99,7 +99,8 @@
routeName:'', routeName:'',
chipArrayJson:[], chipArrayJson:[],
chipArray:[{"index":1,"value":"10000","cls":"10k"},{"index":2,"value":"20000","cls":"20k"},{"index":3,"value":"50000","cls":"50k"},{"index":4,"value":"100000","cls":"100k"}, chipArray:[{"index":1,"value":"10000","cls":"10k"},{"index":2,"value":"20000","cls":"20k"},{"index":3,"value":"50000","cls":"50k"},{"index":4,"value":"100000","cls":"100k"},
{"index":5,"value":"200000","cls":"200k"},{"index":6,"value":"500000","cls":"500k"}], {"index":5,"value":"200000","cls":"200k"},{"index":6,"value":"500000","cls":"500k"},{"index":7,"value":"1000000","cls":"1000k"},{"index":8,"value":"2000000","cls":"2000k"},{"index":9,"value":"5000000","cls":"5000k"},
{"index":10,"value":"10000000","cls":"10000k"},{"index":11,"value":"20000000","cls":"20000k"},{"index":12,"value":"50000000","cls":"50000k"},{"index":13,"value":"100000000","cls":"100000k"}],
chipArrayNoSet:[{"index":1,"value":"10000","cls":"10k"},{"index":2,"value":"20000","cls":"20k"},{"index":3,"value":"50000","cls":"50k"},{"index":4,"value":"100000","cls":"100k"}, chipArrayNoSet:[{"index":1,"value":"10000","cls":"10k"},{"index":2,"value":"20000","cls":"20k"},{"index":3,"value":"50000","cls":"50k"},{"index":4,"value":"100000","cls":"100k"},
{"index":5,"value":"200000","cls":"200k"},{"index":6,"value":"500000","cls":"500k"},{"index":7,"value":"1000000","cls":"1000k"},{"index":8,"value":"2000000","cls":"2000k"},{"index":9,"value":"5000000","cls":"5000k"}, {"index":5,"value":"200000","cls":"200k"},{"index":6,"value":"500000","cls":"500k"},{"index":7,"value":"1000000","cls":"1000k"},{"index":8,"value":"2000000","cls":"2000k"},{"index":9,"value":"5000000","cls":"5000k"},
{"index":10,"value":"10000000","cls":"10000k"},{"index":11,"value":"20000000","cls":"20000k"},{"index":12,"value":"50000000","cls":"50000k"},{"index":13,"value":"100000000","cls":"100000k"} {"index":10,"value":"10000000","cls":"10000k"},{"index":11,"value":"20000000","cls":"20000k"},{"index":12,"value":"50000000","cls":"50000k"},{"index":13,"value":"100000000","cls":"100000k"}
@@ -166,9 +167,7 @@
else {_.remove(chipArray, function(o) {return o.index==index;});} else {_.remove(chipArray, function(o) {return o.index==index;});}
} }
else { else {
if(chipArray.length>=6){this.$message({type: 'warn', message: '筹码数量最多显示6个!'});} chipArray.push({"index":index,"value":chip,"cls":cls})
else { chipArray.push({"index":index,"value":chip,"cls":cls})}
} }
var newchipArray= _.sortBy(chipArray, ['index'],["desc"]); var newchipArray= _.sortBy(chipArray, ['index'],["desc"]);
this.chipArray=newchipArray; this.chipArray=newchipArray;
+551 -5
View File
@@ -3,35 +3,175 @@
<div class="btn off-btn" @click="offPop"></div> <div class="btn off-btn" @click="offPop"></div>
<div class="btn pay2-btn" v-if="userInfo.area_id != 3" @click="isShowPop('recharge')">{{Language.recharge_offline2}} </div> <div class="btn pay2-btn" v-if="userInfo.area_id != 3" @click="isShowPop('recharge')">{{Language.recharge_offline2}} </div>
<div class="title">{{Language.recharge_online2}}</div> <div class="title">{{Language.recharge_online2}}</div>
<!-- 越南 AlinPay 在线充值 --> <!-- 越南地区银行卡 (AlinPay) / USDT (Epay) 双通道 -->
<div class="view" v-if="userInfo.area_id == 3"> <div class="view" v-if="userInfo.area_id == 3">
<div class="alin-form"> <div class="pay-tabs">
<div class="pay-tab" :class="{active: payChannel=='alin'}" @click="payChannel='alin'">
{{Language.recharge_bank || 'Thẻ ngân hàng'}}
</div>
<div class="pay-tab" :class="{active: payChannel=='epay'}" @click="payChannel='epay'">
USDT (TRC20)
</div>
<div class="pay-tab" :class="{active: payChannel=='ccpay'}" @click="payChannel='ccpay'">
{{Language.recharge_bank2 || 'Ngân hàng QR'}}
</div>
</div>
<div class="alin-form" v-if="payChannel=='alin'">
<div class="alin-item"> <div class="alin-item">
<label>{{Language.withdraw_page_withdrawal_amount || '充值金额'}}</label> <label>{{Language.withdraw_page_withdrawal_amount || '充值金额'}}</label>
<input class="input" type="number" v-model="alinAmount" placeholder="Tối thiểu 1,000,000"> <input class="input" type="number" v-model="alinAmount" placeholder="Tối thiểu 1,000,000">
</div> </div>
<button class="btn alin-submit" @click="submitAlin">{{Language.withdraw_page_confirm || '确认充值'}}</button> <button class="btn alin-submit" @click="submitAlin" :disabled="submitting">
{{submitting ? '...' : (Language.withdraw_page_confirm || '确认充值')}}
</button>
</div>
<div class="alin-form" v-if="payChannel=='epay'">
<div class="alin-item">
<label>{{Language.withdraw_page_withdrawal_amount || '充值金额'}} (VND)</label>
<input class="input" type="number" v-model="epayAmount" placeholder="Nhập số tiền VND (vd: 1,000,000)">
</div>
<div class="alin-tip">
{{Language.recharge_usdt_tip || 'Nhập số tiền theo VND — hệ thống tự động quy đổi sang USDT theo tỷ giá 1 USDT ≈ 27,100 VND. Thanh toán qua mạng TRC20.'}}
</div>
<button class="btn alin-submit" @click="submitEpay" :disabled="submitting">
{{submitting ? '...' : (Language.withdraw_page_confirm || '确认充值')}}
</button>
</div>
<div class="alin-form" v-if="payChannel=='ccpay'">
<div class="alin-item">
<label>{{Language.withdraw_page_withdrawal_amount || '充值金额'}} (VND)</label>
<input class="input" type="number" v-model="ccpayAmount" placeholder="Nhập số tiền VND (vd: 1,000,000)">
</div>
<button class="btn alin-submit" @click="submitCcpay" :disabled="submitting">
{{submitting ? '...' : (Language.withdraw_page_confirm || '确认充值')}}
</button>
</div> </div>
</div> </div>
<!-- 其他渠道 iframe --> <!-- 其他渠道 iframe -->
<iframe v-else class="page" :src="webconfig.PayUrl+'?uid='+userInfo.uid+'&api_token='+userInfo.api_token"></iframe> <iframe v-else class="page" :src="webconfig.PayUrl+'?uid='+userInfo.uid+'&api_token='+userInfo.api_token"></iframe>
<!-- USDT 内嵌二维码支付弹窗 -->
<div class="qr-mask" v-if="qr.visible" @click.self="closeQr">
<div class="qr-box">
<div class="qr-close" @click="closeQr">×</div>
<div class="qr-title">USDT (TRC20) {{Language.recharge_online2 || 'Thanh toán'}}</div>
<div class="qr-status" :class="qr.statusClass">{{qr.statusText}}</div>
<div class="qr-code-wrap" ref="qrcodeEl"></div>
<div class="qr-field">
<div class="qr-field-label">{{Language.pay_amount_usdt || 'Số tiền USDT (chính xác)'}}</div>
<div class="qr-field-value amount">
<span>{{qr.data.usdt_amount}} USDT</span>
<button class="qr-copy" @click="copyText(qr.data.usdt_amount, 'amount')">
{{qr.copied==='amount' ? '' : 'Copy'}}
</button>
</div>
</div>
<div class="qr-field">
<div class="qr-field-label">{{Language.pay_wallet_address || 'Địa chỉ ví (TRC20)'}}</div>
<div class="qr-field-value addr">
<span>{{qr.data.usdt_address}}</span>
<button class="qr-copy" @click="copyText(qr.data.usdt_address, 'addr')">
{{qr.copied==='addr' ? '' : 'Copy'}}
</button>
</div>
</div>
<div class="qr-meta">
<span> {{qr.data.vnd_amount}} VND</span>
<span class="qr-countdown"> {{qr.countdownText}}</span>
</div>
<div class="qr-tip">
{{Language.pay_usdt_warning || '⚠ Vui lòng chuyển chính xác số tiền. Sai số sẽ không thể xác định đơn hàng!'}}
</div>
</div>
</div>
<!-- CCpay 银行转账内嵌弹窗 -->
<div class="qr-mask" v-if="bank.visible" @click.self="closeBank">
<div class="qr-box">
<div class="qr-close" @click="closeBank">×</div>
<div class="qr-title">{{Language.recharge_bank2 || 'Ngân hàng QR'}} {{Language.recharge_online2 || 'Thanh toán'}}</div>
<div class="qr-status" :class="bank.statusClass">{{bank.statusText}}</div>
<div class="qr-code-wrap" ref="bankQrcodeEl"></div>
<div class="qr-field">
<div class="qr-field-label">Số tài khoản</div>
<div class="qr-field-value amount">
<span>{{bank.data.bank_account}}</span>
<button class="qr-copy" @click="copyText(bank.data.bank_account, 'bank_acc')">
{{qr.copied==='bank_acc' ? '' : 'Copy'}}
</button>
</div>
</div>
<div class="qr-field">
<div class="qr-field-label">Tên tài khoản Ngân hàng</div>
<div class="qr-field-value addr">
<span>{{bank.data.bank_name}} {{bank.data.bank_short}}</span>
</div>
</div>
<div class="qr-meta">
<span>{{Number(bank.data.amount).toLocaleString()}} VND</span>
<span class="qr-countdown"> {{bank.countdownText}}</span>
</div>
<div class="qr-tip">
{{Language.pay_bank_warning || '⚠ Vui lòng chuyển khoản chính xác số tiền và nội dung. Sai thông tin sẽ không thể xác nhận đơn hàng!'}}
</div>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import './recharge.css' import './recharge.css'
import QRCode from 'qrcodejs2'
import {encrypt,decrypt} from '../../common/js/secret' import {encrypt,decrypt} from '../../common/js/secret'
import { mapState } from 'vuex' import { mapState } from 'vuex'
export default { export default {
data() { data() {
return { return {
payChannel: 'alin',
alinAmount: '', alinAmount: '',
ApiUrl: JSON.parse(localStorage.getItem('ApiUrl')) epayAmount: '',
ccpayAmount: '',
submitting: false,
ApiUrl: JSON.parse(localStorage.getItem('ApiUrl')),
qr: {
visible: false,
data: { usdt_address: '', usdt_amount: '', vnd_amount: '', expires_at: 0, order_sn: '' },
countdownText: '',
statusText: '',
statusClass: 'waiting',
copied: '',
},
_qrInstance: null,
_pollTimer: null,
_countdownTimer: null,
bank: {
visible: false,
data: { bank_account: '', bank_name: '', bank_short: '', qr_data: '', amount: 0, order_sn: '', expires_at: 0, timeout_sec: 600 },
countdownText: '',
statusText: '',
statusClass: 'waiting',
},
_bankQrInstance: null,
_bankPollTimer: null,
_bankCountdownTimer: null,
} }
}, },
mounted: function() { mounted: function() {
}, },
beforeDestroy(){
this.stopQrTimers();
this.stopBankTimers();
},
methods:{ methods:{
offPop(){ offPop(){
this.$store.dispatch('updatemainPop',{type:'',ishow:false}); this.$store.dispatch('updatemainPop',{type:'',ishow:false});
@@ -49,6 +189,8 @@ export default {
this.$message({type:'warning', message:'Số tiền tối thiểu là 1,000,000'}); this.$message({type:'warning', message:'Số tiền tối thiểu là 1,000,000'});
return; return;
} }
if(this.submitting) return;
this.submitting = true;
var encryptstring = encrypt(JSON.stringify({ var encryptstring = encrypt(JSON.stringify({
user_id: this.userInfo.uid, user_id: this.userInfo.uid,
price: this.alinAmount, price: this.alinAmount,
@@ -58,6 +200,7 @@ export default {
})).toString(); })).toString();
this.$axios.post(this.ApiUrl+'/alin_online_order', {encryptData:encryptstring}).then( this.$axios.post(this.ApiUrl+'/alin_online_order', {encryptData:encryptstring}).then(
response=>{ response=>{
this.submitting = false;
if(response.data.Success==1){ if(response.data.Success==1){
const data = JSON.parse(decrypt(response.data.Data)); const data = JSON.parse(decrypt(response.data.Data));
if(data.status == 1 && data.url){ if(data.status == 1 && data.url){
@@ -69,10 +212,258 @@ export default {
this.$message({type:'error', message: response.data.Msg || '充值失败'}); this.$message({type:'error', message: response.data.Msg || '充值失败'});
} }
}).catch(error=>{ }).catch(error=>{
this.submitting = false;
console.log(error); console.log(error);
this.$message({type:'error', message:'充值请求失败'}); this.$message({type:'error', message:'充值请求失败'});
}); });
}, },
submitEpay(){
if(!this.epayAmount || this.epayAmount <= 0){
this.$message({type:'warning', message:'Vui lòng nhập số tiền!'});
return;
}
if(this.epayAmount < 1000000){
this.$message({type:'warning', message:'Số tiền tối thiểu là 1,000,000'});
return;
}
if(this.submitting) return;
this.submitting = true;
var encryptstring = encrypt(JSON.stringify({
user_id: this.userInfo.uid,
price: this.epayAmount,
client: 1,
username: this.userInfo.nickname,
pay_type: 'usdt',
api_token: this.userInfo.api_token,
})).toString();
this.$axios.post(this.ApiUrl+'/epay_online_order', {encryptData:encryptstring}).then(
response=>{
this.submitting = false;
if(response.data.Success==1){
const data = JSON.parse(decrypt(response.data.Data));
if(data.status == 1 && data.qrcode){
this.openQr(data.qrcode);
} else if(data.status == 1 && data.url){
// 后端暂未升级时回退到跳转式
window.open(data.url, '_blank');
} else {
this.$message({type:'error', message: data.message || 'Nạp thất bại'});
}
} else {
this.$message({type:'error', message: response.data.Msg || 'Nạp thất bại'});
}
}).catch(error=>{
this.submitting = false;
console.log(error);
this.$message({type:'error', message:'Yêu cầu thất bại'});
});
},
openQr(qrcode){
this.qr.data = qrcode;
this.qr.visible = true;
this.qr.statusText = this.Language.pay_waiting || 'Đang chờ thanh toán...';
this.qr.statusClass = 'waiting';
this.qr.copied = '';
this.$nextTick(() => {
this.renderQr(qrcode.usdt_address);
});
this.startCountdown();
this.startPolling();
},
renderQr(text){
const el = this.$refs.qrcodeEl;
if(!el) return;
el.innerHTML = '';
this._qrInstance = new QRCode(el, {
text: text,
width: 180,
height: 180,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.M,
});
},
startCountdown(){
const tick = () => {
const left = Math.max(0, this.qr.data.expires_at - Math.floor(Date.now()/1000));
const m = Math.floor(left/60);
const s = left % 60;
this.qr.countdownText = (m<10?'0':'')+m+':'+(s<10?'0':'')+s;
if(left <= 0){
this.qr.statusText = this.Language.pay_expired || 'Đơn hàng đã hết hạn';
this.qr.statusClass = 'expired';
this.stopQrTimers();
}
};
tick();
this._countdownTimer = setInterval(tick, 1000);
},
startPolling(){
const poll = () => {
if(!this.qr.visible || !this.qr.data.order_sn) return;
const encryptstring = encrypt(JSON.stringify({
user_id: this.userInfo.uid,
order_sn: this.qr.data.order_sn,
api_token: this.userInfo.api_token,
})).toString();
this.$axios.post(this.ApiUrl+'/epay_order_status', {encryptData:encryptstring}).then(res=>{
if(res.data.Success!=1) return;
const d = JSON.parse(decrypt(res.data.Data));
if(d.status == 1){
this.qr.statusText = this.Language.pay_success || 'Thanh toán thành công!';
this.qr.statusClass = 'success';
this.stopQrTimers();
this.updateMoney && this.updateMoney();
setTimeout(() => this.closeQr(), 2500);
} else if(d.status == 2){
this.qr.statusText = this.Language.pay_expired || 'Đơn hàng đã hết hạn';
this.qr.statusClass = 'expired';
this.stopQrTimers();
}
}).catch(()=>{});
};
this._pollTimer = setInterval(poll, 3000);
setTimeout(poll, 1000); // 首次提前 1s 探测
},
copyText(text, tag){
const ta = document.createElement('textarea');
ta.value = text;
ta.style.position = 'fixed';
ta.style.left = '-9999px';
document.body.appendChild(ta);
ta.select();
try { document.execCommand('copy'); } catch(e) {}
document.body.removeChild(ta);
this.qr.copied = tag;
setTimeout(() => { if(this.qr.copied === tag) this.qr.copied = ''; }, 1500);
},
closeQr(){
this.qr.visible = false;
this.stopQrTimers();
if(this.$refs.qrcodeEl) this.$refs.qrcodeEl.innerHTML = '';
this._qrInstance = null;
},
stopQrTimers(){
if(this._pollTimer){ clearInterval(this._pollTimer); this._pollTimer = null; }
if(this._countdownTimer){ clearInterval(this._countdownTimer); this._countdownTimer = null; }
},
submitCcpay(){
if(!this.ccpayAmount || this.ccpayAmount <= 0){
this.$message({type:'warning', message:'Vui lòng nhập số tiền!'});
return;
}
if(this.ccpayAmount < 1000000){
this.$message({type:'warning', message:'Số tiền tối thiểu là 1,000,000'});
return;
}
if(this.submitting) return;
this.submitting = true;
var encryptstring = encrypt(JSON.stringify({
user_id: this.userInfo.uid,
price: this.ccpayAmount,
client: 1,
username: this.userInfo.nickname,
api_token: this.userInfo.api_token,
})).toString();
this.$axios.post(this.ApiUrl+'/ccpay_online_order', {encryptData:encryptstring}).then(
response=>{
this.submitting = false;
if(response.data.Success==1){
const data = JSON.parse(decrypt(response.data.Data));
if(data.status == 1 && data.qrcode){
this.openBank(data.qrcode);
} else if(data.status == 1 && data.url){
window.open(data.url, '_blank');
} else {
this.$message({type:'error', message: data.message || 'Nạp thất bại'});
}
} else {
this.$message({type:'error', message: response.data.Msg || 'Nạp thất bại'});
}
}).catch(error=>{
this.submitting = false;
console.log(error);
this.$message({type:'error', message:'Yêu cầu thất bại'});
});
},
openBank(qrcode){
this.bank.data = qrcode;
this.bank.visible = true;
this.bank.statusText = this.Language.pay_waiting || 'Đang chờ thanh toán...';
this.bank.statusClass = 'waiting';
this.$nextTick(() => {
if(qrcode.qr_data){
this.renderBankQr(qrcode.qr_data);
}
});
this.startBankCountdown();
this.startBankPolling();
},
renderBankQr(text){
const el = this.$refs.bankQrcodeEl;
if(!el) return;
el.innerHTML = '';
this._bankQrInstance = new QRCode(el, {
text: text,
width: 180,
height: 180,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.M,
});
},
startBankCountdown(){
const tick = () => {
const left = Math.max(0, this.bank.data.expires_at - Math.floor(Date.now()/1000));
const m = Math.floor(left/60);
const s = left % 60;
this.bank.countdownText = (m<10?'0':'')+m+':'+(s<10?'0':'')+s;
if(left <= 0){
this.bank.statusText = this.Language.pay_expired || 'Đơn hàng đã hết hạn';
this.bank.statusClass = 'expired';
this.stopBankTimers();
}
};
tick();
this._bankCountdownTimer = setInterval(tick, 1000);
},
startBankPolling(){
const poll = () => {
if(!this.bank.visible || !this.bank.data.order_sn) return;
const encryptstring = encrypt(JSON.stringify({
user_id: this.userInfo.uid,
order_sn: this.bank.data.order_sn,
api_token: this.userInfo.api_token,
})).toString();
this.$axios.post(this.ApiUrl+'/ccpay_order_status', {encryptData:encryptstring}).then(res=>{
if(res.data.Success!=1) return;
const d = JSON.parse(decrypt(res.data.Data));
if(d.status == 1){
this.bank.statusText = this.Language.pay_success || 'Thanh toán thành công!';
this.bank.statusClass = 'success';
this.stopBankTimers();
this.updateMoney && this.updateMoney();
setTimeout(() => this.closeBank(), 2500);
} else if(d.status == 2){
this.bank.statusText = this.Language.pay_expired || 'Đơn hàng đã hết hạn';
this.bank.statusClass = 'expired';
this.stopBankTimers();
}
}).catch(()=>{});
};
this._bankPollTimer = setInterval(poll, 3000);
setTimeout(poll, 1000);
},
closeBank(){
this.bank.visible = false;
this.stopBankTimers();
if(this.$refs.bankQrcodeEl) this.$refs.bankQrcodeEl.innerHTML = '';
this._bankQrInstance = null;
},
stopBankTimers(){
if(this._bankPollTimer){ clearInterval(this._bankPollTimer); this._bankPollTimer = null; }
if(this._bankCountdownTimer){ clearInterval(this._bankCountdownTimer); this._bankCountdownTimer = null; }
},
}, },
computed: { computed: {
...mapState(['userInfo','webconfig','Language']) ...mapState(['userInfo','webconfig','Language'])
@@ -122,8 +513,44 @@ export default {
width:100%; width:100%;
height: 250px; height: 250px;
} }
.recharge2 .pay-tabs{
display: flex;
padding: 10px 40px 0;
gap: 10px;
}
.recharge2 .pay-tab{
flex: 1;
text-align: center;
padding: 8px 0;
color: #aaa;
background: rgba(0,0,0,0.3);
border: 1px solid #907545;
border-radius: 5px;
cursor: pointer;
font-size: 13px;
user-select: none;
transition: all .2s;
}
.recharge2 .pay-tab:hover{ color: #e5b932; }
.recharge2 .pay-tab.active{
background: linear-gradient(to right, #e5b932, #c5971e);
color: #161107;
font-weight: bold;
border-color: #e5b932;
}
.recharge2 .alin-tip{
color: #e5b932;
font-size: 12px;
line-height: 1.5;
margin: -5px 0 15px;
opacity: 0.85;
}
.recharge2 .alin-submit:disabled{
opacity: 0.5;
cursor: not-allowed;
}
.recharge2 .alin-form{ .recharge2 .alin-form{
padding: 30px 40px; padding: 20px 40px;
} }
.recharge2 .alin-item{ .recharge2 .alin-item{
margin-bottom: 15px; margin-bottom: 15px;
@@ -183,4 +610,123 @@ export default {
color: #ffeb3b; color: #ffeb3b;
} }
/* ============ 内嵌 USDT 二维码弹窗 ============ */
.qr-mask{
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.72);
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
}
.qr-box{
width: 360px;
background: #1a1206;
border: 1px solid #907545;
border-radius: 10px;
padding: 20px 22px;
box-shadow: 0 0 20px rgba(229,185,50,0.15);
color: #e5b932;
position: relative;
box-sizing: border-box;
}
.qr-close{
position: absolute;
right: 10px; top: 6px;
color: #aaa;
font-size: 22px;
cursor: pointer;
line-height: 1;
padding: 2px 8px;
}
.qr-close:hover{ color: #e5b932; }
.qr-title{
text-align: center;
font-size: 15px;
font-weight: bold;
margin-bottom: 6px;
}
.qr-status{
text-align: center;
font-size: 12px;
padding: 4px 0;
margin-bottom: 10px;
border-radius: 4px;
}
.qr-status.waiting{ color: #e5b932; }
.qr-status.success{ color: #7cd992; }
.qr-status.expired{ color: #e74c3c; }
.qr-code-wrap{
width: 180px;
height: 180px;
margin: 0 auto 14px;
background: #fff;
padding: 8px;
border-radius: 6px;
box-sizing: content-box;
}
.qr-code-wrap img, .qr-code-wrap canvas{
display: block;
width: 180px !important;
height: 180px !important;
}
.qr-field{
margin-bottom: 10px;
}
.qr-field-label{
color: #bbb;
font-size: 11px;
margin-bottom: 4px;
}
.qr-field-value{
display: flex;
align-items: center;
gap: 8px;
background: rgba(0,0,0,0.35);
border: 1px solid #5a4323;
border-radius: 4px;
padding: 6px 8px;
font-size: 12px;
word-break: break-all;
}
.qr-field-value.amount{
color: #fff;
font-weight: bold;
font-size: 14px;
}
.qr-field-value.addr{
color: #e5b932;
font-family: 'Courier New', monospace;
font-size: 11px;
}
.qr-field-value > span{ flex: 1; }
.qr-copy{
flex-shrink: 0;
background: #c5971e;
border: none;
color: #161107;
font-size: 11px;
padding: 3px 10px;
border-radius: 3px;
cursor: pointer;
}
.qr-copy:hover{ background: #e5b932; }
.qr-meta{
display: flex;
justify-content: space-between;
color: #bbb;
font-size: 12px;
margin: 12px 0 6px;
}
.qr-countdown{ color: #e5b932; font-weight: bold; }
.qr-tip{
color: #e74c3c;
font-size: 11px;
text-align: center;
line-height: 1.5;
margin-top: 8px;
opacity: 0.85;
}
</style> </style>
+2
View File
@@ -8,6 +8,8 @@ import store from './store'
import common from './common/js/common' import common from './common/js/common'
import './common/css/reset.css' import './common/css/reset.css'
import './common/css/animate.css' import './common/css/animate.css'
import { setupErrorReporting } from './plugins/error-report'
setupErrorReporting(Vue)
Vue.config.productionTip = false Vue.config.productionTip = false
/* eslint-disable no-new */ /* eslint-disable no-new */
+64
View File
@@ -0,0 +1,64 @@
var queue = []
var sending = false
function getReportUrl() {
var api = localStorage.getItem('ApiUrl')
if (api) {
try { api = JSON.parse(api) } catch(e) { api = '' }
}
return (api || '') + '/log/report'
}
function send(data) {
if (queue.length >= 10) return
data.source = 'pc'
data.time = new Date().toISOString()
data.url = location.href
queue.push(data)
flush()
}
function flush() {
if (sending || queue.length === 0) return
sending = true
var item = queue.shift()
var xhr = new XMLHttpRequest()
xhr.open('POST', getReportUrl())
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.onloadend = function() { sending = false; flush() }
xhr.onerror = function() { sending = false }
xhr.timeout = 3000
xhr.send(JSON.stringify(item))
}
export function setupErrorReporting(Vue) {
Vue.config.errorHandler = function(err, vm, info) {
send({
type: 'vue_error',
message: err.message,
stack: err.stack ? err.stack.substring(0, 2000) : '',
info: info
})
console.error(err)
}
window.onerror = function(message, source, lineno, colno, error) {
send({
type: 'error',
message: String(message),
stack: error && error.stack ? error.stack.substring(0, 2000) : '',
file: source,
line: lineno,
col: colno
})
}
window.addEventListener('unhandledrejection', function(event) {
var reason = event.reason
send({
type: 'unhandledrejection',
message: reason && reason.message ? reason.message : String(reason),
stack: reason && reason.stack ? reason.stack.substring(0, 2000) : ''
})
})
}
+4
View File
@@ -38,6 +38,7 @@ const state = {
backClearBet: false, backClearBet: false,
isTablist: false, isTablist: false,
choselist: [], choselist: [],
_savedChoseIds: JSON.parse(localStorage.getItem("multiChoseIds") || "[]"),
isaudio: true, isaudio: true,
mainPop: { mainPop: {
type: "", type: "",
@@ -88,6 +89,7 @@ const mutations = {
.post(ApiUrl + "/all_table", { encryptData: secret }) .post(ApiUrl + "/all_table", { encryptData: secret })
.then((response) => { .then((response) => {
var data = JSON.parse(decrypt(response.data.Data)); var data = JSON.parse(decrypt(response.data.Data));
data.forEach(function(t) { if (t.count_down === undefined) t.count_down = 0; });
state.tabData = data; state.tabData = data;
}) })
.catch((error) => { .catch((error) => {
@@ -133,6 +135,7 @@ const mutations = {
}, },
// 获取所有游戏台 // 获取所有游戏台
taballData(state, data) { taballData(state, data) {
data.forEach(function(t) { if (t.count_down === undefined) t.count_down = 0; });
state.tabData = data; state.tabData = data;
}, },
// 选择筹码 // 选择筹码
@@ -174,6 +177,7 @@ const mutations = {
}, },
multipleData(state, data) { multipleData(state, data) {
state.choselist = data; state.choselist = data;
localStorage.setItem("multiChoseIds", JSON.stringify(data.map(function(t) { return t.id; })));
}, },
// 刷新视频 // 刷新视频
refresh(state) { refresh(state) {
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More