fix bug 22/4
This commit is contained in:
Vendored
+3
@@ -43,6 +43,7 @@ declare module '@vue/runtime-core' {
|
|||||||
APagination: typeof import('ant-design-vue/es')['Pagination']
|
APagination: typeof import('ant-design-vue/es')['Pagination']
|
||||||
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
APopconfirm: typeof import('ant-design-vue/es')['Popconfirm']
|
||||||
APopover: typeof import('ant-design-vue/es')['Popover']
|
APopover: typeof import('ant-design-vue/es')['Popover']
|
||||||
|
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||||
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
|
||||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||||
ARow: typeof import('ant-design-vue/es')['Row']
|
ARow: typeof import('ant-design-vue/es')['Row']
|
||||||
@@ -54,9 +55,11 @@ declare module '@vue/runtime-core' {
|
|||||||
ATable: typeof import('ant-design-vue/es')['Table']
|
ATable: typeof import('ant-design-vue/es')['Table']
|
||||||
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
||||||
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
||||||
|
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||||
ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
|
ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
|
||||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||||
|
AUpload: typeof import('ant-design-vue/es')['Upload']
|
||||||
BaseButton: typeof import('./src/core/components/BaseButton/index.ts')['default']
|
BaseButton: typeof import('./src/core/components/BaseButton/index.ts')['default']
|
||||||
BaseCard: typeof import('./src/core/components/BaseCard/index.ts')['default']
|
BaseCard: typeof import('./src/core/components/BaseCard/index.ts')['default']
|
||||||
BaseCollapse: typeof import('./src/components/BaseCollapse.vue')['default']
|
BaseCollapse: typeof import('./src/components/BaseCollapse.vue')['default']
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ export const getOrderTable = async (params: TableInput) =>
|
|||||||
await useAxios.post<Array<Order>>('/admin/order/table', params)
|
await useAxios.post<Array<Order>>('/admin/order/table', params)
|
||||||
|
|
||||||
export const createOrder = async (obj: Order) =>
|
export const createOrder = async (obj: Order) =>
|
||||||
await useAxios.post<AddId>(`/admin/single/order`, obj)
|
await useAxios.post<AddId>(`/admin/single/order`, obj, { meta: { silent: true } })
|
||||||
|
|
||||||
export const getSingleOrder = async (id: number) =>
|
export const getSingleOrder = async (id: number) =>
|
||||||
await useAxios.get<Order>(`/admin/order/single/${id}`)
|
await useAxios.get<Order>(`/admin/order/single/${id}`)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
:class="[`sms-credit--${variant}`, { 'sms-credit--label-hint': showLabelHint && isCompactDesktop }]"
|
:class="[`sms-credit--${variant}`, { 'sms-credit--label-hint': showLabelHint && isCompactDesktop }]"
|
||||||
>
|
>
|
||||||
<div class="sms-credit__info">
|
<div class="sms-credit__info">
|
||||||
|
<Icon icon="vuesax-linear:sms" :size="15" class="sms-credit__icon" />
|
||||||
<span v-if="!isCompactDesktop" class="sms-credit__label">اعتبار پیامک:</span>
|
<span v-if="!isCompactDesktop" class="sms-credit__label">اعتبار پیامک:</span>
|
||||||
|
|
||||||
<Transition name="sms-credit-swap" mode="out-in">
|
<Transition name="sms-credit-swap" mode="out-in">
|
||||||
@@ -267,6 +268,11 @@ onUnmounted(stopLabelHintTimers)
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sms-credit__icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: var(--admin-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
.sms-credit-swap-enter-active,
|
.sms-credit-swap-enter-active,
|
||||||
.sms-credit-swap-leave-active {
|
.sms-credit-swap-leave-active {
|
||||||
transition: opacity 0.5s ease;
|
transition: opacity 0.5s ease;
|
||||||
|
|||||||
@@ -9,3 +9,6 @@ export const SELECT_DROPDOWN_Z_INDEX = MODAL_ABOVE_ACTION_SHEET_Z_INDEX + 100
|
|||||||
|
|
||||||
/** z-index برای tooltip راهنما داخل مودال (باید از override جدولها و خود مودال بالاتر باشد) */
|
/** z-index برای tooltip راهنما داخل مودال (باید از override جدولها و خود مودال بالاتر باشد) */
|
||||||
export const TOOLTIP_ABOVE_MODAL_Z_INDEX = SELECT_DROPDOWN_Z_INDEX + 50
|
export const TOOLTIP_ABOVE_MODAL_Z_INDEX = SELECT_DROPDOWN_Z_INDEX + 50
|
||||||
|
|
||||||
|
/** z-index برای toast/message سراسری (باید بالاتر از مودال و backdrop باشد) */
|
||||||
|
export const MESSAGE_ABOVE_MODAL_Z_INDEX = TOOLTIP_ABOVE_MODAL_Z_INDEX + 50
|
||||||
|
|||||||
@@ -89,5 +89,10 @@
|
|||||||
z-index: 1200 !important;
|
z-index: 1200 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// toast/message بالای مودال (مودال: 1100)
|
||||||
|
.ant-message {
|
||||||
|
z-index: 1300 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ export interface Product{
|
|||||||
trade_by_quantity?: boolean
|
trade_by_quantity?: boolean
|
||||||
override_trading_hours?: boolean
|
override_trading_hours?: boolean
|
||||||
use_last_price_if_zero?: boolean
|
use_last_price_if_zero?: boolean
|
||||||
|
has_physical_delivery?: boolean
|
||||||
|
min_physical_delivery_grams?: number | null
|
||||||
title: string
|
title: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
methodOption: number
|
methodOption: number
|
||||||
|
|||||||
@@ -27,6 +27,15 @@
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
@close="stopGetPrice"
|
@close="stopGetPrice"
|
||||||
>
|
>
|
||||||
|
<a-alert
|
||||||
|
v-if="submitError"
|
||||||
|
type="error"
|
||||||
|
:message="submitError"
|
||||||
|
show-icon
|
||||||
|
closable
|
||||||
|
class="mb-3"
|
||||||
|
@close="submitError = ''"
|
||||||
|
/>
|
||||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||||
<div class="grid md:grid-cols-1 gap-4">
|
<div class="grid md:grid-cols-1 gap-4">
|
||||||
<div class="bg-gray-50 px-10 py-3 flex justify-center gap-4">
|
<div class="bg-gray-50 px-10 py-3 flex justify-center gap-4">
|
||||||
@@ -161,6 +170,7 @@ import { initAccountingSettingsFromApi, tahesabEnabledSetting, pargarEnabledSett
|
|||||||
|
|
||||||
//loading
|
//loading
|
||||||
const loading = ref<boolean>(false)
|
const loading = ref<boolean>(false)
|
||||||
|
const submitError = ref('')
|
||||||
const activeTab = ref<'reports' | 'tahesab' | 'customer-sync' | 'pargar' | 'pargar-customer-sync'>('reports')
|
const activeTab = ref<'reports' | 'tahesab' | 'customer-sync' | 'pargar' | 'pargar-customer-sync'>('reports')
|
||||||
const tahesabEnabled = tahesabEnabledSetting
|
const tahesabEnabled = tahesabEnabledSetting
|
||||||
const pargarEnabled = pargarEnabledSetting
|
const pargarEnabled = pargarEnabledSetting
|
||||||
@@ -240,6 +250,7 @@ async function changeUser(val: Customer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function stopGetPrice() {
|
function stopGetPrice() {
|
||||||
|
clearSubmitError()
|
||||||
clearInterval(interval)
|
clearInterval(interval)
|
||||||
console.log('stop')
|
console.log('stop')
|
||||||
}
|
}
|
||||||
@@ -374,10 +385,21 @@ async function edit(record: Customer) {
|
|||||||
form.value = cloneDeep(record)
|
form.value = cloneDeep(record)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearSubmitError() {
|
||||||
|
submitError.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOrderSubmitError(e: unknown): string {
|
||||||
|
const msg = (e as { response?: { data?: { message?: string } } })?.response?.data?.message
|
||||||
|
if (typeof msg === 'string' && msg.trim()) return msg
|
||||||
|
return 'خطا در ثبت سفارش'
|
||||||
|
}
|
||||||
|
|
||||||
//add
|
//add
|
||||||
async function add() {
|
async function add() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
editId = undefined
|
editId = undefined
|
||||||
|
clearSubmitError()
|
||||||
// await store.getUsersList()
|
// await store.getUsersList()
|
||||||
resetData()
|
resetData()
|
||||||
addOrderVisible.value = true
|
addOrderVisible.value = true
|
||||||
@@ -422,8 +444,7 @@ const userInfoVisible = ref<boolean>(false)
|
|||||||
//submit user
|
//submit user
|
||||||
async function ok() {
|
async function ok() {
|
||||||
formRef.value?.validateFields().then(async () => {
|
formRef.value?.validateFields().then(async () => {
|
||||||
// console.log('salam', form.value)
|
clearSubmitError()
|
||||||
// return
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
form.value.amount = form.value.goldValue
|
form.value.amount = form.value.goldValue
|
||||||
@@ -440,7 +461,7 @@ async function ok() {
|
|||||||
// await getManager()
|
// await getManager()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
// message.error('خطا در بارگذاری اطلاعات')
|
submitError.value = getOrderSubmitError(e)
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,6 @@
|
|||||||
|
|
||||||
<div class="grid grid-cols-2 gap-2 md:grid-cols-4">
|
<div class="grid grid-cols-2 gap-2 md:grid-cols-4">
|
||||||
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
||||||
<BasicInfoItem title="نوع کاربر" :value="userInfo?.type_str" />
|
|
||||||
<BasicInfoItem
|
<BasicInfoItem
|
||||||
title="تاریخ تولد"
|
title="تاریخ تولد"
|
||||||
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
||||||
@@ -94,7 +93,6 @@
|
|||||||
<BasicInfoItem title="شماره ملی" :value="userInfo?.n_code ?? '_'" />
|
<BasicInfoItem title="شماره ملی" :value="userInfo?.n_code ?? '_'" />
|
||||||
<BasicInfoItem title="نام استان" :value="userInfo?.province ?? '_'" />
|
<BasicInfoItem title="نام استان" :value="userInfo?.province ?? '_'" />
|
||||||
<BasicInfoItem title="نام شهر" :value="userInfo?.city ?? '_'" />
|
<BasicInfoItem title="نام شهر" :value="userInfo?.city ?? '_'" />
|
||||||
<BasicInfoItem title="سقف اعتبار" :value="userInfo?.gram ? `${userInfo?.gram} گرم` : '_'" />
|
|
||||||
<BasicInfoItem title="کد معرف" :value="userInfo?.referral_id" />
|
<BasicInfoItem title="کد معرف" :value="userInfo?.referral_id" />
|
||||||
<BasicInfoItem
|
<BasicInfoItem
|
||||||
title="کد معرف کاربر"
|
title="کد معرف کاربر"
|
||||||
|
|||||||
@@ -75,7 +75,6 @@
|
|||||||
|
|
||||||
<MobileInfoGrid>
|
<MobileInfoGrid>
|
||||||
<MobileDetailRow label="کد کاربری" :value="row.id ?? '-'" />
|
<MobileDetailRow label="کد کاربری" :value="row.id ?? '-'" />
|
||||||
<MobileDetailRow label="نوع کاربر" :value="row.type_str || '-'" />
|
|
||||||
<MobileDetailRow label="کد معرف" :value="row.referral_id ?? '-'" />
|
<MobileDetailRow label="کد معرف" :value="row.referral_id ?? '-'" />
|
||||||
<MobileDetailRow label="نام معرف" :value="row.referral?.name ?? '-'" />
|
<MobileDetailRow label="نام معرف" :value="row.referral?.name ?? '-'" />
|
||||||
<MobileDetailRow label="آخرین بازدید" :value="lastSeen(row)" value-class="text-xs" />
|
<MobileDetailRow label="آخرین بازدید" :value="lastSeen(row)" value-class="text-xs" />
|
||||||
|
|||||||
@@ -83,41 +83,18 @@
|
|||||||
</template>
|
</template>
|
||||||
<BasicInput v-model:value="form.n_code" />
|
<BasicInput v-model:value="form.n_code" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item name="profit_amount">
|
|
||||||
<template #label>
|
|
||||||
<DashboardLabelWithHelp label="میزان پاداش" :help="profitAmountHelp" size="sm" />
|
|
||||||
</template>
|
|
||||||
<BasicInput v-model:value="form.profit_amount" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item name="add_user_limit">
|
<a-form-item name="add_user_limit">
|
||||||
<template #label>
|
<template #label>
|
||||||
<DashboardLabelWithHelp label="حداکثر معرفی" :help="addUserLimitHelp" size="sm" />
|
<DashboardLabelWithHelp label="حداکثر معرفی" :help="addUserLimitHelp" size="sm" />
|
||||||
</template>
|
</template>
|
||||||
<BasicInput v-model:value="form.add_user_limit" />
|
<BasicInput v-model:value="form.add_user_limit" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item name="type">
|
|
||||||
<template #label>
|
|
||||||
<DashboardLabelWithHelp label="نوع مشتری" :help="customerTypeHelp" size="sm" />
|
|
||||||
</template>
|
|
||||||
<BasicSelect
|
|
||||||
v-model:value="form.type"
|
|
||||||
:items="customerItems"
|
|
||||||
valueName="value"
|
|
||||||
keyName="key"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item name="referral_to_id">
|
<a-form-item name="referral_to_id">
|
||||||
<template #label>
|
<template #label>
|
||||||
<DashboardLabelWithHelp label="کد معرف" :help="referralToIdHelp" size="sm" />
|
<DashboardLabelWithHelp label="کد معرف" :help="referralToIdHelp" size="sm" />
|
||||||
</template>
|
</template>
|
||||||
<BasicInput v-model:value="form.referral_to_id" :disabled="editId" />
|
<BasicInput v-model:value="form.referral_to_id" :disabled="editId" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="editId" name="gram" :rules="inputRules()">
|
|
||||||
<template #label>
|
|
||||||
<DashboardLabelWithHelp label="سقف اعتبار" :help="gramHelp" size="sm" />
|
|
||||||
</template>
|
|
||||||
<BasicInput v-model:value="form.gram" />
|
|
||||||
</a-form-item>
|
|
||||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||||
<BasicInput v-model:value="form.print_name" />
|
<BasicInput v-model:value="form.print_name" />
|
||||||
</a-form-item>-->
|
</a-form-item>-->
|
||||||
@@ -176,7 +153,6 @@
|
|||||||
|
|
||||||
<div class="grid min-w-0 grid-cols-2 gap-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
|
<div class="grid min-w-0 grid-cols-2 gap-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5">
|
||||||
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
||||||
<BasicInfoItem title="نوع کاربر" :value="userInfo?.type_str" />
|
|
||||||
<BasicInfoItem
|
<BasicInfoItem
|
||||||
title="تاریخ تولد"
|
title="تاریخ تولد"
|
||||||
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
||||||
@@ -184,10 +160,6 @@
|
|||||||
<BasicInfoItem title="شماره ملی" :value="userInfo?.n_code ?? '_'" />
|
<BasicInfoItem title="شماره ملی" :value="userInfo?.n_code ?? '_'" />
|
||||||
<BasicInfoItem title="نام استان" :value="userInfo?.province ?? '_'" />
|
<BasicInfoItem title="نام استان" :value="userInfo?.province ?? '_'" />
|
||||||
<BasicInfoItem title="نام شهر" :value="userInfo?.city ?? '_'" />
|
<BasicInfoItem title="نام شهر" :value="userInfo?.city ?? '_'" />
|
||||||
<BasicInfoItem
|
|
||||||
title="سقف اعتبار"
|
|
||||||
:value="userInfo?.gram ? `${userInfo?.gram} گرم` : '_'"
|
|
||||||
/>
|
|
||||||
<BasicInfoItem title="کد معرف" :value="userInfo?.referral_id" />
|
<BasicInfoItem title="کد معرف" :value="userInfo?.referral_id" />
|
||||||
<BasicInfoItem
|
<BasicInfoItem
|
||||||
title="کد معرف کاربر"
|
title="کد معرف کاربر"
|
||||||
@@ -197,10 +169,6 @@
|
|||||||
title="نام معرف کاربر"
|
title="نام معرف کاربر"
|
||||||
:value="userInfo?.referral ? userInfo?.referral?.name : '_'"
|
:value="userInfo?.referral ? userInfo?.referral?.name : '_'"
|
||||||
/>
|
/>
|
||||||
<BasicInfoItem
|
|
||||||
title="میزان سود معرفی"
|
|
||||||
:value="userInfo?.profit_amount ? `${userInfo?.profit_amount} گرم` : '_'"
|
|
||||||
/>
|
|
||||||
<BasicInfoItem
|
<BasicInfoItem
|
||||||
title="حداکثر معرفی"
|
title="حداکثر معرفی"
|
||||||
:value="userInfo?.add_user_limit ? `${userInfo?.add_user_limit} نفر` : '_'"
|
:value="userInfo?.add_user_limit ? `${userInfo?.add_user_limit} نفر` : '_'"
|
||||||
@@ -337,21 +305,12 @@ const cityHelp: DashboardHelp = {
|
|||||||
const nCodeHelp: DashboardHelp = {
|
const nCodeHelp: DashboardHelp = {
|
||||||
description: 'کد ملی ۱۰ رقمی برای احراز هویت.',
|
description: 'کد ملی ۱۰ رقمی برای احراز هویت.',
|
||||||
}
|
}
|
||||||
const profitAmountHelp: DashboardHelp = {
|
|
||||||
description: 'میزان پاداش معرفی این کاربر به گرم طلا.',
|
|
||||||
}
|
|
||||||
const addUserLimitHelp: DashboardHelp = {
|
const addUserLimitHelp: DashboardHelp = {
|
||||||
description: 'حداکثر تعداد نفری که این مشتری میتواند با کد معرف خود دعوت کند.',
|
description: 'حداکثر تعداد نفری که این مشتری میتواند با کد معرف خود دعوت کند.',
|
||||||
}
|
}
|
||||||
const customerTypeHelp: DashboardHelp = {
|
|
||||||
description: 'نوع مشتری: همکار، خانگی یا سرمایهگذار — تعیینکننده دسترسی و قوانین معامله.',
|
|
||||||
}
|
|
||||||
const referralToIdHelp: DashboardHelp = {
|
const referralToIdHelp: DashboardHelp = {
|
||||||
description: 'کد معرف فردی که این مشتری را دعوت کرده. پس از ثبت قابل تغییر نیست.',
|
description: 'کد معرف فردی که این مشتری را دعوت کرده. پس از ثبت قابل تغییر نیست.',
|
||||||
}
|
}
|
||||||
const gramHelp: DashboardHelp = {
|
|
||||||
description: 'حداکثر وزن طلایی که این مشتری میتواند خرید کند (به گرم).',
|
|
||||||
}
|
|
||||||
|
|
||||||
//tabs
|
//tabs
|
||||||
const activeKey = ref('اطلاعات جامع')
|
const activeKey = ref('اطلاعات جامع')
|
||||||
@@ -389,20 +348,6 @@ const confirmItems: Array<Item> = [
|
|||||||
key: false
|
key: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const customerItems: Array<Item> = [
|
|
||||||
{
|
|
||||||
value: 'همکار',
|
|
||||||
key: 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'خانگی',
|
|
||||||
key: 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'سرمایه گذار',
|
|
||||||
key: 3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
//wallet
|
//wallet
|
||||||
const showWalletCharge = ref<boolean>(false)
|
const showWalletCharge = ref<boolean>(false)
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<BasicMainCard>
|
||||||
|
<div class="flex h-full min-h-0 flex-col md:flex-row">
|
||||||
|
<BasicMenu width="11rem" :menu="menu" mode="horizontal" class="overflow-auto md:hidden" />
|
||||||
|
<BasicMenu
|
||||||
|
width="13rem"
|
||||||
|
:menu="menu"
|
||||||
|
class="hidden min-w-[13.5rem] overflow-auto md:inline"
|
||||||
|
/>
|
||||||
|
<RouterView
|
||||||
|
:key="route.name"
|
||||||
|
class="mt-5 min-h-0 w-full flex-1 overflow-hidden md:mr-5 md:mt-0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</BasicMainCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import BasicMenu from '@/components/BasicMenu/index.vue'
|
||||||
|
import { useRouterStore } from '@core/stores/router'
|
||||||
|
import { get } from 'lodash'
|
||||||
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
|
const routerStore = useRouterStore()
|
||||||
|
const route = useRoute()
|
||||||
|
const menu = computed(() => {
|
||||||
|
const item = routerStore.routes.find((item) => item.name === 'hesabKetab')
|
||||||
|
const children = get(item, 'children[0].children', []) as RouteRecordRaw[]
|
||||||
|
return children
|
||||||
|
.filter((child) => !child.meta?.hideMenu)
|
||||||
|
.sort((a, b) => (Number(a.meta?.order) || 99) - (Number(b.meta?.order) || 99))
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
@@ -1,81 +1,100 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<div class="flex flex-col items-center gap-1 rounded-xl bg-gray-50 px-4 py-3 sm:flex-row sm:justify-center sm:gap-4">
|
<div
|
||||||
|
class="flex flex-col items-center gap-1 rounded-xl bg-gray-50 px-4 py-3 sm:flex-row sm:justify-center sm:gap-4"
|
||||||
|
>
|
||||||
<span class="text-sm text-gray-600">{{ metalLabel.goldTradeBuySell(form.direction) }}</span>
|
<span class="text-sm text-gray-600">{{ metalLabel.goldTradeBuySell(form.direction) }}</span>
|
||||||
<span class="text-sm font-700 text-gray-900">{{ marketPriceLabel }}</span>
|
<span class="text-sm font-700 text-gray-900">{{ marketPriceLabel }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-form-item label="نوع تراکنش" name="direction" :rules="inputRules()">
|
<div class="grid gap-3 md:grid-cols-2 md:gap-4 md:items-start">
|
||||||
<a-radio-group v-model:value="form.direction" button-style="solid" @change="$emit('changePrice')">
|
<div class="space-y-3">
|
||||||
<a-radio-button :value="1">خرید</a-radio-button>
|
<a-form-item label="نوع تراکنش" name="direction" :rules="inputRules()" class="mb-0">
|
||||||
<a-radio-button :value="2">فروش</a-radio-button>
|
<a-radio-group
|
||||||
</a-radio-group>
|
v-model:value="form.direction"
|
||||||
</a-form-item>
|
button-style="solid"
|
||||||
|
@change="$emit('changePrice')"
|
||||||
|
>
|
||||||
|
<a-radio-button :value="1">خرید</a-radio-button>
|
||||||
|
<a-radio-button :value="2">فروش</a-radio-button>
|
||||||
|
</a-radio-group>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item
|
<a-form-item
|
||||||
:label="`قیمت ${form.direction === 1 ? 'خرید' : 'فروش'} هر گرم`"
|
:label="`قیمت ${form.direction === 1 ? 'خرید' : 'فروش'} هر گرم`"
|
||||||
name="price"
|
name="price"
|
||||||
:rules="inputRules()"
|
:rules="inputRules()"
|
||||||
>
|
class="mb-0"
|
||||||
<BasicInput
|
>
|
||||||
v-model:value="form.price"
|
<BasicInput
|
||||||
addon-before="ریال"
|
v-model:value="form.price"
|
||||||
type="price"
|
addon-before="ریال"
|
||||||
@change="$emit('changePriceValue')"
|
type="price"
|
||||||
/>
|
@onchange="$emit('changePriceValue')"
|
||||||
</a-form-item>
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="تاریخ سفارش" name="pay_at" :rules="inputRules()">
|
<a-form-item label="تاریخ سفارش" name="pay_at" :rules="inputRules()" class="mb-0">
|
||||||
<BaseDatePicker v-model:value="form.pay_at" format="YYYY-MM-DD HH:mm:ss" />
|
<BaseDatePicker v-model:value="form.pay_at" format="YYYY-MM-DD HH:mm:ss" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="سود" name="difference" :rules="inputRules()">
|
<a-form-item label="سود" name="difference" :rules="inputRules()" class="mb-0">
|
||||||
<BasicInput v-model:value="form.difference" addon-before="ریال" type="price" />
|
<BasicInput v-model:value="form.difference" addon-before="ریال" type="price" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- <a-form-item label="کل قیمت لیمان" name="total_price_liman">
|
<div class="space-y-3">
|
||||||
<BasicInput v-model:value="form.total_price_liman" addon-before="ریال" type="price" />
|
<div class="space-y-2 rounded-xl bg-orange-50 p-3">
|
||||||
</a-form-item>-->
|
<a-form-item label="انتخاب کاربر" name="customer_id" :rules="inputRules()" class="mb-0">
|
||||||
|
<BasicSelect
|
||||||
|
v-model:value="form.customer_id"
|
||||||
|
:items="userItems"
|
||||||
|
valueName="name"
|
||||||
|
keyName="id"
|
||||||
|
@change="$emit('changeUser', $event)"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<BasicInfoItem
|
||||||
|
is-line
|
||||||
|
:title="metalLabel.goldWalletTitle()"
|
||||||
|
:value="selectedCustomer?.wallet?.[0]?.gold ?? '_'"
|
||||||
|
/>
|
||||||
|
<BasicInfoItem
|
||||||
|
is-line
|
||||||
|
title="کیف پول ریالی"
|
||||||
|
:value="selectedCustomer?.wallet?.[0]?.cash ?? '_'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="space-y-2 rounded-xl bg-orange-50 p-3">
|
<div class="space-y-2 rounded-xl bg-blue-50 p-3">
|
||||||
<a-form-item label="انتخاب کاربر" name="customer_id" :rules="inputRules()" class="mb-0">
|
<div class="text-sm font-600 text-gray-700">
|
||||||
<BasicSelect
|
مقدار {{ form.direction === 1 ? 'خرید' : 'فروش' }}:
|
||||||
v-model:value="form.customer_id"
|
</div>
|
||||||
:items="userItems"
|
<a-form-item name="goldCash" :rules="inputRulesNumber()" class="mb-0">
|
||||||
valueName="name"
|
<BasicInput
|
||||||
keyName="id"
|
v-model:value="form.goldCash"
|
||||||
@change="$emit('changeUser', $event)"
|
addon-before="ریال"
|
||||||
/>
|
addon-bg-color="#0A1B37"
|
||||||
</a-form-item>
|
addon-text-color="white"
|
||||||
<BasicInfoItem is-line :title="metalLabel.goldWalletTitle()" :value="selectedCustomer?.wallet?.[0]?.gold ?? '_'" />
|
place-holder="ارزش کل"
|
||||||
<BasicInfoItem is-line title="کیف پول ریالی" :value="selectedCustomer?.wallet?.[0]?.cash ?? '_'" />
|
type="price"
|
||||||
</div>
|
@onchange="$emit('calculateGold', $event)"
|
||||||
|
/>
|
||||||
<div class="space-y-2 rounded-xl bg-blue-50 p-3">
|
</a-form-item>
|
||||||
<div class="text-sm font-600 text-gray-700">مقدار {{ form.direction === 1 ? 'خرید' : 'فروش' }}:</div>
|
<a-form-item name="goldValue" :rules="inputRulesNumber()" class="mb-0">
|
||||||
<a-form-item name="goldCash" :rules="inputRulesNumber()" class="mb-0">
|
<BasicInput
|
||||||
<BasicInput
|
v-model:value="form.goldValue"
|
||||||
v-model:value="form.goldCash"
|
addon-before="گرم"
|
||||||
addon-before="ریال"
|
addon-bg-color="#0A1B37"
|
||||||
addon-bg-color="#0A1B37"
|
addon-text-color="white"
|
||||||
addon-text-color="white"
|
:place-holder="metalLabel.goldPlaceholder()"
|
||||||
place-holder="ارزش کل"
|
type="text"
|
||||||
type="price"
|
@onchange="$emit('calculateCash', $event)"
|
||||||
@onchange="$emit('calculateGold', $event)"
|
/>
|
||||||
/>
|
</a-form-item>
|
||||||
</a-form-item>
|
</div>
|
||||||
<a-form-item name="goldValue" :rules="inputRulesNumber()" class="mb-0">
|
</div>
|
||||||
<BasicInput
|
|
||||||
v-model:value="form.goldValue"
|
|
||||||
addon-before="گرم"
|
|
||||||
addon-bg-color="#0A1B37"
|
|
||||||
addon-text-color="white"
|
|
||||||
:place-holder="metalLabel.goldPlaceholder()"
|
|
||||||
type="tel"
|
|
||||||
@onchange="$emit('calculateCash', $event)"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-form>
|
</a-form>
|
||||||
@@ -101,8 +120,8 @@ defineEmits<{
|
|||||||
(e: 'changePrice'): void
|
(e: 'changePrice'): void
|
||||||
(e: 'changePriceValue'): void
|
(e: 'changePriceValue'): void
|
||||||
(e: 'changeUser', value: Customer): void
|
(e: 'changeUser', value: Customer): void
|
||||||
(e: 'calculateGold', value: number): void
|
(e: 'calculateGold', value: number | string): void
|
||||||
(e: 'calculateCash', value: number): void
|
(e: 'calculateCash', value: number | string): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<BasicActionSheet
|
<BasicActionSheet
|
||||||
v-model:visible="addOrderVisible"
|
v-model:visible="addOrderVisible"
|
||||||
:title="orderSheetTitle"
|
:title="orderSheetTitle"
|
||||||
modal-width="25rem"
|
modal-width="48rem"
|
||||||
drawer-height="90vh"
|
drawer-height="90vh"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:showButton="true"
|
:showButton="true"
|
||||||
@@ -32,6 +32,15 @@
|
|||||||
@cancel="closeAddOrder"
|
@cancel="closeAddOrder"
|
||||||
>
|
>
|
||||||
<div v-if="isMobile" class="mb-3 text-base font-700">{{ orderSheetTitle }}</div>
|
<div v-if="isMobile" class="mb-3 text-base font-700">{{ orderSheetTitle }}</div>
|
||||||
|
<a-alert
|
||||||
|
v-if="submitError"
|
||||||
|
type="error"
|
||||||
|
:message="submitError"
|
||||||
|
show-icon
|
||||||
|
closable
|
||||||
|
class="mb-3"
|
||||||
|
@close="submitError = ''"
|
||||||
|
/>
|
||||||
<OrderEditorFormBody
|
<OrderEditorFormBody
|
||||||
ref="orderEditorRef"
|
ref="orderEditorRef"
|
||||||
:form="form"
|
:form="form"
|
||||||
@@ -85,6 +94,7 @@ import { formatAmountWithUnit } from '@/utils/weightUnit'
|
|||||||
|
|
||||||
//loading
|
//loading
|
||||||
const loading = ref<boolean>(false)
|
const loading = ref<boolean>(false)
|
||||||
|
const submitError = ref('')
|
||||||
|
|
||||||
//define store
|
//define store
|
||||||
const store = useStaticApiListsStore()
|
const store = useStaticApiListsStore()
|
||||||
@@ -131,10 +141,21 @@ let interval: ReturnType<typeof setInterval> | undefined
|
|||||||
|
|
||||||
const orderSheetTitle = computed(() => `${editId ? 'ویرایش' : 'افزودن'} سفارش`)
|
const orderSheetTitle = computed(() => `${editId ? 'ویرایش' : 'افزودن'} سفارش`)
|
||||||
|
|
||||||
|
function clearSubmitError() {
|
||||||
|
submitError.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
function closeAddOrder() {
|
function closeAddOrder() {
|
||||||
|
clearSubmitError()
|
||||||
stopGetPrice()
|
stopGetPrice()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOrderSubmitError(e: unknown): string {
|
||||||
|
const msg = (e as { response?: { data?: { message?: string } } })?.response?.data?.message
|
||||||
|
if (typeof msg === 'string' && msg.trim()) return msg
|
||||||
|
return 'خطا در ثبت سفارش'
|
||||||
|
}
|
||||||
|
|
||||||
async function setIntervalGetPrice() {
|
async function setIntervalGetPrice() {
|
||||||
try {
|
try {
|
||||||
interval = setInterval(async () => {
|
interval = setInterval(async () => {
|
||||||
@@ -149,6 +170,7 @@ async function setIntervalGetPrice() {
|
|||||||
|
|
||||||
function changePrice() {
|
function changePrice() {
|
||||||
form.value.price = form.value.direction === 1 ? dataLast.value?.buy : dataLast.value?.sell
|
form.value.price = form.value.direction === 1 ? dataLast.value?.buy : dataLast.value?.sell
|
||||||
|
changePriceValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPrices() {
|
async function getPrices() {
|
||||||
@@ -270,42 +292,56 @@ function info(val: Order) {
|
|||||||
userInfoVisible.value = true
|
userInfoVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateCash(val: number) {
|
function toOrderNumber(val: unknown): number | undefined {
|
||||||
// console.log(val)
|
if (val === undefined || val === null || val === '') return undefined
|
||||||
if (form.value.price) {
|
const n = Number(String(val).replaceAll(',', ''))
|
||||||
if (form.value.direction === 1) {
|
return Number.isFinite(n) ? n : undefined
|
||||||
if (val >= 0.001) form.value.goldCash = parseFloat((val * form.value.price).toFixed(0))
|
|
||||||
else form.value.goldCash = undefined
|
|
||||||
} else {
|
|
||||||
if (val >= 0.001) form.value.goldCash = parseFloat((val * form.value.price).toFixed(0))
|
|
||||||
else form.value.goldCash = undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateGold(val: number) {
|
/** آخرین فیلدی که کاربر ویرایش کرده — برای همگامسازی هنگام تغییر قیمت هر گرم */
|
||||||
// console.log(val)
|
const amountInputLock = ref<'rial' | 'gram' | null>(null)
|
||||||
// form.value.goldCash = usePriceWithoutType(form.value.goldCash)
|
|
||||||
if (form.value.price) {
|
function calculateCash(val: unknown) {
|
||||||
if (form.value.direction === 1) {
|
amountInputLock.value = 'gram'
|
||||||
if (val / form.value.price >= 0.001)
|
const grams = toOrderNumber(val)
|
||||||
form.value.goldValue = toFixedDownTwoChar(parseFloat(val / form.value.price))
|
const price = toOrderNumber(form.value.price)
|
||||||
else if (val.toString() === '') form.value.goldValue = undefined
|
if (grams === undefined) {
|
||||||
else form.value.goldValue = 0
|
form.value.goldCash = undefined
|
||||||
} else {
|
amountInputLock.value = null
|
||||||
if (val >= form.value.price)
|
return
|
||||||
form.value.goldValue = toFixedDownTwoChar(parseFloat(val / form.value.price))
|
|
||||||
else if (val.toString() === '') form.value.goldValue = undefined
|
|
||||||
else form.value.goldValue = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!price) return
|
||||||
|
if (grams >= 0.001) form.value.goldCash = Math.round(grams * price)
|
||||||
|
else form.value.goldCash = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateGold(val: unknown) {
|
||||||
|
amountInputLock.value = 'rial'
|
||||||
|
const rial = toOrderNumber(val)
|
||||||
|
const price = toOrderNumber(form.value.price)
|
||||||
|
if (rial === undefined) {
|
||||||
|
form.value.goldValue = undefined
|
||||||
|
amountInputLock.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!price) return
|
||||||
|
const grams = rial / price
|
||||||
|
if (grams >= 0.001) form.value.goldValue = toFixedDownTwoChar(grams)
|
||||||
|
else if (rial === 0) form.value.goldValue = 0
|
||||||
|
else form.value.goldValue = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePriceValue() {
|
function changePriceValue() {
|
||||||
calculateCash(form.value.goldValue)
|
if (amountInputLock.value === 'rial' || (form.value.goldValue == null && form.value.goldCash != null)) {
|
||||||
|
calculateGold(form.value.goldCash)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (form.value.goldValue != null) {
|
||||||
|
calculateCash(form.value.goldValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toFixedDownTwoChar(num) {
|
function toFixedDownTwoChar(num: number) {
|
||||||
return Math.floor(num * 100) / 100
|
return Math.floor(num * 100) / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,6 +358,7 @@ async function edit(record: Customer) {
|
|||||||
async function add() {
|
async function add() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
editId = undefined
|
editId = undefined
|
||||||
|
clearSubmitError()
|
||||||
// await store.getUsersList()
|
// await store.getUsersList()
|
||||||
resetData()
|
resetData()
|
||||||
addOrderVisible.value = true
|
addOrderVisible.value = true
|
||||||
@@ -335,6 +372,7 @@ async function add() {
|
|||||||
//reset data
|
//reset data
|
||||||
const resetData = () => {
|
const resetData = () => {
|
||||||
orderEditorRef.value?.resetFields?.()
|
orderEditorRef.value?.resetFields?.()
|
||||||
|
amountInputLock.value = null
|
||||||
form.value = {
|
form.value = {
|
||||||
direction: 1,
|
direction: 1,
|
||||||
price: 0,
|
price: 0,
|
||||||
@@ -366,6 +404,7 @@ const userInfoVisible = ref<boolean>(false)
|
|||||||
//submit user
|
//submit user
|
||||||
async function ok() {
|
async function ok() {
|
||||||
await orderEditorRef.value?.validateFields?.().then(async () => {
|
await orderEditorRef.value?.validateFields?.().then(async () => {
|
||||||
|
clearSubmitError()
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
form.value.amount = form.value.goldValue
|
form.value.amount = form.value.goldValue
|
||||||
@@ -380,6 +419,7 @@ async function ok() {
|
|||||||
refreshTable()
|
refreshTable()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
submitError.value = getOrderSubmitError(e)
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -372,6 +372,23 @@
|
|||||||
<BasicInput v-model:value="form.max_order_cash" addon-before="ریال" type="price" />
|
<BasicInput v-model:value="form.max_order_cash" addon-before="ریال" type="price" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<a-form-item name="has_physical_delivery">
|
||||||
|
<template #label>
|
||||||
|
<DashboardLabelWithHelp label="تحویل فیزیکی" :help="physicalDeliveryHelp" size="sm" />
|
||||||
|
</template>
|
||||||
|
<a-switch v-model:checked="form.has_physical_delivery" @change="onPhysicalDeliveryChange" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item v-if="form.has_physical_delivery" name="min_physical_delivery_grams">
|
||||||
|
<template #label>
|
||||||
|
<DashboardLabelWithHelp label="حداقل گرم برای تحویل" :help="minPhysicalDeliveryHelp" size="sm" />
|
||||||
|
</template>
|
||||||
|
<BasicInput
|
||||||
|
v-model:value="form.min_physical_delivery_grams"
|
||||||
|
addon-before="گرم"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</BaseCollapse>
|
</BaseCollapse>
|
||||||
@@ -521,6 +538,16 @@ const orderLimitHelp: DashboardHelp = {
|
|||||||
description: 'حداقل یکی از «حداقل» یا «حداکثر» الزامی است؛ میتوانید فقط یکی را پر کنید.',
|
description: 'حداقل یکی از «حداقل» یا «حداکثر» الزامی است؛ میتوانید فقط یکی را پر کنید.',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const physicalDeliveryHelp: DashboardHelp = {
|
||||||
|
description:
|
||||||
|
'روشن: این محصول امکان تحویل فیزیکی دارد. خاموش: تحویل فیزیکی ندارد. برای محصولات تعدادی، مقدار به گرم = تعداد × وزن هر واحد سنجیده میشود.',
|
||||||
|
}
|
||||||
|
|
||||||
|
const minPhysicalDeliveryHelp: DashboardHelp = {
|
||||||
|
description:
|
||||||
|
'حداقل موجودی (به گرم) که کاربر باید داشته باشد تا تحویل فیزیکی فعال شود؛ در غیر این صورت پیام «چند گرم مانده تا تحویل» نمایش داده میشود.',
|
||||||
|
}
|
||||||
|
|
||||||
const tradeByQuantityHelp: DashboardHelp = {
|
const tradeByQuantityHelp: DashboardHelp = {
|
||||||
description:
|
description:
|
||||||
'فرم خرید/فروش با «ارزش کل» و «مقدار». فقط هنگام ساخت محصول قابل تعیین است و بعداً تغییر نمیکند.',
|
'فرم خرید/فروش با «ارزش کل» و «مقدار». فقط هنگام ساخت محصول قابل تعیین است و بعداً تغییر نمیکند.',
|
||||||
@@ -616,6 +643,12 @@ function onOrderLimitChange(checked: boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onPhysicalDeliveryChange(checked: boolean) {
|
||||||
|
if (!checked) {
|
||||||
|
props.form.min_physical_delivery_grams = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
(e: 'addPrice'): void
|
(e: 'addPrice'): void
|
||||||
(e: 'minusPrice'): void
|
(e: 'minusPrice'): void
|
||||||
|
|||||||
@@ -337,6 +337,8 @@ async function edit(record: Product) {
|
|||||||
show_in_assets: productData.show_in_assets ?? false,
|
show_in_assets: productData.show_in_assets ?? false,
|
||||||
trade_by_quantity: productData.trade_by_quantity ?? false,
|
trade_by_quantity: productData.trade_by_quantity ?? false,
|
||||||
override_trading_hours: productData.override_trading_hours ?? false,
|
override_trading_hours: productData.override_trading_hours ?? false,
|
||||||
|
has_physical_delivery: productData.has_physical_delivery ?? false,
|
||||||
|
min_physical_delivery_grams: productData.min_physical_delivery_grams ?? undefined,
|
||||||
cash_fee_buy: parseCashFeeValue(productData.cash_fee_buy),
|
cash_fee_buy: parseCashFeeValue(productData.cash_fee_buy),
|
||||||
cash_fee_sell: parseCashFeeValue(productData.cash_fee_sell),
|
cash_fee_sell: parseCashFeeValue(productData.cash_fee_sell),
|
||||||
cash_fee_buy_is_percent: normalizeCashFeeFlags(productData.cash_fee_buy_is_percent),
|
cash_fee_buy_is_percent: normalizeCashFeeFlags(productData.cash_fee_buy_is_percent),
|
||||||
@@ -390,6 +392,8 @@ function resetData() {
|
|||||||
trade_by_quantity: false,
|
trade_by_quantity: false,
|
||||||
override_trading_hours: false,
|
override_trading_hours: false,
|
||||||
use_last_price_if_zero: false,
|
use_last_price_if_zero: false,
|
||||||
|
has_physical_delivery: false,
|
||||||
|
min_physical_delivery_grams: undefined,
|
||||||
inventory: 0,
|
inventory: 0,
|
||||||
min_order_cash: undefined,
|
min_order_cash: undefined,
|
||||||
max_order_cash: undefined,
|
max_order_cash: undefined,
|
||||||
@@ -523,6 +527,19 @@ async function saveProduct() {
|
|||||||
|
|
||||||
normalizeProductOrderLimitForm(payload)
|
normalizeProductOrderLimitForm(payload)
|
||||||
|
|
||||||
|
payload.has_physical_delivery = Boolean(payload.has_physical_delivery)
|
||||||
|
if (!payload.has_physical_delivery) {
|
||||||
|
payload.min_physical_delivery_grams = null
|
||||||
|
} else {
|
||||||
|
const minGrams = Number(payload.min_physical_delivery_grams)
|
||||||
|
if (!Number.isFinite(minGrams) || minGrams <= 0) {
|
||||||
|
showSubmitError('برای فعال کردن تحویل فیزیکی باید حداقل گرم معتبر وارد شود')
|
||||||
|
loading.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
payload.min_physical_delivery_grams = minGrams
|
||||||
|
}
|
||||||
|
|
||||||
if (editId) {
|
if (editId) {
|
||||||
delete payload.trade_by_quantity
|
delete payload.trade_by_quantity
|
||||||
await updateCustomer(editId, payload)
|
await updateCustomer(editId, payload)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
/** ریدایرکت آدرس قدیمی — منو زیر پیکربندی است */
|
/** ریدایرکت آدرس قدیمی — منو زیر حساب کتاب است */
|
||||||
const Accounting: RouteRecordRaw = {
|
const Accounting: RouteRecordRaw = {
|
||||||
name: 'accounting',
|
name: 'accounting',
|
||||||
path: '/accounting',
|
path: '/accounting',
|
||||||
|
|||||||
@@ -1,35 +1,13 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
const Withdraw: RouteRecordRaw = {
|
/** ریدایرکت آدرس قدیمی — منو زیر حساب کتاب است */
|
||||||
|
const Accounts: RouteRecordRaw = {
|
||||||
name: 'accounts',
|
name: 'accounts',
|
||||||
path: '/accounts',
|
path: '/accounts',
|
||||||
component: () => import('@core/layouts/BasicLayout.vue'),
|
|
||||||
redirect: { name: 'accountsMain' },
|
redirect: { name: 'accountsMain' },
|
||||||
meta: {
|
meta: {
|
||||||
icon: 'vuesax-linear:cards',
|
hideMenu: true
|
||||||
// permissionsKey: 'orders',
|
}
|
||||||
title: 'حساب ها',
|
|
||||||
disabled: false,
|
|
||||||
hideMenu: false,
|
|
||||||
hideChildren: true,
|
|
||||||
order: 6
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'accountsMain',
|
|
||||||
path: '',
|
|
||||||
component: () => import('@/pages/menuPages/cards/index.vue'),
|
|
||||||
meta: {
|
|
||||||
// permissionsKey: 'project',
|
|
||||||
icon: 'vuesax-linear:money-send',
|
|
||||||
order: 3,
|
|
||||||
title: 'حساب ها',
|
|
||||||
disabled: false,
|
|
||||||
hideMenu: false
|
|
||||||
//hideChildren: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Withdraw
|
export default Accounts
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
|
const HesabKetab: RouteRecordRaw = {
|
||||||
|
name: 'hesabKetab',
|
||||||
|
path: '/hesab-ketab',
|
||||||
|
component: () => import('@core/layouts/BasicLayout.vue'),
|
||||||
|
redirect: { name: 'hesabKetabMain' },
|
||||||
|
meta: {
|
||||||
|
icon: 'vuesax-linear:book',
|
||||||
|
title: 'حساب کتاب',
|
||||||
|
disabled: false,
|
||||||
|
hideMenu: false,
|
||||||
|
hideChildren: true,
|
||||||
|
order: 6
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'hesabKetabMain',
|
||||||
|
path: '',
|
||||||
|
component: () => import('@/pages/menuPages/hesabKetab/index.vue'),
|
||||||
|
redirect: { name: 'accountsMain' },
|
||||||
|
meta: {
|
||||||
|
icon: 'vuesax-linear:book',
|
||||||
|
order: 5,
|
||||||
|
title: 'حساب کتاب',
|
||||||
|
disabled: false,
|
||||||
|
hideMenu: true
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'accountsMain',
|
||||||
|
path: 'accounts',
|
||||||
|
component: () => import('@/pages/menuPages/cards/index.vue'),
|
||||||
|
meta: {
|
||||||
|
icon: 'vuesax-linear:cards',
|
||||||
|
title: 'حساب ها',
|
||||||
|
order: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'walletMain',
|
||||||
|
path: 'wallet',
|
||||||
|
component: () => import('@/pages/menuPages/wallet/index.vue'),
|
||||||
|
meta: {
|
||||||
|
icon: 'vuesax-linear:wallet',
|
||||||
|
title: 'کیف پول',
|
||||||
|
order: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'physicalWithdrawMain',
|
||||||
|
path: 'physical-withdraw',
|
||||||
|
component: () => import('@/pages/menuPages/physicalWithdraw/index.vue'),
|
||||||
|
meta: {
|
||||||
|
icon: 'vuesax-linear:truck-tick',
|
||||||
|
title: 'برداشت فیزیکی',
|
||||||
|
order: 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'withdrawMain',
|
||||||
|
path: 'withdraw',
|
||||||
|
component: () => import('@/pages/menuPages/withdraw/index.vue'),
|
||||||
|
meta: {
|
||||||
|
icon: 'vuesax-linear:money-change',
|
||||||
|
title: 'برداشت و واریز',
|
||||||
|
order: 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pricingMain',
|
||||||
|
path: 'pricing',
|
||||||
|
component: () => import('@/pages/menuPages/pricing/index.vue'),
|
||||||
|
meta: {
|
||||||
|
permissionsKey: 'pricing',
|
||||||
|
icon: 'vuesax-linear:dollar-circle',
|
||||||
|
title: 'تاریخچه قیمت',
|
||||||
|
order: 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'priceTriggers',
|
||||||
|
path: 'priceTriggers',
|
||||||
|
component: () => import('@/pages/menuPages/priceTriggers/index.vue'),
|
||||||
|
meta: {
|
||||||
|
permissionsKey: 'priceTriggers',
|
||||||
|
icon: 'vuesax-linear:notification-bing',
|
||||||
|
title: 'هشدار قیمت',
|
||||||
|
order: 6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'accountingMain',
|
||||||
|
path: 'accounting',
|
||||||
|
component: () => import('@/pages/menuPages/accounting/index.vue'),
|
||||||
|
meta: {
|
||||||
|
permissionsKey: 'accounting',
|
||||||
|
icon: 'vuesax-linear:calculator',
|
||||||
|
title: 'حسابداری',
|
||||||
|
order: 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HesabKetab
|
||||||
@@ -12,7 +12,7 @@ const Orders: RouteRecordRaw = {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
hideMenu: false,
|
hideMenu: false,
|
||||||
hideChildren: true,
|
hideChildren: true,
|
||||||
order: 7
|
order: 5
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,31 +1,13 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
|
/** ریدایرکت آدرس قدیمی — منو زیر حساب کتاب است */
|
||||||
const PhysicalWithdraw: RouteRecordRaw = {
|
const PhysicalWithdraw: RouteRecordRaw = {
|
||||||
name: 'physicalWithdraw',
|
name: 'physicalWithdraw',
|
||||||
path: '/physical-withdraw',
|
path: '/physical-withdraw',
|
||||||
component: () => import('@core/layouts/BasicLayout.vue'),
|
|
||||||
redirect: { name: 'physicalWithdrawMain' },
|
redirect: { name: 'physicalWithdrawMain' },
|
||||||
meta: {
|
meta: {
|
||||||
icon: 'vuesax-linear:truck-tick',
|
hideMenu: true
|
||||||
title: 'برداشت فیزیکی',
|
}
|
||||||
disabled: false,
|
|
||||||
hideMenu: false,
|
|
||||||
hideChildren: true,
|
|
||||||
order: 7.5
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'physicalWithdrawMain',
|
|
||||||
path: '',
|
|
||||||
component: () => import('@/pages/menuPages/physicalWithdraw/index.vue'),
|
|
||||||
meta: {
|
|
||||||
icon: 'vuesax-linear:truck-tick',
|
|
||||||
title: 'برداشت فیزیکی',
|
|
||||||
disabled: false,
|
|
||||||
hideMenu: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PhysicalWithdraw
|
export default PhysicalWithdraw
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
/** ریدایرکت آدرس قدیمی — منو زیر پیکربندی است */
|
/** ریدایرکت آدرس قدیمی — منو زیر حساب کتاب است */
|
||||||
const Pricing: RouteRecordRaw = {
|
const Pricing: RouteRecordRaw = {
|
||||||
name: 'pricing',
|
name: 'pricing',
|
||||||
path: '/pricing',
|
path: '/pricing',
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const Setting: RouteRecordRaw = {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
hideMenu: false,
|
hideMenu: false,
|
||||||
hideChildren: true,
|
hideChildren: true,
|
||||||
order: 10
|
order: 7
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@@ -43,17 +43,6 @@ const Setting: RouteRecordRaw = {
|
|||||||
order: 1
|
order: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'pricingMain',
|
|
||||||
path: 'pricing',
|
|
||||||
component: () => import('@/pages/menuPages/pricing/index.vue'),
|
|
||||||
meta: {
|
|
||||||
permissionsKey: 'pricing',
|
|
||||||
icon: 'vuesax-linear:dollar-circle',
|
|
||||||
title: 'تاریخچه قیمت',
|
|
||||||
order: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'captureSitesMain',
|
name: 'captureSitesMain',
|
||||||
path: 'capture-sites',
|
path: 'capture-sites',
|
||||||
@@ -62,7 +51,7 @@ const Setting: RouteRecordRaw = {
|
|||||||
permissionsKey: 'pricing',
|
permissionsKey: 'pricing',
|
||||||
icon: 'vuesax-linear:global',
|
icon: 'vuesax-linear:global',
|
||||||
title: 'سایتهای ریگیری',
|
title: 'سایتهای ریگیری',
|
||||||
order: 2.5
|
order: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -115,17 +104,6 @@ const Setting: RouteRecordRaw = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'priceTriggers',
|
|
||||||
path: 'priceTriggers',
|
|
||||||
component: () => import('@/pages/menuPages/priceTriggers/index.vue'),
|
|
||||||
meta: {
|
|
||||||
permissionsKey: 'priceTriggers',
|
|
||||||
icon: 'vuesax-linear:notification-bing',
|
|
||||||
title: 'هشدار قیمت',
|
|
||||||
order: 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'smsMain',
|
name: 'smsMain',
|
||||||
path: 'sms',
|
path: 'sms',
|
||||||
@@ -134,7 +112,7 @@ const Setting: RouteRecordRaw = {
|
|||||||
permissionsKey: 'sms',
|
permissionsKey: 'sms',
|
||||||
icon: 'vuesax-linear:sms',
|
icon: 'vuesax-linear:sms',
|
||||||
title: 'پیامکها',
|
title: 'پیامکها',
|
||||||
order: 6
|
order: 5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -146,7 +124,7 @@ const Setting: RouteRecordRaw = {
|
|||||||
icon: 'vuesax-linear:gift',
|
icon: 'vuesax-linear:gift',
|
||||||
title: 'کارت هدیه',
|
title: 'کارت هدیه',
|
||||||
hideMenu: true,
|
hideMenu: true,
|
||||||
order: 7
|
order: 6
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -158,7 +136,7 @@ const Setting: RouteRecordRaw = {
|
|||||||
icon: 'vuesax-linear:discount-shape',
|
icon: 'vuesax-linear:discount-shape',
|
||||||
title: 'تخفیفات',
|
title: 'تخفیفات',
|
||||||
hideMenu: true,
|
hideMenu: true,
|
||||||
order: 8
|
order: 7
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -169,19 +147,27 @@ const Setting: RouteRecordRaw = {
|
|||||||
permissionsKey: 'user',
|
permissionsKey: 'user',
|
||||||
icon: 'vuesax-linear:profile',
|
icon: 'vuesax-linear:profile',
|
||||||
title: 'مدیران',
|
title: 'مدیران',
|
||||||
order: 9
|
order: 8
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/** ریدایرکت آدرس قدیمی — به حساب کتاب منتقل شد */
|
||||||
{
|
{
|
||||||
name: 'accountingMain',
|
name: 'settingsPricingRedirect',
|
||||||
|
path: 'pricing',
|
||||||
|
redirect: { name: 'pricingMain' },
|
||||||
|
meta: { hideMenu: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'settingsPriceTriggersRedirect',
|
||||||
|
path: 'priceTriggers',
|
||||||
|
redirect: { name: 'priceTriggers' },
|
||||||
|
meta: { hideMenu: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'settingsAccountingRedirect',
|
||||||
path: 'accounting',
|
path: 'accounting',
|
||||||
component: () => import('@/pages/menuPages/accounting/index.vue'),
|
redirect: { name: 'accountingMain' },
|
||||||
meta: {
|
meta: { hideMenu: true }
|
||||||
permissionsKey: 'accounting',
|
|
||||||
icon: 'vuesax-linear:calculator',
|
|
||||||
title: 'حسابداری',
|
|
||||||
order: 10
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const Transactions: RouteRecordRaw = {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
hideMenu: false,
|
hideMenu: false,
|
||||||
hideChildren: true,
|
hideChildren: true,
|
||||||
order: 5
|
order: 4
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,35 +1,13 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
|
/** ریدایرکت آدرس قدیمی — منو زیر حساب کتاب است */
|
||||||
const Wallet: RouteRecordRaw = {
|
const Wallet: RouteRecordRaw = {
|
||||||
name: 'wallet',
|
name: 'wallet',
|
||||||
path: '/wallet',
|
path: '/wallet',
|
||||||
component: () => import('@core/layouts/BasicLayout.vue'),
|
|
||||||
redirect: { name: 'walletMain' },
|
redirect: { name: 'walletMain' },
|
||||||
meta: {
|
meta: {
|
||||||
icon: 'vuesax-linear:wallet',
|
hideMenu: true
|
||||||
// permissionsKey: 'project',
|
}
|
||||||
title: 'کیف پول',
|
|
||||||
disabled: false,
|
|
||||||
hideMenu: false,
|
|
||||||
hideChildren: true,
|
|
||||||
order: 4
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'walletMain',
|
|
||||||
path: '',
|
|
||||||
component: () => import('@/pages/menuPages/wallet/index.vue'),
|
|
||||||
meta: {
|
|
||||||
// permissionsKey: 'wallet',
|
|
||||||
icon: 'vuesax-linear:wallet',
|
|
||||||
order: 3,
|
|
||||||
title: 'پروژه ها',
|
|
||||||
disabled: false,
|
|
||||||
hideMenu: false
|
|
||||||
//hideChildren: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Wallet
|
export default Wallet
|
||||||
|
|||||||
@@ -1,35 +1,13 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
|
|
||||||
|
/** ریدایرکت آدرس قدیمی — منو زیر حساب کتاب است */
|
||||||
const Withdraw: RouteRecordRaw = {
|
const Withdraw: RouteRecordRaw = {
|
||||||
name: 'withdraw',
|
name: 'withdraw',
|
||||||
path: '/withdraw',
|
path: '/withdraw',
|
||||||
component: () => import('@core/layouts/BasicLayout.vue'),
|
|
||||||
redirect: { name: 'withdrawMain' },
|
redirect: { name: 'withdrawMain' },
|
||||||
meta: {
|
meta: {
|
||||||
icon: 'vuesax-linear:money-change',
|
hideMenu: true
|
||||||
// permissionsKey: 'orders',
|
}
|
||||||
title: 'برداشت و واریز',
|
|
||||||
disabled: false,
|
|
||||||
hideMenu: false,
|
|
||||||
hideChildren: true,
|
|
||||||
order: 8
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
name: 'withdrawMain',
|
|
||||||
path: '',
|
|
||||||
component: () => import('@/pages/menuPages/withdraw/index.vue'),
|
|
||||||
meta: {
|
|
||||||
// permissionsKey: 'project',
|
|
||||||
icon: 'vuesax-linear:money-change',
|
|
||||||
order: 3,
|
|
||||||
title: 'برداشت و واریز',
|
|
||||||
disabled: false,
|
|
||||||
hideMenu: false
|
|
||||||
//hideChildren: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Withdraw
|
export default Withdraw
|
||||||
|
|||||||
Reference in New Issue
Block a user