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 () =>
|
export const getZaarboxProducts = async () =>
|
||||||
await useAxios.get<ZaarboxProductsResponse>('/admin/zaarbox/products')
|
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)"
|
@update:value="emit('update:value', $event)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<MontzarProductIdField
|
||||||
|
v-else-if="isMontzarProductId"
|
||||||
|
:model-value="modelValue"
|
||||||
|
:disabled="disabled"
|
||||||
|
@update:value="emit('update:value', $event)"
|
||||||
|
/>
|
||||||
|
|
||||||
<TemplateTextField
|
<TemplateTextField
|
||||||
v-else-if="isTemplateField"
|
v-else-if="isTemplateField"
|
||||||
:model-value="modelValue"
|
:model-value="modelValue"
|
||||||
@@ -128,6 +135,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import MontzarProductIdField from './MontzarProductIdField.vue'
|
||||||
import MainWalletProductsField from './MainWalletProductsField.vue'
|
import MainWalletProductsField from './MainWalletProductsField.vue'
|
||||||
import PartnerServerUrlsField from './PartnerServerUrlsField.vue'
|
import PartnerServerUrlsField from './PartnerServerUrlsField.vue'
|
||||||
import SettingToggle from './SettingToggle.vue'
|
import SettingToggle from './SettingToggle.vue'
|
||||||
@@ -175,6 +183,7 @@ const fieldType = computed<SettingFieldType>(() =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
const isZaarboxPriceKey = computed(() => props.settingKey === 'zaarbox_price_key')
|
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 isMainWalletProducts = computed(() => props.settingKey === 'main_wallet_products')
|
||||||
const isSupportMessengers = computed(() => props.settingKey === 'support_messengers')
|
const isSupportMessengers = computed(() => props.settingKey === 'support_messengers')
|
||||||
const isPartnerServerUrls = computed(() => props.settingKey === 'zaarbox_api_url')
|
const isPartnerServerUrls = computed(() => props.settingKey === 'zaarbox_api_url')
|
||||||
|
|||||||
@@ -713,7 +713,7 @@ const KEY_HELP_FALLBACK: Record<string, string> = {
|
|||||||
montzar_password:
|
montzar_password:
|
||||||
'رمز عبور حساب اتصال به سرویس همکار قیمت. محرمانه نگه دارید.',
|
'رمز عبور حساب اتصال به سرویس همکار قیمت. محرمانه نگه دارید.',
|
||||||
montzar_product_id:
|
montzar_product_id:
|
||||||
'شناسه محصول مرجع در سرویس همکار قیمت.',
|
'محصول مرجع آبشده در API همکار — از لیست محصولات همکار انتخاب کنید.',
|
||||||
montzar_base_url:
|
montzar_base_url:
|
||||||
'آدرس پایه سرور سرویس همکار (بدون اسلش انتهایی).',
|
'آدرس پایه سرور سرویس همکار (بدون اسلش انتهایی).',
|
||||||
zaarbox_api_url:
|
zaarbox_api_url:
|
||||||
|
|||||||
Reference in New Issue
Block a user