176 lines
4.9 KiB
Vue
176 lines
4.9 KiB
Vue
<template>
|
|
<el-dialog
|
|
v-model="visible"
|
|
:title="$t('page.form.walletTitle')"
|
|
width="480px"
|
|
align-center
|
|
:close-on-click-modal="false"
|
|
@close="handleClose"
|
|
>
|
|
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
|
|
<el-form-item :label="$t('page.form.walletPlayer')">
|
|
<el-input :model-value="player?.username" disabled placeholder="-" />
|
|
</el-form-item>
|
|
<el-form-item :label="$t('page.form.walletBalance')">
|
|
<el-input-number
|
|
:model-value="walletBalance"
|
|
disabled
|
|
:precision="2"
|
|
controls-position="right"
|
|
style="width: 100%"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item :label="$t('page.form.operationType')" prop="type">
|
|
<el-select v-model="formData.type" :placeholder="$t('form.placeholderSelect')" clearable style="width: 100%">
|
|
<el-option :label="$t('page.form.typeAdd')" :value="3" />
|
|
<el-option :label="$t('page.form.typeSub')" :value="4" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item :label="$t('page.form.coinChange')" prop="coin">
|
|
<el-input-number
|
|
v-model="formData.coin"
|
|
:min="0.01"
|
|
:precision="2"
|
|
:placeholder="$t('page.form.placeholderCoinChange')"
|
|
controls-position="right"
|
|
style="width: 100%"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item :label="$t('form.labelRemark')" prop="remark">
|
|
<el-input
|
|
v-model="formData.remark"
|
|
type="textarea"
|
|
:rows="2"
|
|
:placeholder="$t('page.form.placeholderRemarkOptional')"
|
|
maxlength="500"
|
|
show-word-limit
|
|
/>
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
|
|
<el-button type="primary" :loading="submitting" @click="handleSubmit">{{ $t('common.confirm') }}</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import walletRecordApi from '../../../api/player_wallet_record/index'
|
|
import { ElMessage } from 'element-plus'
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
const { t } = useI18n()
|
|
|
|
interface PlayerRow {
|
|
id: number
|
|
username?: string
|
|
coin?: number
|
|
}
|
|
|
|
interface Props {
|
|
modelValue: boolean
|
|
player: PlayerRow | null
|
|
}
|
|
|
|
interface Emits {
|
|
(e: 'update:modelValue', value: boolean): void
|
|
(e: 'success'): void
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
modelValue: false,
|
|
player: null
|
|
})
|
|
|
|
const emit = defineEmits<Emits>()
|
|
|
|
const formRef = ref<FormInstance>()
|
|
const submitting = ref(false)
|
|
|
|
const visible = computed({
|
|
get: () => props.modelValue,
|
|
set: (v) => emit('update:modelValue', v)
|
|
})
|
|
|
|
const walletBalance = computed(() => {
|
|
const c = props.player?.coin
|
|
return c != null ? Number(c) : 0
|
|
})
|
|
|
|
const rules = computed<FormRules>(() => ({
|
|
type: [{ required: true, message: t('page.form.ruleSelectType'), trigger: 'change' }],
|
|
coin: [
|
|
{ required: true, message: t('page.form.ruleEnterCoin'), trigger: 'blur' },
|
|
{
|
|
validator: (_rule, value, callback) => {
|
|
const n = Number(value)
|
|
if (Number.isNaN(n) || n <= 0) {
|
|
callback(new Error(t('page.form.ruleCoinPositive')))
|
|
return
|
|
}
|
|
if (formData.type === 4 && n > walletBalance.value) {
|
|
callback(new Error(t('page.form.ruleDeductExceed')))
|
|
return
|
|
}
|
|
callback()
|
|
},
|
|
trigger: 'blur'
|
|
}
|
|
]
|
|
}))
|
|
|
|
const initialFormData = {
|
|
type: null as 3 | 4 | null,
|
|
coin: null as number | null,
|
|
remark: ''
|
|
}
|
|
|
|
const formData = reactive({ ...initialFormData })
|
|
|
|
watch(
|
|
() => props.modelValue,
|
|
(open) => {
|
|
if (open) {
|
|
Object.assign(formData, initialFormData)
|
|
formData.type = 3
|
|
}
|
|
}
|
|
)
|
|
|
|
const handleClose = () => {
|
|
visible.value = false
|
|
formRef.value?.resetFields()
|
|
}
|
|
|
|
const handleSubmit = async () => {
|
|
if (!formRef.value || !props.player?.id) return
|
|
try {
|
|
await formRef.value.validate()
|
|
const coin = Number(formData.coin) || 0
|
|
if (coin <= 0) {
|
|
ElMessage.warning(t('page.form.ruleCoinPositive'))
|
|
return
|
|
}
|
|
if (formData.type === 4 && coin > walletBalance.value) {
|
|
ElMessage.warning(t('page.form.ruleDeductExceed'))
|
|
return
|
|
}
|
|
submitting.value = true
|
|
await walletRecordApi.adminOperate({
|
|
player_id: props.player.id,
|
|
type: formData.type!,
|
|
coin,
|
|
remark: formData.remark?.trim() || undefined
|
|
})
|
|
ElMessage.success(t('page.form.operateSuccess'))
|
|
emit('success')
|
|
handleClose()
|
|
} catch (e) {
|
|
if ((e as any)?.message) ElMessage.warning((e as any).message)
|
|
} finally {
|
|
submitting.value = false
|
|
}
|
|
}
|
|
</script>
|