fixed ui and some bugs
This commit is contained in:
@@ -39,7 +39,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import SettingValueField from './SettingValueField.vue'
|
||||
import { helpText, resolveSettingFieldType, type SettingFieldType } from './settingTypes'
|
||||
import {
|
||||
helpText,
|
||||
KEY_LABEL_FALLBACK,
|
||||
resolveSettingFieldType,
|
||||
type SettingFieldType
|
||||
} from './settingTypes'
|
||||
import type { Const } from '@/model/configuration'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -58,7 +63,9 @@ const emit = defineEmits<{
|
||||
const settingKey = computed(() => props.row.key ?? '')
|
||||
const settingType = computed(() => props.row.type)
|
||||
const description = computed(() => props.row.description)
|
||||
const title = computed(() => props.row.title_fa || props.row.key || '—')
|
||||
const title = computed(
|
||||
() => props.row.title_fa || (props.row.key && KEY_LABEL_FALLBACK[props.row.key]) || props.row.key || '—'
|
||||
)
|
||||
|
||||
const fieldType = computed<SettingFieldType>(() =>
|
||||
resolveSettingFieldType({ key: props.row.key, type: props.row.type })
|
||||
|
||||
@@ -31,6 +31,18 @@
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
||||
<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"
|
||||
/>
|
||||
|
||||
<a-input-number
|
||||
v-else-if="fieldType === 'price'"
|
||||
:value="priceValue"
|
||||
@@ -130,6 +142,12 @@ function onSelectChange(val: string | undefined) {
|
||||
emit('update:value', val ?? '')
|
||||
}
|
||||
|
||||
function onTimeChange(val: string | string[] | undefined) {
|
||||
const v = Array.isArray(val) ? val[0] : val
|
||||
emit('update:value', v ?? '')
|
||||
emit('blur')
|
||||
}
|
||||
|
||||
const priceValue = computed(() => {
|
||||
const n = parseFloat(String(props.modelValue || '').replace(/,/g, ''))
|
||||
return Number.isFinite(n) ? n : undefined
|
||||
|
||||
@@ -16,12 +16,18 @@ export const EDITABLE_SETTING_GROUPS: SettingGroupDef[] = [
|
||||
k
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'trading_hours',
|
||||
title: 'ساعت کاری و نمایش قیمت',
|
||||
icon: 'vuesax-linear:clock',
|
||||
match: (k) => /^(close_price|startDay|endDay|show_last_price)$/.test(k)
|
||||
},
|
||||
{
|
||||
id: 'pricing',
|
||||
title: 'کارمزد و محدودیتها',
|
||||
icon: 'vuesax-linear:dollar-circle',
|
||||
match: (k) =>
|
||||
/^(fee_|buy_fee|sell_fee|min_|minimum_|show_last_price|close_price|startDay|endDay|up_price|down_price|price_extreme_date|balance_report_exclude)/.test(
|
||||
/^(fee_|buy_fee|sell_fee|min_|minimum_|up_price|down_price|price_extreme_date|balance_report_exclude)/.test(
|
||||
k
|
||||
) || k.includes('charge_percentage')
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Const } from '@/model/configuration'
|
||||
import { isStoreApp } from '@/utils/config'
|
||||
|
||||
export type SettingFieldType = 'text' | 'number' | 'price' | 'switch' | 'select' | 'longtext'
|
||||
export type SettingFieldType = 'text' | 'number' | 'price' | 'switch' | 'select' | 'longtext' | 'time'
|
||||
|
||||
/** کلیدهای legacy — در پنل نمایش داده نمیشوند */
|
||||
export const HIDDEN_LEGACY_SETTING_KEYS = new Set([
|
||||
@@ -42,7 +42,8 @@ export const SETTING_TYPE_OPTIONS = [
|
||||
{ key: 'price', value: 'مبلغ (ریال)' },
|
||||
{ key: 'switch', value: 'روشن/خاموش' },
|
||||
{ key: 'select', value: 'انتخابی' },
|
||||
{ key: 'longtext', value: 'متن بلند' }
|
||||
{ key: 'longtext', value: 'متن بلند' },
|
||||
{ key: 'time', value: 'ساعت' }
|
||||
]
|
||||
|
||||
const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
|
||||
@@ -73,6 +74,8 @@ const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
|
||||
open_register: 'switch',
|
||||
auto_active_customer: 'switch',
|
||||
close_price: 'switch',
|
||||
startDay: 'time',
|
||||
endDay: 'time',
|
||||
show_last_price: 'switch',
|
||||
send_to_tahesab: 'switch',
|
||||
profit_gold_api_enabled: 'switch',
|
||||
@@ -136,7 +139,7 @@ export function referralRequiredToString(checked: boolean): string {
|
||||
|
||||
export function resolveSettingFieldType(row: Pick<Const, 'key' | 'type'>): SettingFieldType {
|
||||
const raw = (row.type || '').trim().toLowerCase()
|
||||
if (['text', 'number', 'price', 'switch', 'select', 'longtext'].includes(raw)) {
|
||||
if (['text', 'number', 'price', 'switch', 'select', 'longtext', 'time'].includes(raw)) {
|
||||
return raw as SettingFieldType
|
||||
}
|
||||
if (row.key && KEY_TYPE_FALLBACK[row.key]) {
|
||||
@@ -205,6 +208,9 @@ export function formatValueForSave(
|
||||
if (type === 'number') {
|
||||
return String(value ?? '').replace(/,/g, '')
|
||||
}
|
||||
if (type === 'time') {
|
||||
return normalizeTimeValue(value)
|
||||
}
|
||||
return value ?? ''
|
||||
}
|
||||
|
||||
@@ -218,12 +224,45 @@ export function switchLabels(key: string | undefined): { on: string; off: string
|
||||
return { on: 'فعال', off: 'غیرفعال' }
|
||||
}
|
||||
|
||||
/** توضیحات کامل و ساده برای کلیدهای مهم — اگر description در دیتابیس خالی بود استفاده میشود */
|
||||
const KEY_HELP_FALLBACK: Record<string, string> = {
|
||||
close_price:
|
||||
'فیلتر اصلی فروشگاه. وقتی روشن باشد، خرید و فروش و نمایش قیمت فقط در بازهٔ «ساعت شروع» تا «ساعت پایان» انجام میشود و خارج از این بازه به مشتری پیام «فروشگاه بسته است» نشان داده میشود. اگر خاموش باشد، فروشگاه همیشه باز است (مگر اینکه برای محصولی بهصورت اختصاصی ساعت تعریف کرده باشید).',
|
||||
startDay:
|
||||
'ساعت شروع فعالیت فروشگاه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال میشود. ساعت را از روی ساعتشمار انتخاب کنید (مثلاً ۰۹:۰۰).',
|
||||
endDay:
|
||||
'ساعت پایان فعالیت فروشگاه. فقط وقتی «بستن خودکار خارج از ساعت کاری» روشن باشد اعمال میشود. بعد از این ساعت فروشگاه بسته میشود (مثلاً ۱۷:۰۰).',
|
||||
show_last_price:
|
||||
'وقتی قیمت زندهٔ لحظهای در دسترس نباشد: اگر روشن باشد، آخرین قیمت ذخیرهشده در دیتابیس به مشتری نشان داده میشود؛ اگر خاموش باشد، بهجای قیمت صفر پیام «مظنه در دسترس نیست» نمایش داده میشود.'
|
||||
}
|
||||
|
||||
/** برچسب فارسی ساده برای کلیدهای مهم — اگر سرور برچسبی نفرستد */
|
||||
export const KEY_LABEL_FALLBACK: Record<string, string> = {
|
||||
close_price: 'بستن خودکار خارج از ساعت کاری',
|
||||
startDay: 'ساعت شروع',
|
||||
endDay: 'ساعت پایان',
|
||||
show_last_price: 'نمایش آخرین قیمت ذخیرهشده'
|
||||
}
|
||||
|
||||
export function helpText(row: Const): string {
|
||||
const desc = (row.description || '').trim()
|
||||
if (!desc) return ''
|
||||
if (!desc) {
|
||||
return (row.key && KEY_HELP_FALLBACK[row.key]) || ''
|
||||
}
|
||||
if (resolveSettingFieldType(row) === 'select' && desc.includes(',')) {
|
||||
const parts = desc.split('|')
|
||||
return parts.length > 1 ? parts[0].trim() : ''
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
/** نرمالسازی ساعت به فرمت HH:mm:ss برای ذخیره و سازگاری با بکاند */
|
||||
export function normalizeTimeValue(value: string | undefined | null): string {
|
||||
const raw = String(value ?? '').trim()
|
||||
if (!raw) return ''
|
||||
const parts = raw.split(':')
|
||||
const pad = (n: string) => n.padStart(2, '0')
|
||||
if (parts.length >= 3) return `${pad(parts[0])}:${pad(parts[1])}:${pad(parts[2])}`
|
||||
if (parts.length === 2) return `${pad(parts[0])}:${pad(parts[1])}:00`
|
||||
return raw
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user