Merge branch 'test'

This commit is contained in:
2024-01-27 14:13:25 +08:00
9 changed files with 523 additions and 60 deletions

View File

@@ -1,22 +1,26 @@
# 资源公共路径,需要以 /开头和结尾
VITE_PUBLIC_PATH='/'
# 是否启用MOCK
VITE_USE_MOCK=false
# 是否启用代理
VITE_USE_PROXY=true
# base api
VITE_BASE_API='https://test.wanzhuanyongcheng.cn/admin'
VITE_WS1_URL='game.wanzhuanyongcheng.cn/dice/home'
VITE_WS_URL='test.wanzhuanyongcheng.cn/admin/data'
VITE_MER_LOGIN_URL='//localhost:3100/login'
VITE_GAME_API='https://www.jdt168.com'
# 是否启用监控
VITE_SENTRY=false
# 资源公共路径,需要以 /开头和结尾
VITE_PUBLIC_PATH='/'
# 是否启用MOCK
VITE_USE_MOCK=false
# 是否启用代理
VITE_USE_PROXY=true
# base api
VITE_BASE_API='https://test.wanzhuanyongcheng.cn/admin'
VITE_WS1_URL='game.wanzhuanyongcheng.cn/dice/home'
VITE_WS_URL='test.wanzhuanyongcheng.cn/admin/data'
VITE_MER_LOGIN_URL='//localhost:3100/login'
VITE_GAME_API='https://www.jdt168.com'
# 转盘相关
VITE_TRUN_WS_URL='test.wanzhuanyongcheng.cn/admin/turntable'
VITE_TRUN_WS1_URL='game2.wanzhuanyongcheng.cn/turntable/home'
# 是否启用监控
VITE_SENTRY=false

View File

@@ -24,5 +24,9 @@ VITE_GAME_API='https://game.wanzhuanyongcheng.cn'
VITE_MER_LOGIN_URL='//jdt-test-mer.wanzhuanyongcheng.cn/login'
# 转盘相关
VITE_TRUN_WS_URL='test.wanzhuanyongcheng.cn/admin/turntable'
VITE_TRUN_WS1_URL='game2.wanzhuanyongcheng.cn/turntable/home'
# 是否启用监控
VITE_SENTRY=false

View File

@@ -58,32 +58,32 @@ function getMenuItem(route, basePath = '') {
if (!visibleChildren.length) return menuItem
if (visibleChildren.length === 1) {
// 单个子路由处理
const singleRoute = visibleChildren[0]
menuItem = {
...menuItem,
label: singleRoute.meta?.title || singleRoute.name,
key: singleRoute.name,
path: resolvePath(menuItem.path, singleRoute.path),
icon: getIcon(singleRoute.meta),
}
const visibleItems = singleRoute.children
? singleRoute.children.filter((item) => item.name && !item.isHidden)
: []
// if (visibleChildren.length === 1) {
// // 单个子路由处理
// const singleRoute = visibleChildren[0]
// menuItem = {
// ...menuItem,
// label: singleRoute.meta?.title || singleRoute.name,
// key: singleRoute.name,
// path: resolvePath(menuItem.path, singleRoute.path),
// icon: getIcon(singleRoute.meta),
// }
// const visibleItems = singleRoute.children
// ? singleRoute.children.filter((item) => item.name && !item.isHidden)
// : []
if (visibleItems.length === 1) {
menuItem = getMenuItem(visibleItems[0], menuItem.path)
} else if (visibleItems.length > 1) {
menuItem.children = visibleItems
.map((item) => getMenuItem(item, menuItem.path))
.sort((a, b) => a.order - b.order)
}
} else {
menuItem.children = visibleChildren
.map((item) => getMenuItem(item, menuItem.path))
.sort((a, b) => a.order - b.order)
}
// if (visibleItems.length === 1) {
// menuItem = getMenuItem(visibleItems[0], menuItem.path)
// } else if (visibleItems.length > 1) {
// menuItem.children = visibleItems
// .map((item) => getMenuItem(item, menuItem.path))
// .sort((a, b) => a.order - b.order)
// }
// } else {
menuItem.children = visibleChildren
.map((item) => getMenuItem(item, menuItem.path))
.sort((a, b) => a.order - b.order)
// }
return menuItem
}

View File

@@ -6,4 +6,6 @@ export default {
getMerType: () => request.post('/store/getOther'),
// 一键登录
login: (data) => request.post('/store/easy/login', data),
// 退积分
outJf: (data) => request.post('/store/set/integral', data),
}

View File

@@ -153,6 +153,39 @@
</n-form>
</n-drawer-content>
</n-drawer>
<!-- 退积分 -->
<n-modal v-model:show="showModalJf">
<n-card
style="width: 600px"
title="退积分"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<n-form ref="formRefJf" :model="model" :rules="rulesJf" label-placement="left">
<n-grid :cols="24" :x-gap="24">
<n-form-item-gi :span="12" label="商家名称:">
<n-input v-model:value="model.name" disabled placeholder="商家名称" />
</n-form-item-gi>
<n-form-item-gi :span="24" label="退积分:" path="number">
<n-input-number
v-model:value="model.number"
placeholder="请输入积分"
clearable
:precision="3"
/>
</n-form-item-gi>
<n-form-item-gi span="24">
<n-button class="w-100" attr-type="button" type="primary" @click="handleOutClick">
提交
</n-button>
<n-button class="ml-10 w-100" @click="handleClearOutClick">取消</n-button>
</n-form-item-gi>
</n-grid>
</n-form>
</n-card>
</n-modal>
</CommonPage>
</template>
@@ -165,12 +198,67 @@ const vPerms = resolveDirective('perms')
const isEdit = computed(() => drawerTitle.value === '编辑商户')
const showModalJf = ref(false)
const formRefJf = ref(null)
const model = ref({
name: '',
bid: null,
number: null,
})
const rulesJf = ref({
number: {
required: true,
type: 'number',
message: '请输入退积分',
trigger: 'blur',
},
})
const handleOutClick = (e) => {
e.preventDefault()
formRefJf.value?.validate(async (errors) => {
if (!errors) {
try {
await api.outJf({
bid: model.value.bid,
number: model.value.number,
})
$message.success('成功')
handleClearOutClick()
await getMertype()
await getList()
showModalJf.value = false
} catch (error) {
$message.error(error.msg)
}
} else {
$message.error('Invalid')
}
})
}
const handleClearOutClick = () => {
formRefJf.value?.restoreValidation()
model.value = {
number: null,
}
showModalJf.value = false
}
const columns = ref([
{
title: '商户名称',
align: 'center',
key: 'name',
},
{
title: '电话',
align: 'center',
key: 'phone',
},
{
title: '状态',
align: 'center',
@@ -179,6 +267,16 @@ const columns = ref([
return h('span', row.status === 1 ? '正常' : '禁用')
},
},
{
title: '积分',
align: 'center',
key: 'integral',
},
{
title: '创建时间',
align: 'center',
key: 'add_time',
},
{
title: '操作',
align: 'center',
@@ -202,6 +300,24 @@ const columns = ref([
),
[[vPerms, ['/admin/store/edit']]]
),
withDirectives(
h(
NButton,
{
class: 'ml-10',
type: 'primary',
text: true,
size: 'small',
onClick: () => {
model.value.name = row.name
model.value.bid = row.bid
showModalJf.value = true
},
},
() => '退积分'
),
[[vPerms, ['/admin/store/set/integral']]]
),
withDirectives(
h(
NButton,

View File

@@ -27,17 +27,23 @@ export default {
// 全部投注用户
allUser: () => request.post('/all/draw/user', {}),
// 吹气球相关
// 转盘相关
// 游戏状态
getisBalloonStart: () => request.post('/getisBalloonStart'),
getisBalloonStart: () => request.post('/getisTurntableStart'),
// 修改游戏状态
setisBalloonStart: (data) => request.post('/isBalloonStart', data),
setisBalloonStart: (data) => request.post('/isTurntableStart', data),
// 你猜
setZsNum: () => request.post('/setTurntable'),
// 全部开奖记录
getBalloonList: () => request.post('/balloon/draw'),
getBalloonList: () => request.post('/turntable/draw'),
// 本局投注记录
getBalloonUser: () => request.post('/now/balloon/draw/user'),
getBalloonUser: () => request.post('/now/turntable/draw/user'),
// 全部投注记录
getAllBalloonUser: () => request.post('/all/balloon/draw/user'),
getAllBalloonUser: () => request.post('/all/turntable/draw/user'),
// 统计全部投注和中奖列表
getUserList: () => request.post('/user/balloon/list'),
getTjList: () => request.post('/user/turntable/list'),
// 宙斯记录
getZsBalloon: (data) => request.post('/turntable/log', data),
// 宙斯中奖
getZsBalloonUser: (data) => request.post('/log/turntable/list', data),
}

View File

@@ -7,7 +7,7 @@
v-model:value="gameStatus"
:checked-value="1"
:unchecked-value="2"
@update:value="handleUpdateValue"
@update:value="handleUpdateValue1"
/>
</div>
<div ml-20 flex items-center>
@@ -19,6 +19,69 @@
<n-button type="primary" @click="openModal(2)">预览</n-button>
</div>
</div>
<div flex>
<div>
预开期数
<span text-25>{{ list[0]?.Periods || 0 }}</span>
</div>
<div ml-20>
剩余开奖时间
<span text-25>{{ time || 0 }}</span>
</div>
<div ml-20>
本局总下注
<span text-25>{{ totalA || 0 }}</span>
</div>
</div>
<div>
<div>
<span text-25>{{ data[0]?.Periods || 0 }}</span>
期开奖结果
<span text-20>{{ data[0]?.Name || 0 }}</span>
</div>
</div>
<n-spin size="large" :show="show">
<div flex flex-wrap justify-between>
<n-card
v-for="item in list"
:key="item.ID"
class="mb-10 mt-10 h-120 w-250 flex-shrink-0 cursor-pointer"
:title="item.name"
>
<p text-25 op-60 :style="{ color: item.count === 0 ? 'green' : 'red' }">
{{ item.count }}
</p>
</n-card>
<div h-0 w-250></div>
<div h-0 w-250></div>
</div>
</n-spin>
<n-spin size="large" :show="show1">
<div flex flex-wrap justify-between>
<n-card
v-for="item in list1"
:key="item.ID"
class="mb-10 mt-10 h-150 w-250 flex-shrink-0 cursor-pointer"
:title="`${item.NumName}(${item.Name})`"
>
<p text-25 op-60 :style="{ color: item.Total === 0 ? 'green' : 'red' }">
{{ item.Total }}
</p>
<n-popconfirm @positive-click="handleUpdateValue(item.ID)">
<template #trigger>
<n-button>你猜</n-button>
</template>
一切都将一去杳然任何人都无法将其捕获
</n-popconfirm>
</n-card>
<div h-0 w-250></div>
<div h-0 w-250></div>
<div h-0 w-250></div>
<div h-0 w-250></div>
</div>
</n-spin>
<n-modal v-model:show="showModal">
<n-card
style="width: 900px"
@@ -79,21 +142,100 @@
<script setup>
import api from '../../api'
import { getToken } from '@/utils'
const ws = new WebSocket(`wss://${import.meta.env.VITE_TRUN_WS_URL}`)
const ws1 = new WebSocket(`wss://${import.meta.env.VITE_TRUN_WS1_URL}`)
const gameStatus = ref(2)
const t_1 = ref()
const t_2 = ref()
const show = ref(true)
const show1 = ref(true)
const list = ref([])
const list1 = ref([])
const totalA = ref(0)
const time = ref(0)
const data = ref([])
onBeforeUnmount(() => {
clearInterval(t_1.value)
clearInterval(t_2.value)
})
ws.onopen = () => {
t_1.value = setInterval(() => {
ws.send('ping')
}, 2500)
}
ws1.onopen = () => {
t_2.value = setInterval(() => {
ws1.send('ping')
}, 2500)
}
ws.onmessage = (e) => {
const res = JSON.parse(e.data)
list.value = res.betting.sort((a, b) => b.Total - a.Total)
show.value = false
list1.value = res.list.sort((a, b) => b.Total - a.Total)
show1.value = false
totalA.value = res.total
}
ws1.onmessage = (e) => {
const res = JSON.parse(e.data)
switch (res.code) {
case 200:
// let num = res.data
time.value = res.data
break
case 301:
$message.error(res.msg)
break
}
}
onMounted(() => {
get_status()
get_kj_jl()
})
const get_kj_jl = async () => {
try {
const res = await api.getBalloonList()
data.value = res.data.data
} catch (error) {
$message.error(error.msg)
throw error
}
}
const get_status = async () => {
const res = await api.getisBalloonStart()
gameStatus.value = res.data.balloonStart
gameStatus.value = res.data.diceStart
}
const handleUpdateValue = async (e) => {
const res = await api.setDS({
status: 1,
id: e,
user_id: getToken(),
Periods: list.value[0]?.Periods,
})
$message.success(res.msg)
}
const handleUpdateValue1 = async (e) => {
await api.setisBalloonStart({
Start: e,
start: e,
})
$message.success('修改成功')
get_status()
@@ -144,7 +286,7 @@ const { value: tempCol } = ref([
sortOrder: false,
},
{
title: '购买秒数',
title: '购买选项',
key: 'DrawTime',
align: 'center',
},

View File

@@ -127,7 +127,7 @@ const columns = ref([
align: 'center',
},
{
title: '开奖秒数',
title: '开奖号码',
key: 'Name',
align: 'center',
},
@@ -167,7 +167,7 @@ const getList = async () => {
dataObj.StartTime = range.value[0]
dataObj.EndTime = range.value[1]
}
const res = await api.getUserList(dataObj)
const res = await api.getTjList(dataObj)
const newData = res.data.data || []
data.value = newData
option.value.xAxis.data = []

View File

@@ -0,0 +1,189 @@
<template>
<CommonPage show-footer :title="$route.title">
<n-data-table
:max-height="500"
:loading="loading"
:columns="columns"
:data="data"
:bordered="true"
:virtual-scroll="true"
:pagination="pagination"
remote
/>
<!-- -->
<n-modal v-model:show="showModal">
<n-card
style="width: 800px"
title="宙斯的眷顾"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<n-data-table
:loading="zsLoading"
:columns="zsColumns"
:data="zsData"
:pagination="zsPagination"
:bordered="false"
/>
</n-card>
</n-modal>
</CommonPage>
</template>
<script setup>
import api from '../../api.js'
import { NButton } from 'naive-ui'
import { h, ref, onMounted } from 'vue'
const loading = ref(false)
const columns = ref([
{
title: '期数',
key: 'periods',
align: 'center',
},
{
title: '开奖号码',
key: 'betting_name',
align: 'center',
},
{
title: '开奖数字',
key: 'betting_number',
align: 'center',
},
{
title: '操作人',
key: 'name',
align: 'center',
},
{
title: '开奖时间',
key: 'draw_time',
align: 'center',
},
{
title: '操作时间',
key: 'add_time',
align: 'center',
},
{
title: '操作IP',
key: 'ip',
align: 'center',
},
{
title: '操作',
slot: 'action',
align: 'center',
render: (row) => {
return [
h(
NButton,
{
strong: true,
secondary: true,
onClick: () => {
openModal(row)
},
},
{ default: () => '查看' }
),
]
},
},
])
const data = ref([])
onMounted(() => {
getData()
})
const pagination = ref({
page: 1,
pageSize: 10,
itemCount: 0,
onChange: (page) => {
pagination.value.page = page
getData()
},
})
const getData = async () => {
const res = await api.getZsBalloon({
pageNum: pagination.value.page,
pageSize: pagination.value.pageSize,
})
data.value = res.data.data || []
pagination.value.itemCount = res.data.total
}
const showModal = ref(false)
const zsLoading = ref(false)
const zsColumns = ref([
{
title: '期数',
key: 'Periods',
align: 'center',
},
{
title: '数字',
key: 'PeriodsNum',
align: 'center',
},
{
title: '总投注(豆子)',
key: 'NumberSum',
align: 'center',
},
{
title: '赔付(积分)',
key: 'TotalCount',
align: 'center',
},
{
title: '选中用户',
key: 'User',
align: 'center',
},
{
title: '电话号码',
key: 'Phone',
align: 'center',
},
])
const zsData = ref([])
const zsPagination = ref({
page: 1,
pageSize: 10,
itemCount: 0,
onChange: (page) => {
zsPagination.value.page = page
getData()
},
})
const openModal = async (row) => {
showModal.value = true
zsLoading.value = true
const res = await api.getZsBalloonUser({
periods: row.periods,
draw_time: row.draw_time,
pageNum: zsPagination.value.page,
pageSize: zsPagination.value.pageSize,
})
zsData.value = res.data.data || []
zsPagination.value.itemCount = res.data.total
zsLoading.value = false
}
</script>
<style lang="scss" scoped></style>