added pdf in withdraw and deposit and fix bug
This commit is contained in:
@@ -12,3 +12,23 @@ export const getPriceTable = async (params: TableInput) =>
|
|||||||
export const getLastPrice = async () => await useAxios.get<last>(`/api/price/last`)
|
export const getLastPrice = async () => await useAxios.get<last>(`/api/price/last`)
|
||||||
|
|
||||||
export const methodePrices = async () => await useAxios.get<MethodePrices[]>('/admin/p')
|
export const methodePrices = async () => await useAxios.get<MethodePrices[]>('/admin/p')
|
||||||
|
|
||||||
|
export interface ZaarboxProductOption {
|
||||||
|
key: string
|
||||||
|
name: string
|
||||||
|
id: string
|
||||||
|
category: string
|
||||||
|
active: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ZaarboxProductsResponse {
|
||||||
|
code: number
|
||||||
|
message: string
|
||||||
|
data: {
|
||||||
|
items: ZaarboxProductOption[]
|
||||||
|
api_url: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getZaarboxProducts = async () =>
|
||||||
|
await useAxios.get<ZaarboxProductsResponse>('/admin/zaarbox/products')
|
||||||
|
|||||||
+6
-1
@@ -10,9 +10,14 @@ export const chargeWallet = async (params: Charge, type: 'gold' | 'money') =>
|
|||||||
? await useAxios.post<boolean>('/admin/wallet/charge', params)
|
? await useAxios.post<boolean>('/admin/wallet/charge', params)
|
||||||
: await useAxios.post<boolean>('/admin/wallet/charge_gold', params)
|
: await useAxios.post<boolean>('/admin/wallet/charge_gold', params)
|
||||||
|
|
||||||
export const getWithdrawTable = async (params: TableInput) =>
|
export const getWithdrawTable = async (params: TableInput & { flow_type?: string }) =>
|
||||||
await useAxios.post<Array<Withdraw>>('/admin/wallet/withdraw/table', params)
|
await useAxios.post<Array<Withdraw>>('/admin/wallet/withdraw/table', params)
|
||||||
|
|
||||||
|
export const exportWithdrawReport = async (params: TableInput & { flow_type?: string }) =>
|
||||||
|
await useAxios.post<string>('/admin/wallet/withdraw/report', params, {
|
||||||
|
responseType: 'text'
|
||||||
|
})
|
||||||
|
|
||||||
export const completeWithdraw = async (params: Withdraw) =>
|
export const completeWithdraw = async (params: Withdraw) =>
|
||||||
await useAxios.post<boolean>('/admin/wallet/withdraw/complete', params)
|
await useAxios.post<boolean>('/admin/wallet/withdraw/complete', params)
|
||||||
|
|
||||||
|
|||||||
@@ -79,8 +79,13 @@
|
|||||||
z-index: 1100 !important;
|
z-index: 1100 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-picker-dropdown{
|
// dropdown سلکت و date picker داخل مودال (باید بالاتر از 1100 باشد)
|
||||||
z-index: 1100 !important;
|
.ant-select-dropdown {
|
||||||
|
z-index: 1200 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-picker-dropdown {
|
||||||
|
z-index: 1200 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -193,6 +193,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<ASelect
|
<ASelect
|
||||||
|
placeholder="مرتب سازی"
|
||||||
class="flex-1"
|
class="flex-1"
|
||||||
:options="sortableColumns"
|
:options="sortableColumns"
|
||||||
v-model:value="orderColumnKey"
|
v-model:value="orderColumnKey"
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export interface Product{
|
|||||||
open_buy: boolean
|
open_buy: boolean
|
||||||
open_sell: boolean
|
open_sell: boolean
|
||||||
show: boolean
|
show: boolean
|
||||||
|
show_in_assets?: boolean
|
||||||
title: string
|
title: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
methodOption: number
|
methodOption: number
|
||||||
|
|||||||
+2
-2
@@ -20,7 +20,7 @@ export interface Withdraw {
|
|||||||
cash?: number
|
cash?: number
|
||||||
gold?: number
|
gold?: number
|
||||||
note?: string
|
note?: string
|
||||||
tracked_number?: number
|
tracked_number?: string
|
||||||
date_at?: string
|
date_at?: string
|
||||||
sts?: number
|
sts?: number
|
||||||
created_at?: string
|
created_at?: string
|
||||||
@@ -28,7 +28,7 @@ export interface Withdraw {
|
|||||||
sts_str?: string
|
sts_str?: string
|
||||||
daj?: string
|
daj?: string
|
||||||
customer?: User
|
customer?: User
|
||||||
bank_account?: { cart_number?: string }
|
bank_account?: { cart_number?: string; shaba_number?: string }
|
||||||
transaction?: WithdrawTransaction[]
|
transaction?: WithdrawTransaction[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,13 @@
|
|||||||
<template #unCheckedChildren>غیرفعال</template>
|
<template #unCheckedChildren>غیرفعال</template>
|
||||||
</a-switch>
|
</a-switch>
|
||||||
|
|
||||||
|
<ZaarboxPriceKeyField
|
||||||
|
v-else-if="isZaarboxPriceKey"
|
||||||
|
:model-value="modelValue"
|
||||||
|
:disabled="disabled"
|
||||||
|
@update:value="emit('update:value', $event)"
|
||||||
|
/>
|
||||||
|
|
||||||
<a-select
|
<a-select
|
||||||
v-else-if="fieldType === 'select'"
|
v-else-if="fieldType === 'select'"
|
||||||
:value="modelValue || undefined"
|
:value="modelValue || undefined"
|
||||||
@@ -54,6 +61,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import ZaarboxPriceKeyField from './ZaarboxPriceKeyField.vue'
|
||||||
import {
|
import {
|
||||||
isSwitchOn,
|
isSwitchOn,
|
||||||
parseSelectOptions,
|
parseSelectOptions,
|
||||||
@@ -83,6 +91,8 @@ const fieldType = computed<SettingFieldType>(() =>
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const isZaarboxPriceKey = computed(() => props.settingKey === 'zaarbox_price_key')
|
||||||
|
|
||||||
const selectItems = computed(() =>
|
const selectItems = computed(() =>
|
||||||
parseSelectOptions({
|
parseSelectOptions({
|
||||||
key: props.settingKey,
|
key: props.settingKey,
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<a-select
|
||||||
|
:value="modelValue || undefined"
|
||||||
|
: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.key"
|
||||||
|
:value="item.key"
|
||||||
|
:label="`${item.name} ${item.key}`"
|
||||||
|
>
|
||||||
|
<div class="leading-snug">
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
<div class="text-xs text-gray-400 direction-ltr text-right">{{ item.key }}</div>
|
||||||
|
</div>
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, onMounted, ref } from 'vue'
|
||||||
|
import { getZaarboxProducts, type ZaarboxProductOption } 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<ZaarboxProductOption[]>([])
|
||||||
|
|
||||||
|
const allOptions = computed(() => {
|
||||||
|
const current = (props.modelValue ?? '').trim()
|
||||||
|
if (!current || options.value.some((item) => item.key === current)) {
|
||||||
|
return options.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{ key: current, name: current, id: '', category: '', active: true },
|
||||||
|
...options.value,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
void loadOptions()
|
||||||
|
})
|
||||||
|
|
||||||
|
async function loadOptions() {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const response = await getZaarboxProducts()
|
||||||
|
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>
|
||||||
@@ -289,7 +289,7 @@ const SETTING_GROUPS: Array<{
|
|||||||
id: 'general',
|
id: 'general',
|
||||||
title: 'عمومی و اطلاعات اپ',
|
title: 'عمومی و اطلاعات اپ',
|
||||||
icon: 'vuesax-linear:home-2',
|
icon: 'vuesax-linear:home-2',
|
||||||
match: (k) => /^(name_|app_|admin_|server_|bace_|key$|color_|logo_|title_pwa|title_fav|metal_type)/.test(k)
|
match: (k) => /^(name_|app_|admin_|server_|bace_|key$|color_|logo_|title_pwa|title_fav|metal_type|unit$)/.test(k)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pricing',
|
id: 'pricing',
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
|
|||||||
external_order_api_enabled: 'switch',
|
external_order_api_enabled: 'switch',
|
||||||
store_status: 'select',
|
store_status: 'select',
|
||||||
credit_rial_price_unit: 'select',
|
credit_rial_price_unit: 'select',
|
||||||
|
zaarbox_price_key: 'select',
|
||||||
node_client_id: 'text',
|
node_client_id: 'text',
|
||||||
node_shared_secret: 'text',
|
node_shared_secret: 'text',
|
||||||
support_messenger_id: 'text',
|
support_messenger_id: 'text',
|
||||||
@@ -99,6 +100,7 @@ const SELECT_OPTIONS_BY_KEY: Record<string, string> = {
|
|||||||
payping_gateway_name: 'sepal,',
|
payping_gateway_name: 'sepal,',
|
||||||
credit_rial_price_unit: 'gram,mesghal,unit',
|
credit_rial_price_unit: 'gram,mesghal,unit',
|
||||||
store_status: 'باز,بسته',
|
store_status: 'باز,بسته',
|
||||||
|
unit: 'گرم,کیلوگرم',
|
||||||
support_messenger: 'bale,telegram,whatsapp,rubika,eitaa,soroush'
|
support_messenger: 'bale,telegram,whatsapp,rubika,eitaa,soroush'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,57 @@
|
|||||||
<BaseCollapse title="اطلاعات محصول" active-key="0" :actives="activeKey">
|
<BaseCollapse title="اطلاعات محصول" active-key="0" :actives="activeKey">
|
||||||
<template #content>
|
<template #content>
|
||||||
<div
|
<div
|
||||||
v-if="form.group_type === '' || form.group_type !== 'آبشده'"
|
v-if="isMeltedCategory"
|
||||||
|
class="md:flex flex-col gap-3 border-1 border-solid rounded-lg border-gray-200 p-3"
|
||||||
|
>
|
||||||
|
<div class="items-center">
|
||||||
|
<span class="ml-4">مرجع قیمت :</span>
|
||||||
|
<a-radio-group :value="meltedPriceOption" name="meltedPriceGroup" @update:value="$emit('update:meltedPriceOption', $event)">
|
||||||
|
<a-radio value="app">قیمت اپ (صفحه اصلی)</a-radio>
|
||||||
|
<a-radio value="fixed">ثابت</a-radio>
|
||||||
|
<a-radio value="reference">مرجع متفاوت</a-radio>
|
||||||
|
</a-radio-group>
|
||||||
|
</div>
|
||||||
|
<div v-if="meltedPriceOption === 'fixed'" class="md:flex items-center gap-3">
|
||||||
|
<span>قیمت ثابت :</span>
|
||||||
|
<BasicInput class="md:w-[20rem]" addon-before="ریال" type="price" v-model:value="form.price" />
|
||||||
|
</div>
|
||||||
|
<div v-if="meltedPriceOption === 'reference'" class="flex flex-col gap-2">
|
||||||
|
<div class="md:flex justify-between items-center">
|
||||||
|
<div class="ml-4">مرجع قیمت :</div>
|
||||||
|
<BasicSelect class="w-11rem method_style" allowClear :items="pricesList" valueName="name" keyName="id" v-model:value="form.reading_method" />
|
||||||
|
</div>
|
||||||
|
<div class="md:flex justify-between items-center">
|
||||||
|
<div class="ml-4">تعدیل نسبت به قیمت مرجع (٪) :</div>
|
||||||
|
<BasicInput
|
||||||
|
class="w-11rem"
|
||||||
|
type="number"
|
||||||
|
v-model:value="form.price_offset_percent"
|
||||||
|
placeholder="مثلاً 5 یا -3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-500">
|
||||||
|
مثبت = گرانتر، منفی = ارزانتر نسبت به قیمت مرجع.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="meltedPriceOption === 'app'" class="flex flex-col gap-2">
|
||||||
|
<div class="md:flex justify-between items-center">
|
||||||
|
<div class="ml-4">تعدیل نسبت به قیمت اپ (٪) :</div>
|
||||||
|
<BasicInput
|
||||||
|
class="w-11rem"
|
||||||
|
type="number"
|
||||||
|
v-model:value="form.price_offset_percent"
|
||||||
|
placeholder="مثلاً 5 یا -3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="text-xs text-gray-500">
|
||||||
|
قیمت خرید/فروش از قیمت صفحه اصلی اپ محاسبه میشود. مثبت = گرانتر، منفی = ارزانتر.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="!isMeltedCategory"
|
||||||
class="md:flex justify-between border-1 border-solid rounded-lg border-gray-200 p-2"
|
class="md:flex justify-between border-1 border-solid rounded-lg border-gray-200 p-2"
|
||||||
>
|
>
|
||||||
<div class="items-center">
|
<div class="items-center">
|
||||||
@@ -46,7 +96,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="form.group_type === '' || form.group_type !== 'آبشده'"
|
v-if="!isMeltedCategory"
|
||||||
class="md:flex justify-between p-2 border-1 border-solid rounded-lg border-gray-200 mt-2"
|
class="md:flex justify-between p-2 border-1 border-solid rounded-lg border-gray-200 mt-2"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
@@ -59,36 +109,30 @@
|
|||||||
<div v-if="weightOption === '1'" class="flex items-center">
|
<div v-if="weightOption === '1'" class="flex items-center">
|
||||||
<span class="ml-4 ">{{ weightFieldLabel }} :</span>
|
<span class="ml-4 ">{{ weightFieldLabel }} :</span>
|
||||||
<BasicInput v-model:value="form.amount" type="number" />
|
<BasicInput v-model:value="form.amount" type="number" />
|
||||||
<div class="mt-1 mr-4" v-if="form.amount && form.amount < 1 && 0 < form.amount && !isBourseCuProject">معادل {{ form.amount * 1000 }} سوت</div>
|
<div class="mt-1 mr-4" v-if="form.amount && form.amount < 1 && 0 < form.amount && tradeWeightUnit === 'گرم'">معادل {{ form.amount * 1000 }} سوت</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||||
<div class="grid md:grid-cols-2 gap-4">
|
<div class="grid md:grid-cols-2 gap-4">
|
||||||
<a-form-item label="عنوان" name="title" :rules="inputRules()"><BasicInput v-model:value="form.title" /></a-form-item>
|
<a-form-item label="عنوان" name="title" :rules="inputRules()"><BasicInput v-model:value="form.title" /></a-form-item>
|
||||||
<a-form-item v-if="getConfigApp('name') === 'boursecu'" label="دسته بندی" name="group_type" :rules="inputRules()">
|
<a-form-item label="دسته بندی" name="group_type" :rules="inputRules()">
|
||||||
<BasicSelect v-model:value="form.group_type" :items="boursemesCategoryItems" valueName="value" keyName="value" />
|
<BasicSelect v-model:value="form.group_type" :items="categoryItems" valueName="value" keyName="key" />
|
||||||
</a-form-item>
|
|
||||||
<a-form-item v-else-if="getConfigApp('name') === 'garoosi'" label="دسته بندی" name="group_type" :rules="inputRules()">
|
|
||||||
<BasicSelect v-model:value="form.group_type" :items="garoosiCategoryItems" valueName="value" keyName="value" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item v-else label="دسته بندی" name="group_type" :rules="inputRules()">
|
|
||||||
<BasicSelect v-model:value="form.group_type" :items="categoryItems" valueName="value" keyName="value" />
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="جنس فلز" name="metal_id" :rules="inputRules()">
|
<a-form-item label="جنس فلز" name="metal_id" :rules="inputRules()">
|
||||||
<BasicSelect v-model:value="form.metal_id" :items="metalItems" valueName="value" keyName="key" />
|
<BasicSelect v-model:value="form.metal_id" :items="metalItems" valueName="value" keyName="key" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="نوع قیمت" name="direct_price" :rules="inputRules()">
|
<a-form-item v-if="!isMeltedCategory" label="نوع قیمت" name="direct_price" :rules="inputRules()">
|
||||||
<BasicSelect v-model:value="form.direct_price" :items="priceItems" valueName="value" keyName="key" />
|
<BasicSelect v-model:value="form.direct_price" :items="priceItems" valueName="value" keyName="key" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="واحد" name="unit" :rules="inputRules()">
|
<a-form-item label="واحد" name="unit" :rules="inputRules()">
|
||||||
<BasicSelect v-model:value="form.unit" :items="unitItems" valueName="value" keyName="value" />
|
<BasicSelect v-model:value="form.unit" :items="unitItems" valueName="value" keyName="value" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="form.group_type === '' || form.group_type !== 'آبشده'" label="هزینه نقدی موقع خرید" name="cash_fee_buy" :rules="inputRules()">
|
<a-form-item label="هزینه نقدی موقع خرید" name="cash_fee_buy" :rules="inputRules()">
|
||||||
<BasicInput v-model:value="form.cash_fee_buy" type="number" />
|
<BasicInput v-model:value="form.cash_fee_buy" addon-before="ریال" type="price" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="form.group_type === '' || form.group_type !== 'آبشده'" label="هزینه نقدی موقع فروش" name="cash_fee_sell" :rules="inputRules()">
|
<a-form-item label="هزینه نقدی موقع فروش" name="cash_fee_sell" :rules="inputRules()">
|
||||||
<BasicInput v-model:value="form.cash_fee_sell" type="number" />
|
<BasicInput v-model:value="form.cash_fee_sell" addon-before="ریال" type="price" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="زمان شروع فعال سازی" name="auto_open_at">
|
<a-form-item label="زمان شروع فعال سازی" name="auto_open_at">
|
||||||
<TimePicker v-model:value="form.auto_open_at" :locale="customLocale" placeholder="انتخاب زمان" :defaultValue="dayjs('00:00:00', 'HH:mm:ss')" />
|
<TimePicker v-model:value="form.auto_open_at" :locale="customLocale" placeholder="انتخاب زمان" :defaultValue="dayjs('00:00:00', 'HH:mm:ss')" />
|
||||||
@@ -99,6 +143,9 @@
|
|||||||
<a-form-item label="محدودیت مبلغ سفارش" name="order_limit_enabled">
|
<a-form-item label="محدودیت مبلغ سفارش" name="order_limit_enabled">
|
||||||
<a-switch v-model:checked="form.order_limit_enabled" @change="onOrderLimitChange" />
|
<a-switch v-model:checked="form.order_limit_enabled" @change="onOrderLimitChange" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="نمایش در صفحه داراییها" name="show_in_assets">
|
||||||
|
<a-switch v-model:checked="form.show_in_assets" />
|
||||||
|
</a-form-item>
|
||||||
<template v-if="form.order_limit_enabled">
|
<template v-if="form.order_limit_enabled">
|
||||||
<div class="col-span-2 text-xs text-gray-500 -mt-2 mb-1">
|
<div class="col-span-2 text-xs text-gray-500 -mt-2 mb-1">
|
||||||
حداقل یکی از «حداقل» یا «حداکثر» الزامی است؛ میتوانید فقط یکی را پر کنید.
|
حداقل یکی از «حداقل» یا «حداکثر» الزامی است؛ میتوانید فقط یکی را پر کنید.
|
||||||
@@ -135,19 +182,20 @@ import { inputRules } from '@/utils/inputRules'
|
|||||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||||
import BaseCollapse from '@/components/BaseCollapse.vue'
|
import BaseCollapse from '@/components/BaseCollapse.vue'
|
||||||
import IndexImageUploader from '@/components/ProductUploader/IndexImageUploader.vue'
|
import IndexImageUploader from '@/components/ProductUploader/IndexImageUploader.vue'
|
||||||
import { getConfigApp } from '@/utils/config'
|
import { getConfiguration } from '@/api/configuration'
|
||||||
|
import { isMeltedTradeGroup } from '@/utils/productCategories'
|
||||||
|
import { resolveTradeWeightUnit, weightFieldLabelForUnit } from '@/utils/weightUnit'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { computed } from 'vue'
|
import { computed, onMounted, ref, watch } from 'vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
form: any
|
form: any
|
||||||
formRef: any
|
formRef: any
|
||||||
methodOption: string
|
methodOption: string
|
||||||
weightOption: string
|
weightOption: string
|
||||||
|
meltedPriceOption: string
|
||||||
activeKey: string[]
|
activeKey: string[]
|
||||||
pricesList: Array<{ id: string; name: string }>
|
pricesList: Array<{ id: string; name: string }>
|
||||||
boursemesCategoryItems: any[]
|
|
||||||
garoosiCategoryItems: any[]
|
|
||||||
categoryItems: any[]
|
categoryItems: any[]
|
||||||
metalItems: any[]
|
metalItems: any[]
|
||||||
priceItems: any[]
|
priceItems: any[]
|
||||||
@@ -157,13 +205,47 @@ const props = defineProps<{
|
|||||||
editId?: number
|
editId?: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const isBourseCuProject = computed(() => getConfigApp('name') === 'boursecu')
|
const tradeWeightUnit = ref('گرم')
|
||||||
const weightFieldLabel = computed(() =>
|
const isMeltedCategory = computed(() => isMeltedTradeGroup(props.form.group_type))
|
||||||
isBourseCuProject.value && (props.form.unit === 'کیلوگرم' || !props.form.unit)
|
|
||||||
? 'وزن به کیلوگرم'
|
watch(
|
||||||
: 'وزن به گرم'
|
() => props.meltedPriceOption,
|
||||||
|
(option) => {
|
||||||
|
if (option === 'app' || option === 'fixed') {
|
||||||
|
props.form.reading_method = null
|
||||||
|
}
|
||||||
|
if (option === 'app') {
|
||||||
|
props.form.direct_price = 0
|
||||||
|
}
|
||||||
|
if (option === 'fixed') {
|
||||||
|
props.form.direct_price = 1
|
||||||
|
props.form.price_offset_percent = 0
|
||||||
|
}
|
||||||
|
if (option === 'reference') {
|
||||||
|
props.form.direct_price = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
const rows = await getConfiguration()
|
||||||
|
const unitRow = Array.isArray(rows) ? rows.find((row) => row.key === 'unit') : null
|
||||||
|
tradeWeightUnit.value = resolveTradeWeightUnit(unitRow?.value)
|
||||||
|
} catch {
|
||||||
|
tradeWeightUnit.value = 'گرم'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const weightFieldLabel = computed(() => {
|
||||||
|
const productUnit = props.form.unit?.trim()
|
||||||
|
if (productUnit === 'کیلوگرم' || productUnit === 'گرم') {
|
||||||
|
return weightFieldLabelForUnit(productUnit)
|
||||||
|
}
|
||||||
|
|
||||||
|
return weightFieldLabelForUnit(tradeWeightUnit.value)
|
||||||
|
})
|
||||||
|
|
||||||
function onOrderLimitChange(checked: boolean) {
|
function onOrderLimitChange(checked: boolean) {
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
props.form.min_order_cash = undefined
|
props.form.min_order_cash = undefined
|
||||||
@@ -176,6 +258,7 @@ defineEmits<{
|
|||||||
(e: 'minusPrice'): void
|
(e: 'minusPrice'): void
|
||||||
(e: 'update:methodOption', value: string): void
|
(e: 'update:methodOption', value: string): void
|
||||||
(e: 'update:weightOption', value: string): void
|
(e: 'update:weightOption', value: string): void
|
||||||
|
(e: 'update:meltedPriceOption', value: string): void
|
||||||
(e: 'update:activeKey', value: string[]): void
|
(e: 'update:activeKey', value: string[]): void
|
||||||
(e: 'update:productIndexImage', value: any[]): void
|
(e: 'update:productIndexImage', value: any[]): void
|
||||||
(e: 'uploadedIndexFile', id: number, response?: Record<string, any>): void
|
(e: 'uploadedIndexFile', id: number, response?: Record<string, any>): void
|
||||||
|
|||||||
@@ -23,17 +23,17 @@
|
|||||||
:weightOption="weightOption"
|
:weightOption="weightOption"
|
||||||
:activeKey="activeKey_"
|
:activeKey="activeKey_"
|
||||||
:pricesList="pricesList"
|
:pricesList="pricesList"
|
||||||
:boursemesCategoryItems="BoursemesCategoryItems"
|
:categoryItems="categorySelectItems"
|
||||||
:garoosiCategoryItems="GaroosiCategoryItems"
|
|
||||||
:categoryItems="categoryItems"
|
|
||||||
:metalItems="metalItems"
|
:metalItems="metalItems"
|
||||||
:priceItems="priceItems"
|
:priceItems="priceItems"
|
||||||
:unitItems="unitItems"
|
:unitItems="unitItems"
|
||||||
:customLocale="customLocale"
|
:customLocale="customLocale"
|
||||||
:productIndexImage="ProductIndexImage"
|
:productIndexImage="ProductIndexImage"
|
||||||
:editId="editId"
|
:editId="editId"
|
||||||
|
:meltedPriceOption="meltedPriceOption"
|
||||||
@update:methodOption="methodOption = $event"
|
@update:methodOption="methodOption = $event"
|
||||||
@update:weightOption="weightOption = $event"
|
@update:weightOption="weightOption = $event"
|
||||||
|
@update:meltedPriceOption="meltedPriceOption = $event"
|
||||||
@update:activeKey="activeKey_ = $event"
|
@update:activeKey="activeKey_ = $event"
|
||||||
@update:productIndexImage="ProductIndexImage = $event"
|
@update:productIndexImage="ProductIndexImage = $event"
|
||||||
@addPrice="addPrice"
|
@addPrice="addPrice"
|
||||||
@@ -73,7 +73,7 @@ import {
|
|||||||
unwrapApiRecord
|
unwrapApiRecord
|
||||||
} from '@/utils/file'
|
} from '@/utils/file'
|
||||||
import { normalizeProductOrderLimitForm, validateProductOrderLimitForm } from '@/utils/productOrderLimit'
|
import { normalizeProductOrderLimitForm, validateProductOrderLimitForm } from '@/utils/productOrderLimit'
|
||||||
import { getConfigApp } from '@/utils/config'
|
import { buildCategorySelectItems, isMeltedTradeGroup, resolveMeltedPriceSource } from '@/utils/productCategories'
|
||||||
|
|
||||||
dayjs.extend(customParseFormat)
|
dayjs.extend(customParseFormat)
|
||||||
|
|
||||||
@@ -83,6 +83,7 @@ const refreshTable = () => table.value?.fetch()
|
|||||||
|
|
||||||
const methodOption = ref('1')
|
const methodOption = ref('1')
|
||||||
const weightOption = ref('1')
|
const weightOption = ref('1')
|
||||||
|
const meltedPriceOption = ref('app')
|
||||||
const activeKey_ = ref(['0'])
|
const activeKey_ = ref(['0'])
|
||||||
const ProductIndexImage = ref<Array<FileList>>([])
|
const ProductIndexImage = ref<Array<FileList>>([])
|
||||||
const addUserVisible = ref(false)
|
const addUserVisible = ref(false)
|
||||||
@@ -104,42 +105,18 @@ const customLocale = ref({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const unitItems = computed<Array<Item>>(() => {
|
const unitItems = computed<Array<Item>>(() => [
|
||||||
if (getConfigApp('name') === 'boursecu') {
|
{ value: 'گرم' },
|
||||||
return [{ value: 'کیلوگرم' }, { value: 'عدد' }, { value: 'گرم' }]
|
{ value: 'کیلوگرم' },
|
||||||
}
|
{ value: 'عدد' }
|
||||||
|
])
|
||||||
|
|
||||||
return [{ value: 'عدد' }, { value: 'گرم' }]
|
|
||||||
})
|
|
||||||
|
|
||||||
const GaroosiCategoryItems: Array<Item> = [
|
|
||||||
{ value: 'طلا' },
|
|
||||||
{ value: 'مکعب' },
|
|
||||||
{ value: 'گوی' },
|
|
||||||
{ value: 'سکه' },
|
|
||||||
{ value: 'سکه پارسیان' },
|
|
||||||
{ value: 'مس' },
|
|
||||||
{ value: 'نقره' }
|
|
||||||
]
|
|
||||||
const BoursemesCategoryItems: Array<Item> = [
|
|
||||||
{ value: 'آبشده' },
|
|
||||||
{ value: 'کاتد مس' },
|
|
||||||
{ value: 'مفتول مس' }
|
|
||||||
]
|
|
||||||
const categoryItems: Array<Item> = [
|
|
||||||
{ value: 'آبشده' },
|
|
||||||
{ value: 'مکعب' },
|
|
||||||
{ value: 'گوی' },
|
|
||||||
{ value: 'سکه' },
|
|
||||||
{ value: 'سکه پارسیان' },
|
|
||||||
{ value: 'مس' },
|
|
||||||
{ value: 'نقره' }
|
|
||||||
]
|
|
||||||
const metalItems: Array<Item> = [
|
const metalItems: Array<Item> = [
|
||||||
{ key: 1, value: 'طلا' },
|
{ key: 1, value: 'طلا' },
|
||||||
{ key: 2, value: 'نقره' },
|
{ key: 2, value: 'نقره' },
|
||||||
{ key: 3, value: 'مس' }
|
{ key: 3, value: 'مس' },
|
||||||
]
|
]
|
||||||
|
const categorySelectItems = computed(() => buildCategorySelectItems(metalItems))
|
||||||
const priceItems: Array<Item> = [
|
const priceItems: Array<Item> = [
|
||||||
{ key: 0, value: 'متغیر' },
|
{ key: 0, value: 'متغیر' },
|
||||||
{ key: 1, value: 'ثابت' }
|
{ key: 1, value: 'ثابت' }
|
||||||
@@ -241,6 +218,10 @@ async function edit(record: Product) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
methodOption.value = productData.reading_method ? '2' : '1'
|
methodOption.value = productData.reading_method ? '2' : '1'
|
||||||
|
meltedPriceOption.value = resolveMeltedPriceSource(productData)
|
||||||
|
if (isMeltedTradeGroup(productData.group_type)) {
|
||||||
|
methodOption.value = '1'
|
||||||
|
}
|
||||||
weightOption.value = productData.amount && productData.amount !== 1 ? '1' : '2'
|
weightOption.value = productData.amount && productData.amount !== 1 ? '1' : '2'
|
||||||
|
|
||||||
const start = productData.auto_open_at
|
const start = productData.auto_open_at
|
||||||
@@ -277,6 +258,7 @@ function resetData() {
|
|||||||
ProductIndexImage.value = []
|
ProductIndexImage.value = []
|
||||||
methodOption.value = '1'
|
methodOption.value = '1'
|
||||||
weightOption.value = '1'
|
weightOption.value = '1'
|
||||||
|
meltedPriceOption.value = 'app'
|
||||||
form.value = {
|
form.value = {
|
||||||
unit: '',
|
unit: '',
|
||||||
group_type: '',
|
group_type: '',
|
||||||
@@ -291,6 +273,7 @@ function resetData() {
|
|||||||
file_id: undefined,
|
file_id: undefined,
|
||||||
file: undefined,
|
file: undefined,
|
||||||
order_limit_enabled: false,
|
order_limit_enabled: false,
|
||||||
|
show_in_assets: true,
|
||||||
min_order_cash: undefined,
|
min_order_cash: undefined,
|
||||||
max_order_cash: undefined,
|
max_order_cash: undefined,
|
||||||
auto_open_at: dayjs('00:00:00', 'HH:mm:ss'),
|
auto_open_at: dayjs('00:00:00', 'HH:mm:ss'),
|
||||||
@@ -314,8 +297,25 @@ async function ok() {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (methodOption.value === '1') {
|
if (isMeltedTradeGroup(payload.group_type)) {
|
||||||
delete payload.reading_method
|
payload.amount = 1
|
||||||
|
payload.direct_price = meltedPriceOption.value === 'fixed' ? 1 : 0
|
||||||
|
payload.cash_fee_buy = payload.cash_fee_buy ?? 0
|
||||||
|
payload.cash_fee_sell = payload.cash_fee_sell ?? 0
|
||||||
|
|
||||||
|
if (meltedPriceOption.value === 'app') {
|
||||||
|
payload.reading_method = null
|
||||||
|
delete payload.price
|
||||||
|
payload.price_offset_percent = Number(payload.price_offset_percent ?? 0)
|
||||||
|
} else if (meltedPriceOption.value === 'fixed') {
|
||||||
|
payload.reading_method = null
|
||||||
|
payload.price_offset_percent = 0
|
||||||
|
} else {
|
||||||
|
delete payload.price
|
||||||
|
payload.price_offset_percent = Number(payload.price_offset_percent ?? 0)
|
||||||
|
}
|
||||||
|
} else if (methodOption.value === '1') {
|
||||||
|
payload.reading_method = null
|
||||||
payload.price_offset_percent = 0
|
payload.price_offset_percent = 0
|
||||||
} else {
|
} else {
|
||||||
delete payload.price
|
delete payload.price
|
||||||
|
|||||||
@@ -32,13 +32,24 @@
|
|||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
import { getWithdrawTable, updateSts } from '@/api/wallet'
|
import { getWithdrawTable, updateSts } from '@/api/wallet'
|
||||||
import type { Withdraw } from '@/model/wallet'
|
import type { Withdraw } from '@/model/wallet'
|
||||||
|
import type { TableInput } from '@core/type/baseTable'
|
||||||
import MobileCardList from '@/components/mobile/MobileCardList.vue'
|
import MobileCardList from '@/components/mobile/MobileCardList.vue'
|
||||||
import { useMobileDetailSheet } from '@/components/mobile/composables/useMobileDetailSheet'
|
import { useMobileDetailSheet } from '@/components/mobile/composables/useMobileDetailSheet'
|
||||||
import { useMobileTableList } from '@/components/mobile/composables/useMobileTableList'
|
import { useMobileTableList } from '@/components/mobile/composables/useMobileTableList'
|
||||||
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
||||||
|
import type { WithdrawFlowType } from '@/pages/menuPages/withdraw/types'
|
||||||
import WithdrawMobileDetailSheet from './WithdrawMobileDetailSheet.vue'
|
import WithdrawMobileDetailSheet from './WithdrawMobileDetailSheet.vue'
|
||||||
import WithdrawMobileListItem from './WithdrawMobileListItem.vue'
|
import WithdrawMobileListItem from './WithdrawMobileListItem.vue'
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
flowType?: WithdrawFlowType
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
flowType: 'all'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'withdraw', item: Withdraw): void
|
(e: 'withdraw', item: Withdraw): void
|
||||||
(e: 'weight', item: Withdraw): void
|
(e: 'weight', item: Withdraw): void
|
||||||
@@ -47,10 +58,17 @@ const emit = defineEmits<{
|
|||||||
const { sheetVisible, selectedItem, openSheet, syncSelectedItem } = useMobileDetailSheet<Withdraw>()
|
const { sheetVisible, selectedItem, openSheet, syncSelectedItem } = useMobileDetailSheet<Withdraw>()
|
||||||
|
|
||||||
const { loading, search, items, hasMore, reload, loadMore, fetch } = useMobileTableList<Withdraw>({
|
const { loading, search, items, hasMore, reload, loadMore, fetch } = useMobileTableList<Withdraw>({
|
||||||
fetchApi: getWithdrawTable,
|
fetchApi: (params: TableInput) => getWithdrawTable({ ...params, flow_type: props.flowType }),
|
||||||
onFetched: (rows) => syncSelectedItem(rows)
|
onFetched: (rows) => syncSelectedItem(rows)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.flowType,
|
||||||
|
() => {
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
async function changeStatusHandler(
|
async function changeStatusHandler(
|
||||||
item: Withdraw,
|
item: Withdraw,
|
||||||
statusEntry: [string, (typeof status)[keyof typeof status]]
|
statusEntry: [string, (typeof status)[keyof typeof status]]
|
||||||
|
|||||||
@@ -74,6 +74,7 @@
|
|||||||
<MobileDetailRow label="کد کاربر" :value="row.customer_id ?? '-'" />
|
<MobileDetailRow label="کد کاربر" :value="row.customer_id ?? '-'" />
|
||||||
<MobileDetailRow label="نام و نام خانوادگی" full-width :value="row.customer?.name || '-'" />
|
<MobileDetailRow label="نام و نام خانوادگی" full-width :value="row.customer?.name || '-'" />
|
||||||
<MobileDetailRow label="شماره کارت" full-width :value="row.bank_account?.cart_number || '-'" />
|
<MobileDetailRow label="شماره کارت" full-width :value="row.bank_account?.cart_number || '-'" />
|
||||||
|
<MobileDetailRow label="شماره شبا" full-width :value="row.bank_account?.shaba_number || '-'" />
|
||||||
<MobileDetailRow label="تاریخ ثبت" full-width :value="dateLabel(row)" />
|
<MobileDetailRow label="تاریخ ثبت" full-width :value="dateLabel(row)" />
|
||||||
</MobileInfoGrid>
|
</MobileInfoGrid>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
||||||
<BasicShowContext title="لیست برداشت و واریز">
|
<BasicShowContext title="لیست برداشت و واریز">
|
||||||
<div class="flex h-full min-h-0 flex-col">
|
<div class="flex h-full min-h-0 flex-col">
|
||||||
<BaseTable v-if="!isMobile" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
<BaseTable v-if="!isMobile" :key="flowType" class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
||||||
<template #extraHeader>
|
<template #extraHeader>
|
||||||
<!-- <BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
<!-- <BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||||
<div>افزودن مشتری عمده</div>
|
<div>افزودن مشتری عمده</div>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<template #tracked="{ column, record }">
|
<template #tracked="{ column, record }">
|
||||||
<div v-if="record.tracked_number">{{ record.tracked_number }}</div>
|
<div v-if="record.tracked_number">{{ record.tracked_number }}</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<BaseButton @click="emits('withdraw', record.id)">تایید برداشت</BaseButton>
|
<BaseButton @click="emits('withdraw', record)">{{ confirmButtonLabel }}</BaseButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #action="{ column, record }">
|
<template #action="{ column, record }">
|
||||||
@@ -67,6 +67,7 @@
|
|||||||
v-else
|
v-else
|
||||||
ref="mobileListRef"
|
ref="mobileListRef"
|
||||||
class="min-h-0 flex-1"
|
class="min-h-0 flex-1"
|
||||||
|
:flow-type="props.flowType"
|
||||||
@withdraw="(row) => emits('withdraw', row)"
|
@withdraw="(row) => emits('withdraw', row)"
|
||||||
@weight="(row) => emits('weight', row)"
|
@weight="(row) => emits('weight', row)"
|
||||||
/>
|
/>
|
||||||
@@ -88,6 +89,16 @@ import { getOrderTable } from '@/api/order'
|
|||||||
import {getWithdrawTable, updateSts} from '@/api/wallet'
|
import {getWithdrawTable, updateSts} from '@/api/wallet'
|
||||||
import WithdrawMobileCardList from './WithdrawMobileCardList.vue'
|
import WithdrawMobileCardList from './WithdrawMobileCardList.vue'
|
||||||
import { isMobile } from '@core/utils/is'
|
import { isMobile } from '@core/utils/is'
|
||||||
|
import type { WithdrawFlowType } from '../types'
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
flowType?: WithdrawFlowType
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
flowType: 'all'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const [submit, reload] = useBaseTable()
|
const [submit, reload] = useBaseTable()
|
||||||
const mobileListRef = ref<null | { fetch: () => Promise<void> }>(null)
|
const mobileListRef = ref<null | { fetch: () => Promise<void> }>(null)
|
||||||
@@ -107,14 +118,28 @@ function checkPermission(temp: string) {
|
|||||||
|
|
||||||
//define table
|
//define table
|
||||||
const table = ref(null)
|
const table = ref(null)
|
||||||
|
const lastTableParams = ref<TableInput & { flow_type?: string }>({})
|
||||||
|
|
||||||
const tblProps = ref<any>({
|
const confirmButtonLabel = computed(() =>
|
||||||
|
props.flowType === 'deposit' ? 'تایید واریز' : 'تایید برداشت'
|
||||||
|
)
|
||||||
|
|
||||||
|
const tblProps = computed(() => ({
|
||||||
columns: cols,
|
columns: cols,
|
||||||
api: (params: TableInput) => {
|
api: async (params: TableInput) => {
|
||||||
return getWithdrawTable(params)
|
const payload = { ...params, flow_type: props.flowType }
|
||||||
|
lastTableParams.value = payload
|
||||||
|
return getWithdrawTable(payload)
|
||||||
}
|
}
|
||||||
//bordered: true
|
}))
|
||||||
})
|
|
||||||
|
watch(
|
||||||
|
() => props.flowType,
|
||||||
|
() => {
|
||||||
|
reload()
|
||||||
|
},
|
||||||
|
{ flush: 'post' }
|
||||||
|
)
|
||||||
const loading = ref<boolean>(false)
|
const loading = ref<boolean>(false)
|
||||||
|
|
||||||
async function changeCustomerActivationFunction(id: number) {
|
async function changeCustomerActivationFunction(id: number) {
|
||||||
@@ -138,8 +163,8 @@ async function fetch() {
|
|||||||
// table?.value?.loading.value = val
|
// table?.value?.loading.value = val
|
||||||
// }
|
// }
|
||||||
defineExpose({
|
defineExpose({
|
||||||
fetch
|
fetch,
|
||||||
// spinTable
|
getExportParams: () => ({ ...lastTableParams.value, flow_type: props.flowType })
|
||||||
})
|
})
|
||||||
|
|
||||||
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
||||||
|
|||||||
@@ -96,6 +96,15 @@ export const cols: BaseTableColumn[] = [
|
|||||||
return data.record.bank_account?.cart_number ?? '_'
|
return data.record.bank_account?.cart_number ?? '_'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'شماره شبا',
|
||||||
|
dataIndex: 'bank_account.shaba_number',
|
||||||
|
key: 'bank_account.shaba_number',
|
||||||
|
type: 'Text',
|
||||||
|
customRender: (data) => {
|
||||||
|
return data.record.bank_account?.shaba_number ?? '_'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'وضعیت',
|
title: 'وضعیت',
|
||||||
dataIndex: 'sts',
|
dataIndex: 'sts',
|
||||||
|
|||||||
@@ -1,10 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<BasicMainCard>
|
<BasicMainCard>
|
||||||
<div class="flex w-full h-full">
|
<div class="flex w-full h-full flex-col">
|
||||||
|
<div class="mb-3 flex shrink-0 flex-wrap items-center justify-between gap-3 px-1">
|
||||||
|
<ARadioGroup v-model:value="flowType" button-style="solid">
|
||||||
|
<ARadioButton value="all">همه</ARadioButton>
|
||||||
|
<ARadioButton value="withdraw">برداشت</ARadioButton>
|
||||||
|
<ARadioButton value="deposit">واریز</ARadioButton>
|
||||||
|
</ARadioGroup>
|
||||||
|
<BaseButton
|
||||||
|
icon="vuesax-linear:document-download"
|
||||||
|
:loading="exportLoading"
|
||||||
|
@click="exportPdf"
|
||||||
|
>
|
||||||
|
خروجی PDF
|
||||||
|
</BaseButton>
|
||||||
|
</div>
|
||||||
<tbl
|
<tbl
|
||||||
ref="table"
|
ref="table"
|
||||||
class="w-full h-full"
|
class="min-h-0 flex-1 w-full"
|
||||||
|
:flow-type="flowType"
|
||||||
@edit="edit"
|
@edit="edit"
|
||||||
@delete="deleteItem"
|
@delete="deleteItem"
|
||||||
@withdraw="openWithdraw"
|
@withdraw="openWithdraw"
|
||||||
@@ -28,7 +43,7 @@
|
|||||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||||
<div class="">
|
<div class="">
|
||||||
<a-form-item label="شماره پیگیری" name="tracked_number" :rules="inputRules()">
|
<a-form-item label="شماره پیگیری" name="tracked_number" :rules="inputRules()">
|
||||||
<BasicInput v-model:value="form.tracked_number" type="number" />
|
<BasicInput v-model:value="form.tracked_number" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="تاریخ" name="date_at">
|
<a-form-item label="تاریخ" name="date_at">
|
||||||
<BaseDatePicker v-model:value="form.date_at" show-time format="YYYY-MM-DD HH:mm" />
|
<BaseDatePicker v-model:value="form.date_at" show-time format="YYYY-MM-DD HH:mm" />
|
||||||
@@ -99,8 +114,10 @@ import type { Customer } from '@/model/customer'
|
|||||||
import { createCustomer, deleteCustomer, updateCustomer } from '@/api/customer'
|
import { createCustomer, deleteCustomer, updateCustomer } from '@/api/customer'
|
||||||
import type { Order } from '@/model/order'
|
import type { Order } from '@/model/order'
|
||||||
import type { Wallet, Withdraw } from '@/model/wallet'
|
import type { Wallet, Withdraw } from '@/model/wallet'
|
||||||
import {completeWithdraw, getWithdrawById, sendWeights} from '@/api/wallet'
|
import {completeWithdraw, exportWithdrawReport, getWithdrawById, sendWeights} from '@/api/wallet'
|
||||||
import Button from "@core/components/BaseButton";
|
import Button from "@core/components/BaseButton";
|
||||||
|
import type { WithdrawFlowType } from '@/pages/menuPages/withdraw/types'
|
||||||
|
import { openHtmlPrintWindow } from '@/pages/menuPages/withdraw/utils/openHtmlPrintWindow'
|
||||||
//import DatePicker from '@core/components/_sample/components/datePicker.vue'
|
//import DatePicker from '@core/components/_sample/components/datePicker.vue'
|
||||||
|
|
||||||
//loading
|
//loading
|
||||||
@@ -110,9 +127,29 @@ const loading = ref<boolean>(false)
|
|||||||
const store = useStaticApiListsStore()
|
const store = useStaticApiListsStore()
|
||||||
|
|
||||||
//define tbl
|
//define tbl
|
||||||
const table = ref(null)
|
const table = ref<{ fetch: () => Promise<void>; getExportParams?: () => Record<string, unknown> } | null>(null)
|
||||||
const refreshTable = () => table?.value?.fetch()
|
const refreshTable = () => table?.value?.fetch()
|
||||||
|
|
||||||
|
const flowType = ref<WithdrawFlowType>('all')
|
||||||
|
const exportLoading = ref(false)
|
||||||
|
|
||||||
|
async function exportPdf() {
|
||||||
|
try {
|
||||||
|
exportLoading.value = true
|
||||||
|
const params = {
|
||||||
|
...(table.value?.getExportParams?.() ?? {}),
|
||||||
|
flow_type: flowType.value
|
||||||
|
}
|
||||||
|
const html = await exportWithdrawReport(params as any)
|
||||||
|
openHtmlPrintWindow(html)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
message.error('خطا در تهیه خروجی PDF')
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let updateKey = ref<number>(0)
|
let updateKey = ref<number>(0)
|
||||||
|
|
||||||
//form
|
//form
|
||||||
@@ -215,8 +252,8 @@ async function edit(record: Customer) {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
function openWithdraw(val: Withdraw) {
|
function openWithdraw(val: Withdraw | number) {
|
||||||
confirmWithdraw.value = val
|
confirmWithdraw.value = typeof val === 'number' ? { id: val } : val
|
||||||
resetData()
|
resetData()
|
||||||
confirmWithdrawVisible.value = true
|
confirmWithdrawVisible.value = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export type WithdrawFlowType = 'all' | 'withdraw' | 'deposit'
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export function openHtmlPrintWindow(html: string) {
|
||||||
|
const printWindow = window.open('', '_blank')
|
||||||
|
if (!printWindow) {
|
||||||
|
throw new Error('popup blocked')
|
||||||
|
}
|
||||||
|
|
||||||
|
printWindow.document.open()
|
||||||
|
printWindow.document.write(html)
|
||||||
|
printWindow.document.close()
|
||||||
|
printWindow.focus()
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/** دستهبندی یکسان محصول در همه اپهای ماژولار */
|
||||||
|
export const PRODUCT_CATEGORY_ABSHODE = 'آبشده'
|
||||||
|
|
||||||
|
export const UNIFIED_PRODUCT_CATEGORIES = [
|
||||||
|
PRODUCT_CATEGORY_ABSHODE,
|
||||||
|
'مکعب',
|
||||||
|
'گوی',
|
||||||
|
'سکه',
|
||||||
|
'سکه پارسیان',
|
||||||
|
'مس',
|
||||||
|
'نقره',
|
||||||
|
] as const
|
||||||
|
|
||||||
|
export const LEGACY_GROUP_KATOD = 'کاتد مس'
|
||||||
|
export const LEGACY_GROUP_MAFTOL = 'مفتول مس'
|
||||||
|
export const LEGACY_GROUP_GOLD = 'طلا'
|
||||||
|
|
||||||
|
export function normalizeProductGroupType(groupType?: string | null) {
|
||||||
|
return (groupType ?? '').trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isMeltedTradeGroup(groupType?: string | null) {
|
||||||
|
const group = normalizeProductGroupType(groupType)
|
||||||
|
return group === PRODUCT_CATEGORY_ABSHODE || group === LEGACY_GROUP_KATOD
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MeltedPriceSource = 'app' | 'fixed' | 'reference'
|
||||||
|
|
||||||
|
export function resolveMeltedPriceSource(product?: {
|
||||||
|
reading_method?: string | null
|
||||||
|
direct_price?: number | null
|
||||||
|
} | null): MeltedPriceSource {
|
||||||
|
if (product?.reading_method) {
|
||||||
|
return 'reference'
|
||||||
|
}
|
||||||
|
if (Number(product?.direct_price) === 1) {
|
||||||
|
return 'fixed'
|
||||||
|
}
|
||||||
|
return 'app'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildCategorySelectItems(metalItems: Array<{ key: number; value: string }>) {
|
||||||
|
const metalHint = metalItems.map((item) => item.value).join('، ')
|
||||||
|
|
||||||
|
return UNIFIED_PRODUCT_CATEGORIES.map((category) => ({
|
||||||
|
key: category,
|
||||||
|
value: category === PRODUCT_CATEGORY_ABSHODE ? `${category} (${metalHint})` : category,
|
||||||
|
}))
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
export const TRADE_WEIGHT_UNIT_GRAM = 'گرم'
|
||||||
|
export const TRADE_WEIGHT_UNIT_KILOGRAM = 'کیلوگرم'
|
||||||
|
|
||||||
|
export function isKilogramUnit(unit?: string | null) {
|
||||||
|
const value = (unit ?? '').trim()
|
||||||
|
return value === TRADE_WEIGHT_UNIT_KILOGRAM || value === 'kilogram' || value === 'kg'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveTradeWeightUnit(settingValue?: string | number | null) {
|
||||||
|
return isKilogramUnit(settingValue?.toString()) ? TRADE_WEIGHT_UNIT_KILOGRAM : TRADE_WEIGHT_UNIT_GRAM
|
||||||
|
}
|
||||||
|
|
||||||
|
export function weightFieldLabelForUnit(unit?: string | null) {
|
||||||
|
return isKilogramUnit(unit) ? 'وزن به کیلوگرم' : 'وزن به گرم'
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user