Files
jdt-game/src/pages/yaotouzi/index/index.vue

698 lines
21 KiB
Vue

<template>
<view class="index">
<!-- 公告 -->
<view class="subColor tips"></view>
<scroll-view style="height: 100vh" scroll-y>
<!-- 用户信息 -->
<view class="subColor userInfo">
<view class="left">
<image :src="userInfo.avatarUrl"></image>
<view class="userText">
<view class="userName">{{ userInfo.nickName || '用户' }}</view>
<view class="userScore">积分: {{ userInfo.integral || 0 }}</view>
</view>
</view>
<view class="right">
<view class="icon"></view>
<view class="bean">{{ userInfo.pulse || 0 }}</view>
</view>
</view>
<!-- 游戏信息 -->
<view class="subColor gameInfo">
<view class="left">
<image src="../../../static/tx.png"></image>
<view class="game_box">
<view class="gameName">{{ kJData[0]?.Periods || 0 }}期开奖</view>
<view class="lottery">
<text class="text">{{ kJData[0]?.Start || 0 }}</text>
<text class="text">{{ kJData[0]?.End || 0 }}</text>
<!-- <text class="text">6</text>-->
</view>
</view>
</view>
<view class="center">
<view>剩余{{ time }}s开奖</view>
</view>
<view class="right">
<view class="btn" @click="utils.vibrateShort(() => toPage(1))">开奖记录</view>
<view class="btn mt-15" @click="utils.vibrateShort(() => toPage(2))">
投注记录
</view>
</view>
</view>
<!-- 选项区 -->
<view class="opt">
<view
class="subColor item"
:class="{ flicker: item.flicker }"
v-for="item in odds"
:key="item.id"
@click.stop="utils.vibrateShort(() => addNum(item))"
>
<view class="name">{{ item.name }}</view>
<view class="odd">{{ item.odds }}</view>
<view class="mask" v-if="item.status">
<!-- <view class="text">{{ item.markNum }}</view> -->
<view class="text">{{ item.numStr }}</view>
</view>
<view
class="close"
v-if="item.status"
@click.stop="utils.vibrateShort(() => clearOneBet(item))"
>
x
</view>
</view>
</view>
<view class="opt1" v-if="odds1.length > 0">
<view class="optt">
<view
class="subColor item"
:class="{ flicker: odds1[0].flicker }"
@click.stop="utils.vibrateShort(() => addNum(odds1[0]))"
>
<view class="name">{{ odds1[0].name }}</view>
<view class="odd">{{ odds1[0].odds }}</view>
<view class="mask" v-if="odds1[0].status">
<!-- <view class="text">{{ odds1[0].markNum }}</view> -->
<view class="text">{{ odds1[0].numStr }}</view>
</view>
<view
class="close"
v-if="odds1[0].status"
@click.stop="utils.vibrateShort(() => clearOneBet(odds1[0]))"
>
x
</view>
</view>
<view
class="subColor item"
:class="{ flicker: odds1[1].flicker }"
@click.stop="utils.vibrateShort(() => addNum(odds1[1]))"
>
<view class="name">{{ odds1[1].name }}</view>
<view class="odd">{{ odds1[1].odds }}</view>
<view class="mask" v-if="odds1[1].status">
<!-- <view class="text">{{ odds1[1].markNum }}</view> -->
<view class="text">{{ odds1[1].numStr }}</view>
</view>
<view
class="close"
v-if="odds1[1].status"
@click.stop="utils.vibrateShort(() => clearOneBet(odds1[1]))"
>
x
</view>
</view>
</view>
<view class="base">
<view class="qz">
<view :class="{ activeQz: isExpanding }">
{{ qzTitle }}
</view>
</view>
<view class="expanding-div" v-if="isShow">
{{ nowKJInfo.Start }} - {{ nowKJInfo.End }}
</view>
</view>
<view class="optt">
<view
class="subColor item"
style="height: 100%"
:class="{ flicker: odds1[2].flicker }"
@click.stop="utils.vibrateShort(() => addNum(odds1[2]))"
>
<view class="name">{{ odds1[2].name }}</view>
<view class="odd">{{ odds1[2].odds }}</view>
<view class="mask" v-if="odds1[2].status">
<!-- <view class="text">{{ odds1[2].markNum }}</view> -->
<view class="text">{{ odds1[2].numStr }}</view>
</view>
<view
class="close"
v-if="odds1[2].status"
@click.stop="utils.vibrateShort(() => clearOneBet(odds1[2]))"
>
x
</view>
</view>
<!-- <view
class="subColor item"
:class="{ flicker: odds1[3].flicker }"
@click.stop="addNum(odds1[3])"
>
<view class="name">{{ odds1[3].name }}</view>
<view class="odd">{{ odds1[3].odds }}</view>
<view class="mask" v-if="odds1[3].status">
<view class="text">{{ odds1[3].markNum }}</view>
</view>
</view> -->
</view>
</view>
<view class="opt">
<view
class="subColor item item1"
:class="{ flicker: item.flicker }"
v-for="item in odds2"
:key="item.id"
@click.stop="utils.vibrateShort(() => addNum(item))"
>
<view class="name">{{ item.name }}</view>
<view class="odd">{{ item.odds }}</view>
<view class="mask" v-if="item.status">
<!-- <view class="text">{{ item.markNum }}</view> -->
<view class="text">{{ item.numStr }}</view>
</view>
<view
class="close"
v-if="item.status"
@click.stop="utils.vibrateShort(() => clearOneBet(item))"
>
x
</view>
</view>
</view>
<scroll-view style="height: 25%" scroll-y>
<view class="card subColor" v-for="(item,index) in kjList as any[]" :key="index">
<view>
<view>
{{ item.Periods }}期开奖:
<text style="color: red">{{ item.Start }} , {{ item.End }}</text>
<text
v-for="(num, i) in item.Name"
:key="i"
:style="{
color: numColor(num),
}"
>
, {{ num }}
</text>
</view>
<!-- <view class="sub">开奖个数:-->
<!-- <text v-for="(num,i) in item.Name" :key="i" :style="{-->
<!-- color: numColor(num)-->
<!-- }">{{ num }},-->
<!-- </text>-->
<!-- </view>-->
</view>
</view>
</scroll-view>
</scroll-view>
<!-- 底部操作栏 -->
<view class="subColor bottomBar">
<view class="btn1" @click="utils.vibrateShort(() => clearBet(true))">重置</view>
<view class="btn2" @click="utils.vibrateShort(() => changeOdd())">X{{ oddVal }}</view>
<view class="btn3" @click="utils.vibrateShort(() => verifyBet())">投注</view>
</view>
</view>
</template>
<script lang="ts" setup>
import { ref, onBeforeUnmount } from 'vue'
import Taro from '@tarojs/taro'
import { app } from '@/config'
import { getGameOption, getKaiJiangList, getJfDz } from '@/api'
import utils from '@/utils'
const ws = ref<null | WebSocket>(null)
// 是否显示开奖动画
const isShow = ref(false)
// 是否开启文字放大动画
const isExpanding = ref(false)
interface Odd {
id?: number
name?: string
odds?: number
markNum?: number
status?: boolean
flicker?: boolean
numStr?: number
}
const odds = ref<Odd[]>([])
const odds1 = ref<Odd[]>([])
const odds2 = ref<Odd[]>([])
const qzTitle = ref('请投注')
const time = ref(0)
const nowKJInfo = ref<{
Start?: string
End?: string
Periods?: number
}>({})
const userInfo = ref<{
pulse?: number
integral?: number
nickName?: string
avatarUrl?: string
}>({})
const zjObj = ref<any>([])
const iMsgNum = ref(0)
const numColor = (num: string) => {
switch (num) {
case '大':
return 'red'
case '小':
return 'green'
// case '单':
// return 'orange'
// case '双':
// return 'blue'
case '和':
return 'purple'
default:
return 'black'
}
}
Taro.useDidShow(() => {
startMusic('https://files.wanzhuanyongcheng.com/file/music/yaotouzi/bg.MP3', true)
initWs()
initData()
})
Taro.useDidHide(() => {
console.log('useDidHide')
ws.value?.close()
})
onBeforeUnmount(() => {
console.log('useBeforeUnmount')
ws.value?.close()
})
const initData = () => {
qzTitle.value = '请投注'
getOddList()
getKJList()
getUserInfo()
}
const arr = ['2+2', '3+3', '4+4', '5+5', '6+6']
// const arr1 = ["大", "小", "单", "双"];
// const arr2 = ["和", "3", "4", "5", "6", "8", "9", "10", "11"];
const arr1 = ['大', '小', '和']
const arr2 = ['3', '4', '5', '6', '8', '9', '10', '11']
// 投注列表
const getOddList = async () => {
const res = await getGameOption()
odds.value = []
odds1.value = []
odds2.value = []
res.data.data.forEach((item: any) => {
const { name, ID, odds: odd, max } = item
const newItem = {
id: ID,
name: name,
odds: odd,
max: max,
markNum: 0,
numStr: 0,
status: false,
flicker: false,
}
if (Taro.getStorageSync('odds')) {
odds.value = Taro.getStorageSync('odds')
odds1.value = Taro.getStorageSync('odds1')
odds2.value = Taro.getStorageSync('odds2')
} else {
if (arr1.includes(name)) {
odds1.value.push(newItem)
} else if (arr.includes(name)) {
odds.value.push(newItem)
} else if (arr2.includes(name)) {
odds2.value.push(newItem)
}
}
})
// const el = odds2.value.splice(0, 1)[0];
// odds2.value.splice(4, 0, el);
// console.log(odds1.value)
}
// 获取个人信息
const getUserInfo = async () => {
const res = await getJfDz(Taro.getStorageSync('uid'))
userInfo.value = res.data.data
}
const kJData = ref<any>([])
const kjList = ref<any>([])
// 开奖列表
const getKJList = async () => {
const res = await getKaiJiangList()
kJData.value = res.data.data
kjList.value = res.data.data.map((item: any) => {
return {
...item,
Name: item.Name.split('-'),
}
})
}
// 初始化游戏
const initWs = () => {
ws.value = new WebSocket(`${app.API_WS()}`)
ws.value.onopen = async () => {
Taro.showToast({
title: '连接游戏服务器成功',
mask: true,
icon: 'none',
})
}
ws.value.onmessage = async (e: any) => {
const res = JSON.parse(e.data)
switch (res.code) {
case 200:
let num = Number(res.data)
time.value = num
if (num === 5) {
openDraw()
}
break
case 401:
Taro.showToast({
title: '未登录',
mask: true,
icon: 'none',
})
break
case 403:
Taro.showToast({
title: '未能操作',
mask: true,
icon: 'none',
})
break
case 400:
Taro.showToast({
title: '豆子不足',
mask: true,
icon: 'none',
})
break
case 5:
Taro.showToast({
title: '投注成功',
mask: true,
icon: 'none',
})
break
case 100:
Taro.showToast({
title: res.msg,
icon: 'none',
})
break
case 101:
Taro.showToast({
title: res.msg,
icon: 'none',
})
break
case 301:
Taro.showToast({
title: res.msg,
icon: 'none',
})
setTimeout(() => {
Taro.navigateBack({
delta: 1,
})
}, 2000)
default:
iMsgNum.value++
zjObj.value = res
break
}
}
ws.value.onerror = () => {
console.log('连接游戏服务器失败')
Taro.showToast({
title: '连接游戏服务器失败',
mask: true,
icon: 'none',
})
}
}
const isKj = ref(false)
// 开奖倒计时
const openDraw = () => {
isExpanding.value = true
isKj.value = true
startMusic('https://files.wanzhuanyongcheng.com/file/music/yaotouzi/djs.MP3', false)
for (let i = 5; i > 0; i--) {
setTimeout(() => {
// i <= 3 && (fontColor.value = "red");
qzTitle.value = i.toString()
}, 1000 * (5 - i))
}
setTimeout(async () => {
isExpanding.value = false
const res = await getKaiJiangList()
nowKJInfo.value = res.data.data[0]
qzTitle.value = `${nowKJInfo.value?.Periods || 0}期开奖`
playAminExpand()
setTimeout(() => {
startFlicker()
}, 6000)
isKj.value = false
}, 5000)
}
const oddVal = ref(100)
const changeOdd = () => {
switch (oddVal.value) {
case 100:
oddVal.value = 1000
break
// case 10:
// oddVal.value = 100
// break
case 1000:
oddVal.value = 100
break
}
}
const clearBet = (val: boolean) => {
clearItems(odds.value, val)
clearItems(odds1.value, val)
clearItems(odds2.value, val)
savsData()
}
const clearItems = (items: any[], isClear: boolean = false) => {
items.forEach((item: any) => {
item.markNum = 0
if (isClear) {
item.numStr = 0
item.status = false
}
})
}
const addNum = (item: any) => {
if (isKj.value)
return Taro.showToast({
title: '正在开奖,不能下注',
icon: 'none',
})
if (item.name === '单' || item.name === '双')
return Taro.showToast({
title: `${item.name}不能下注`,
icon: 'none',
})
item.status = true
item.markNum += oddVal.value
item.numStr += oddVal.value
if (item.markNum >= item.max && item.numStr >= item.max) {
item.markNum = item.max
item.numStr = item.max
Taro.showToast({
title: `单注不能超过${item.max}`,
icon: 'none',
})
}
savsData()
}
// 投注
const verifyBet = () => {
if (isKj.value)
return Taro.showToast({
title: '正在开奖,不能下注',
icon: 'none',
})
let numCount = 0
odds.value.forEach((item: any) => {
if (item.markNum > 0) {
numCount += item.markNum
}
})
odds1.value.forEach((item: any) => {
if (item.markNum > 0) {
numCount += item.markNum
}
})
odds2.value.forEach((item: any) => {
if (item.markNum > 0) {
numCount += item.markNum
}
})
if (numCount === 0)
return Taro.showToast({
title: '请选择选项,再投注',
icon: 'none',
})
if (numCount > (userInfo.value?.pulse as number))
return Taro.showToast({
title: '投注豆子不足',
icon: 'none',
})
const data: any[] = []
odds.value.forEach((item: any) => {
if (item.markNum > 0) {
data.push({
bid: item.id,
number: item.markNum,
name: item.name,
})
}
})
odds1.value.forEach((item: any) => {
if (item.markNum > 0) {
data.push({
bid: item.id,
number: item.markNum,
name: item.name,
})
}
})
odds2.value.forEach((item: any) => {
if (item.markNum > 0) {
data.push({
bid: item.id,
number: item.markNum,
name: item.name,
})
}
})
ws.value?.send(
JSON.stringify({
type: 1,
data: data,
})
)
setTimeout(() => {
getUserInfo()
}, 1000)
qzTitle.value = '已投注'
clearBet(false)
savsData()
}
// 前往开奖和投注记录
const toPage = (type: number) => {
Taro.navigateTo({
url: `/pages/yaotouzi/records/index?type=${type}`,
})
}
// 播放展开动画
const playAminExpand = () => {
isShow.value = true
startMusic('https://files.wanzhuanyongcheng.com/file/music/yaotouzi/kj.MP3', false)
setTimeout(() => {
isShow.value = false
initData()
}, 10000)
}
// 开始闪烁
const startFlicker = () => {
flickerItems(odds.value)
flickerItems(odds1.value)
flickerItems(odds2.value)
zjObj.value = []
}
const flickerItems = (items: any[]) => {
delData()
items.forEach((item) => {
zjObj.value.forEach((item2: any) => {
if (item.name === item2.name) {
item.flicker = true
setTimeout(() => {
item.flicker = false
}, 3000)
}
})
})
startMusic('https://files.wanzhuanyongcheng.com/file/music/yaotouzi/bg.MP3', true)
}
const innerAudioContext = Taro.createInnerAudioContext()
const startMusic = (path: string, loop: boolean = false) => {
// const innerAudioContext = Taro.createInnerAudioContext()
innerAudioContext.autoplay = true
innerAudioContext.src = path
innerAudioContext.loop = loop
innerAudioContext.onPlay()
innerAudioContext.onError()
}
const clearOneBet = (item: Odd) => {
item.markNum = 0
item.numStr = 0
item.status = false
savsData()
}
const savsData = () => {
Taro.setStorageSync('odds', odds.value)
Taro.setStorageSync('odds1', odds1.value)
Taro.setStorageSync('odds2', odds2.value)
}
const delData = () => {
Taro.removeStorageSync('odds')
Taro.removeStorageSync('odds1')
Taro.removeStorageSync('odds2')
}
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>