[游戏管理]游戏实时对局
This commit is contained in:
@@ -22,8 +22,8 @@ export default {
|
||||
idempotency_key: 'Idempotency key',
|
||||
create_time: 'Created',
|
||||
update_time: 'Updated',
|
||||
gamePeriod_period_no: 'Period (relation)',
|
||||
gamePeriod_status: 'Period status',
|
||||
gameRecord_period_no: 'Round (relation)',
|
||||
gameRecord_status: 'Round status',
|
||||
user_username: 'Username',
|
||||
channel_name: 'Channel',
|
||||
}
|
||||
|
||||
14
web/src/lang/backend/en/game/live.ts
Normal file
14
web/src/lang/backend/en/game/live.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
tip: 'Listen to pushed bet stream in real time and show the AI default number (minimum estimated platform loss).',
|
||||
current_record: 'Current round',
|
||||
ai_default_number: 'AI default number',
|
||||
candidate_title: 'Candidate payout estimates',
|
||||
number: 'Number',
|
||||
estimated_loss: 'Estimated payout',
|
||||
bet_stream_title: 'Realtime bet stream',
|
||||
bet_id: 'Bet ID',
|
||||
user_id: 'Player ID',
|
||||
pick_numbers: 'Pick numbers',
|
||||
unit_amount: 'Unit amount',
|
||||
streak_at_bet: 'Streak at bet',
|
||||
}
|
||||
27
web/src/lang/backend/en/game/record.ts
Normal file
27
web/src/lang/backend/en/game/record.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export default {
|
||||
'quick Search Fields': 'Round No. / ID',
|
||||
id: 'ID',
|
||||
period_no: 'Round No.',
|
||||
period_start_at: 'Start time',
|
||||
status: 'Status',
|
||||
'status 0': 'Betting open',
|
||||
'status 1': 'Closed',
|
||||
'status 2': 'Settling',
|
||||
'status 3': 'Paying',
|
||||
'status 4': 'Ended',
|
||||
'status 5': 'Void',
|
||||
draw_mode: 'Draw mode',
|
||||
'draw_mode 0': 'Auto AI',
|
||||
'draw_mode 1': 'Manual preset',
|
||||
preset_number: 'Preset number',
|
||||
result_number: 'Result number',
|
||||
void_reason: 'Void reason',
|
||||
create_time: 'Created',
|
||||
update_time: 'Updated',
|
||||
section_auto: 'Auto draw & new round',
|
||||
auto_create_label: 'Allow auto-create next round',
|
||||
auto_create_tip: 'When enabled, ticker inserts next round if no active one exists',
|
||||
manual_create_label: 'Allow manual create next round',
|
||||
manual_create_tip: 'When enabled, button below can create next round manually',
|
||||
btn_create_next: 'Create next round (manual)',
|
||||
}
|
||||
@@ -22,14 +22,14 @@
|
||||
idempotency_key: 'Idempotency key',
|
||||
create_time: 'Created',
|
||||
update_time: 'Updated',
|
||||
gamePeriod_period_no: 'Period (relation)',
|
||||
gamePeriod_status: 'Period status',
|
||||
'gamePeriod_status 0': 'Open for betting',
|
||||
'gamePeriod_status 1': 'Closed',
|
||||
'gamePeriod_status 2': 'Settling tickets',
|
||||
'gamePeriod_status 3': 'Paying out',
|
||||
'gamePeriod_status 4': 'Finished',
|
||||
'gamePeriod_status 5': 'Voided',
|
||||
gameRecord_period_no: 'Round (relation)',
|
||||
gameRecord_status: 'Round status',
|
||||
'gameRecord_status 0': 'Open for betting',
|
||||
'gameRecord_status 1': 'Closed',
|
||||
'gameRecord_status 2': 'Settling tickets',
|
||||
'gameRecord_status 3': 'Paying out',
|
||||
'gameRecord_status 4': 'Finished',
|
||||
'gameRecord_status 5': 'Voided',
|
||||
user_username: 'Username',
|
||||
channel_name: 'Channel',
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ export default {
|
||||
idempotency_key: '幂等键',
|
||||
create_time: '创建时间',
|
||||
update_time: '更新时间',
|
||||
gamePeriod_period_no: '对局期号',
|
||||
gamePeriod_status: '期状态',
|
||||
gameRecord_period_no: '对局期号',
|
||||
gameRecord_status: '期状态',
|
||||
user_username: '用户名',
|
||||
channel_name: '渠道',
|
||||
}
|
||||
|
||||
14
web/src/lang/backend/zh-cn/game/live.ts
Normal file
14
web/src/lang/backend/zh-cn/game/live.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export default {
|
||||
tip: '实时监听页面推送的压注记录,并展示AI默认最优开奖号码(平台预估亏损最少)',
|
||||
current_record: '当前对局',
|
||||
ai_default_number: 'AI默认开奖号码',
|
||||
candidate_title: '候选号码赔付预估',
|
||||
number: '号码',
|
||||
estimated_loss: '预估赔付',
|
||||
bet_stream_title: '实时压注记录',
|
||||
bet_id: '注单ID',
|
||||
user_id: '玩家ID',
|
||||
pick_numbers: '压注号码',
|
||||
unit_amount: '单号金额',
|
||||
streak_at_bet: '下注时连胜',
|
||||
}
|
||||
27
web/src/lang/backend/zh-cn/game/record.ts
Normal file
27
web/src/lang/backend/zh-cn/game/record.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export default {
|
||||
'quick Search Fields': '局号/ID',
|
||||
id: 'ID',
|
||||
period_no: '局号',
|
||||
period_start_at: '开始时间',
|
||||
status: '状态',
|
||||
'status 0': '下注开放',
|
||||
'status 1': '已封盘',
|
||||
'status 2': '算票中',
|
||||
'status 3': '派彩中',
|
||||
'status 4': '已结束',
|
||||
'status 5': '已作废',
|
||||
draw_mode: '开奖方式',
|
||||
'draw_mode 0': '自动AI',
|
||||
'draw_mode 1': '手动预设',
|
||||
preset_number: '预设号码',
|
||||
result_number: '开奖号码',
|
||||
void_reason: '作废原因',
|
||||
create_time: '创建时间',
|
||||
update_time: '更新时间',
|
||||
section_auto: '自动开奖与新建对局',
|
||||
auto_create_label: '允许自动创建下一局',
|
||||
auto_create_tip: '开启后由后台定时任务在无进行中对局时自动插入新局',
|
||||
manual_create_label: '允许手动创建下一局',
|
||||
manual_create_tip: '开启后可在本页使用「手动创建下一局」按钮',
|
||||
btn_create_next: '手动创建下一局',
|
||||
}
|
||||
@@ -22,14 +22,14 @@
|
||||
idempotency_key: '幂等键',
|
||||
create_time: '创建时间',
|
||||
update_time: '更新时间',
|
||||
gamePeriod_period_no: '对局期号',
|
||||
gamePeriod_status: '期状态',
|
||||
'gamePeriod_status 0': '下注开放',
|
||||
'gamePeriod_status 1': '已封盘',
|
||||
'gamePeriod_status 2': '算票中',
|
||||
'gamePeriod_status 3': '派彩中',
|
||||
'gamePeriod_status 4': '已结束',
|
||||
'gamePeriod_status 5': '已作废',
|
||||
gameRecord_period_no: '对局期号',
|
||||
gameRecord_status: '期状态',
|
||||
'gameRecord_status 0': '下注开放',
|
||||
'gameRecord_status 1': '已封盘',
|
||||
'gameRecord_status 2': '算票中',
|
||||
'gameRecord_status 3': '派彩中',
|
||||
'gameRecord_status 4': '已结束',
|
||||
'gameRecord_status 5': '已作废',
|
||||
user_username: '用户名',
|
||||
channel_name: '渠道',
|
||||
}
|
||||
|
||||
140
web/src/views/backend/game/live/index.vue
Normal file
140
web/src/views/backend/game/live/index.vue
Normal file
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<el-alert type="info" :title="t('game.live.tip')" show-icon class="mb-12" />
|
||||
|
||||
<el-card shadow="never" class="mb-12">
|
||||
<div class="header-row">
|
||||
<div>
|
||||
<div>{{ t('game.live.current_record') }}: {{ snapshot.record?.period_no || '-' }}</div>
|
||||
<div>{{ t('game.live.ai_default_number') }}: {{ snapshot.ai_default_number ?? '-' }}</div>
|
||||
</div>
|
||||
<el-button type="primary" :loading="loading" @click="loadSnapshot">{{ t('Refresh') }}</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<el-card shadow="never">
|
||||
<template #header>{{ t('game.live.candidate_title') }}</template>
|
||||
<el-table :data="snapshot.candidate_numbers" height="420">
|
||||
<el-table-column prop="number" :label="t('game.live.number')" width="100" />
|
||||
<el-table-column prop="estimated_loss" :label="t('game.live.estimated_loss')" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card shadow="never">
|
||||
<template #header>{{ t('game.live.bet_stream_title') }}</template>
|
||||
<el-table :data="snapshot.bets" height="420">
|
||||
<el-table-column prop="id" :label="t('game.live.bet_id')" width="90" />
|
||||
<el-table-column prop="user_id" :label="t('game.live.user_id')" width="90" />
|
||||
<el-table-column prop="pick_numbers" :label="t('game.live.pick_numbers')">
|
||||
<template #default="scope">
|
||||
{{ formatPicks(scope.row.pick_numbers) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="unit_amount" :label="t('game.live.unit_amount')" width="120" />
|
||||
<el-table-column prop="streak_at_bet" :label="t('game.live.streak_at_bet')" width="90" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import createAxios from '/@/utils/axios'
|
||||
|
||||
interface Snapshot {
|
||||
record: anyObj | null
|
||||
bets: anyObj[]
|
||||
candidate_numbers: anyObj[]
|
||||
ai_default_number: number | null
|
||||
}
|
||||
|
||||
const { t } = useI18n()
|
||||
const loading = ref(false)
|
||||
const snapshot = reactive<Snapshot>({
|
||||
record: null,
|
||||
bets: [],
|
||||
candidate_numbers: [],
|
||||
ai_default_number: null,
|
||||
})
|
||||
|
||||
let pushClient: any = null
|
||||
let pushChannel: any = null
|
||||
|
||||
function formatPicks(v: unknown): string {
|
||||
if (Array.isArray(v)) return JSON.stringify(v)
|
||||
if (typeof v === 'string') return v
|
||||
return '-'
|
||||
}
|
||||
|
||||
async function loadSnapshot() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await createAxios({ url: '/admin/game.Live/snapshot', method: 'get', showCodeMessage: false })
|
||||
if (res.code === 1 && res.data) {
|
||||
snapshot.record = res.data.record
|
||||
snapshot.bets = res.data.bets || []
|
||||
snapshot.candidate_numbers = res.data.candidate_numbers || []
|
||||
snapshot.ai_default_number = res.data.ai_default_number
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initPush() {
|
||||
const cfgRes = await createAxios({ url: '/admin/game.Live/pushConfig', method: 'get', showCodeMessage: false })
|
||||
if (cfgRes.code !== 1 || !cfgRes.data) {
|
||||
return
|
||||
}
|
||||
const { url, app_key, channel, event } = cfgRes.data
|
||||
|
||||
await loadPushJs()
|
||||
const PushCtor = (window as any).Push
|
||||
if (!PushCtor) {
|
||||
return
|
||||
}
|
||||
pushClient = new PushCtor({ url, app_key })
|
||||
pushChannel = pushClient.subscribe(channel)
|
||||
pushChannel.on(event, (payload: anyObj) => {
|
||||
snapshot.record = payload.record || null
|
||||
snapshot.bets = payload.bets || []
|
||||
snapshot.candidate_numbers = payload.candidate_numbers || []
|
||||
snapshot.ai_default_number = payload.ai_default_number ?? null
|
||||
})
|
||||
}
|
||||
|
||||
async function loadPushJs() {
|
||||
if ((window as any).Push) {
|
||||
return
|
||||
}
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const script = document.createElement('script')
|
||||
script.src = '/plugin/webman/push/push.js'
|
||||
script.onload = () => resolve()
|
||||
script.onerror = () => reject(new Error('load push.js failed'))
|
||||
document.head.appendChild(script)
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadSnapshot()
|
||||
await initPush()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb-12 {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
203
web/src/views/backend/game/record/index.vue
Normal file
203
web/src/views/backend/game/record/index.vue
Normal file
@@ -0,0 +1,203 @@
|
||||
<template>
|
||||
<div class="default-main ba-table-box">
|
||||
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
|
||||
|
||||
<el-card v-if="canSettings" class="record-settings-card" shadow="never">
|
||||
<template #header>
|
||||
<span>{{ t('game.record.section_auto') }}</span>
|
||||
</template>
|
||||
<div v-loading="settingsLoading" class="record-settings-body">
|
||||
<div class="record-setting-row">
|
||||
<span class="record-setting-label">{{ t('game.record.auto_create_label') }}</span>
|
||||
<el-switch v-model="autoCreate" :disabled="settingsSaving" @change="onSwitchChange" />
|
||||
<span class="record-setting-tip">{{ t('game.record.auto_create_tip') }}</span>
|
||||
</div>
|
||||
<div class="record-setting-row">
|
||||
<span class="record-setting-label">{{ t('game.record.manual_create_label') }}</span>
|
||||
<el-switch v-model="manualCreate" :disabled="settingsSaving" @change="onSwitchChange" />
|
||||
<span class="record-setting-tip">{{ t('game.record.manual_create_tip') }}</span>
|
||||
</div>
|
||||
<div v-if="canManual" class="record-setting-actions">
|
||||
<el-button type="primary" :loading="createLoading" @click="onCreateNextManual">
|
||||
{{ t('game.record.btn_create_next') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<TableHeader
|
||||
:buttons="['refresh', 'add', 'edit', 'delete', 'comSearch', 'quickSearch', 'columnDisplay']"
|
||||
:quick-search-placeholder="t('Quick search placeholder', { fields: t('game.record.quick Search Fields') })"
|
||||
></TableHeader>
|
||||
|
||||
<Table ref="tableRef"></Table>
|
||||
|
||||
<PopupForm />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, provide, ref, useTemplateRef } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import PopupForm from './popupForm.vue'
|
||||
import { baTableApi } from '/@/api/common'
|
||||
import { defaultOptButtons } from '/@/components/table'
|
||||
import TableHeader from '/@/components/table/header/index.vue'
|
||||
import Table from '/@/components/table/index.vue'
|
||||
import createAxios from '/@/utils/axios'
|
||||
import baTableClass from '/@/utils/baTable'
|
||||
import { auth } from '/@/utils/common'
|
||||
|
||||
defineOptions({
|
||||
name: 'game/record',
|
||||
})
|
||||
|
||||
const { t } = useI18n()
|
||||
const tableRef = useTemplateRef('tableRef')
|
||||
const optButtons: OptButton[] = defaultOptButtons(['edit', 'delete'])
|
||||
|
||||
const settingsLoading = ref(false)
|
||||
const settingsSaving = ref(false)
|
||||
const createLoading = ref(false)
|
||||
const autoCreate = ref(false)
|
||||
const manualCreate = ref(false)
|
||||
const settingsReady = ref(false)
|
||||
|
||||
const canSettings = computed(() => auth('recordSettings'))
|
||||
const canManual = computed(() => auth('createNextManual'))
|
||||
|
||||
const baTable = new baTableClass(
|
||||
new baTableApi('/admin/game.Record/'),
|
||||
{
|
||||
pk: 'id',
|
||||
column: [
|
||||
{ type: 'selection', align: 'center', operator: false },
|
||||
{ label: t('game.record.id'), prop: 'id', align: 'center', width: 100, operator: 'RANGE', sortable: 'custom' },
|
||||
{ label: t('game.record.period_no'), prop: 'period_no', align: 'center', minWidth: 180, operatorPlaceholder: t('Fuzzy query'), operator: 'LIKE' },
|
||||
{ label: t('game.record.period_start_at'), prop: 'period_start_at', align: 'center', width: 170, render: 'datetime', operator: 'RANGE', comSearchRender: 'datetime', sortable: 'custom', timeFormat: 'yyyy-mm-dd hh:MM:ss' },
|
||||
{
|
||||
label: t('game.record.status'),
|
||||
prop: 'status',
|
||||
align: 'center',
|
||||
width: 110,
|
||||
operator: 'eq',
|
||||
render: 'tag',
|
||||
effect: 'dark',
|
||||
custom: { '0': 'success', '1': 'warning', '2': 'info', '3': 'primary', '4': 'warning', '5': 'danger' },
|
||||
replaceValue: { '0': t('game.record.status 0'), '1': t('game.record.status 1'), '2': t('game.record.status 2'), '3': t('game.record.status 3'), '4': t('game.record.status 4'), '5': t('game.record.status 5') },
|
||||
},
|
||||
{
|
||||
label: t('game.record.draw_mode'),
|
||||
prop: 'draw_mode',
|
||||
align: 'center',
|
||||
width: 110,
|
||||
operator: 'eq',
|
||||
render: 'tag',
|
||||
custom: { '0': 'info', '1': 'warning' },
|
||||
replaceValue: { '0': t('game.record.draw_mode 0'), '1': t('game.record.draw_mode 1') },
|
||||
},
|
||||
{ label: t('game.record.preset_number'), prop: 'preset_number', align: 'center', width: 100, operator: 'RANGE' },
|
||||
{ label: t('game.record.result_number'), prop: 'result_number', align: 'center', width: 100, operator: 'RANGE' },
|
||||
{ label: t('game.record.void_reason'), prop: 'void_reason', align: 'center', minWidth: 140, operatorPlaceholder: t('Fuzzy query'), operator: 'LIKE', showOverflowTooltip: true },
|
||||
{ label: t('game.record.create_time'), prop: 'create_time', align: 'center', render: 'datetime', operator: 'RANGE', comSearchRender: 'datetime', sortable: 'custom', width: 170, timeFormat: 'yyyy-mm-dd hh:MM:ss' },
|
||||
{ label: t('game.record.update_time'), prop: 'update_time', align: 'center', render: 'datetime', operator: 'RANGE', comSearchRender: 'datetime', sortable: 'custom', width: 170, timeFormat: 'yyyy-mm-dd hh:MM:ss' },
|
||||
{ label: t('Operate'), align: 'center', width: 100, render: 'buttons', buttons: optButtons, operator: false, fixed: 'right' },
|
||||
],
|
||||
dblClickNotEditColumn: [undefined],
|
||||
},
|
||||
{
|
||||
defaultItems: { status: 0, draw_mode: 0, void_reason: '' },
|
||||
}
|
||||
)
|
||||
|
||||
provide('baTable', baTable)
|
||||
|
||||
async function loadRecordSettings() {
|
||||
if (!canSettings.value) return
|
||||
settingsLoading.value = true
|
||||
try {
|
||||
const res = await createAxios({ url: '/admin/game.Record/recordSettings', method: 'get', showCodeMessage: false })
|
||||
if (res.code === 1 && res.data) {
|
||||
autoCreate.value = res.data.period_auto_create_enabled === 1
|
||||
manualCreate.value = res.data.period_manual_create_enabled === 1
|
||||
settingsReady.value = true
|
||||
}
|
||||
} finally {
|
||||
settingsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function onSaveSettings() {
|
||||
if (!canSettings.value) return
|
||||
settingsSaving.value = true
|
||||
try {
|
||||
await createAxios({
|
||||
url: '/admin/game.Record/recordSettings',
|
||||
method: 'post',
|
||||
data: {
|
||||
period_auto_create_enabled: autoCreate.value ? 1 : 0,
|
||||
period_manual_create_enabled: manualCreate.value ? 1 : 0,
|
||||
},
|
||||
showSuccessMessage: true,
|
||||
})
|
||||
} finally {
|
||||
settingsSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function onSwitchChange() {
|
||||
if (!settingsReady.value) return
|
||||
void onSaveSettings()
|
||||
}
|
||||
|
||||
async function onCreateNextManual() {
|
||||
if (!canManual.value) return
|
||||
createLoading.value = true
|
||||
try {
|
||||
await createAxios({ url: '/admin/game.Record/createNextManual', method: 'post', showSuccessMessage: true })
|
||||
await baTable.getData()
|
||||
} finally {
|
||||
createLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
baTable.table.ref = tableRef.value
|
||||
baTable.mount()
|
||||
void loadRecordSettings()
|
||||
baTable.getData()?.then(() => {
|
||||
baTable.initSort()
|
||||
baTable.dragSort()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.record-settings-card {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.record-settings-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.record-setting-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.record-setting-label {
|
||||
min-width: 160px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.record-setting-tip {
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
}
|
||||
.record-setting-actions {
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
62
web/src/views/backend/game/record/popupForm.vue
Normal file
62
web/src/views/backend/game/record/popupForm.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<el-dialog class="ba-operate-dialog" :close-on-click-modal="false" :model-value="['Add', 'Edit'].includes(baTable.form.operate!)" @close="baTable.toggleForm">
|
||||
<template #header>
|
||||
<div class="title" v-drag="['.ba-operate-dialog', '.el-dialog__header']" v-zoom="'.ba-operate-dialog'">
|
||||
{{ baTable.form.operate ? t(baTable.form.operate) : '' }}
|
||||
</div>
|
||||
</template>
|
||||
<el-scrollbar v-loading="baTable.form.loading" class="ba-table-form-scrollbar">
|
||||
<div class="ba-operate-form" :class="'ba-' + baTable.form.operate + '-form'" :style="config.layout.shrink ? '' : 'width: calc(100% - ' + baTable.form.labelWidth! / 2 + 'px)'">
|
||||
<el-form v-if="!baTable.form.loading" ref="formRef" @submit.prevent="" @keyup.enter="baTable.onSubmit(formRef)" :model="baTable.form.items" :label-position="config.layout.shrink ? 'top' : 'right'" :label-width="baTable.form.labelWidth + 'px'" :rules="rules">
|
||||
<FormItem :label="t('game.record.period_no')" type="string" v-model="baTable.form.items!.period_no" prop="period_no" />
|
||||
<FormItem :label="t('game.record.period_start_at')" type="datetime" v-model="baTable.form.items!.period_start_at" prop="period_start_at" />
|
||||
<FormItem
|
||||
:label="t('game.record.status')"
|
||||
type="radio"
|
||||
v-model="baTable.form.items!.status"
|
||||
prop="status"
|
||||
:input-attr="{ content: { '0': t('game.record.status 0'), '1': t('game.record.status 1'), '2': t('game.record.status 2'), '3': t('game.record.status 3'), '4': t('game.record.status 4'), '5': t('game.record.status 5') } }"
|
||||
/>
|
||||
<FormItem
|
||||
:label="t('game.record.draw_mode')"
|
||||
type="radio"
|
||||
v-model="baTable.form.items!.draw_mode"
|
||||
prop="draw_mode"
|
||||
:input-attr="{ content: { '0': t('game.record.draw_mode 0'), '1': t('game.record.draw_mode 1') } }"
|
||||
/>
|
||||
<FormItem :label="t('game.record.preset_number')" type="number" v-model="baTable.form.items!.preset_number" prop="preset_number" :input-attr="{ step: 1, min: 1, max: 36 }" />
|
||||
<FormItem :label="t('game.record.result_number')" type="number" v-model="baTable.form.items!.result_number" prop="result_number" :input-attr="{ step: 1, min: 1, max: 36 }" />
|
||||
<FormItem :label="t('game.record.void_reason')" type="textarea" v-model="baTable.form.items!.void_reason" prop="void_reason" :input-attr="{ rows: 3 }" />
|
||||
</el-form>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<template #footer>
|
||||
<div :style="'width: calc(100% - ' + baTable.form.labelWidth! / 1.8 + 'px)'">
|
||||
<el-button @click="baTable.toggleForm()">{{ t('Cancel') }}</el-button>
|
||||
<el-button v-blur :loading="baTable.form.submitLoading" @click="baTable.onSubmit(formRef)" type="primary">
|
||||
{{ baTable.form.operateIds && baTable.form.operateIds.length > 1 ? t('Save and edit next item') : t('Save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { FormItemRule } from 'element-plus'
|
||||
import { inject, reactive, useTemplateRef } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import FormItem from '/@/components/formItem/index.vue'
|
||||
import { useConfig } from '/@/stores/config'
|
||||
import type baTableClass from '/@/utils/baTable'
|
||||
|
||||
const config = useConfig()
|
||||
const formRef = useTemplateRef('formRef')
|
||||
const baTable = inject('baTable') as baTableClass
|
||||
const { t } = useI18n()
|
||||
|
||||
const rules: Partial<Record<string, FormItemRule[]>> = reactive({
|
||||
period_no: [{ required: true, message: t('Please input field', { field: t('game.record.period_no') }) }],
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@@ -68,8 +68,8 @@ const baTable = new baTableClass(
|
||||
operator: 'LIKE',
|
||||
},
|
||||
{
|
||||
label: t('order.betOrder.gamePeriod_period_no'),
|
||||
prop: 'gamePeriod.period_no',
|
||||
label: t('order.betOrder.gameRecord_period_no'),
|
||||
prop: 'gameRecord.period_no',
|
||||
align: 'center',
|
||||
minWidth: 160,
|
||||
operatorPlaceholder: t('Fuzzy query'),
|
||||
@@ -77,8 +77,8 @@ const baTable = new baTableClass(
|
||||
render: 'tags',
|
||||
},
|
||||
{
|
||||
label: t('order.betOrder.gamePeriod_status'),
|
||||
prop: 'gamePeriod.status',
|
||||
label: t('order.betOrder.gameRecord_status'),
|
||||
prop: 'gameRecord.status',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
operator: 'eq',
|
||||
@@ -93,12 +93,12 @@ const baTable = new baTableClass(
|
||||
'5': 'danger',
|
||||
},
|
||||
replaceValue: {
|
||||
'0': t('order.betOrder.gamePeriod_status 0'),
|
||||
'1': t('order.betOrder.gamePeriod_status 1'),
|
||||
'2': t('order.betOrder.gamePeriod_status 2'),
|
||||
'3': t('order.betOrder.gamePeriod_status 3'),
|
||||
'4': t('order.betOrder.gamePeriod_status 4'),
|
||||
'5': t('order.betOrder.gamePeriod_status 5'),
|
||||
'0': t('order.betOrder.gameRecord_status 0'),
|
||||
'1': t('order.betOrder.gameRecord_status 1'),
|
||||
'2': t('order.betOrder.gameRecord_status 2'),
|
||||
'3': t('order.betOrder.gameRecord_status 3'),
|
||||
'4': t('order.betOrder.gameRecord_status 4'),
|
||||
'5': t('order.betOrder.gameRecord_status 5'),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user