2026-06-05 22:01:10 +03:30
|
|
|
|
<template>
|
|
|
|
|
|
<div class="setting-value-field">
|
|
|
|
|
|
<a-switch
|
|
|
|
|
|
v-if="fieldType === 'switch'"
|
|
|
|
|
|
:checked="switchChecked"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
@change="onSwitchChange"
|
|
|
|
|
|
>
|
2026-06-13 17:38:35 +03:30
|
|
|
|
<template #checkedChildren>{{ labels.on }}</template>
|
|
|
|
|
|
<template #unCheckedChildren>{{ labels.off }}</template>
|
2026-06-05 22:01:10 +03:30
|
|
|
|
</a-switch>
|
|
|
|
|
|
|
2026-07-12 18:30:09 +03:30
|
|
|
|
<SupportMessengersField
|
|
|
|
|
|
v-else-if="isSupportMessengers"
|
|
|
|
|
|
:model-value="modelValue"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
@update:value="emit('update:value', $event)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
2026-07-01 16:15:51 +03:30
|
|
|
|
<MainWalletProductsField
|
|
|
|
|
|
v-else-if="isMainWalletProducts"
|
|
|
|
|
|
:model-value="modelValue"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
@update:value="emit('update:value', $event)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
2026-06-09 21:06:29 +03:30
|
|
|
|
<ZaarboxPriceKeyField
|
|
|
|
|
|
v-else-if="isZaarboxPriceKey"
|
|
|
|
|
|
:model-value="modelValue"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
@update:value="emit('update:value', $event)"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
2026-06-05 22:01:10 +03:30
|
|
|
|
<a-select
|
|
|
|
|
|
v-else-if="fieldType === 'select'"
|
|
|
|
|
|
:value="modelValue || undefined"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
allow-clear
|
|
|
|
|
|
placeholder="انتخاب کنید"
|
|
|
|
|
|
class="w-full"
|
|
|
|
|
|
@update:value="onSelectChange"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-select-option v-for="opt in selectItems" :key="opt.key" :value="opt.key">
|
|
|
|
|
|
{{ opt.value }}
|
|
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
|
2026-07-07 21:10:23 +03:30
|
|
|
|
<a-select
|
|
|
|
|
|
v-else-if="fieldType === 'multiselect'"
|
|
|
|
|
|
:value="multiSelectValue"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
mode="multiple"
|
|
|
|
|
|
allow-clear
|
|
|
|
|
|
placeholder="انتخاب کنید"
|
|
|
|
|
|
class="w-full"
|
|
|
|
|
|
@update:value="onMultiSelectChange"
|
|
|
|
|
|
>
|
|
|
|
|
|
<a-select-option v-for="opt in selectItems" :key="opt.key" :value="opt.key">
|
|
|
|
|
|
{{ opt.value }}
|
|
|
|
|
|
</a-select-option>
|
|
|
|
|
|
</a-select>
|
|
|
|
|
|
|
2026-06-28 21:48:17 +03:30
|
|
|
|
<a-time-picker
|
|
|
|
|
|
v-else-if="fieldType === 'time'"
|
|
|
|
|
|
:value="modelValue || undefined"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
class="w-full"
|
|
|
|
|
|
format="HH:mm"
|
|
|
|
|
|
value-format="HH:mm:ss"
|
|
|
|
|
|
:minute-step="5"
|
|
|
|
|
|
placeholder="انتخاب ساعت"
|
|
|
|
|
|
@update:value="onTimeChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
2026-06-05 22:01:10 +03:30
|
|
|
|
<a-input-number
|
2026-06-22 12:08:47 +03:30
|
|
|
|
v-else-if="fieldType === 'price'"
|
|
|
|
|
|
:value="priceValue"
|
2026-06-05 22:01:10 +03:30
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
class="w-full"
|
|
|
|
|
|
:formatter="(v: string) => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
|
|
|
|
|
|
:parser="(v: string) => v.replace(/,/g, '')"
|
2026-06-22 12:08:47 +03:30
|
|
|
|
@update:value="onPriceChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<a-input
|
|
|
|
|
|
v-else-if="fieldType === 'number'"
|
|
|
|
|
|
:value="modelValue"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
inputmode="numeric"
|
|
|
|
|
|
allow-clear
|
|
|
|
|
|
class="w-full"
|
|
|
|
|
|
@update:value="onPlainNumberChange"
|
|
|
|
|
|
@blur="emit('blur')"
|
2026-06-05 22:01:10 +03:30
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<a-textarea
|
|
|
|
|
|
v-else-if="fieldType === 'longtext'"
|
|
|
|
|
|
:value="modelValue"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
:rows="rows"
|
|
|
|
|
|
class="w-full font-mono text-sm"
|
|
|
|
|
|
@update:value="emit('update:value', $event)"
|
2026-06-17 17:34:21 +03:30
|
|
|
|
@blur="emit('blur')"
|
2026-06-05 22:01:10 +03:30
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<a-input
|
|
|
|
|
|
v-else
|
|
|
|
|
|
:value="modelValue"
|
|
|
|
|
|
:disabled="disabled"
|
|
|
|
|
|
allow-clear
|
|
|
|
|
|
@update:value="emit('update:value', $event)"
|
2026-06-17 17:34:21 +03:30
|
|
|
|
@blur="emit('blur')"
|
2026-06-05 22:01:10 +03:30
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2026-07-01 16:15:51 +03:30
|
|
|
|
import MainWalletProductsField from './MainWalletProductsField.vue'
|
2026-07-12 18:30:09 +03:30
|
|
|
|
import SupportMessengersField from './SupportMessengersField.vue'
|
2026-06-09 21:06:29 +03:30
|
|
|
|
import ZaarboxPriceKeyField from './ZaarboxPriceKeyField.vue'
|
2026-06-05 22:01:10 +03:30
|
|
|
|
import {
|
|
|
|
|
|
parseSelectOptions,
|
|
|
|
|
|
resolveSettingFieldType,
|
2026-06-13 17:38:35 +03:30
|
|
|
|
resolveSwitchChecked,
|
|
|
|
|
|
switchLabels,
|
|
|
|
|
|
switchValueFromChecked,
|
2026-06-05 22:01:10 +03:30
|
|
|
|
type SettingFieldType
|
|
|
|
|
|
} from './settingTypes'
|
|
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
|
|
defineProps<{
|
|
|
|
|
|
modelValue: string
|
|
|
|
|
|
settingKey?: string
|
|
|
|
|
|
settingType?: string
|
|
|
|
|
|
description?: string
|
|
|
|
|
|
disabled?: boolean
|
|
|
|
|
|
rows?: number
|
|
|
|
|
|
}>(),
|
|
|
|
|
|
{ disabled: false, rows: 10 }
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-06-17 17:34:21 +03:30
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
|
'update:value': [value: string]
|
|
|
|
|
|
blur: []
|
|
|
|
|
|
}>()
|
2026-06-05 22:01:10 +03:30
|
|
|
|
|
|
|
|
|
|
const fieldType = computed<SettingFieldType>(() =>
|
|
|
|
|
|
resolveSettingFieldType({
|
|
|
|
|
|
key: props.settingKey,
|
|
|
|
|
|
type: props.settingType
|
|
|
|
|
|
})
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-06-09 21:06:29 +03:30
|
|
|
|
const isZaarboxPriceKey = computed(() => props.settingKey === 'zaarbox_price_key')
|
2026-07-01 16:15:51 +03:30
|
|
|
|
const isMainWalletProducts = computed(() => props.settingKey === 'main_wallet_products')
|
2026-07-12 18:30:09 +03:30
|
|
|
|
const isSupportMessengers = computed(() => props.settingKey === 'support_messengers')
|
2026-06-09 21:06:29 +03:30
|
|
|
|
|
2026-06-05 22:01:10 +03:30
|
|
|
|
const selectItems = computed(() =>
|
|
|
|
|
|
parseSelectOptions({
|
|
|
|
|
|
key: props.settingKey,
|
|
|
|
|
|
description: props.description,
|
|
|
|
|
|
type: props.settingType
|
|
|
|
|
|
})
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-06-13 17:38:35 +03:30
|
|
|
|
const labels = computed(() => switchLabels(props.settingKey))
|
|
|
|
|
|
|
|
|
|
|
|
const switchChecked = computed(() => resolveSwitchChecked(props.settingKey, props.modelValue))
|
2026-06-05 22:01:10 +03:30
|
|
|
|
|
|
|
|
|
|
function onSwitchChange(checked: boolean) {
|
2026-06-13 17:38:35 +03:30
|
|
|
|
emit('update:value', switchValueFromChecked(props.settingKey, checked))
|
2026-06-05 22:01:10 +03:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onSelectChange(val: string | undefined) {
|
|
|
|
|
|
emit('update:value', val ?? '')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-07 21:10:23 +03:30
|
|
|
|
const multiSelectValue = computed<string[]>(() =>
|
|
|
|
|
|
String(props.modelValue || '')
|
|
|
|
|
|
.split(',')
|
|
|
|
|
|
.map((s) => s.trim())
|
|
|
|
|
|
.filter((s) => s !== '')
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
function onMultiSelectChange(val: string[] | undefined) {
|
|
|
|
|
|
const list = Array.isArray(val) ? val.map((s) => s.trim()).filter((s) => s !== '') : []
|
|
|
|
|
|
emit('update:value', list.join(','))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-28 21:48:17 +03:30
|
|
|
|
function onTimeChange(val: string | string[] | undefined) {
|
|
|
|
|
|
const v = Array.isArray(val) ? val[0] : val
|
|
|
|
|
|
emit('update:value', v ?? '')
|
|
|
|
|
|
emit('blur')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-22 12:08:47 +03:30
|
|
|
|
const priceValue = computed(() => {
|
2026-06-05 22:01:10 +03:30
|
|
|
|
const n = parseFloat(String(props.modelValue || '').replace(/,/g, ''))
|
|
|
|
|
|
return Number.isFinite(n) ? n : undefined
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-06-22 12:08:47 +03:30
|
|
|
|
function onPriceChange(val: number | string | null) {
|
2026-06-05 22:01:10 +03:30
|
|
|
|
if (val === null || val === undefined || val === '') {
|
|
|
|
|
|
emit('update:value', '')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
emit('update:value', String(val))
|
|
|
|
|
|
}
|
2026-06-22 12:08:47 +03:30
|
|
|
|
|
|
|
|
|
|
function normalizePlainNumberInput(value: string): string {
|
|
|
|
|
|
const latin = value.replace(/[۰-۹]/g, (d) => String('۰۱۲۳۴۵۶۷۸۹'.indexOf(d)))
|
|
|
|
|
|
let out = ''
|
|
|
|
|
|
let hasDot = false
|
|
|
|
|
|
for (const ch of latin.replace(/,/g, '')) {
|
|
|
|
|
|
if (ch >= '0' && ch <= '9') out += ch
|
|
|
|
|
|
else if (ch === '.' && !hasDot) {
|
|
|
|
|
|
hasDot = true
|
|
|
|
|
|
out += ch
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return out
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onPlainNumberChange(val: string) {
|
|
|
|
|
|
emit('update:value', normalizePlainNumberInput(val ?? ''))
|
|
|
|
|
|
}
|
2026-06-05 22:01:10 +03:30
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.setting-value-field {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
.setting-value-field :deep(.ant-input-number) {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|