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) */
|
||||
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',
|
||||
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 { useRouterStore } from '@core/stores/router'
|
||||
import { get } from 'lodash'
|
||||
import { customerSpecialPricingEnabledSetting, goldCreditEnabledSetting, initWalletSettingsFromApi } from '@/utils/config'
|
||||
import { customerSpecialPricingEnabledSetting, digipayInstallmentEnabledSetting, goldCreditEnabledSetting, initWalletSettingsFromApi } from '@/utils/config'
|
||||
|
||||
initWalletSettingsFromApi()
|
||||
|
||||
@@ -36,6 +36,7 @@ const menu = computed(() => {
|
||||
.filter((child) => {
|
||||
if (child.name === 'customerMain_specialPrice') return customerSpecialPricingEnabledSetting.value
|
||||
if (child.name === 'customerMain_goldCredit') return goldCreditEnabledSetting.value
|
||||
if (child.name === 'customerMain_digipayInstallment') return digipayInstallmentEnabledSetting.value
|
||||
return true
|
||||
})
|
||||
.sort((a, b) => (a.meta?.order ?? 99) - (b.meta?.order ?? 99))
|
||||
|
||||
@@ -81,6 +81,16 @@ const Customers: RouteRecordRaw = {
|
||||
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',
|
||||
path: 'gold-credit',
|
||||
|
||||
@@ -183,6 +183,9 @@ export const customersArchivePageIntro =
|
||||
export const customersOnlinePageIntro =
|
||||
'مشتریانی که الان اپ را باز دارند. با بستن اپ از لیست حذف میشوند. برای جزئیات روی کارت بزنید.'
|
||||
|
||||
export const digipayInstallmentPageIntro =
|
||||
'بعد از احراز کاربر در دیجیپی، مانده اعتبار ۴ قسط و ۱۲ قسط را با موبایل مشتری اینجا بنویسید. خرید از اپ همان مانده را کم میکند و مس را به کیف مینشاند.'
|
||||
|
||||
export const goldCreditPageIntro =
|
||||
'اعتبار طلایی مشتریان: درخواستهای جدید و اعتبارهای فعال. از تبها بین درخواست و فعال جابهجا شوید.'
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
customerSpecialPricingEnabledSetting,
|
||||
getConfigApp,
|
||||
giftCardEnabledSetting,
|
||||
digipayInstallmentEnabledSetting,
|
||||
goldCreditEnabledSetting,
|
||||
hasLandingSetting,
|
||||
isStoreApp,
|
||||
@@ -64,6 +65,12 @@ export const ADMIN_PAGE_TREE: AccessNode[] = [
|
||||
title: 'اعتبار',
|
||||
route: 'customerMain_goldCredit',
|
||||
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: 'delete', label: 'حذف' }
|
||||
],
|
||||
customerMain_digipayInstallment: [{ key: 'edit', label: 'ثبت اعتبار' }],
|
||||
customerMain_goldCredit: [
|
||||
{ key: 'detail', label: 'جزئیات' },
|
||||
{ key: 'edit', label: 'ویرایش' },
|
||||
|
||||
@@ -80,6 +80,9 @@ export const customerSpecialPricingEnabledSetting = ref(false)
|
||||
/** reactive — زیرمنوی اعتبار طلایی در مشتریان */
|
||||
export const goldCreditEnabledSetting = ref(false)
|
||||
|
||||
/** reactive — زیرمنوی خرید اقساطی دیجیپی */
|
||||
export const digipayInstallmentEnabledSetting = ref(false)
|
||||
|
||||
/** reactive — منو و زنگوله اعلان داخل اپ */
|
||||
export const appNotificationEnabledSetting = ref(true)
|
||||
|
||||
@@ -185,6 +188,10 @@ export function setCustomerSpecialPricingEnabledFromSettings(value: boolean): vo
|
||||
customerSpecialPricingEnabledSetting.value = value
|
||||
}
|
||||
|
||||
export function setDigipayInstallmentEnabledFromSettings(value: boolean): void {
|
||||
digipayInstallmentEnabledSetting.value = value
|
||||
}
|
||||
|
||||
export function setGoldCreditEnabledFromSettings(value: boolean): void {
|
||||
goldCreditEnabledSetting.value = value
|
||||
}
|
||||
@@ -314,6 +321,13 @@ export function applyCustomerSpecialPricingFromRows(
|
||||
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(
|
||||
rows: Array<{ key?: string; value?: string | null }>
|
||||
) {
|
||||
@@ -340,6 +354,7 @@ export function applySuperAdminAccessFlagsFromItems(
|
||||
applyGroupSmsFromRows(rows)
|
||||
applyCustomerSpecialPricingFromRows(rows)
|
||||
applyGoldCreditEnabledFromRows(rows)
|
||||
applyDigipayInstallmentEnabledFromRows(rows)
|
||||
applyConditionalOrderEnabledFromRows(rows)
|
||||
applyAutomationEnabledFromRows(rows)
|
||||
applyProductFundsEnabledFromRows(rows)
|
||||
@@ -442,6 +457,7 @@ async function bootstrapSettingsFromApi(): Promise<void> {
|
||||
applyGroupSmsFromRows(list)
|
||||
applyCustomerSpecialPricingFromRows(list)
|
||||
applyGoldCreditEnabledFromRows(list)
|
||||
applyDigipayInstallmentEnabledFromRows(list)
|
||||
applyConditionalOrderEnabledFromRows(list)
|
||||
applyAutomationEnabledFromRows(list)
|
||||
applyProductFundsEnabledFromRows(list)
|
||||
|
||||
Reference in New Issue
Block a user