完善接口和后台页面
This commit is contained in:
@@ -1,48 +1,231 @@
|
||||
<template>
|
||||
<el-dialog class="ba-operate-dialog" :close-on-click-modal="false" :model-value="['Add', 'Edit'].includes(baTable.form.operate!)" @close="baTable.toggleForm">
|
||||
<template>
|
||||
<el-dialog
|
||||
class="ba-operate-dialog deposit-detail-dialog"
|
||||
:close-on-click-modal="false"
|
||||
:model-value="isOpen"
|
||||
width="640px"
|
||||
@close="onDialogClose"
|
||||
>
|
||||
<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>
|
||||
<div class="title" v-drag="['.ba-operate-dialog', '.el-dialog__header']" v-zoom="'.ba-operate-dialog'">
|
||||
{{ t('order.depositOrder.detail_title') }}
|
||||
</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('order.depositOrder.order_no')" type="string" v-model="baTable.form.items!.order_no" prop="order_no" />
|
||||
<FormItem :label="t('order.depositOrder.user_id')" type="number" v-model="baTable.form.items!.user_id" prop="user_id" :input-attr="{ min: 1, step: 1 }" />
|
||||
<FormItem :label="t('order.depositOrder.channel_id')" type="number" v-model="baTable.form.items!.channel_id" prop="channel_id" :input-attr="{ min: 1, step: 1 }" />
|
||||
<FormItem :label="t('order.depositOrder.amount')" type="number" v-model="baTable.form.items!.amount" prop="amount" :input-attr="{ step: 0.0001, precision: 4, min: 0 }" />
|
||||
<FormItem :label="t('order.depositOrder.status')" type="radio" v-model="baTable.form.items!.status" prop="status" :input-attr="{ content: { '0': t('order.depositOrder.status 0'), '1': t('order.depositOrder.status 1'), '2': t('order.depositOrder.status 2'), '3': t('order.depositOrder.status 3') } }" />
|
||||
<FormItem :label="t('order.depositOrder.pay_channel')" type="string" v-model="baTable.form.items!.pay_channel" prop="pay_channel" />
|
||||
<FormItem :label="t('order.depositOrder.pay_time')" type="datetime" v-model="baTable.form.items!.pay_time" prop="pay_time" />
|
||||
<FormItem :label="t('order.depositOrder.remark')" type="textarea" v-model="baTable.form.items!.remark" prop="remark" :input-attr="{ rows: 2 }" />
|
||||
|
||||
<el-scrollbar v-loading="loading" class="ba-table-form-scrollbar">
|
||||
<div
|
||||
class="ba-operate-form ba-edit-form"
|
||||
:style="config.layout.shrink ? '' : 'width: calc(100% - ' + (baTable.form.labelWidth ?? 120) / 2 + 'px)'"
|
||||
>
|
||||
<el-form
|
||||
v-if="!loading"
|
||||
:label-position="config.layout.shrink ? 'top' : 'right'"
|
||||
:label-width="(baTable.form.labelWidth ?? 120) + 'px'"
|
||||
@submit.prevent=""
|
||||
>
|
||||
<el-form-item :label="t('order.depositOrder.order_no')">
|
||||
<el-input :model-value="form.order_no" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.idempotency_key')">
|
||||
<el-input :model-value="form.idempotency_key || '-'" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.user_username')">
|
||||
<el-input :model-value="form.user_text" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.channel_name')">
|
||||
<el-input :model-value="form.channel_text" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.status')">
|
||||
<el-tag :type="statusTagType" effect="dark" size="small">{{ statusLabel }}</el-tag>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('order.depositOrder.amount')">
|
||||
<el-input :model-value="amountText" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.bonus_amount')">
|
||||
<el-input :model-value="bonusText" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.total_credit')">
|
||||
<el-input :model-value="totalCreditText" readonly />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="t('order.depositOrder.pay_channel')">
|
||||
<el-input :model-value="form.pay_channel || '-'" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.pay_time')">
|
||||
<el-input :model-value="form.pay_time_text" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.deposit_tier_id')">
|
||||
<el-input :model-value="form.deposit_tier_id || '-'" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.remark')">
|
||||
<el-input v-model="form.remark" type="textarea" :rows="2" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('order.depositOrder.create_time')">
|
||||
<el-input :model-value="form.create_time_text" readonly />
|
||||
</el-form-item>
|
||||
</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 class="detail-footer">
|
||||
<el-button type="primary" v-blur @click="onDialogClose">{{ t('order.depositOrder.close_btn') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { FormItemRule } from 'element-plus'
|
||||
import { inject, reactive, useTemplateRef } from 'vue'
|
||||
import { computed, inject, reactive, ref, watch } 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({
|
||||
order_no: [{ required: true, message: t('Please input field', { field: t('order.depositOrder.order_no') }) }],
|
||||
user_id: [{ required: true, message: t('Please input field', { field: t('order.depositOrder.user_id') }) }],
|
||||
const loading = ref(false)
|
||||
|
||||
const form = reactive({
|
||||
id: 0,
|
||||
order_no: '',
|
||||
idempotency_key: '',
|
||||
user_text: '-',
|
||||
channel_text: '-',
|
||||
pay_channel: '',
|
||||
pay_time_text: '-',
|
||||
deposit_tier_id: '',
|
||||
remark: '',
|
||||
create_time_text: '-',
|
||||
amount: 0,
|
||||
bonus_amount: 0,
|
||||
status: 0,
|
||||
})
|
||||
|
||||
const isOpen = computed(() => ['Edit'].includes(baTable.form.operate ?? ''))
|
||||
|
||||
watch(
|
||||
() => ({ visible: isOpen.value, loadingState: baTable.form.loading, items: baTable.form.items }),
|
||||
({ visible, loadingState }) => {
|
||||
if (!visible) return
|
||||
loading.value = loadingState === true
|
||||
if (loadingState) return
|
||||
hydrate()
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
)
|
||||
|
||||
const hydrate = () => {
|
||||
const row = baTable.form.items as Record<string, unknown> | undefined
|
||||
if (!row || !row['id']) {
|
||||
return
|
||||
}
|
||||
form.id = Number(row['id'] ?? 0)
|
||||
form.order_no = String(row['order_no'] ?? '')
|
||||
form.idempotency_key = String(row['idempotency_key'] ?? '')
|
||||
form.pay_channel = String(row['pay_channel'] ?? '')
|
||||
form.deposit_tier_id = String(row['deposit_tier_id'] ?? '')
|
||||
form.remark = String(row['remark'] ?? '')
|
||||
form.amount = parseNumber(row['amount'])
|
||||
form.bonus_amount = parseNumber(row['bonus_amount'])
|
||||
form.status = Number(row['status'] ?? 0)
|
||||
form.create_time_text = formatTime(row['create_time'])
|
||||
form.pay_time_text = formatTime(row['pay_time'])
|
||||
form.user_text = resolveRelationText(row, 'user', row['user_id'])
|
||||
form.channel_text = resolveRelationText(row, 'channel', row['channel_id'])
|
||||
}
|
||||
|
||||
const statusLabel = computed(() => t('order.depositOrder.status ' + form.status))
|
||||
const statusTagType = computed(() => {
|
||||
switch (form.status) {
|
||||
case 1:
|
||||
return 'success'
|
||||
case 2:
|
||||
return 'danger'
|
||||
case 3:
|
||||
return 'warning'
|
||||
default:
|
||||
return 'info'
|
||||
}
|
||||
})
|
||||
|
||||
const amountText = computed(() => formatAmount(form.amount))
|
||||
const bonusText = computed(() => formatAmount(form.bonus_amount))
|
||||
const totalCreditText = computed(() => formatAmount(Number((form.amount + form.bonus_amount).toFixed(2))))
|
||||
|
||||
const onDialogClose = () => {
|
||||
baTable.toggleForm()
|
||||
}
|
||||
|
||||
function parseNumber(raw: unknown): number {
|
||||
if (raw === null || raw === undefined || raw === '') return 0
|
||||
const n = Number(raw)
|
||||
if (!Number.isFinite(n)) return 0
|
||||
return Number(n.toFixed(2))
|
||||
}
|
||||
|
||||
function formatAmount(value: number): string {
|
||||
if (!Number.isFinite(value)) return '0.00'
|
||||
return value.toFixed(2)
|
||||
}
|
||||
|
||||
function formatTime(raw: unknown): string {
|
||||
if (raw === null || raw === undefined || raw === '' || raw === 0) return '-'
|
||||
const sec = Number(raw)
|
||||
if (!Number.isFinite(sec) || sec <= 0) return '-'
|
||||
const d = new Date(sec * 1000)
|
||||
const pad = (n: number) => (n < 10 ? '0' + n : String(n))
|
||||
return (
|
||||
d.getFullYear() +
|
||||
'-' +
|
||||
pad(d.getMonth() + 1) +
|
||||
'-' +
|
||||
pad(d.getDate()) +
|
||||
' ' +
|
||||
pad(d.getHours()) +
|
||||
':' +
|
||||
pad(d.getMinutes()) +
|
||||
':' +
|
||||
pad(d.getSeconds())
|
||||
)
|
||||
}
|
||||
|
||||
function resolveRelationText(row: Record<string, unknown>, relationKey: string, fallbackId: unknown): string {
|
||||
const rel = row[relationKey]
|
||||
if (rel && typeof rel === 'object') {
|
||||
const r = rel as Record<string, unknown>
|
||||
const name = r['username'] ?? r['name']
|
||||
if (typeof name === 'string' && name !== '') {
|
||||
const id = fallbackId === null || fallbackId === undefined || fallbackId === '' ? '' : ' (ID: ' + String(fallbackId) + ')'
|
||||
return name + id
|
||||
}
|
||||
}
|
||||
if (fallbackId === null || fallbackId === undefined || fallbackId === '') {
|
||||
return '-'
|
||||
}
|
||||
return 'ID: ' + String(fallbackId)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<style scoped lang="scss">
|
||||
.deposit-detail-dialog {
|
||||
:deep(.el-dialog__body) {
|
||||
padding-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
:deep(.deposit-detail-dialog) {
|
||||
width: calc(100vw - 24px) !important;
|
||||
max-width: 100vw;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user