feat(custom): 新增大转盘第一版

This commit is contained in:
2023-12-27 02:28:18 +08:00
parent 74bce614f6
commit 7b6e0f3754
12 changed files with 8771 additions and 3224 deletions

View File

@@ -2,7 +2,7 @@
# TARO_APP_ID="开发环境下的小程序appid"
TARO_APP_API = 'https://game.wanzhuanyongcheng.cn/dice'
TARO_APP_API = 'https://game.wanzhuanyongcheng.cn'
TARO_APP_WS = 'wss://game.wanzhuanyongcheng.cn/dice/home'

View File

@@ -1,114 +1,115 @@
{
"name": "test",
"version": "1.0.0",
"private": true,
"description": "",
"templateInfo": {
"name": "default",
"typescript": true,
"css": "sass"
},
"scripts": {
"build:weapp": "taro build --type weapp",
"build:swan": "taro build --type swan",
"build:alipay": "taro build --type alipay",
"build:tt": "taro build --type tt",
"build:h5": "taro build --type h5",
"build:h5:test": "taro build --type h5 --mode test",
"build:one": "taro build --type h5 --mode one",
"build:tow": "taro build --type h5 --mode tow",
"build:rn": "taro build --type rn",
"build:qq": "taro build --type qq",
"build:jd": "taro build --type jd",
"build:quickapp": "taro build --type quickapp",
"dev:weapp": "npm run build:weapp -- --watch",
"dev:swan": "npm run build:swan -- --watch",
"dev:alipay": "npm run build:alipay -- --watch",
"dev:tt": "npm run build:tt -- --watch",
"dev:h5": "npm run build:h5 -- --watch",
"dev:rn": "npm run build:rn -- --watch",
"dev:qq": "npm run build:qq -- --watch",
"dev:jd": "npm run build:jd -- --watch",
"dev:quickapp": "npm run build:quickapp -- --watch",
"test": "jest",
"lint": "eslint --ext .ts,.vue .",
"lint:fix": "eslint --fix --ext .ts,.vue .",
"lint:staged": "lint-staged",
"prepare": "husky install",
"preview": "vite preview",
"cz": "cz",
"lf": "npx prettier --write --end-of-line lf ."
},
"browserslist": [
"last 3 versions",
"Android >= 4.1",
"ios >= 8"
],
"lint-staged": {
"*.{ts,vue}": [
"eslint --ext .ts,.vue .",
"npx prettier --write --end-of-line lf ."
]
},
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
},
"author": "",
"dependencies": {
"@babel/runtime": "^7.22.11",
"@sentry/browser": "^7.81.0",
"@sentry/vue": "^7.81.0",
"@sentry/webpack-plugin": "^2.10.1",
"@tarojs/components": "3.6.20",
"@tarojs/helper": "3.6.20",
"@tarojs/plugin-framework-vue3": "3.6.20",
"@tarojs/plugin-platform-alipay": "3.6.20",
"@tarojs/plugin-platform-h5": "3.6.20",
"@tarojs/plugin-platform-jd": "3.6.20",
"@tarojs/plugin-platform-qq": "3.6.20",
"@tarojs/plugin-platform-swan": "3.6.20",
"@tarojs/plugin-platform-tt": "3.6.20",
"@tarojs/plugin-platform-weapp": "3.6.20",
"@tarojs/runtime": "3.6.20",
"@tarojs/shared": "3.6.20",
"@tarojs/taro": "3.6.20",
"vue": "^3.3.4"
},
"devDependencies": {
"@babel/core": "^7.22.11",
"@commitlint/cli": "^18.2.0",
"@commitlint/config-conventional": "^18.1.0",
"@tarojs/cli": "3.6.20",
"@tarojs/taro-loader": "3.6.20",
"@tarojs/test-utils-vue3": "^0.1.1",
"@tarojs/webpack5-runner": "3.6.20",
"@types/jest": "^29.5.4",
"@types/node": "^20.5.7",
"@types/webpack-env": "^1.18.1",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
"@vue/babel-plugin-jsx": "^1.1.5",
"@vue/compiler-sfc": "^3.3.4",
"babel-preset-taro": "3.6.20",
"commitizen": "^4.3.0",
"css-loader": "6.8.1",
"cz-customizable": "^7.0.0",
"eslint": "^8.48.0",
"eslint-config-taro": "3.6.20",
"eslint-plugin-vue": "^9.17.0",
"husky": "^8.0.0",
"jest": "^29.6.4",
"jest-environment-jsdom": "^29.6.4",
"lint-staged": "^15.0.2",
"postcss": "^8.4.29",
"style-loader": "3.3.3",
"stylelint": "^15.10.3",
"ts-node": "^10.9.1",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"typescript": "^5.2.2",
"vue-loader": "^17.2.2",
"webpack": "5.88.2"
}
"name": "test",
"version": "1.0.0",
"private": true,
"description": "",
"templateInfo": {
"name": "default",
"typescript": true,
"css": "sass"
},
"scripts": {
"build:weapp": "taro build --type weapp",
"build:swan": "taro build --type swan",
"build:alipay": "taro build --type alipay",
"build:tt": "taro build --type tt",
"build:h5": "taro build --type h5",
"build:h5:test": "taro build --type h5 --mode test",
"build:one": "taro build --type h5 --mode one",
"build:tow": "taro build --type h5 --mode tow",
"build:rn": "taro build --type rn",
"build:qq": "taro build --type qq",
"build:jd": "taro build --type jd",
"build:quickapp": "taro build --type quickapp",
"dev:weapp": "npm run build:weapp -- --watch",
"dev:swan": "npm run build:swan -- --watch",
"dev:alipay": "npm run build:alipay -- --watch",
"dev:tt": "npm run build:tt -- --watch",
"dev:h5": "npm run build:h5 -- --watch",
"dev:rn": "npm run build:rn -- --watch",
"dev:qq": "npm run build:qq -- --watch",
"dev:jd": "npm run build:jd -- --watch",
"dev:quickapp": "npm run build:quickapp -- --watch",
"test": "jest",
"lint": "eslint --ext .ts,.vue .",
"lint:fix": "eslint --fix --ext .ts,.vue .",
"lint:staged": "lint-staged",
"prepare": "husky install",
"preview": "vite preview",
"cz": "cz",
"lf": "npx prettier --write --end-of-line lf ."
},
"browserslist": [
"last 3 versions",
"Android >= 4.1",
"ios >= 8"
],
"lint-staged": {
"*.{ts,vue}": [
"eslint --ext .ts,.vue .",
"npx prettier --write --end-of-line lf ."
]
},
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
},
"author": "",
"dependencies": {
"@babel/runtime": "^7.22.11",
"@sentry/browser": "^7.81.0",
"@sentry/vue": "^7.81.0",
"@sentry/webpack-plugin": "^2.10.1",
"@tarojs/components": "3.6.21",
"@tarojs/helper": "3.6.21",
"@tarojs/plugin-framework-vue3": "3.6.21",
"@tarojs/plugin-platform-alipay": "3.6.21",
"@tarojs/plugin-platform-h5": "3.6.21",
"@tarojs/plugin-platform-jd": "3.6.21",
"@tarojs/plugin-platform-qq": "3.6.21",
"@tarojs/plugin-platform-swan": "3.6.21",
"@tarojs/plugin-platform-tt": "3.6.21",
"@tarojs/plugin-platform-weapp": "3.6.21",
"@tarojs/runtime": "3.6.21",
"@tarojs/shared": "3.6.21",
"@tarojs/taro": "3.6.21",
"dayjs": "^1.11.10",
"vue": "^3.3.4"
},
"devDependencies": {
"@babel/core": "^7.22.11",
"@commitlint/cli": "^18.2.0",
"@commitlint/config-conventional": "^18.1.0",
"@tarojs/cli": "3.6.21",
"@tarojs/taro-loader": "3.6.21",
"@tarojs/test-utils-vue3": "^0.1.1",
"@tarojs/webpack5-runner": "3.6.21",
"@types/jest": "^29.5.4",
"@types/node": "^20.5.7",
"@types/webpack-env": "^1.18.1",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
"@vue/babel-plugin-jsx": "^1.1.5",
"@vue/compiler-sfc": "^3.3.4",
"babel-preset-taro": "3.6.21",
"commitizen": "^4.3.0",
"css-loader": "6.8.1",
"cz-customizable": "^7.0.0",
"eslint": "^8.48.0",
"eslint-config-taro": "3.6.21",
"eslint-plugin-vue": "^9.17.0",
"husky": "^8.0.0",
"jest": "^29.6.4",
"jest-environment-jsdom": "^29.6.4",
"lint-staged": "^15.0.2",
"postcss": "^8.4.29",
"style-loader": "3.3.3",
"stylelint": "^15.10.3",
"ts-node": "^10.9.1",
"tsconfig-paths-webpack-plugin": "^4.1.0",
"typescript": "^5.2.2",
"vue-loader": "^17.2.2",
"webpack": "5.88.2"
}
}

11198
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,16 +2,37 @@ import request from '@/utils/request'
export const getGameOption = () =>
request({
url: '/betting',
url: '/dice/betting',
method: 'GET',
})
export const getKaiJiangList = () => request({ url: '/draw', method: 'GET' })
export const getKaiJiangList = () => request({ url: '/dice/draw', method: 'GET' })
// 用户信息
export const getJfDz = (uid: string) =>
request({ url: `/userBettingInfo?uid=${uid}`, method: 'GET' })
request({ url: `/dice/userBettingInfo?uid=${uid}`, method: 'GET' })
// 用户投注记录
export const getTzJl = (uid: string) =>
request({ url: `/userBettingRecord?uid=${uid}`, method: 'GET' })
request({ url: `/dice/userBettingRecord?uid=${uid}`, method: 'GET' })
// 大转盘相关api
// 获取开奖记录
export const get_turntable_list = () => request({ url: '/australia/list', method: 'GET' })
// 获取个人信息
export const get_user_info = (uid: string) =>
request({ url: `/australia/user/info?uid=${uid}`, method: 'GET' })
// 大转盘投注
export const turntable_bet = (data: any) =>
request({ url: '/australia/user/dice', method: 'POST', data })
// 获取大转盘投注记录
export const get_turntable_bet_record = (uid: string, date: string) =>
request({ url: `/australia/user/record?uid=${uid}&date=${date}`, method: 'GET' })
// 获取大转盘开奖记录
export const get_turntable_open_record = () =>
request({ url: `/australia/history/list`, method: 'GET' })

View File

@@ -6,6 +6,8 @@ export default defineAppConfig({
'pages/yaotouzi/records/index',
'pages/balloon/index/index',
'pages/balloon/records/index',
'pages/aoshi/index/index',
'pages/aoshi/records/index',
],
window: {
backgroundTextStyle: 'light',

View File

@@ -1,8 +1,6 @@
.taro_page {
background-color: #f5f5f5 !important;
// width: 100vw !important;
// height: 100vh !important;
}
// .taro_page {
// background-color: #f5f5f5 !important;
// }
.mt-15 {
margin-top: 15px;

View File

@@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: '大转盘',
})

View File

@@ -0,0 +1,188 @@
.taro_page {
background-color: #fff !important;
}
.container {
font-size: 30px;
padding: 30px;
box-sizing: border-box;
.header {
display: flex;
justify-content: space-between;
align-items: center;
.right {
display: flex;
.btn {
padding: 5px 10px;
border: 1px solid #a6a6a6;
border-radius: 10px;
&:active {
color: #a6a6a6;
}
}
.btn:nth-child(2) {
margin-left: 10px;
}
}
}
.user-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 40px;
border: 1px solid #a6a6a6;
padding: 20px 50px;
background-color: #f4f4f4;
border-radius: 15px;
.left {
display: flex;
align-items: center;
.avatar {
margin-right: 20px;
width: 100px;
height: 100px;
image {
border-radius: 50%;
}
}
}
}
.turntable {
width: 500px;
height: 500px;
border: 1px solid #a6a6a6;
border-radius: 50%;
margin: 50px auto;
position: relative;
&::before,
&::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #a6a6a6;
}
&::before {
width: 2px;
height: 100%;
left: 50%;
top: 0;
transform: translateX(-50%);
}
&::after {
width: 100%;
height: 2px;
left: 0;
top: 50%;
transform: translateY(-50%);
}
.num-box {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
position: relative;
padding: 50px;
.item {
width: 200px;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 80px;
.icon {
position: absolute;
}
}
}
}
.kj-box {
.title {
font-size: 35px;
font-weight: bold;
.num {
color: red;
}
}
.title-sub {
text-align: center;
margin-top: 20px;
font-size: 40px;
display: flex;
.item {
width: 50px;
height: 50px;
line-height: 50px;
margin-right: 20px;
}
.item:nth-child(1) {
font-weight: bold;
color: red;
}
.item:nth-child(2) {
font-weight: bold;
color: red;
}
.item:nth-child(3) {
font-weight: bold;
color: red;
}
}
}
.countdown {
margin: 30px auto;
width: 100%;
height: 100px;
background-color: #ff0000;
text-align: center;
line-height: 100px;
border-radius: 15px;
color: #fff;
font-size: 40px;
}
.bet-opt {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.item {
width: 200px;
height: 100px;
border: 1px solid #ff0000;
border-radius: 10px;
margin-bottom: 20px;
text-align: center;
line-height: 100px;
}
}
.rule-box {
color: #ff0000;
font-size: 35px;
font-weight: bold;
margin-top: 20px;
text-align: center;
}
}

View File

@@ -0,0 +1,203 @@
<template>
<view class="container">
<view class="header">
<view class="left">公告开奖结果同步傲拾</view>
<view class="right">
<view class="btn" @click="toPage(1)">投注记录</view>
<view class="btn" @click="toPage(2)">开奖记录</view>
</view>
</view>
<view class="user-info">
<view class="left">
<view class="avatar">
<image :src="userInfo.avatarUrl || require('../../../static/tx.png')" />
</view>
<view class="info">
<view class="name">{{ userInfo.nickName || '用户' }}</view>
<view class="level">积分: {{ userInfo.integral || 0 }}</view>
</view>
</view>
<view class="right">豆子{{ userInfo.pulse || 0 }}</view>
</view>
<view class="turntable">
<view class="num-box">
<view
class="item"
v-for="(item, index) in nums"
:key="index"
:style="{
color: item.active ? '#ff0000' : '#000',
}"
@click="handleClick(item)"
>
<text>{{ item.value }}</text>
<image v-show="item.optActive" class="icon" src="../../../static/dz.png" />
</view>
</view>
</view>
<view class="kj-box">
<view class="title">
<text class="num">{{ kjData.nowPeriods || 0 }}</text>
期已开奖:
</view>
<view class="title-sub">
<view class="item" v-for="(item, index) in kjNums" :key="index">
{{ item }}
</view>
</view>
</view>
<view class="countdown">
{{ Number(kjData.nowPeriods) + 1 || 0 }}期开奖还剩: {{ timeStr || '0分0秒' }}
</view>
<view class="bet-opt">
<view class="item" v-for="(item, index) in betOpts" :key="index" @click="handleBet(item)">
{{ item.max }}豆子
</view>
</view>
<view class="rule-box" @click="handleRule">| 游戏规则 |</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { get_turntable_list, get_user_info, turntable_bet } from '@/api'
import Taro from '@tarojs/taro'
import * as dayjs from 'dayjs'
const userInfo = ref<any>({})
const nums = ref([
{
optActive: false,
active: false,
value: 1,
},
{
optActive: false,
active: false,
value: 2,
},
{
optActive: false,
active: false,
value: 4,
},
{
optActive: false,
active: false,
value: 3,
},
])
const kjNums = ref([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
interface BetOpts {
ID?: number
max?: number
odds?: number
}
const betOpts = ref<BetOpts[]>([])
Taro.useDidShow(() => {
get_info()
get_list()
})
const kjData = ref<any>({})
const timeId = ref<NodeJS.Timeout>()
const get_list = async () => {
const res = await get_turntable_list()
kjData.value = res.data || {}
kjNums.value = kjData.value.nowDraw.split(',').map((item) => Number(item))
betOpts.value = kjData.value.list
nums.value.forEach((item) => {
if (item.value === kjData.value.drawNumber) {
item.active = true
} else {
item.active = false
}
})
timeId.value = setInterval(() => {
countdownFn()
}, 1000)
}
const timeStr = ref('')
const countdownFn = () => {
const { drawTime } = kjData.value
const currentTimestamp = dayjs().valueOf()
const timeLeft = drawTime * 1000 - currentTimestamp
timeStr.value = dayjs(timeLeft).format('mm分ss秒')
if (currentTimestamp > drawTime * 1000) {
clearInterval(timeId.value)
get_list()
}
}
const get_info = async () => {
const res = await get_user_info(Taro.getStorageSync('uid'))
userInfo.value = res.data.data || {}
}
const handleClick = (itemOpt) => {
nums.value.forEach((item) => {
item.optActive = false
})
itemOpt.optActive = true
}
const handleBet = (item: BetOpts) => {
const newNums = nums.value.filter((item) => item.optActive === true)
if (newNums.length === 0)
return Taro.showToast({
title: '请选择投注项',
icon: 'none',
})
Taro.showModal({
title: '确认投注吗?',
content: `投注豆子:${item.max}`,
success: async (res) => {
if (res.confirm) {
const game_info = Taro.getStorageSync('gameItem')
const uid = Taro.getStorageSync('uid')
const res = await turntable_bet({
uid: uid,
number: nums.value.filter((item) => item.optActive === true)[0].value,
aid: item.max,
game_id: game_info.ID,
})
Taro.showToast({
title: res.msg,
icon: 'none',
})
}
},
})
}
const handleRule = () => {
Taro.showToast({
title: '暂无规则',
icon: 'none',
})
}
// 前往开奖和投注记录
const toPage = (type: number) => {
Taro.navigateTo({
url: `/pages/aoshi/records/index?type=${type}`,
})
}
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>

View File

@@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarBackgroundColor: '#23684B',
enablePullDownRefresh: true,
})

View File

@@ -0,0 +1,132 @@
<template>
<view class="app">
<template v-if="typeNum === 1">
<view class="card" v-for="(item,index) in list as any[]" :key="index">
<view>
<view>
{{ item.preDrawIssue }}期开奖:
<text
v-for="(num, i) in item.preDrawCode"
:key="i"
:style="{
color: numColor(num),
}"
>
{{ num }}
</text>
</view>
<view>开奖时间: {{ item.preDrawTime }}</view>
<view>开奖数字: {{ item.drawIssue }}</view>
</view>
</view>
</template>
<template v-else>
<view v-if="list.length > 0">
<view class="card desc" v-for="(item,index) in list as any[]" :key="index">
<view>
<view>{{ item.Periods }}期投注:</view>
<view>
点数:
<text style="color: red">{{ item.Name }}</text>
</view>
<view class="sub">
投注时间:
<text>{{ item.DrawTime }}</text>
</view>
</view>
<view style="text-align: right">
<view style="color: red" v-if="item.State === 1">+{{ item.DrawNum }}积分</view>
<view style="color: green">-{{ item.Number }}豆子</view>
</view>
</view>
</view>
<view v-else>
<view style="margin-top: 100px">暂无记录.....</view>
</view>
</template>
</view>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import Taro from '@tarojs/taro'
import { get_turntable_bet_record, get_turntable_open_record } from '@/api'
const list = ref<any[]>([])
const typeNum = ref(0)
Taro.useLoad((options) => {
typeNum.value = Number(options.type)
Taro.setNavigationBarTitle({
title: options.type === '1' ? '开奖记录' : '投注记录',
})
getData()
})
Taro.usePullDownRefresh(() => {
getData()
})
const numColor = (num: string) => {
switch (num) {
case '大':
return 'red'
case '小':
return 'green'
case '单':
return 'orange'
case '双':
return 'blue'
case '和':
return 'purple'
default:
return 'black'
}
}
const getData = async () => {
let res: any
if (typeNum.value === 1) {
res = await get_turntable_open_record()
list.value = res.data.data.result.data || []
} else {
res = await get_turntable_bet_record(Taro.getStorageSync('uid'), '1')
list.value = res.data.data || []
}
Taro.stopPullDownRefresh()
}
</script>
<style lang="scss" scoped>
.app {
display: flex;
flex-direction: column;
align-items: center;
//justify-content: center;
font-size: 35px;
width: 100%;
padding: 10px;
box-sizing: border-box;
}
.card {
width: 95%;
padding: 20px;
background-color: #fff;
margin-top: 10px;
border-radius: 10px;
.sub {
margin-top: 10px;
color: #555555;
}
}
.desc {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
</style>

View File

@@ -28,7 +28,6 @@ Taro.useLoad(() => {
const list = ref(['https://files.wanzhuanyongcheng.com/file/img/yaotouzi/banner/qietu.png'])
const startGame = () => {
console.log(info.value)
Taro.navigateTo({
url: info.value.url,
})