feat(settings): montzar_product_id as select from partner product API
Load products from /admin/montzar/products with searchable select UI. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -44,3 +44,22 @@ export interface ZaarboxProductsResponse {
|
||||
|
||||
export const getZaarboxProducts = async () =>
|
||||
await useAxios.get<ZaarboxProductsResponse>('/admin/zaarbox/products')
|
||||
|
||||
export interface MontzarProductOption {
|
||||
id: string
|
||||
name: string
|
||||
price: number
|
||||
buy: number
|
||||
sell: number
|
||||
}
|
||||
|
||||
export interface MontzarProductsResponse {
|
||||
code: number
|
||||
message: string
|
||||
data: {
|
||||
items: MontzarProductOption[]
|
||||
}
|
||||
}
|
||||
|
||||
export const getMontzarProducts = async () =>
|
||||
await useAxios.get<MontzarProductsResponse>('/admin/montzar/products')
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<a-select
|
||||
:value="selectValue"
|
||||
:disabled="disabled"
|
||||
:loading="loading"
|
||||
allow-clear
|
||||
show-search
|
||||
placeholder="انتخاب محصول همکار"
|
||||
class="w-full"
|
||||
option-filter-prop="label"
|
||||
@update:value="onSelectChange"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="item in allOptions"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="`${item.name} ${item.id}`"
|
||||
>
|
||||
<div class="leading-snug">
|
||||
<div>
|
||||
{{ item.name }}
|
||||
<span v-if="item.price > 0" class="text-gray-500">({{ formatPrice(item.price) }} ریال)</span>
|
||||
<span v-else class="text-gray-400">(بدون قیمت)</span>
|
||||
</div>
|
||||
<div class="text-xs text-gray-400 direction-ltr text-right">#{{ item.id }}</div>
|
||||
</div>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { getMontzarProducts, type MontzarProductOption } from '@/api/price'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: string
|
||||
disabled?: boolean
|
||||
}>(),
|
||||
{ disabled: false }
|
||||
)
|
||||
|
||||
const emit = defineEmits<{ 'update:value': [value: string] }>()
|
||||
|
||||
const loading = ref(false)
|
||||
const options = ref<MontzarProductOption[]>([])
|
||||
|
||||
const selectValue = computed(() => {
|
||||
const current = String(props.modelValue ?? '').trim()
|
||||
return current || undefined
|
||||
})
|
||||
|
||||
const allOptions = computed(() => {
|
||||
const current = String(props.modelValue ?? '').trim()
|
||||
if (!current || options.value.some((item) => item.id === current)) {
|
||||
return options.value
|
||||
}
|
||||
|
||||
return [
|
||||
{ id: current, name: `محصول #${current}`, price: 0, buy: 0, sell: 0 },
|
||||
...options.value,
|
||||
]
|
||||
})
|
||||
|
||||
function formatPrice(value: number): string {
|
||||
return value.toLocaleString('en-US')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void loadOptions()
|
||||
})
|
||||
|
||||
async function loadOptions() {
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await getMontzarProducts()
|
||||
options.value = response?.data?.items ?? []
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
options.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function onSelectChange(val: string | undefined) {
|
||||
emit('update:value', val ?? '')
|
||||
}
|
||||
</script>
|
||||
@@ -36,6 +36,13 @@
|
||||
@update:value="emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<MontzarProductIdField
|
||||
v-else-if="isMontzarProductId"
|
||||
:model-value="modelValue"
|
||||
:disabled="disabled"
|
||||
@update:value="emit('update:value', $event)"
|
||||
/>
|
||||
|
||||
<TemplateTextField
|
||||
v-else-if="isTemplateField"
|
||||
:model-value="modelValue"
|
||||
@@ -128,6 +135,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MontzarProductIdField from './MontzarProductIdField.vue'
|
||||
import MainWalletProductsField from './MainWalletProductsField.vue'
|
||||
import PartnerServerUrlsField from './PartnerServerUrlsField.vue'
|
||||
import SettingToggle from './SettingToggle.vue'
|
||||
@@ -175,6 +183,7 @@ const fieldType = computed<SettingFieldType>(() =>
|
||||
)
|
||||
|
||||
const isZaarboxPriceKey = computed(() => props.settingKey === 'zaarbox_price_key')
|
||||
const isMontzarProductId = computed(() => props.settingKey === 'montzar_product_id')
|
||||
const isMainWalletProducts = computed(() => props.settingKey === 'main_wallet_products')
|
||||
const isSupportMessengers = computed(() => props.settingKey === 'support_messengers')
|
||||
const isPartnerServerUrls = computed(() => props.settingKey === 'zaarbox_api_url')
|
||||
|
||||
@@ -713,7 +713,7 @@ const KEY_HELP_FALLBACK: Record<string, string> = {
|
||||
montzar_password:
|
||||
'رمز عبور حساب اتصال به سرویس همکار قیمت. محرمانه نگه دارید.',
|
||||
montzar_product_id:
|
||||
'شناسه محصول مرجع در سرویس همکار قیمت.',
|
||||
'محصول مرجع آبشده در API همکار — از لیست محصولات همکار انتخاب کنید.',
|
||||
montzar_base_url:
|
||||
'آدرس پایه سرور سرویس همکار (بدون اسلش انتهایی).',
|
||||
zaarbox_api_url:
|
||||
|
||||
Reference in New Issue
Block a user