Compare commits

4 Commits
Author SHA1 Message Date
safavimohadeseh78 3a1269c30b fix(ui): center page loading spinner and use accent spin color
Apply shared app-page-content-loading layout and theme-aligned spin dots across the app.
2026-08-31 02:36:56 -04:00
MojtabaSoumi 6c56a409e5 1405/01/22-fix bugs in gift card 2026-04-11 17:53:21 +03:30
MojtabaSoumi f4572575d7 1405/01/20-add giftcard & discount 2026-04-09 14:05:21 +03:30
MojtabaSoumi 8833749f51 1405/01/20-add giftcard & discount 2026-04-09 13:40:54 +03:30
9 changed files with 1227 additions and 4 deletions
+14
View File
@@ -0,0 +1,14 @@
import type { TableInput } from '@core/type/baseTable'
import useAxios from '@core/utils/useAxios'
import type { Order } from '@/model/order'
import type { AddId, Customer } from '@/model/customer'
import type {Giftcard, GiftcardInput} from "@/model/giftCard";
export const getGiftCardTable = async (params: TableInput) =>
await useAxios.post<Array<Giftcard>>('/admin/giftcard/table', params)
export const createGiftCard = async (obj: GiftcardInput) =>
await useAxios.post<Giftcard>(`/admin/giftcard/generate`, obj)
+14 -2
View File
@@ -69,7 +69,19 @@
@apply px-1 py-3; @apply px-1 py-3;
} }
.ant-spin-dot-item,
.ant-spin-dot i {
background-color: var(--ant-primary-color, @primary-color) !important;
}
/* لودینگ محتوای صفحه — وسط ناحیه محتوا (موبایل و دسکتاپ یکسان) */
.app-page-content-loading {
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: 100%;
min-height: min(52vh, 22rem);
padding: 2rem 1rem;
}
@@ -1,5 +1,5 @@
<template> <template>
<ASwitch v-model:checked="checked"></ASwitch> <ASwitch v-model:checked="checked" ></ASwitch>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
+48
View File
@@ -0,0 +1,48 @@
export interface Giftcard {
id: number
customer_id: any
count: number
amount: number
total: number
unit: number
unique_code: any
created_at: string
sts: any
expiry_date: string
used_count: any
updated_at: string
description: string
sts_str: any
giftcardcodes: Giftcardcode[]
}
export interface Giftcardcode {
id: number
giftcard_id: number
code: string
sts: number
unit: number
amount: number
assigned_to: AssignedTo
used_at: string
expiry_date: string
created_at: string
updated_at: string
}
export interface AssignedTo {
id: number
name: string
mobile: string
}
export interface GiftcardInput {
mobile: string
name: string
count: number
amount: number
unit: string
expiry_date: string
description: string
code:string
use_once:boolean
}
@@ -0,0 +1,139 @@
<template>
<div>
<BasicShowContext title="لیست کارت های هدیه">
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
<template #extraHeader>
<div class="flex gap-2">
<BaseButton v-if="!customerId" type="primary" size="small" class="flex" @click="emits('add', 'gift')">
<div>افزودن کارت هدیه</div>
<BaseIcon icon="vuesax-linear:gift" Size="16px" />
</BaseButton>
<BaseButton v-if="!customerId" type="primary" size="small" class="flex" @click="emits('add' ,'code')">
<div>افزودن کد تخفیف</div>
<BaseIcon icon="vuesax-linear:discount-circle" Size="16px" />
</BaseButton>
</div>
</template>
<template #action="{ column, record }">
<div class="gap-2 flex justify-center">
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('info', record)">
<template #title>
<span>مشخصات</span>
</template>
<Icon icon="vuesax-linear:stickynote" color="#10913A" />
</a-tooltip>
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('giftcardcodes', record)">
<template #title>
<div>کدهای {{record.unit==3?'تخفیف':'کارت هدیه'}}</div>
</template>
<Icon icon="vuesax-linear:document-text" color="#1890ff" />
</a-tooltip>
</div>
</template>
</BaseTable>
</BasicShowContext>
</div>
</template>
<script lang="tsx" setup>
import type { TableInput } from '@core/type/baseTable'
import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable'
import Icon from '@core/components/BaseIcon/src/Icon.vue'
import { changeCustomerActivation, getCustomerTable } from '@/api/customer'
import { cols } from '../hooks/orderColumns'
import { useUserStore } from '@/store/userStore'
import { usePrefix } from '@core/composable/usePrefix'
import { message } from 'ant-design-vue'
import { getOrderTable } from '@/api/order'
import {getGiftCardTable} from "@/api/giftCard";
const [submit, reload] = useBaseTable()
/*const select = (val) => {
val.sts === 1 ? return ['1'] : ['2']
}*/
//emits
interface Prop {
customerId: number
}
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'giftcardcodes'])
const props = defineProps<Prop>()
const { prefixCls } = usePrefix('pophoverstatus')
//permission
function checkPermission(temp: string) {
const store = useUserStore()
return store.canAccess(temp)
}
//define table
const table = ref(null)
const tblProps = ref<any>({
columns: cols,
api: (params: TableInput) => {
if (props.customerId) {
params.filters = []
params.filters?.push({
field: "customer_id",
type: "text",
value: props.customerId,
cr: "and",
op: "eq",
hidden: false
})
}
return getGiftCardTable(params)
}
//bordered: true
})
const loading = ref<boolean>(false)
async function changeCustomerActivationFunction(id: number) {
try {
loading.value = true
await changeCustomerActivation(id)
reload()
message.success('تغییر وضعیت با موفقیت انجام شد')
} catch (e) {
console.error(e)
} finally {
loading.value = false
}
}
const fetch = () => {
// console.log('sss')
reload()
}
// const spinTable = (val: boolean) => {
// // console.log('sss')
// table?.value?.loading.value = val
// }
defineExpose({
fetch
// spinTable
})
</script>
<style lang="less">
@prefix: ~'@{prefixCls}-pophoverstatus';
.@{prefix} {
.ant-menu-rtl.ant-menu-inline,
.ant-menu-rtl.ant-menu-vertical {
border-left: none;
}
.ant-menu-item-only-child {
border-radius: @border-radius-base;
}
//bor
/* .ant-input-group-addon:first-child {
!* border: #d9d9d9 1px solid;
border-radius: 0 6px 6px 0;*!
}*/
}
</style>
@@ -0,0 +1,268 @@
import type { BaseTableColumn } from '@core/type/baseTable'
import { toJalali, toJalaliNoTime, toTime } from '@core/utils/useDataTime'
import CustomTag from '@/components/CustomTag.vue'
import { usePrice } from '@core/utils/usePrice'
/*import BudgetSelect from '@/components/BudgetSelect.vue'
import { useStaticApiListsStore } from '@/store/staticApisStore'
import type { FilterSelect } from '@/model/filterSelect'
import type { DocItem } from '@/model/docType'*/
//define store
//const store = useStaticApiListsStore()
//document types
/*let docTypes: DocItem[]*/
/*onMounted(async () => {
docTypes = await store.readyDocTypeList()
})
const filteredDocTypes: FilterSelect = docTypes?.map((x: DocItem) => {
return {
label: x.title,
value: x.id
}
})*/
export const cols: BaseTableColumn[] = [
{
title: 'ردیف',
dataIndex: 'id',
key: 'id',
filterable: false,
sortable: false,
customRender: (record: any) => {
return record.index + 1
}
},
{
title: 'کد ',
dataIndex: 'id',
key: 'id',
type: 'Number'
// className: 'column-money'
},
{
title: 'نوع کد',
dataIndex: 'unit',
key: 'unit',
filterable: false,
customRender: ({ record }) => {
switch (record.unit) {
case 2:
return (
<div class="flex justify-center">
<CustomTag textColor="#C53030" bgColor="#FECACA">
کارت هدیه طلایی
</CustomTag>
</div>
)
case 1:
return (
<div class="flex justify-center">
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
کارت هدیه ریالی
</CustomTag>
</div>
)
case 3:
return (
<div class="flex justify-center">
<CustomTag textColor="#377ef4" bgColor="#ccedff">
کد تخفیف
</CustomTag>
</div>
)
}
}
},
{
title: 'تعداد کد ها',
dataIndex: 'count',
key: 'count',
type: 'Number'
},
{
title: 'مقدار',
dataIndex: 'amount',
key: 'amount',
type: 'Text',
customRender: (record: any) => {
if (record.record.unit==3)
return `${record.text*100} درصد`
else if (record.record.unit==2)
return `${record.text} گرم`
else return'-'
}
},
{
title: 'مبلغ کل (ریال)',
dataIndex: 'total',
key: 'total',
type: 'Number',
customRender: (data) => {
if (data.record.unit==1)
return usePrice(data.record?.total ?? 0, true, '')
else
return '-'
}
},
{
title: 'کد یکتا',
dataIndex: 'unique_code',
key: 'unique_code',
type: 'Text'
},
{
title: 'تعداد استفاده شده',
dataIndex: 'used_count',
key: 'used_count',
type: 'Number'
},
{
title: 'نام پویش',
dataIndex: 'name',
key: 'name',
type: 'Text',
customRender: ({ record }) => {
return record.name ?? '-'
}
},
// {
// title: 'مشتری',
// dataIndex: 'customer.name',
// key: 'customer.name',
// type: 'Text',
// customRender: ({ record }) => {
// return record.customer?.name ?? '-'
// }
// },
// {
// title: 'شماره موبایل مشتری',
// dataIndex: 'customer.mobile',
// key: 'customer.mobile',
// type: 'Number',
// customRender: ({ record }) => {
// return record.customer?.mobile ?? '-'
// }
// },
{
title: 'توضیحات',
dataIndex: 'description',
key: 'description',
type: 'Text'
},
{
title: 'وضعیت',
dataIndex: 'sts',
key: 'sts',
filterable: false,
customRender: ({ record }) => {
switch (record.sts) {
case 1:
return (
<div class="flex justify-center">
<CustomTag textColor="#ca8a04" bgColor="#fef3c7">
{record.sts_str}
</CustomTag>
</div>
)
case 2:
return (
<div class="flex justify-center">
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
{record.sts_str}
</CustomTag>
</div>
)
default:
return (
<div class="flex justify-center">
<CustomTag textColor="#C53030" bgColor="#FECACA">
{record.sts_str}
</CustomTag>
</div>
)
}
}
},
{
title: 'تاریخ ثبت',
dataIndex: 'created_at',
key: 'created_at',
type: 'DateTime',
customRender: (record: any) => {
return toJalali(record.record.created_at)
}
},
{
title: 'تاریخ انقضا',
dataIndex: 'expiry_date',
key: 'expiry_date',
type: 'DateTime',
customRender: (record: any) => {
return toJalali(record.record.expiry_date)
}
},
/*{
title: 'نقش',
dataIndex: 'user_type_record',
key: 'user_type_record',
type: 'Select',
filterable: false,
sortable: false,
filterComponentProps: {
multiple: true
},
filterField: 'user_type_obj.id',
filterComponent: ReadyUserTypeSelect,
/!* customRender: (record: any) => {
return record.record.user_type_record?.value
}*!/
customRender: ({ record }) => {
const items = record.is_admin ? (
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
ادمین
</CustomTag>
) : (
record.user_type_obj.map((item: { title: any }, index: any) => {
if (item) {
return (
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
{item?.title}
</CustomTag>
)
}
})
)
return <div class="flex justify-center items-center gap-2">{items}</div>
}
},
{
title: 'حوزه',
dataIndex: 'section',
key: 'section'
},
{
title: 'شماره موبایل',
dataIndex: 'mobile',
type: 'Number',
key: 'mobile'
},
{
title: 'تاریخ ثبت',
dataIndex: 'created_at',
key: 'created_at',
type: 'DateTime',
customRender: (record: any) => {
return toJalaliNoTime(record.record.created_at)
}
},*/
{
title: 'عملیات',
dataIndex: 'action',
key: 'action',
slot: 'action',
fixed: 'right',
filterable: false
}
]
+708
View File
@@ -0,0 +1,708 @@
<template>
<div>
<BasicMainCard>
<div class="flex w-full h-full">
<tbl
ref="table"
class="w-full h-full"
@info="info"
@edit="edit"
@delete="deleteItem"
@add="add"
@giftcardcodes="showGiftCardCodes"
/>
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
<component :is="selectedComponent" class="mr-5" />-->
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
</div>
</BasicMainCard>
<BasicModal
v-model:visible="addGiftCardVisible"
width="30rem"
:title="`${editId ? 'ویرایش' : 'افزودن'} کارت هدیه یا کد تخفیف`"
@ok="ok"
:loading="loading"
@close="addGiftCardVisible = false"
>
<a-form :model="form" ref="formRef" autocomplete="off">
<div class="grid md:grid-cols-1 gap-4">
<!-- <a-form-item label="شماره موبایل مشتری" name="mobile" :rules="inputLenRules(11)">-->
<!-- <BasicInput-->
<!-- v-model:value="form.mobile"-->
<!-- type="tel"-->
<!-- placeholder="09123456789"-->
<!-- />-->
<!-- </a-form-item>-->
<a-form-item label="نام پویش" name="name" >
<BasicInput
v-model:value="form.name"
placeholder="نام پویش"
/>
</a-form-item>
<a-form-item label="نوع کارت هدیه" name="unit" :rules="inputRules()">
<a-radio-group
v-model:value="form.unit"
button-style="solid"
>
<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 label="کد یکبار مصرف" name="unit" :rules="inputRules()">
<ASwitch v-model:checked="form.use_once"
checked-children="بله"
un-checked-children="خیر">
</ASwitch>
</a-form-item>
<a-form-item label="تعداد کدها" name="count" :rules="inputRulesNumber()">
<BasicInput
v-model:value="form.count"
type="tel"
placeholder="تعداد کدهای کارت هدیه"
/>
</a-form-item>
<a-form-item
:label="`مقدار ${form.unit === '2' ? '(گرم)' : '(ریال)'}`"
name="amount"
:rules="inputRulesNumber()"
>
<BasicInput
v-model:value="form.amount"
:addon-before="form.unit === '2' ? 'گرم' : 'ریال'"
type="tel"
placeholder="مقدار کارت هدیه"
/>
</a-form-item>
<a-form-item v-if="!form.use_once" label="کد سفارشی" name="code">
<BasicInput
v-model:value="form.code"
placeholder="کد سفارشی"
/>
</a-form-item>
<a-form-item label="تاریخ انقضا" name="expiry_date" :rules="inputRules()">
<BaseDatePicker v-model:value="form.expiry_date" format="YYYY-MM-DD"/>
</a-form-item>
<a-form-item label="توضیحات" name="description">
<BasicTextArea
v-model:value="form.description"
place-holder="توضیحات اختیاری"
/>
</a-form-item>
</div>
</a-form>
</BasicModal>
<BasicModal
v-model:visible="addDiscountVisible"
width="30rem"
:title="`${editId ? 'ویرایش' : 'افزودن'} کد تخفیف`"
@ok="ok"
:loading="loading"
@close="addDiscountVisible = false"
>
<a-form :model="form" ref="formRef" autocomplete="off">
<div class="grid md:grid-cols-1 gap-4">
<!-- <a-form-item label="شماره موبایل مشتری" name="mobile" :rules="inputLenRules(11)">-->
<!-- <BasicInput-->
<!-- v-model:value="form.mobile"-->
<!-- type="tel"-->
<!-- placeholder="09123456789"-->
<!-- />-->
<!-- </a-form-item>-->
<a-form-item label="نام پویش" name="name" >
<BasicInput
v-model:value="form.name"
placeholder="نام پویش"
/>
</a-form-item>
<!-- <a-form-item label="نوع کارت هدیه" name="unit" :rules="inputRules()">-->
<!-- <a-radio-group-->
<!-- v-model:value="form.unit"-->
<!-- button-style="solid"-->
<!-- >-->
<!-- <a-radio-button value="1">ریالی</a-radio-button>-->
<!-- <a-radio-button value="2">طلایی</a-radio-button>-->
<!-- <a-radio-button value="3">کد تخفیف</a-radio-button>-->
<!-- </a-radio-group>-->
<!-- </a-form-item>-->
<a-form-item label="کد یکبار مصرف" name="unit" :rules="inputRules()">
<ASwitch v-model:checked="form.use_once"
checked-children="بله"
un-checked-children="خیر">
</ASwitch>
</a-form-item>
<a-form-item label="تعداد کدها" name="count" :rules="inputRulesNumber()">
<BasicInput
v-model:value="form.count"
type="tel"
placeholder="تعداد کدهای کارت هدیه"
/>
</a-form-item>
<a-form-item
label="درصد تخفیف"
name="amount"
:rules="inputRulesNumber()"
>
<BasicInput
v-model:value="form.amount"
addon-before="درصد"
type="tel"
placeholder="مقدار کارت هدیه"
/>
</a-form-item>
<a-form-item v-if="!form.use_once" label="کد سفارشی" name="code">
<BasicInput
v-model:value="form.code"
placeholder="کد سفارشی"
/>
</a-form-item>
<a-form-item label="تاریخ انقضا" name="expiry_date" :rules="inputRules()">
<BaseDatePicker v-model:value="form.expiry_date" format="YYYY-MM-DD"/>
</a-form-item>
<a-form-item label="توضیحات" name="description">
<BasicTextArea
v-model:value="form.description"
place-holder="توضیحات اختیاری"
/>
</a-form-item>
</div>
</a-form>
</BasicModal>
<BasicInfoModal
v-model:visible="userInfoVisible"
@close="userInfoVisible = false"
:title="infoParams.title"
:date="infoParams.date"
:time="infoParams.time"
:type="infoParams.type"
:name="infoParams.name"
:items="infoParams.items"
/>
<BasicModal
v-model:visible="giftCardCodesVisible"
width="80%"
title="لیست کدهای کارت هدیه"
custom-footer
@close="giftCardCodesVisible = false"
>
<template #footer>
<a-button @click="giftCardCodesVisible = false">بستن</a-button>
</template>
<a-table
:columns="giftCardCodesColumns"
:data-source="selectedGiftCardCodes"
:pagination="{ pageSize: 10 }"
row-key="id"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.key === 'index'">
{{ index + 1 }}
</template>
<template v-else-if="column.key === 'sts'">
<CustomTag
v-if="record.sts === 1"
textColor="#ca8a04"
bgColor="#fef3c7"
>
فعال
</CustomTag>
<CustomTag
v-else-if="record.sts === 2"
textColor="#25855A"
bgColor="#E3F4E9"
>
استفاده شده
</CustomTag>
<CustomTag
v-else
textColor="#C53030"
bgColor="#FECACA"
>
غیرفعال
</CustomTag>
</template>
<template v-else-if="column.key === 'unit'">
<CustomTag
v-if="record.unit === 2"
textColor="#C53030"
bgColor="#FECACA"
>
طلایی
</CustomTag>
<CustomTag
v-else
textColor="#25855A"
bgColor="#E3F4E9"
>
ریالی
</CustomTag>
</template>
<template v-else-if="column.key === 'amount'">
{{ record.amount }} {{ record.unit === 2 ? 'گرم' : 'ریال' }}
</template>
<template v-else-if="column.key === 'expiry_date'">
{{ record.expiry_date ? toJalali(record.expiry_date) : '-' }}
</template>
<template v-else-if="column.key === 'used_at'">
{{ record.used_at ? toJalali(record.used_at) : '-' }}
</template>
<template v-else-if="column.key === 'assigned_to_name'">
{{ record.assigned_to?.name ?? '-' }}
</template>
<template v-else-if="column.key === 'assigned_to_mobile'">
{{ record.assigned_to?.mobile ?? '-' }}
</template>
</template>
</a-table>
</BasicModal>
<BasicModal
v-model:visible="discountCodesVisible"
width="80%"
title="لیست کدهای تخفیف"
custom-footer
@close="discountCodesVisible = false"
>
<template #footer>
<a-button @click="discountCodesVisible = false">بستن</a-button>
</template>
<a-table
:columns="discountCodesColumns"
:data-source="selectedGiftCardCodes"
:pagination="{ pageSize: 10 }"
row-key="id"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.key === 'index'">
{{ index + 1 }}
</template>
<template v-else-if="column.key === 'sts'">
<CustomTag
v-if="record.sts === 1"
textColor="#ca8a04"
bgColor="#fef3c7"
>
فعال
</CustomTag>
<CustomTag
v-else-if="record.sts === 2"
textColor="#25855A"
bgColor="#E3F4E9"
>
استفاده شده
</CustomTag>
<CustomTag
v-else
textColor="#C53030"
bgColor="#FECACA"
>
غیرفعال
</CustomTag>
</template>
<template v-else-if="column.key === 'unit'">
<CustomTag
v-if="record.unit === 2"
textColor="#C53030"
bgColor="#FECACA"
>
طلایی
</CustomTag>
<CustomTag
v-else
textColor="#25855A"
bgColor="#E3F4E9"
>
ریالی
</CustomTag>
</template>
<template v-else-if="column.key === 'amount'">
{{ record.amount*100 }}
</template>
<template v-else-if="column.key === 'expiry_date'">
{{ record.expiry_date ? toJalali(record.expiry_date) : '-' }}
</template>
<template v-else-if="column.key === 'used_at'">
{{ record.used_at ? toJalali(record.used_at) : '-' }}
</template>
<template v-else-if="column.key === 'assigned_to_name'">
{{ record.assigned_to?.name ?? '-' }}
</template>
<template v-else-if="column.key === 'assigned_to_mobile'">
{{ record.assigned_to?.mobile ?? '-' }}
</template>
</template>
</a-table>
</BasicModal>
</div>
</template>
<script setup lang="ts">
// import BasicInfoModal from '@/components/BasicInfoModal'
import {inputLenRules, inputRules, inputRulesNumber} from '@/utils/inputRules'
import {useStaticApiListsStore} from '@/store/staticApisStore'
import {ref} from 'vue'
import tbl from './components/table.vue'
import type {FormInstance} from 'ant-design-vue'
import BasicInfoModal from '@/components/BasicInfoModal/index.vue'
import {message} from 'ant-design-vue/es'
import type {Info} from '@/components/BasicInfoModal/model/Info'
import {toJalaliNoTime, toTime} from '@core/utils/useDataTime'
import {confirmDeleteItem} from '@/utils/confirmModal'
import {cloneDeep} from 'lodash'
import type {Item} from '@/model/Item'
import type {Customer} from '@/model/customer'
import {createCustomer, deleteCustomer, getCustomersList, updateCustomer} from '@/api/customer'
import {usePrice} from '@core/utils/usePrice'
import type {Giftcard, Giftcardcode, GiftcardInput} from '@/model/giftCard'
import CustomTag from '@/components/CustomTag.vue'
import {toJalali} from '@core/utils/useDataTime'
import {createGiftCard} from '@/api/giftCard'
import dayjs from 'dayjs'
//loading
const loading = ref<boolean>(false)
//define store
const store = useStaticApiListsStore()
//define tbl
const table = ref(null)
const refreshTable = () => table?.value?.fetch()
//form
const form = ref<GiftcardInput>({
name: '',
count: undefined,
amount: undefined,
unit: '1',
code: '',
use_once: false,
expiry_date: '',
description: ''
})
const formRef = ref<FormInstance>()
//info
let infoParams = reactive<Info>({})
const giftCardCodesVisible = ref<boolean>(false)
const discountCodesVisible = ref<boolean>(false)
const selectedGiftCardCodes = ref<Giftcardcode[]>([])
const giftCardCodesColumns = [
{
title: 'ردیف',
key: 'index',
dataIndex: 'index'
},
{
title: 'کد',
dataIndex: 'code',
key: 'code'
},
{
title: 'نوع',
dataIndex: 'unit',
key: 'unit'
},
{
title: 'مقدار',
dataIndex: 'amount',
key: 'amount'
},
{
title: 'وضعیت',
dataIndex: 'sts',
key: 'sts'
},
{
title: 'تاریخ انقضا',
dataIndex: 'expiry_date',
key: 'expiry_date'
},
{
title: 'تاریخ استفاده',
dataIndex: 'used_at',
key: 'used_at'
},
{
title: 'نام کاربر اختصاص داده شده',
dataIndex: 'assigned_to.name',
key: 'assigned_to_name'
},
{
title: 'شماره موبایل کاربر اختصاص داده شده',
dataIndex: 'assigned_to.mobile',
key: 'assigned_to_mobile'
}
]
const discountCodesColumns = [
{
title: 'ردیف',
key: 'index',
dataIndex: 'index'
},
{
title: 'کد',
dataIndex: 'code',
key: 'code'
},
// {
// title: 'نوع',
// dataIndex: 'unit',
// key: 'unit'
// },
{
title: 'درصد',
dataIndex: 'amount',
key: 'amount'
},
{
title: 'وضعیت',
dataIndex: 'sts',
key: 'sts'
},
{
title: 'تاریخ انقضا',
dataIndex: 'expiry_date',
key: 'expiry_date'
},
{
title: 'تاریخ استفاده',
dataIndex: 'used_at',
key: 'used_at'
},
{
title: 'نام پویش',
dataIndex: 'name',
key: 'name'
},
// {
// title: 'شماره موبایل کاربر اختصاص داده شده',
// dataIndex: 'assigned_to.mobile',
// key: 'assigned_to_mobile'
// }
]
function info(val: Giftcard) {
// نمایش اطلاعات اصلی در BasicInfoModal
if (val.unit==3){
infoParams.title = 'اطلاعات کد تخفیف'
infoParams.name = val.name ?? '-'
// infoParams.type = val.customer?.mobile ?? '-'
infoParams.date = toJalaliNoTime(val.created_at)
infoParams.time = toTime(val.created_at)
infoParams.itemsTitle = 'اطلاعات کد تخفیف'
infoParams.items = [
{
key: 'کد',
value: val.id ?? '-'
},
{
key: 'تعداد کدها',
value: val.count ?? '-'
},
{
key: 'درصد تخفیف',
value: val.amount*100 ?? '-'
},
{
key: 'کد یکبار مصرف است؟',
value: val.use_once ? 'بله':'خیر'
},
{
key: 'کد یکتا',
value: val.unique_code ?? '-'
},
{
key: 'تعداد استفاده شده',
value: val.used_count ?? '-'
},
{
key: 'وضعیت',
value: val.sts_str ?? '-'
},
{
key: 'تاریخ ثبت',
value: toJalaliNoTime(val.created_at)
},
{
key: 'تاریخ انقضا',
value: toJalaliNoTime(val.expiry_date)
},
{
key: 'توضیحات',
value: val.description ?? '-'
}
]
}
else {
infoParams.title = 'اطلاعات کارت هدیه'
infoParams.name = val.name ?? '-'
// infoParams.type = val.customer?.mobile ?? '-'
infoParams.date = toJalaliNoTime(val.created_at)
infoParams.time = toTime(val.created_at)
infoParams.itemsTitle = 'اطلاعات کارت هدیه'
infoParams.items = [
{
key: 'کد',
value: val.id ?? '-'
},
{
key: 'نوع کارت هدیه',
value: val.unit === 2 ? 'طلایی' : 'ریالی'
},
{
key: 'تعداد کدها',
value: val.count ?? '-'
},
{
key: 'مقدار (گرم)',
value: val.amount ?? '-'
},
{
key: 'مبلغ کل (ریال)',
value: usePrice(val.total ?? 0)
},
{
key: 'کد یکتا',
value: val.unique_code ?? '-'
},
{
key: 'تعداد استفاده شده',
value: val.used_count ?? '-'
},
{
key: 'وضعیت',
value: val.sts_str ?? '-'
},
{
key: 'تاریخ ثبت',
value: toJalaliNoTime(val.created_at)
},
{
key: 'تاریخ انقضا',
value: toJalaliNoTime(val.expiry_date)
},
{
key: 'توضیحات',
value: val.description ?? '-'
}
]
}
userInfoVisible.value = true
}
function showGiftCardCodes(val: Giftcard) {
// نمایش کدها در مودال جداگانه
if (val.unit==3){
if (val.giftcardcodes && val.giftcardcodes.length > 0) {
selectedGiftCardCodes.value = val.giftcardcodes
discountCodesVisible.value = true
} else {
message.info('کد‌ی برای این تخفیف وجود ندارد')
}
}else {
if (val.giftcardcodes && val.giftcardcodes.length > 0) {
selectedGiftCardCodes.value = val.giftcardcodes
giftCardCodesVisible.value = true
} else {
message.info('کد کارت هدیه‌ای برای این کارت وجود ندارد')
}
}
}
//edit
let editId: number | undefined = undefined
async function edit(record: Giftcard) {
addGiftCardVisible.value = true
editId = record.id
form.value = {
name: record.customer?.name ?? '',
count: record.count,
amount: record.amount,
unit: record.unit.toString(),
expiry_date: record.expiry_date,
description: record.description ?? ''
}
}
//add
async function add(typeAdd: string) {
editId = undefined
resetData()
console.log(typeAdd)
if (typeAdd == "gift") {
addGiftCardVisible.value = true
} else if (typeAdd == "code") {
addDiscountVisible.value = true
form.value.unit = '3'
}
}
//reset data
const resetData = () => {
formRef.value?.resetFields()
form.value = {
name: '',
count: undefined,
amount: undefined,
unit: '1',
code: '',
use_once: false,
expiry_date: '',
description: ''
}
}
//delete
const deleteItem = (id: number) => confirmDeleteItem('کارت هدیه', id, deleteCustomer, refreshTable)
//add project modal
const addGiftCardVisible = ref<boolean>(false)
const addDiscountVisible = ref<boolean>(false)
const userInfoVisible = ref<boolean>(false)
//submit gift card
async function ok() {
formRef.value?.validateFields().then(async () => {
loading.value = true
try {
// تنظیم تاریخ انقضا به آخر همان روز (23:59:59) و تبدیل به میلادی
const formData = {...form.value}
if (formData.expiry_date) {
// تبدیل به میلادی و تنظیم به آخر روز
formData.expiry_date = dayjs(formData.expiry_date)
.calendar('gregory')
.endOf('day')
.format('YYYY-MM-DD HH:mm:ss')
}
await createGiftCard(formData)
message.success(`${addGiftCardVisible.value?'کارت هدیه':'کد تخفیف'} با موفقیت ثبت شد`)
addGiftCardVisible.value = false
addDiscountVisible.value=false
resetData()
refreshTable()
} catch (e) {
console.error(e)
message.error(`خطا در ثبت ${addGiftCardVisible.value?'کارت هدیه':'کد تخفیف'}`)
} finally {
loading.value = false
}
})
}
</script>
<style scoped></style>
@@ -740,7 +740,6 @@ async function ok() {
addUserVisible.value = false; addUserVisible.value = false;
refreshTable(); refreshTable();
message.success("عملیات با موفقیت انجام شد"); message.success("عملیات با موفقیت انجام شد");
resetData(); resetData();
// await getResponsible() // await getResponsible()
+35
View File
@@ -0,0 +1,35 @@
import type { RouteRecordRaw } from 'vue-router'
const Orders: RouteRecordRaw = {
name: 'giftCard',
path: '/giftCard',
component: () => import('@core/layouts/BasicLayout.vue'),
redirect: { name: 'giftCardMain' },
meta: {
icon: 'vuesax-linear:gift',
permissionsKey: 'giftCard',
title: 'کارت هدیه و تخفیف',
disabled: false,
hideMenu: false,
hideChildren: true,
order: 7
},
children: [
{
name: 'giftCardMain',
path: '',
component: () => import('@/pages/menuPages/giftCards/index.vue'),
meta: {
permissionsKey: 'project',
icon: 'vuesax-linear:empty-wallet-time',
order: 3,
title: 'کارت هدیه و تخفیف',
disabled: false,
hideMenu: false
//hideChildren: false
}
}
]
}
export default Orders