优化
This commit is contained in:
@@ -96,26 +96,40 @@
|
||||
type="number"
|
||||
v-model="baTable.form.items!.score"
|
||||
prop="score"
|
||||
:block-help="t('mall.item.score_tip')"
|
||||
:input-attr="{ step: 1 }"
|
||||
:placeholder="t('Please input field', { field: t('mall.item.score') })"
|
||||
/>
|
||||
|
||||
<!-- BONUS / WITHDRAW:现金面值、流水倍数 -->
|
||||
<FormItem
|
||||
v-if="isBonusOrWithdraw"
|
||||
:label="t('mall.item.amount')"
|
||||
type="number"
|
||||
v-model="baTable.form.items!.amount"
|
||||
prop="amount"
|
||||
:input-attr="{ step: 0.01 }"
|
||||
:placeholder="t('Please input field', { field: t('mall.item.amount') })"
|
||||
/>
|
||||
<el-form-item v-if="isBonusOrWithdraw" :label="t('mall.item.amount')" prop="amount">
|
||||
<el-input-number
|
||||
v-model="baTable.form.items!.amount"
|
||||
:min="0"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
class="w100"
|
||||
:placeholder="t('Please input field', { field: t('mall.item.amount') })"
|
||||
/>
|
||||
<div v-if="suggestedAmount !== null" class="form-tip amount-suggest-row">
|
||||
<span>{{ suggestedAmountHint }}</span>
|
||||
<el-button type="primary" link @click="applySuggestedAmount">
|
||||
{{ t('mall.item.amount_apply_suggested') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-else-if="isBonusOrWithdraw && pointsRatioLoaded" class="form-tip">
|
||||
{{ t('mall.item.amount_ratio_missing') }}
|
||||
</div>
|
||||
<div class="form-tip">{{ amountBlockHelp }}</div>
|
||||
</el-form-item>
|
||||
<FormItem
|
||||
v-if="isBonusOrWithdraw"
|
||||
:label="t('mall.item.multiplier')"
|
||||
type="number"
|
||||
v-model="baTable.form.items!.multiplier"
|
||||
prop="multiplier"
|
||||
:block-help="t('mall.item.multiplier_tip')"
|
||||
:input-attr="{ step: 1 }"
|
||||
:placeholder="t('Please input field', { field: t('mall.item.multiplier') })"
|
||||
/>
|
||||
@@ -190,8 +204,9 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { FormItemRule } from 'element-plus'
|
||||
import { computed, inject, reactive, useTemplateRef, watch } from 'vue'
|
||||
import { computed, inject, reactive, ref, useTemplateRef, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { index as fetchPlayxConfig } from '/@/api/backend/mall/playxConfig'
|
||||
import FormItem from '/@/components/formItem/index.vue'
|
||||
import { useConfig } from '/@/stores/config'
|
||||
import type baTableClass from '/@/utils/baTable'
|
||||
@@ -203,6 +218,79 @@ const baTable = inject('baTable') as baTableClass
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const pointsToCashRatio = ref<number | null>(null)
|
||||
const pointsRatioLoaded = ref(false)
|
||||
|
||||
const loadPointsToCashRatio = () => {
|
||||
pointsRatioLoaded.value = false
|
||||
fetchPlayxConfig()
|
||||
.then((res) => {
|
||||
const row = res.data.row ?? {}
|
||||
const raw = row.points_to_cash_ratio
|
||||
if (raw !== undefined && raw !== null && raw !== '') {
|
||||
const parsed = parseFloat(String(raw))
|
||||
pointsToCashRatio.value = Number.isFinite(parsed) ? parsed : null
|
||||
} else {
|
||||
pointsToCashRatio.value = null
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
pointsToCashRatio.value = null
|
||||
})
|
||||
.finally(() => {
|
||||
pointsRatioLoaded.value = true
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => baTable.form.operate,
|
||||
(op) => {
|
||||
if (op === 'Add' || op === 'Edit') {
|
||||
loadPointsToCashRatio()
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const suggestedAmount = computed(() => {
|
||||
const ratio = pointsToCashRatio.value
|
||||
if (ratio === null || ratio < 0) {
|
||||
return null
|
||||
}
|
||||
const score = Number(baTable.form.items?.score)
|
||||
if (!Number.isFinite(score) || score < 0) {
|
||||
return null
|
||||
}
|
||||
return Math.round(score * ratio * 100) / 100
|
||||
})
|
||||
|
||||
const suggestedAmountHint = computed(() => {
|
||||
if (suggestedAmount.value === null || pointsToCashRatio.value === null) {
|
||||
return ''
|
||||
}
|
||||
const score = Number(baTable.form.items?.score)
|
||||
return t('mall.item.amount_suggested', {
|
||||
amount: suggestedAmount.value,
|
||||
score: Number.isFinite(score) ? score : 0,
|
||||
ratio: pointsToCashRatio.value,
|
||||
})
|
||||
})
|
||||
|
||||
const amountBlockHelp = computed(() => {
|
||||
const base = t('mall.item.amount_tip')
|
||||
if (pointsToCashRatio.value === null) {
|
||||
return base
|
||||
}
|
||||
return `${base} ${t('mall.item.points_to_cash_ratio_label')}:${pointsToCashRatio.value}。`
|
||||
})
|
||||
|
||||
const applySuggestedAmount = () => {
|
||||
if (suggestedAmount.value === null || !baTable.form.items) {
|
||||
return
|
||||
}
|
||||
baTable.form.items.amount = suggestedAmount.value
|
||||
}
|
||||
|
||||
const itemType = computed(() => baTable.form.items!.type)
|
||||
const isBonus = computed(() => itemType.value === 1 || itemType.value === '1')
|
||||
const isPhysical = computed(() => itemType.value === 2 || itemType.value === '2')
|
||||
@@ -359,4 +447,20 @@ const rules: Partial<Record<string, FormItemRule[]>> = reactive({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<style scoped lang="scss">
|
||||
.w100 {
|
||||
width: 100%;
|
||||
}
|
||||
.form-tip {
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.amount-suggest-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 4px 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -15,6 +15,33 @@
|
||||
@keyup.enter="onSubmit()"
|
||||
>
|
||||
<el-tabs v-model="activeTab" class="playx-config-tabs">
|
||||
<el-tab-pane :label="t('mall.playxConfig.tab_regular')" name="regular">
|
||||
<el-form-item :label="t('mall.playxConfig.unlock_ratio')" prop="unlock_ratio">
|
||||
<el-input-number
|
||||
v-model="form.unlock_ratio"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
class="w100"
|
||||
/>
|
||||
<div class="form-tip">{{ t('mall.playxConfig.unlock_ratio_tip') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('mall.playxConfig.points_to_cash_ratio')" prop="points_to_cash_ratio">
|
||||
<el-input-number
|
||||
v-model="form.points_to_cash_ratio"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:step="0.01"
|
||||
:precision="4"
|
||||
controls-position="right"
|
||||
class="w100"
|
||||
/>
|
||||
<div class="form-tip">{{ t('mall.playxConfig.points_to_cash_ratio_tip') }}</div>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="t('mall.playxConfig.tab_event')" name="event">
|
||||
<el-divider content-position="left">{{ t('mall.playxConfig.section_event_period') }}</el-divider>
|
||||
<el-form-item :label="t('mall.playxConfig.mall_open_date')" prop="mall_open_date">
|
||||
@@ -94,34 +121,6 @@
|
||||
<div class="form-tip">{{ t('mall.playxConfig.calculate_lifetime_tip') }}</div>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="t('mall.playxConfig.tab_regular')" name="regular">
|
||||
<el-divider content-position="left">{{ t('mall.playxConfig.section_other') }}</el-divider>
|
||||
<el-form-item :label="t('mall.playxConfig.unlock_ratio')" prop="unlock_ratio">
|
||||
<el-input-number
|
||||
v-model="form.unlock_ratio"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
class="w100"
|
||||
/>
|
||||
<div class="form-tip">{{ t('mall.playxConfig.unlock_ratio_tip') }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('mall.playxConfig.points_to_cash_ratio')" prop="points_to_cash_ratio">
|
||||
<el-input-number
|
||||
v-model="form.points_to_cash_ratio"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:step="0.01"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
class="w100"
|
||||
/>
|
||||
<div class="form-tip">{{ t('mall.playxConfig.points_to_cash_ratio_tip') }}</div>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-form-item class="playx-config-submit">
|
||||
@@ -150,14 +149,14 @@ const loading = ref(true)
|
||||
const submitting = ref(false)
|
||||
const calculating = ref(false)
|
||||
const remark = ref('')
|
||||
const activeTab = ref('event')
|
||||
const activeTab = ref('regular')
|
||||
const activeMallOpenDate = ref('')
|
||||
const activeEventEndDate = ref('')
|
||||
|
||||
const form = reactive({
|
||||
return_ratio: 0.1,
|
||||
unlock_ratio: 0.1,
|
||||
points_to_cash_ratio: 0.1,
|
||||
points_to_cash_ratio: 0.01,
|
||||
daily_points_enabled: true,
|
||||
lifetime_points_enabled: false,
|
||||
lifetime_points_ratio: 0.1,
|
||||
|
||||
@@ -120,7 +120,8 @@ const baTable = new baTableClass(
|
||||
label: t('mall.userAsset.event_period_win_loss_net'),
|
||||
prop: 'event_period_win_loss_net',
|
||||
align: 'center',
|
||||
minWidth: 160,
|
||||
minWidth: 140,
|
||||
showOverflowTooltip: true,
|
||||
operator: 'RANGE',
|
||||
sortable: true,
|
||||
},
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
type="number"
|
||||
v-model="baTable.form.items!.today_limit"
|
||||
prop="today_limit"
|
||||
:block-help="t('mall.userAsset.today_limit_tip')"
|
||||
:input-attr="{ step: 1, min: 0 }"
|
||||
:placeholder="t('Please input field', { field: t('mall.userAsset.today_limit') })"
|
||||
/>
|
||||
@@ -82,6 +83,7 @@
|
||||
type="number"
|
||||
v-model="baTable.form.items!.event_period_win_loss_net"
|
||||
prop="event_period_win_loss_net"
|
||||
:block-help="t('mall.userAsset.event_period_win_loss_net_tip')"
|
||||
:input-attr="{ disabled: true, step: 0.01 }"
|
||||
/>
|
||||
<FormItem
|
||||
|
||||
Reference in New Issue
Block a user