feat(customers): add Digipay installment admin section
Wire routes, settings groups, page access, and customer UI for installment management.
This commit is contained in:
@@ -15,6 +15,12 @@ export type SettingGroupDef = {
|
|||||||
|
|
||||||
/** گروههای صفحه تنظیمات عادی (فقط can_edit=1) */
|
/** گروههای صفحه تنظیمات عادی (فقط can_edit=1) */
|
||||||
export const EDITABLE_SETTING_GROUPS: SettingGroupDef[] = [
|
export const EDITABLE_SETTING_GROUPS: SettingGroupDef[] = [
|
||||||
|
{
|
||||||
|
id: 'digipay_installment',
|
||||||
|
title: 'خرید اقساطی دیجیپی',
|
||||||
|
icon: 'vuesax-linear:calendar',
|
||||||
|
match: (k) => k === 'enable_digipay_installment' || k.startsWith('digipay_')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'general',
|
id: 'general',
|
||||||
title: 'عمومی و برند',
|
title: 'عمومی و برند',
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<BasicShowContext title="خرید اقساطی" :help="digipayInstallmentPageIntro">
|
||||||
|
<div class="flex flex-col gap-2 p-2.5">
|
||||||
|
<div class="text-sm font-bold">ثبت اعتبار بعد از دیجیپی</div>
|
||||||
|
<p class="text-xs opacity-70">
|
||||||
|
کاربر اول با لینک تنظیمات به دیجیپی میرود. بعد از احراز، مانده اعتبارش را اینجا بنویسید تا در اپ بتواند مس بخرد.
|
||||||
|
</p>
|
||||||
|
<a-form layout="vertical" class="sm:grid sm:grid-cols-2 sm:gap-2" @finish="save">
|
||||||
|
<a-form-item label="موبایل مشتری" name="mobile" :rules="[{ required: true, message: 'موبایل را وارد کنید' }]">
|
||||||
|
<a-input v-model:value="form.mobile" placeholder="09..." />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="مانده ۴ قسط (تومان)" name="plan4">
|
||||||
|
<a-input-number v-model:value="form.plan4_toman" class="w-full" :min="0" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="مانده ۱۲ قسط (تومان)" name="plan12">
|
||||||
|
<a-input-number v-model:value="form.plan12_toman" class="w-full" :min="0" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label=" " class="flex items-end">
|
||||||
|
<a-button type="primary" html-type="submit" :loading="saving">ثبت اعتبار</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
|
||||||
|
<div class="mt-2 text-sm font-bold">خریدهای اخیر</div>
|
||||||
|
<a-table
|
||||||
|
size="small"
|
||||||
|
row-key="id"
|
||||||
|
:loading="loading"
|
||||||
|
:data-source="rows"
|
||||||
|
:pagination="false"
|
||||||
|
:columns="columns"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</BasicShowContext>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
|
import { message } from 'ant-design-vue'
|
||||||
|
import useAxios from '@core/utils/useAxios'
|
||||||
|
import { digipayInstallmentPageIntro } from '@/utils/adminHelpCopy'
|
||||||
|
|
||||||
|
const form = reactive({ mobile: '', plan4_toman: 0, plan12_toman: 0 })
|
||||||
|
const saving = ref(false)
|
||||||
|
const loading = ref(false)
|
||||||
|
const rows = ref<Record<string, unknown>[]>([])
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: 'مشتری', dataIndex: 'name' },
|
||||||
|
{ title: 'موبایل', dataIndex: 'mobile' },
|
||||||
|
{ title: 'طرح', dataIndex: 'plan' },
|
||||||
|
{ title: 'مبلغ مس (تومان)', dataIndex: 'amount_toman' },
|
||||||
|
{ title: 'کارمزد (تومان)', dataIndex: 'fee_toman' },
|
||||||
|
{ title: 'مقدار', dataIndex: 'grams' }
|
||||||
|
]
|
||||||
|
|
||||||
|
async function load() {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await useAxios.post('/admin/digipay_installment/orders')
|
||||||
|
rows.value = res?.data?.data || res?.data || []
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
saving.value = true
|
||||||
|
try {
|
||||||
|
await useAxios.post('/admin/digipay_installment/credit', {
|
||||||
|
mobile: form.mobile,
|
||||||
|
plan4_toman: form.plan4_toman || 0,
|
||||||
|
plan12_toman: form.plan12_toman || 0
|
||||||
|
})
|
||||||
|
message.success('اعتبار ثبت شد')
|
||||||
|
await load()
|
||||||
|
} catch (e: any) {
|
||||||
|
message.error(e?.response?.data?.message || 'ثبت اعتبار انجام نشد')
|
||||||
|
} finally {
|
||||||
|
saving.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(load)
|
||||||
|
</script>
|
||||||
@@ -21,7 +21,7 @@ import { computed } from 'vue'
|
|||||||
import BasicMenu from '@/components/BasicMenu/index.vue'
|
import BasicMenu from '@/components/BasicMenu/index.vue'
|
||||||
import { useRouterStore } from '@core/stores/router'
|
import { useRouterStore } from '@core/stores/router'
|
||||||
import { get } from 'lodash'
|
import { get } from 'lodash'
|
||||||
import { customerSpecialPricingEnabledSetting, goldCreditEnabledSetting, initWalletSettingsFromApi } from '@/utils/config'
|
import { customerSpecialPricingEnabledSetting, digipayInstallmentEnabledSetting, goldCreditEnabledSetting, initWalletSettingsFromApi } from '@/utils/config'
|
||||||
|
|
||||||
initWalletSettingsFromApi()
|
initWalletSettingsFromApi()
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@ const menu = computed(() => {
|
|||||||
.filter((child) => {
|
.filter((child) => {
|
||||||
if (child.name === 'customerMain_specialPrice') return customerSpecialPricingEnabledSetting.value
|
if (child.name === 'customerMain_specialPrice') return customerSpecialPricingEnabledSetting.value
|
||||||
if (child.name === 'customerMain_goldCredit') return goldCreditEnabledSetting.value
|
if (child.name === 'customerMain_goldCredit') return goldCreditEnabledSetting.value
|
||||||
|
if (child.name === 'customerMain_digipayInstallment') return digipayInstallmentEnabledSetting.value
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
.sort((a, b) => (a.meta?.order ?? 99) - (b.meta?.order ?? 99))
|
.sort((a, b) => (a.meta?.order ?? 99) - (b.meta?.order ?? 99))
|
||||||
|
|||||||
@@ -81,6 +81,16 @@ const Customers: RouteRecordRaw = {
|
|||||||
order: 4
|
order: 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'customerMain_digipayInstallment',
|
||||||
|
path: 'digipay-installment',
|
||||||
|
component: () => import('@/pages/menuPages/customers/digipayInstallment/index.vue'),
|
||||||
|
meta: {
|
||||||
|
icon: 'vuesax-linear:calendar',
|
||||||
|
title: 'خرید اقساطی',
|
||||||
|
order: 6
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'customerMain_goldCredit',
|
name: 'customerMain_goldCredit',
|
||||||
path: 'gold-credit',
|
path: 'gold-credit',
|
||||||
|
|||||||
@@ -183,6 +183,9 @@ export const customersArchivePageIntro =
|
|||||||
export const customersOnlinePageIntro =
|
export const customersOnlinePageIntro =
|
||||||
'مشتریانی که الان اپ را باز دارند. با بستن اپ از لیست حذف میشوند. برای جزئیات روی کارت بزنید.'
|
'مشتریانی که الان اپ را باز دارند. با بستن اپ از لیست حذف میشوند. برای جزئیات روی کارت بزنید.'
|
||||||
|
|
||||||
|
export const digipayInstallmentPageIntro =
|
||||||
|
'بعد از احراز کاربر در دیجیپی، مانده اعتبار ۴ قسط و ۱۲ قسط را با موبایل مشتری اینجا بنویسید. خرید از اپ همان مانده را کم میکند و مس را به کیف مینشاند.'
|
||||||
|
|
||||||
export const goldCreditPageIntro =
|
export const goldCreditPageIntro =
|
||||||
'اعتبار طلایی مشتریان: درخواستهای جدید و اعتبارهای فعال. از تبها بین درخواست و فعال جابهجا شوید.'
|
'اعتبار طلایی مشتریان: درخواستهای جدید و اعتبارهای فعال. از تبها بین درخواست و فعال جابهجا شوید.'
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
customerSpecialPricingEnabledSetting,
|
customerSpecialPricingEnabledSetting,
|
||||||
getConfigApp,
|
getConfigApp,
|
||||||
giftCardEnabledSetting,
|
giftCardEnabledSetting,
|
||||||
|
digipayInstallmentEnabledSetting,
|
||||||
goldCreditEnabledSetting,
|
goldCreditEnabledSetting,
|
||||||
hasLandingSetting,
|
hasLandingSetting,
|
||||||
isStoreApp,
|
isStoreApp,
|
||||||
@@ -64,6 +65,12 @@ export const ADMIN_PAGE_TREE: AccessNode[] = [
|
|||||||
title: 'اعتبار',
|
title: 'اعتبار',
|
||||||
route: 'customerMain_goldCredit',
|
route: 'customerMain_goldCredit',
|
||||||
enabled: () => goldCreditEnabledSetting.value
|
enabled: () => goldCreditEnabledSetting.value
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'customerMain_digipayInstallment',
|
||||||
|
title: 'خرید اقساطی',
|
||||||
|
route: 'customerMain_digipayInstallment',
|
||||||
|
enabled: () => digipayInstallmentEnabledSetting.value
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -240,6 +247,7 @@ export const PAGE_TABLE_ACTIONS: Record<string, PageTableAction[]> = {
|
|||||||
{ key: 'toggle', label: 'فعال/غیرفعال' },
|
{ key: 'toggle', label: 'فعال/غیرفعال' },
|
||||||
{ key: 'delete', label: 'حذف' }
|
{ key: 'delete', label: 'حذف' }
|
||||||
],
|
],
|
||||||
|
customerMain_digipayInstallment: [{ key: 'edit', label: 'ثبت اعتبار' }],
|
||||||
customerMain_goldCredit: [
|
customerMain_goldCredit: [
|
||||||
{ key: 'detail', label: 'جزئیات' },
|
{ key: 'detail', label: 'جزئیات' },
|
||||||
{ key: 'edit', label: 'ویرایش' },
|
{ key: 'edit', label: 'ویرایش' },
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ export const customerSpecialPricingEnabledSetting = ref(false)
|
|||||||
/** reactive — زیرمنوی اعتبار طلایی در مشتریان */
|
/** reactive — زیرمنوی اعتبار طلایی در مشتریان */
|
||||||
export const goldCreditEnabledSetting = ref(false)
|
export const goldCreditEnabledSetting = ref(false)
|
||||||
|
|
||||||
|
/** reactive — زیرمنوی خرید اقساطی دیجیپی */
|
||||||
|
export const digipayInstallmentEnabledSetting = ref(false)
|
||||||
|
|
||||||
/** reactive — منو و زنگوله اعلان داخل اپ */
|
/** reactive — منو و زنگوله اعلان داخل اپ */
|
||||||
export const appNotificationEnabledSetting = ref(true)
|
export const appNotificationEnabledSetting = ref(true)
|
||||||
|
|
||||||
@@ -185,6 +188,10 @@ export function setCustomerSpecialPricingEnabledFromSettings(value: boolean): vo
|
|||||||
customerSpecialPricingEnabledSetting.value = value
|
customerSpecialPricingEnabledSetting.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setDigipayInstallmentEnabledFromSettings(value: boolean): void {
|
||||||
|
digipayInstallmentEnabledSetting.value = value
|
||||||
|
}
|
||||||
|
|
||||||
export function setGoldCreditEnabledFromSettings(value: boolean): void {
|
export function setGoldCreditEnabledFromSettings(value: boolean): void {
|
||||||
goldCreditEnabledSetting.value = value
|
goldCreditEnabledSetting.value = value
|
||||||
}
|
}
|
||||||
@@ -314,6 +321,13 @@ export function applyCustomerSpecialPricingFromRows(
|
|||||||
if (row) setCustomerSpecialPricingEnabledFromSettings(isSwitchOn(row.value))
|
if (row) setCustomerSpecialPricingEnabledFromSettings(isSwitchOn(row.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function applyDigipayInstallmentEnabledFromRows(
|
||||||
|
rows: Array<{ key?: string; value?: string | null }>
|
||||||
|
) {
|
||||||
|
const row = rows.find((item) => item.key === 'enable_digipay_installment')
|
||||||
|
if (row) setDigipayInstallmentEnabledFromSettings(isSwitchOn(row.value))
|
||||||
|
}
|
||||||
|
|
||||||
export function applyGoldCreditEnabledFromRows(
|
export function applyGoldCreditEnabledFromRows(
|
||||||
rows: Array<{ key?: string; value?: string | null }>
|
rows: Array<{ key?: string; value?: string | null }>
|
||||||
) {
|
) {
|
||||||
@@ -340,6 +354,7 @@ export function applySuperAdminAccessFlagsFromItems(
|
|||||||
applyGroupSmsFromRows(rows)
|
applyGroupSmsFromRows(rows)
|
||||||
applyCustomerSpecialPricingFromRows(rows)
|
applyCustomerSpecialPricingFromRows(rows)
|
||||||
applyGoldCreditEnabledFromRows(rows)
|
applyGoldCreditEnabledFromRows(rows)
|
||||||
|
applyDigipayInstallmentEnabledFromRows(rows)
|
||||||
applyConditionalOrderEnabledFromRows(rows)
|
applyConditionalOrderEnabledFromRows(rows)
|
||||||
applyAutomationEnabledFromRows(rows)
|
applyAutomationEnabledFromRows(rows)
|
||||||
applyProductFundsEnabledFromRows(rows)
|
applyProductFundsEnabledFromRows(rows)
|
||||||
@@ -442,6 +457,7 @@ async function bootstrapSettingsFromApi(): Promise<void> {
|
|||||||
applyGroupSmsFromRows(list)
|
applyGroupSmsFromRows(list)
|
||||||
applyCustomerSpecialPricingFromRows(list)
|
applyCustomerSpecialPricingFromRows(list)
|
||||||
applyGoldCreditEnabledFromRows(list)
|
applyGoldCreditEnabledFromRows(list)
|
||||||
|
applyDigipayInstallmentEnabledFromRows(list)
|
||||||
applyConditionalOrderEnabledFromRows(list)
|
applyConditionalOrderEnabledFromRows(list)
|
||||||
applyAutomationEnabledFromRows(list)
|
applyAutomationEnabledFromRows(list)
|
||||||
applyProductFundsEnabledFromRows(list)
|
applyProductFundsEnabledFromRows(list)
|
||||||
|
|||||||
Reference in New Issue
Block a user