Compare commits

..
8 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
165 changed files with 187 additions and 67 deletions
+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 : '请确认密码',
+73 -54
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() {
function audioMp3(mp3List,audios){ try {
var WebConfig=JSON.parse(localStorage.getItem("WebConfig")); const config = JSON.parse(localStorage.getItem('WebConfig') || '{}')
audio=audios; return config.sound && config.sound == 2 ? '/static/sound2/' : '/static/sound/'
Mp3List=mp3List; } catch (e) {
var mp3=new Object(); return '/static/sound/'
mp3.mp3List=mp3List;
mp3.url="/static/sound/";
if(WebConfig.sound&&WebConfig.sound==2){mp3.url="/static/sound2/";}
mp3.auto_play=false;
mp3.loop=false;
mp3.Play=function(){
audio.src=this.url+this.mp3List[0];
audio.load();
audio.play();
}
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}; async function loadBuffer(key) {
if (bufferCache.has(key)) return bufferCache.get(key)
try {
const ctx = getAudioContext()
const url = getSoundBase() + key
const response = await fetch(url)
if (!response.ok) return null
const arrayBuffer = await response.arrayBuffer()
const audioBuffer = await ctx.decodeAudioData(arrayBuffer)
bufferCache.set(key, audioBuffer)
return audioBuffer
} catch (e) {
return null
}
}
function playBuffer(buffer) {
return new Promise((resolve) => {
const ctx = getAudioContext()
const source = ctx.createBufferSource()
source.buffer = buffer
source.connect(ctx.destination)
source.onended = resolve
source.start(0)
})
}
function audioMp3(mp3List, _audioEl) {
const myId = ++chainId
const list = mp3List || []
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 }
+2 -2
View File
@@ -279,8 +279,8 @@ function SoloPath(gameId,ctb,unit,x,y,type,corners,luck_six,dragon_seven,panda_e
ctb.lineWidth = unit*0.05; ctb.lineWidth = unit*0.05;
}else if(gameId==1 && dragon_seven > 0){ }else if(gameId==1 && dragon_seven > 0){
var color='#b8860b', fonts="7"; var color='#b8860b', fonts="7";
ctb.strokeStyle = "#c9980a"; ctb.strokeStyle = "#ff2202";
ctb.lineWidth = unit*0.05; ctb.lineWidth = unit*0.08;
}else if(gameId==1 && panda_eight > 0){ }else if(gameId==1 && panda_eight > 0){
var color='#34495e', fonts="8"; var color='#34495e', fonts="8";
ctb.strokeStyle = "#506878"; ctb.strokeStyle = "#506878";
@@ -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;
+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.
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