1404/11/04- first
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<div class="text-gray-400">{{title}}:</div>
|
||||
<div v-if="value" class="font-bold mt-1">{{value}}</div>
|
||||
<slot v-else></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
interface Prop {
|
||||
title: string
|
||||
value?: string
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,250 @@
|
||||
<template>
|
||||
<ADrawer :class="prefixCls" v-model:visible="localValue" placement="bottom" class="wrapp-taraz">
|
||||
<div>
|
||||
<div class="rounded-lg border-solid border-1px border-gray-200 p-2 mb-5">
|
||||
<div class="flex items-center gap-5">
|
||||
<div class="font-bold">تعیین وضعیت:</div>
|
||||
<a-radio-group v-model:value="localSts" :options="stsOptions" />
|
||||
</div>
|
||||
<transition>
|
||||
<div v-if="localSts === 3" class="flex items-center gap-3">
|
||||
<div class="font-bold">قیمت پیشنهادی:</div>
|
||||
<BasicInput
|
||||
v-model:value="suggestedPrice"
|
||||
addon-before="ریال"
|
||||
type="price"
|
||||
@click="hotSelect"
|
||||
/>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<div class="w-full bg-gray-50 border-solid border-1px border-gray-200 p-2 rounded-lg">
|
||||
<div class="font-bold">مشخصات سفارش</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div
|
||||
class="rounded-lg bg-white grid grid-cols-2 col-span-2 p-2 mt-2 border-solid border-1px border-gray-100"
|
||||
>
|
||||
<Item title="شماره" :value="selectedItem?.id ?? '-'" />
|
||||
<Item
|
||||
title="مقدار"
|
||||
:value="`${selectedItem?.amount ?? '-'} ${
|
||||
selectedItem?.product?.unit === 'گرم' ? 'گرم' : 'عدد'
|
||||
}`"
|
||||
/>
|
||||
<Item title="قیمت کل برای مشتری" :value="usePrice(selectedItem?.total_price ?? 0)" />
|
||||
<Item title="سود کل برای مدیر" :value="usePrice(selectedItem?.total_fee_master ?? 0)" />
|
||||
</div>
|
||||
<Item title="میزان پرداخت شده" :value="usePrice(selectedItem?.payment_amount ?? 0)" />
|
||||
<Item title="میزان مبلغ باقیمانده" :value="usePrice(selectedItem?.payment_remind ?? 0)" />
|
||||
<Item
|
||||
v-if="selectedItem?.product?.unit === 'گرم'"
|
||||
title="قیمت هر مثقال"
|
||||
:value="usePrice(parseInt((selectedItem?.price * 4.331800000515843).toFixed(0)))"
|
||||
/>
|
||||
<Item title="قیمت هر واحد برای مشتری" :value="usePrice(selectedItem?.price ?? 0)" />
|
||||
<Item
|
||||
title="قیمت هر واحد بدون سود"
|
||||
:value="usePrice(selectedItem?.price_original ?? 0)"
|
||||
/>
|
||||
<Item
|
||||
title="قیمت کل بدون سود"
|
||||
:value="usePrice(selectedItem?.total_price_original ?? 0)"
|
||||
/>
|
||||
<Item title="سود هر واحد برای نماینده" :value="usePrice(selectedItem?.fee_agent ?? 0)" />
|
||||
<Item title="سود کل برای نماینده" :value="usePrice(selectedItem?.total_fee_agent ?? 0)" />
|
||||
<Item title="سود هر واحد برای مدیر" :value="usePrice(selectedItem?.fee_master ?? 0)" />
|
||||
<Item title="قیمت پیشنهادی مدیر" :value="usePrice(selectedItem?.offer_price ?? 0)" />
|
||||
<Item title="قیمت پیشنهادی قبلی مشتری" :value="usePrice(selectedItem?.pre_price ?? 0)" />
|
||||
<Item title="تاریخ ایجاد رکورد" :value="toJalali(selectedItem?.created_at)" />
|
||||
<Item title="تاریخ انجام سفارش" :value="toJalali(selectedItem?.pay_at)" />
|
||||
<Item title="وضعیت پرداخت">
|
||||
<CustomTag bg-color="#e0f2fe" text-color="#0284c7" class="px-3 font-bold py-1">
|
||||
{{ paymentStsString(selectedItem?.payment_sts) }}
|
||||
</CustomTag>
|
||||
</Item>
|
||||
<Item title="وضعیت سفارش">
|
||||
<CustomTag
|
||||
:bg-color="returnStsBgColor(selectedItem?.sts)"
|
||||
:text-color="returnStsTextColor(selectedItem?.sts)"
|
||||
class="px-3 font-bold py-1"
|
||||
>{{ selectedItem?.sts_str }}
|
||||
</CustomTag>
|
||||
</Item>
|
||||
</div>
|
||||
<div class="font-bold mt-5">مشخصات محصول</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<Item title="کد" :value="selectedItem?.product?.id ?? '-'" />
|
||||
<Item title="نام محصول" :value="selectedItem?.product?.title ?? '-'" />
|
||||
<Item title="واحد" :value="selectedItem?.product?.unit ?? '-'" />
|
||||
</div>
|
||||
<div class="font-bold mt-5">مشخصات مشتری و نماینده</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<Item title="کد مشتری" :value="selectedItem?.customer?.id ?? '-'" />
|
||||
<Item title="کد نماینده" :value="selectedItem?.customer?.agent_id ?? '-'" />
|
||||
<Item title="نام و نام خانوادگی مشتری" :value="selectedItem?.customer?.name ?? '-'" />
|
||||
<Item title="نام و نام خانوادگی نماینده" :value="selectedItem?.customer?.name ?? '-'" />
|
||||
<Item title="نوع کاربر">
|
||||
<CustomTag bg-color="#e0f2fe" text-color="#0284c7" class="px-3 font-bold py-1">
|
||||
{{ selectedItem?.type === 1 ? 'نماینده' : 'مشتری' }}
|
||||
</CustomTag>
|
||||
</Item>
|
||||
<Item title="شماره موبایل مشتری" :value="selectedItem?.customer?.mobile ?? '-'" />
|
||||
<Item title="شماره موبایل نماینده" :value="selectedItem?.customer?.mobile ?? '-'" />
|
||||
</div>
|
||||
<ADivider class="!my-2" />
|
||||
<div class="font-bold mt-5 mb-3 border-t">تراکنش ها</div>
|
||||
<div
|
||||
class="grid grid-cols-2 py-2 gap-2"
|
||||
:class="[{'border-b-solid border-b-1px border-gray-300':selectedItem?.transaction?.length-1 !== index}]"
|
||||
v-for="(item, index) in selectedItem?.transaction"
|
||||
:key="index"
|
||||
>
|
||||
<Item title="عنوان تراکنش" :value="item?.title ?? '-'" />
|
||||
<Item title="مقدار مبادله شده" :value="item.amount ?? '-'" />
|
||||
<Item title="کد تراکنش" :value="item.id ?? '-'" />
|
||||
<Item title="تاریخ ایجاد" :value="item.caj ?? '-'" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end mt-2">
|
||||
<BaseButton @click="setStatus" type="primary">ثبت</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</ADrawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
const [reload] = useBaseTable()
|
||||
const { prefixCls } = usePrefix('base-transactions')
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { hotSelect, loading } from '@/utils'
|
||||
import { message, type RadioGroupProps, Tooltip } from 'ant-design-vue'
|
||||
import { toJalali } from '@core/utils/useDataTime'
|
||||
import type { Order } from '@/model/order'
|
||||
import Item from '@/pages/balance/components/Item.vue'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
import { changeOrderSts } from '@/api/order'
|
||||
interface Prop {
|
||||
showTransactionsDrawer?: boolean
|
||||
selectedItem?: object
|
||||
}
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const emits = defineEmits(['update:showTransactionsDrawer', 'update:selectedSts'])
|
||||
const stsOptions: RadioGroupProps['options'] = [
|
||||
{ label: 'باز', value: 1 },
|
||||
{ label: 'تایید شده', value: 2 },
|
||||
{ label: 'ردشده', value: 4 },
|
||||
{ label: 'رد شده و ثبت قیمت جدید', value: 3 }
|
||||
]
|
||||
function paymentStsString(localSts: number) {
|
||||
switch (localSts) {
|
||||
case 1:
|
||||
return 'در انتظار پرداخت'
|
||||
case 2:
|
||||
return 'در حال پرداخت'
|
||||
case 3:
|
||||
return 'قسمتی پرداخت شده'
|
||||
case 4:
|
||||
return 'پرداخت شده'
|
||||
case 5:
|
||||
return 'قسمتی باز پرداخت شده'
|
||||
case 6:
|
||||
return 'مرجوعی'
|
||||
case 7:
|
||||
return 'پرداخت نشده'
|
||||
}
|
||||
}
|
||||
|
||||
const suggestedPrice = ref<number>(0)
|
||||
|
||||
const localValue = computed({
|
||||
get() {
|
||||
return props.showTransactionsDrawer
|
||||
},
|
||||
|
||||
set(value) {
|
||||
emits('update:showTransactionsDrawer', value)
|
||||
}
|
||||
})
|
||||
const localSts = computed({
|
||||
get() {
|
||||
return props.selectedItem?.sts
|
||||
},
|
||||
|
||||
set(value) {
|
||||
emits('update:selectedSts', value)
|
||||
}
|
||||
})
|
||||
|
||||
function returnStsTextColor(val: number | undefined) {
|
||||
switch (val) {
|
||||
case 1:
|
||||
return '#2563eb'
|
||||
case 2:
|
||||
return '#16a34a'
|
||||
case 3:
|
||||
return '#ca8a04'
|
||||
case 4:
|
||||
return '#dc2626'
|
||||
case 6:
|
||||
return '#57534e'
|
||||
default:
|
||||
return '#7c3aed'
|
||||
}
|
||||
}
|
||||
|
||||
function returnStsBgColor(val: number | undefined) {
|
||||
switch (val) {
|
||||
case 1:
|
||||
return '#dbeafe'
|
||||
case 2:
|
||||
return '#dcfce7'
|
||||
case 3:
|
||||
return '#fef9c3'
|
||||
case 4:
|
||||
return '#fee2e2'
|
||||
case 6:
|
||||
return '#f5f5f4'
|
||||
default:
|
||||
return '#ede9fe'
|
||||
}
|
||||
}
|
||||
|
||||
async function setStatus() {
|
||||
try {
|
||||
loading.value = true
|
||||
if (localSts.value === 3 && suggestedPrice.value === 0) {
|
||||
message.error('لطفا قیمت پیشنهادی خود را وارد کنید')
|
||||
return
|
||||
} else {
|
||||
await changeOrderSts({
|
||||
order_id: props.selectedItem?.id,
|
||||
sts: localSts.value,
|
||||
offer_price: suggestedPrice.value
|
||||
})
|
||||
reload()
|
||||
emits('update:showTransactionsDrawer', false)
|
||||
message.success('وضعیت با موفقیت تغییر یافت')
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@prefix:~ '@{prefixCls}-base-transactions';
|
||||
.@{prefix}{
|
||||
.layout-item{
|
||||
cursor: pointer;
|
||||
border:2px solid #eee;
|
||||
padding:5px;
|
||||
&.active{
|
||||
border-color: @primary-color;
|
||||
color:#000000
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,252 @@
|
||||
<template>
|
||||
<div class="wrapp">
|
||||
<div class="w-full flex items-baseline gap-10 p-2 rounded-lg col-span-2">
|
||||
<div class="w-full flex items-baseline flex-1 gap-3">
|
||||
<p class="font-bold">تراز از :</p>
|
||||
<BaseDatePicker
|
||||
v-model:value="startTaraz"
|
||||
@on-change="getTaraz(startTaraz, endTaraz)"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
class="flex-1"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full flex items-baseline flex-1 gap-3">
|
||||
<p class="font-bold">تا :</p>
|
||||
<BaseDatePicker
|
||||
v-model:value="endTaraz"
|
||||
@on-change="getTaraz(startTaraz, endTaraz)"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
class="flex-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-5 mr-2">
|
||||
<a-switch
|
||||
v-model:checked="directionChangeCheck"
|
||||
checked-children="ارائه دهنده"
|
||||
un-checked-children="مشتری"
|
||||
/>
|
||||
</div>
|
||||
<div class="px-2 col-span-2 grid grid-cols-4 gap-1">
|
||||
<div class="bg-blue rounded text-white py-1 flex justify-center items-center">تراز ها</div>
|
||||
<div class="bg-blue rounded text-white py-1 flex justify-center items-center">
|
||||
تراز ریالی (ریال)
|
||||
</div>
|
||||
<div class="bg-blue rounded text-white py-1 flex justify-center items-center">
|
||||
تراز طلایی (گرم)
|
||||
</div>
|
||||
<div class="bg-blue rounded text-white py-1 flex justify-center items-center">
|
||||
تراز مظنه (ریال)
|
||||
</div>
|
||||
<div class="bg-blue rounded text-white py-1 flex justify-center items-center">
|
||||
تراز افجو
|
||||
</div>
|
||||
<div
|
||||
class="rounded text-white py-1 flex justify-center items-center"
|
||||
:class="
|
||||
(balance?.cashBalanceOfLiman ?? 0) > 0
|
||||
? 'bg-green'
|
||||
: (balance?.cashBalanceOfLiman ?? 0) === 0
|
||||
? 'bg-yellow'
|
||||
: 'bg-red'
|
||||
"
|
||||
>
|
||||
{{ usePrice(balance?.cashBalanceOfLiman ?? 0, true, '') }}
|
||||
</div>
|
||||
<div
|
||||
class="rounded text-white py-1 flex justify-center items-center"
|
||||
:class="
|
||||
(balance?.goldBalanceOfLiman ?? 0) > 0
|
||||
? 'bg-green'
|
||||
: (balance?.goldBalanceOfLiman ?? 0) === 0
|
||||
? 'bg-yellow'
|
||||
: 'bg-red'
|
||||
"
|
||||
>
|
||||
{{ (balance?.goldBalanceOfLiman ?? 0).toFixed(2) }}
|
||||
</div>
|
||||
<div
|
||||
class="rounded text-white py-1 flex justify-center items-center"
|
||||
:class="
|
||||
(balance?.mazanehBalanceOfLiman ?? 0) > 0
|
||||
? 'bg-green'
|
||||
: (balance?.mazanehBalanceOfLiman ?? 0) === 0
|
||||
? 'bg-yellow'
|
||||
: 'bg-red'
|
||||
"
|
||||
>
|
||||
{{
|
||||
balance?.mazanehBalanceOfLiman
|
||||
? usePrice(parseInt(balance?.mazanehBalanceOfLiman.toFixed(0)), true, '')
|
||||
: 0
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center items-center mx-2">
|
||||
<a-spin :spinning="loading" size="40">
|
||||
<div>
|
||||
<div class="mt-2" v-if="balance?.liman?.orders.length">
|
||||
<div class="px-2 col-span-2 grid grid-cols-4 gap-1">
|
||||
<div class="bg-blue text-white py-1 flex justify-center items-center rounded">
|
||||
کاربر
|
||||
</div>
|
||||
<div
|
||||
class="bg-blue text-white py-1 flex justify-center items-center text-center rounded"
|
||||
>
|
||||
قیمت
|
||||
</div>
|
||||
<div
|
||||
class="bg-blue text-white py-1 flex justify-center items-center text-center rounded"
|
||||
>
|
||||
میزان
|
||||
</div>
|
||||
<div
|
||||
class="bg-blue text-white py-1 flex justify-center items-center text-center rounded"
|
||||
>
|
||||
تاریخ ثبت
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(order, index) in balance?.liman?.orders"
|
||||
:key="index"
|
||||
class="px-2 col-span-2 grid grid-cols-4 mt-1 bg-gray-100 hover:bg-gray-200 cursor-pointer"
|
||||
@click="selectedOrder(order)"
|
||||
>
|
||||
<div class="py-1 flex justify-center items-center">
|
||||
<p class="text-[12px] mb-0">{{ order?.customer?.name }}</p>
|
||||
</div>
|
||||
<div class="p-1">
|
||||
<div
|
||||
:class="[
|
||||
getDirectionChange(order, directionChangeCheck) === 'خرید'
|
||||
? 'text-[#006c05]'
|
||||
: 'text-[#c3030a]'
|
||||
]"
|
||||
>
|
||||
<p
|
||||
class="text-[14px] mb-0 rounded text-center font-600"
|
||||
:class="[order?.input_mode === 'gold' ? 'text-[#000000]' : '']"
|
||||
>
|
||||
{{ usePrice(order?.total_price ?? 0, true, '') }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="min-w-[100px]">
|
||||
<label class="text-[8px] mb-0"> در مظنه : </label>
|
||||
<label class="text-[12px] mb-0 text-center">
|
||||
{{ usePrice(order?.price_in_mesghal ?? 0, true, '') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-1 flex flex-col items-center justify-center">
|
||||
<div
|
||||
:class="[
|
||||
getDirectionChange(order, directionChangeCheck) === 'خرید'
|
||||
? 'text-[#006c05]'
|
||||
: 'text-[#c3030a]'
|
||||
]"
|
||||
>
|
||||
<p
|
||||
class="text-[14px] mb-0 rounded text-center font-600"
|
||||
:class="[order?.input_mode === 'cash' ? 'text-[#000000]' : '']"
|
||||
>
|
||||
{{ order?.amount.toFixed(3) }}
|
||||
</p>
|
||||
</div>
|
||||
<p
|
||||
class="text-[12px] mb-0 inline rounded px-2 font-600 pr"
|
||||
:class="[
|
||||
getDirectionChange(order, directionChangeCheck) === 'خرید'
|
||||
? 'text-[#006c05]'
|
||||
: 'text-[#c3030a]'
|
||||
]"
|
||||
>
|
||||
{{ getDirectionChange(order, directionChangeCheck) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="py-1 flex justify-center items-center text-center">
|
||||
<p class="text-[12px] mb-0 min-w-[100px]">{{ toJalali(order?.pay_at) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p v-else class="mb-0 mt-2 text-center text-[15px]">هیچ سفارشی موجود نیست</p>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
<TransactionDetail
|
||||
v-model:showTransactionsDrawer="visible"
|
||||
:selectedItem="selectedItem"
|
||||
@update:selectedSts="editSts"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TransactionDetail from './components/TransactionDetail.vue'
|
||||
import { loading } from '@/utils/index'
|
||||
import { balance, getTaraz } from '@core/utils/price'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { getNow, toJalali } from '@core/utils/useDataTime'
|
||||
const startTaraz = ref<string>('')
|
||||
const endTaraz = ref<string>('')
|
||||
const selectedItem = ref<object>({})
|
||||
const visible = ref<boolean>(false)
|
||||
const directionChangeCheck = ref<boolean>(false)
|
||||
const orginalDirectionget = ref<number>()
|
||||
const color = ref<string>()
|
||||
onMounted(async () => {
|
||||
startTaraz.value = getNow('YYYY-MM-DD HH:mm:ss')
|
||||
endTaraz.value = getNow('YYYY-MM-DD HH:mm:ss')
|
||||
await getTaraz(startTaraz.value, endTaraz.value)
|
||||
})
|
||||
type Order = {
|
||||
direction?: number
|
||||
}
|
||||
|
||||
//---------------مشتری یا ارایه دهنده
|
||||
function getDirectionChange(order: Order | null, directionChangeCheck: boolean): string {
|
||||
let directionChange: number | undefined
|
||||
let caption: string | undefined
|
||||
directionChange = order?.direction
|
||||
if (directionChangeCheck) {
|
||||
if (directionChange === 1) {
|
||||
directionChange = 2
|
||||
caption = 'فروش'
|
||||
color.value = '#c3030a'
|
||||
} else {
|
||||
directionChange = 1
|
||||
caption = 'خرید'
|
||||
color.value = '#006c05'
|
||||
}
|
||||
} else {
|
||||
if (order?.direction === 1) {
|
||||
caption = 'خرید'
|
||||
color.value = '#006c05'
|
||||
} else {
|
||||
caption = 'فروش'
|
||||
color.value = '#c3030a'
|
||||
}
|
||||
}
|
||||
orginalDirectionget.value = directionChange
|
||||
return caption
|
||||
}
|
||||
|
||||
function selectedOrder(val: object) {
|
||||
visible.value = true
|
||||
selectedItem.value = val
|
||||
}
|
||||
|
||||
function editSts(sts: number) {
|
||||
const order = selectedItem?.value
|
||||
order.sts = sts
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.wrapp {
|
||||
@media screen and (min-width: 768px) {
|
||||
width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,131 @@
|
||||
<svg width="373" height="368" viewBox="0 0 373 368" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M187.568 367.346C283.412 367.346 361.11 289.649 361.11 193.804C361.11 97.9595 283.412 20.2622 187.568 20.2622C91.7232 20.2622 14.0259 97.9595 14.0259 193.804C14.0259 289.649 91.7232 367.346 187.568 367.346Z" fill="url(#paint0_linear_595_23892)"/>
|
||||
<path d="M281.192 60.6445H88.9443C76.9613 60.6445 67.2471 70.3587 67.2471 82.3418H302.889C302.889 70.3587 293.175 60.6445 281.192 60.6445Z" fill="url(#paint1_linear_595_23892)"/>
|
||||
<path d="M67.2471 81.7495H302.889V261.219C302.889 269.198 299.72 276.85 294.077 282.493C288.435 288.135 280.783 291.305 272.803 291.305H97.3331C89.3538 291.305 81.7013 288.135 76.0591 282.493C70.4168 276.85 67.2471 269.198 67.2471 261.219V81.7495Z" fill="url(#paint2_linear_595_23892)"/>
|
||||
<path d="M262.384 104.417H107.829C104.61 104.417 102.001 107.024 102.001 110.239C102.001 113.454 104.61 116.061 107.829 116.061H262.384C265.603 116.061 268.212 113.454 268.212 110.239C268.212 107.024 265.603 104.417 262.384 104.417Z" fill="url(#paint3_linear_595_23892)"/>
|
||||
<path d="M262.384 153.885H107.829C104.61 153.885 102.001 156.492 102.001 159.707C102.001 162.922 104.61 165.529 107.829 165.529H262.384C265.603 165.529 268.212 162.922 268.212 159.707C268.212 156.492 265.603 153.885 262.384 153.885Z" fill="url(#paint4_linear_595_23892)"/>
|
||||
<path d="M262.384 203.354H107.829C104.61 203.354 102.001 205.96 102.001 209.175C102.001 212.39 104.61 214.997 107.829 214.997H262.384C265.603 214.997 268.212 212.39 268.212 209.175C268.212 205.96 265.603 203.354 262.384 203.354Z" fill="url(#paint5_linear_595_23892)"/>
|
||||
<path d="M262.384 252.822H107.829C104.61 252.822 102.001 255.428 102.001 258.643C102.001 261.859 104.61 264.465 107.829 264.465H262.384C265.603 264.465 268.212 261.859 268.212 258.643C268.212 255.428 265.603 252.822 262.384 252.822Z" fill="url(#paint6_linear_595_23892)"/>
|
||||
<g filter="url(#filter0_d_595_23892)">
|
||||
<path d="M106.782 192.744H24.484C17.8724 192.744 12.5127 198.103 12.5127 204.715V322.347C12.5127 328.958 17.8724 334.318 24.484 334.318H106.782C113.394 334.318 118.754 328.958 118.754 322.347V204.715C118.754 198.103 113.394 192.744 106.782 192.744Z" fill="url(#paint7_linear_595_23892)"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d_595_23892)">
|
||||
<path d="M341.059 9H250.158C245.922 9 242.488 12.4339 242.488 16.6697V59.3957C242.488 63.6315 245.922 67.0654 250.158 67.0654H341.059C345.295 67.0654 348.729 63.6315 348.729 59.3957V16.6697C348.729 12.4339 345.295 9 341.059 9Z" fill="url(#paint8_linear_595_23892)"/>
|
||||
</g>
|
||||
<path d="M97.5989 251.591H33.6677C31.5149 251.591 29.7698 253.336 29.7698 255.489V255.501C29.7698 257.654 31.5149 259.399 33.6677 259.399H97.5989C99.7517 259.399 101.497 257.654 101.497 255.501V255.489C101.497 253.336 99.7517 251.591 97.5989 251.591Z" fill="url(#paint9_linear_595_23892)"/>
|
||||
<path d="M97.6349 306.535H34.2531C32.1188 306.535 30.3887 308.226 30.3887 310.312V310.324C30.3887 312.409 32.1188 314.1 34.2531 314.1H97.6349C99.7692 314.1 101.499 312.409 101.499 310.324V310.312C101.499 308.226 99.7692 306.535 97.6349 306.535Z" fill="url(#paint10_linear_595_23892)"/>
|
||||
<path d="M97.6349 277.789H34.2531C32.1188 277.789 30.3887 279.479 30.3887 281.565V281.577C30.3887 283.663 32.1188 285.354 34.2531 285.354H97.6349C99.7692 285.354 101.499 283.663 101.499 281.577V281.565C101.499 279.479 99.7692 277.789 97.6349 277.789Z" fill="url(#paint11_linear_595_23892)"/>
|
||||
<path d="M57.0429 210.909H38.3606C34.2222 210.909 30.8674 214.263 30.8674 218.402V223.586C30.8674 227.725 34.2222 231.08 38.3606 231.08H57.0429C61.1812 231.08 64.536 227.725 64.536 223.586V218.402C64.536 214.263 61.1812 210.909 57.0429 210.909Z" fill="url(#paint12_linear_595_23892)"/>
|
||||
<path d="M264.922 46.8443C269.792 46.8443 273.74 42.8965 273.74 38.0266C273.74 33.1568 269.792 29.209 264.922 29.209C260.053 29.209 256.105 33.1568 256.105 38.0266C256.105 42.8965 260.053 46.8443 264.922 46.8443Z" fill="#81D5E7"/>
|
||||
<path d="M296.434 46.8443C301.303 46.8443 305.251 42.8965 305.251 38.0266C305.251 33.1568 301.303 29.209 296.434 29.209C291.564 29.209 287.616 33.1568 287.616 38.0266C287.616 42.8965 291.564 46.8443 296.434 46.8443Z" fill="#81D5E7"/>
|
||||
<path d="M327.945 46.8443C332.815 46.8443 336.763 42.8965 336.763 38.0266C336.763 33.1568 332.815 29.209 327.945 29.209C323.075 29.209 319.127 33.1568 319.127 38.0266C319.127 42.8965 323.075 46.8443 327.945 46.8443Z" fill="#81D5E7"/>
|
||||
<path d="M173.889 310.14C174.407 307.996 177.457 307.996 177.974 310.14L181.812 326.038C181.997 326.804 182.595 327.403 183.361 327.588L199.26 331.425C201.404 331.943 201.404 334.993 199.26 335.51L183.361 339.348C182.595 339.533 181.997 340.131 181.812 340.897L177.974 356.796C177.457 358.94 174.407 358.94 173.889 356.796L170.052 340.897C169.867 340.131 169.269 339.533 168.502 339.348L152.604 335.51C150.46 334.993 150.46 331.943 152.604 331.425L168.502 327.588C169.269 327.403 169.867 326.804 170.052 326.038L173.889 310.14Z" fill="url(#paint13_linear_595_23892)"/>
|
||||
<path d="M48.3111 19.6453C48.8287 17.5013 51.8783 17.5013 52.3959 19.6453L56.2336 35.5436C56.4186 36.3098 57.0168 36.908 57.783 37.093L73.6813 40.9308C75.8254 41.4483 75.8254 44.4979 73.6813 45.0155L57.783 48.8533C57.0168 49.0382 56.4186 49.6364 56.2336 50.4026L52.3959 66.301C51.8783 68.445 48.8287 68.445 48.3111 66.301L44.4734 50.4026C44.2884 49.6364 43.6902 49.0382 42.924 48.8533L27.0257 45.0155C24.8816 44.4979 24.8816 41.4483 27.0257 40.9308L42.924 37.093C43.6902 36.908 44.2884 36.3098 44.4734 35.5436L48.3111 19.6453Z" fill="url(#paint14_linear_595_23892)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.649 25.7543C183.575 25.7543 185.947 23.3823 185.947 20.4562C185.947 17.5302 183.575 15.1581 180.649 15.1581C177.723 15.1581 175.351 17.5302 175.351 20.4562C175.351 23.3823 177.723 25.7543 180.649 25.7543ZM180.649 29.7279C185.769 29.7279 189.921 25.5768 189.921 20.4562C189.921 15.3356 185.769 11.1846 180.649 11.1846C175.528 11.1846 171.377 15.3356 171.377 20.4562C171.377 25.5768 175.528 29.7279 180.649 29.7279Z" fill="url(#paint15_linear_595_23892)"/>
|
||||
<path d="M345.008 170.135C344.675 168.829 345.881 167.652 347.179 168.016L363.426 172.582C364.723 172.947 365.139 174.579 364.175 175.521L352.097 187.308C351.133 188.249 349.511 187.794 349.178 186.488L345.008 170.135Z" fill="url(#paint16_linear_595_23892)"/>
|
||||
<path d="M36.2812 148.512C37.5876 148.181 38.7628 149.388 38.3965 150.685L33.8099 166.926C33.4436 168.223 31.8105 168.637 30.8703 167.672L19.0985 155.579C18.1584 154.613 18.6163 152.992 19.9227 152.661L36.2812 148.512Z" fill="url(#paint17_linear_595_23892)"/>
|
||||
<path d="M288.951 331.584C290.257 331.253 291.433 332.46 291.066 333.757L286.48 349.998C286.113 351.296 284.48 351.71 283.54 350.744L271.768 338.651C270.828 337.685 271.286 336.064 272.592 335.733L288.951 331.584Z" fill="url(#paint18_linear_595_23892)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M357.669 102.917C360.595 102.917 362.967 100.545 362.967 97.6188C362.967 94.6928 360.595 92.3207 357.669 92.3207C354.743 92.3207 352.371 94.6928 352.371 97.6188C352.371 100.545 354.743 102.917 357.669 102.917ZM357.669 106.89C362.789 106.89 366.941 102.739 366.941 97.6188C366.941 92.4982 362.789 88.3472 357.669 88.3472C352.548 88.3472 348.397 92.4982 348.397 97.6188C348.397 102.739 352.548 106.89 357.669 106.89Z" fill="url(#paint19_linear_595_23892)"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_595_23892" x="0.512695" y="184.744" width="136.241" height="171.575" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="3" dy="7"/>
|
||||
<feGaussianBlur stdDeviation="7.5"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.104618 0 0 0 0 0.465612 0 0 0 0 0.545833 0 0 0 0.15 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_595_23892"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_595_23892" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_595_23892" x="235.488" y="0" width="132.241" height="84.0654" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dx="6" dy="4"/>
|
||||
<feGaussianBlur stdDeviation="6.5"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.104618 0 0 0 0 0.465612 0 0 0 0 0.545833 0 0 0 0.09 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_595_23892"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_595_23892" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_595_23892" x1="186.23" y1="-36.2473" x2="189.785" y2="573.205" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#8EE2F4"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_595_23892" x1="66.9802" y1="65.652" x2="303.007" y2="82.2949" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90E3F5"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_595_23892" x1="60.1717" y1="238.89" x2="400.595" y2="244.942" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BCF3FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_595_23892" x1="94.9712" y1="115.581" x2="278.043" y2="115.581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#65C8DE"/>
|
||||
<stop offset="1" stop-color="#D2F7FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_595_23892" x1="94.9712" y1="165.048" x2="278.043" y2="165.048" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#65C8DE"/>
|
||||
<stop offset="1" stop-color="#D2F7FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_595_23892" x1="94.9712" y1="214.517" x2="278.043" y2="214.517" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#65C8DE"/>
|
||||
<stop offset="1" stop-color="#D2F7FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_595_23892" x1="94.9712" y1="263.985" x2="278.043" y2="263.985" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#65C8DE"/>
|
||||
<stop offset="1" stop-color="#D2F7FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_595_23892" x1="9.32274" y1="298.907" x2="212.951" y2="315.631" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BCF3FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_595_23892" x1="239.298" y1="52.5419" x2="392.7" y2="56.9794" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="#BCF3FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_595_23892" x1="109.821" y1="259.632" x2="23.5804" y2="259.632" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D2F7FF"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_595_23892" x1="109.752" y1="314.326" x2="24.2525" y2="314.326" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D2F7FF"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_595_23892" x1="109.752" y1="285.579" x2="24.2525" y2="285.579" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D2F7FF"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_595_23892" x1="87.8826" y1="230.885" x2="26.6064" y2="230.885" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.243799" stop-color="#D2F7FF"/>
|
||||
<stop offset="1" stop-color="#6BCBE0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint13_linear_595_23892" x1="144.071" y1="316.352" x2="208.066" y2="316.767" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90E3F5"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint14_linear_595_23892" x1="18.4929" y1="25.8573" x2="82.4878" y2="26.2728" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90E3F5"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint15_linear_595_23892" x1="171.356" y1="15.4641" x2="190.021" y2="15.5853" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90E3F5"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint16_linear_595_23892" x1="339.029" y1="180.843" x2="358.232" y2="162.343" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90E3F5"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint17_linear_595_23892" x1="25.58" y1="142.519" x2="44.0555" y2="161.746" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90E3F5"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint18_linear_595_23892" x1="278.25" y1="325.591" x2="296.725" y2="344.818" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90E3F5"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint19_linear_595_23892" x1="348.376" y1="92.6267" x2="367.041" y2="92.7479" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#90E3F5"/>
|
||||
<stop offset="1" stop-color="#65C8DE"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<div class="w-full flex md:block justify-between md:justify-unset items-center">
|
||||
<div class="flex items-center gap-2 mx-2">
|
||||
<div class="p-1 h-8 aspect-square rounded-full" :class="bgColor">
|
||||
<BaseIcon icon="vuesax-linear:profile-add" :class="textColor" />
|
||||
</div>
|
||||
<div class="text-xs font-bold">{{ title }}</div>
|
||||
</div>
|
||||
<div class="flex flex-row-reverse gap-1 mt-5 items-center md:w-full pl-2 items-end">
|
||||
<div class="text-xs">{{ unit }}</div>
|
||||
<div class="font-bold text-xl">{{ count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Prop {
|
||||
color: string
|
||||
title: string
|
||||
count?: number
|
||||
unit: 'نفر' | 'گرم'
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
|
||||
const bgColor = computed(() => {
|
||||
switch (props.color) {
|
||||
case 'fuchsia':
|
||||
return 'bg-fuchsia-100'
|
||||
case 'orange':
|
||||
return 'bg-orange-100'
|
||||
case 'green':
|
||||
return 'bg-green-100'
|
||||
case 'blue':
|
||||
return 'bg-blue-100'
|
||||
}
|
||||
})
|
||||
const textColor = computed(() => {
|
||||
switch (props.color) {
|
||||
case 'fuchsia':
|
||||
return 'text-fuchsia-600'
|
||||
case 'orange':
|
||||
return 'text-orange-600'
|
||||
case 'green':
|
||||
return 'text-green-600'
|
||||
case 'blue':
|
||||
return 'text-blue-600'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,876 @@
|
||||
<template>
|
||||
<div class="p-5">
|
||||
<a-spin size="large" :spinning="loading">
|
||||
<div
|
||||
class="w-full bg-[#0A1B37] flex p-2 rounded-lg md:justify-evenly flex-col md:flex-row shadow-lg"
|
||||
>
|
||||
<div class="flex text-white gap-2 items-center">
|
||||
<div>مظنه روز:</div>
|
||||
<div class="font-bold">
|
||||
{{ usePrice(parseInt(dashboardInf?.price ?? '0'), true, '') }}
|
||||
</div>
|
||||
<div class="text-xs">ریال</div>
|
||||
</div>
|
||||
<div class="flex text-white gap-2 items-center">
|
||||
<div>آخرین تاریخ به روز رسانی:</div>
|
||||
</div>
|
||||
<div class="flex text-white gap-2 items-center">
|
||||
<div>هر مثقال طلا:</div>
|
||||
<div class="font-bold"></div>
|
||||
<div class="text-xs">ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center md:items-unset md:grid md:grid-cols-7 gap-4 mt-3">
|
||||
<BaseCard class="w-full md:w-none md:col-span-7">
|
||||
<div class="text-lg font-bold">مشتری</div>
|
||||
<div
|
||||
class="flex flex-col md:flex-row justify-around mt-5 justify-between items-dashboard h-full"
|
||||
>
|
||||
<DashboardItem
|
||||
class="md:w-1/3"
|
||||
color="blue"
|
||||
title="مشتری جدید"
|
||||
unit="نفر"
|
||||
:count="dashboardInf?.new_customer_single"
|
||||
/>
|
||||
<div class="h-[60%] hidden md:block bg-gray-200 w-[1px]" />
|
||||
<DashboardItem
|
||||
class="md:w-1/3"
|
||||
color="green"
|
||||
title="کل مشتریان"
|
||||
unit="نفر"
|
||||
:count="dashboardInf?.all_customer_single"
|
||||
/>
|
||||
<div class="h-[60%] hidden md:block bg-gray-200 w-[1px]" />
|
||||
<DashboardItem
|
||||
class="md:w-1/3"
|
||||
color="orange"
|
||||
title="مشتریان بایگانی شده"
|
||||
unit="نفر"
|
||||
:count="dashboardInf?.archive_customer_single"
|
||||
/>
|
||||
</div>
|
||||
</BaseCard>
|
||||
<BaseCard class="md:hidden w-full">
|
||||
<div class="grid grid-cols-3 gap-1 text-xs">
|
||||
<div class="bg-blue-600 text-white rounded p-1">مجموع</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">ریال</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">گرم</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">کیف طلا</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="
|
||||
sums?.goldToCash >= 0
|
||||
? sums?.goldToCash === 0
|
||||
? 'bg-amber-600'
|
||||
: 'bg-green-600'
|
||||
: 'bg-red-600'
|
||||
"
|
||||
>
|
||||
{{ usePrice(sums?.goldToCash ?? 0, true, '') }}
|
||||
</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="
|
||||
sums?.gold >= 0
|
||||
? sums?.gold === 0
|
||||
? 'bg-amber-600'
|
||||
: 'bg-green-600'
|
||||
: 'bg-red-600'
|
||||
"
|
||||
>
|
||||
{{ usePrice(sums?.gold ?? 0, true, '') }}
|
||||
</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">کیف پول</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="
|
||||
sums?.cash >= 0
|
||||
? sums?.cash === 0
|
||||
? 'bg-amber-600'
|
||||
: 'bg-green-600'
|
||||
: 'bg-red-600'
|
||||
"
|
||||
>
|
||||
{{ usePrice(sums?.cash ?? 0, true, '') }}
|
||||
</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="
|
||||
sums?.cashToGold >= 0
|
||||
? sums?.cashToGold === 0
|
||||
? 'bg-amber-600'
|
||||
: 'bg-green-600'
|
||||
: 'bg-red-600'
|
||||
"
|
||||
>
|
||||
{{ usePrice(sums?.cashToGold ?? 0, true, '') }}
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
<BaseCard class="h-full md:col-span-7">
|
||||
<ASpin :spinning="tarazLoading">
|
||||
<div class="grid md:grid-cols-3 gap-3 mt-2">
|
||||
<div>
|
||||
<div class="md:flex content-center gap-3">
|
||||
<div class="w-full md:flex items-baseline gap-10 bg-gray-100 p-2 rounded-lg">
|
||||
<p class="font-bold mr-2">تاریخ تراز</p>
|
||||
<div class="w-full flex items-baseline flex-1 gap-3">
|
||||
<p class="font-bold">از:</p>
|
||||
<BaseDatePicker
|
||||
v-model:value="startTaraz"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
class="flex-1"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full flex items-baseline flex-1 gap-3">
|
||||
<p class="font-bold">تا:</p>
|
||||
<BaseDatePicker
|
||||
v-model:value="endTaraz"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
class="flex-1"
|
||||
/>
|
||||
</div>
|
||||
<BaseButton @click="getTaraz()">ثبت تاریخ</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex font-bold p-2">
|
||||
<span>جمع واریزی : </span>
|
||||
<div class="mr-4">{{ usePrice(balance_?.income_money ?? 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col gap-3 bg-yellow-100 p-2 rounded-lg w-full cursor-pointer"
|
||||
@click="openNewTabBalance"
|
||||
>
|
||||
<span class="text-center text-base font-700 bg-yellow text-white rounded-lg">
|
||||
تراز طلایی
|
||||
</span>
|
||||
<div class="flex flex-col md:flex-row items-center justify-between md:gap-15">
|
||||
<div class="w-full flex flex-col gap-3">
|
||||
<div class="flex justify-between mx-5">
|
||||
<span class="font-600">تراز اصلی:</span>
|
||||
<span
|
||||
class="text-base"
|
||||
:class="
|
||||
(balance_?.goldBalance ?? 0) > 0
|
||||
? 'text-green-600'
|
||||
: (balance_?.goldBalance ?? 0) === 0
|
||||
? 'text-yellow-600'
|
||||
: 'text-red'
|
||||
"
|
||||
>
|
||||
{{ balance_?.goldBalance?.toFixed(3) }} گرم
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col gap-3 bg-blue-100 p-2 rounded-lg w-full cursor-pointer"
|
||||
@click="openNewTabBalance"
|
||||
>
|
||||
<span class="text-center text-base font-700 bg-blue-6 rounded-lg text-white">
|
||||
تراز ریالی
|
||||
</span>
|
||||
<div class="flex flex-col md:flex-row items-center justify-between md:gap-15">
|
||||
<div class="w-full flex flex-col gap-3">
|
||||
<div class="flex justify-between mx-5">
|
||||
<span class="font-600">تراز اصلی:</span>
|
||||
<span
|
||||
class="text-base"
|
||||
:class="
|
||||
(balance_?.cashBalance ?? 0) > 0
|
||||
? 'text-green-600'
|
||||
: (balance_?.cashBalance ?? 0) === 0
|
||||
? 'text-yellow-600'
|
||||
: 'text-red'
|
||||
"
|
||||
>
|
||||
{{ usePrice(balance_?.cashBalance ?? 0) }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ASpin>
|
||||
</BaseCard>
|
||||
<BaseCard class="w-full md:w-none md:col-span-2">
|
||||
<div class="text-lg font-bold">تراز بدهی</div>
|
||||
<div ref="main" class="w-full aspect-square"></div>
|
||||
</BaseCard>
|
||||
|
||||
<BaseCard class="md:col-span-5">
|
||||
<div id="chart">
|
||||
<div class="font-bold text-lg mt-2 text-center md:text-right mb-2">مقایسه قیمت ها</div>
|
||||
<apexchart
|
||||
type="bar"
|
||||
height="350"
|
||||
:options="otherPricesOptions"
|
||||
:series="otherPricesSeries"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="md:grid grid-cols-4 gap-4 mt-4 justify-between text-center">
|
||||
<div class="grid-cols-1 grid gap-2 bg-blue-100 rounded-lg shadow-lg">
|
||||
<div class="flex items-center text-right p-2">
|
||||
<img src="/src/assets/img/saminLogo_.png" class="w-2rem h-2rem" />
|
||||
<div class="mr-4">
|
||||
<div>قیمت ثمین گلد</div>
|
||||
<div>
|
||||
{{ usePrice(othersPrices?.price_last ? othersPrices?.price_last : 0) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-cols-1 grid gap-2 bg-red-100 rounded-lg shadow-lg">
|
||||
<div class="flex items-center text-right p-2">
|
||||
<img src="/src/assets/img/milliLogo.png" class="w-2rem h-2rem" />
|
||||
<div class="mr-4">
|
||||
<div>قیمت سایت میلی</div>
|
||||
<div>{{ usePrice(othersPrices?.milli ? othersPrices?.milli : 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-cols-1 grid gap-2 bg-green-100 rounded-lg shadow-lg">
|
||||
<div class="flex items-center text-right p-2">
|
||||
<img src="/src/assets/img/henzaLogo.png" class="w-2rem h-2rem" />
|
||||
<div class="mr-4">
|
||||
<div>قیمت سایت هنزا</div>
|
||||
<div>{{ usePrice(othersPrices?.henzagold ? othersPrices?.henzagold : 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-cols-1 grid gap-2 bg-orange-100 rounded-lg shadow-lg">
|
||||
<div class="flex items-center text-right p-2">
|
||||
<img src="/src/assets/img/talaLogo.png" class="w-2rem h-2rem" />
|
||||
<div class="mr-4">
|
||||
<div>قیمت سایت طلا</div>
|
||||
<div>{{ usePrice(othersPrices?.tala_ir ? othersPrices?.tala_ir : 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
<div class="md:col-span-7 md:grid gap-4">
|
||||
<BaseCard>
|
||||
<div class=" ">
|
||||
<div class="flex flex-col md:flex-row justify-between items-center">
|
||||
<div class="flex items-end">
|
||||
<div class="text-2xl font-bold ml-2">{{ usePrice(123456789123, true, '') }}</div>
|
||||
<div class="text-lg">تومان</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="flex bg-gray-50 px-1 py-1 dashboard-tabs-class border-size-[1px] border-gray-200 border-solid rounded-lg"
|
||||
>
|
||||
<div :class="type === 'week' ? 'selected_item' : ''" @click="setType('week')">
|
||||
هفتگی
|
||||
</div>
|
||||
<div :class="type === 'month' ? 'selected_item' : ''" @click="setType('month')">
|
||||
ماهانه
|
||||
</div>
|
||||
<div :class="type === 'year' ? 'selected_item' : ''" @click="setType('year')">
|
||||
سالانه
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-10">جمع فروش به مشتری</div>
|
||||
<apexchart
|
||||
type="area"
|
||||
height="350"
|
||||
ref="chart"
|
||||
:options="sumOfSellCoworkerOption"
|
||||
:series="sumOfSellCoworkerSeries"
|
||||
></apexchart>
|
||||
</BaseCard>
|
||||
<div class="flex flex-col items-center md:items-unset md:grid md:grid-cols-7 gap-4">
|
||||
<BaseCard class="w-full md:w-none md:col-span-7">
|
||||
<div>
|
||||
<div class="font-bold text-lg mt-2 text-center md:text-right">
|
||||
حسابداری ثمین گلد در یک نگاه
|
||||
</div>
|
||||
<div class="md:flex mt-6">
|
||||
<div class="flex items-baseline flex-1 gap-3">
|
||||
<p>از:</p>
|
||||
<BaseDatePicker
|
||||
v-model:value="startDate"
|
||||
@on-change="getTaraz"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
class="flex-1"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex items-baseline flex-1 gap-3">
|
||||
<p class="md:mr-6">تا:</p>
|
||||
<BaseDatePicker
|
||||
v-model:value="endDate"
|
||||
@on-change="getTaraz"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
class="flex-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-cols-1 grid gap-2 bg-green-100 rounded-lg shadow-lg">
|
||||
<div class="p-4">
|
||||
<div class="font-bold text-lg">دریافتی</div>
|
||||
<div class="md:grid-cols-5 grid gap-2 mt-4">
|
||||
<div>
|
||||
<div>کل سود دریافت شده</div>
|
||||
<div class="font-bold">{{ usePrice(balance?.fullPriceSood ?? 0) }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>کل کارمزد</div>
|
||||
<div class="font-bold">{{ usePrice(balance?.fullPriceKaermozd ?? 0) }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>تعداد سفارشات</div>
|
||||
<div class="font-bold">{{ balance?.orderCount }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="ml-2">قیمت نهایی محاسبه شده با روش اول</div>
|
||||
<div class="font-bold">{{ usePrice(balance?.fullPriceM1 ?? 0) }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="ml-2">قیمت نهایی محاسبه شده با روش دوم</div>
|
||||
<div class="font-bold">{{ usePrice(balance?.fullPriceM2 ?? 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 bg-red-100 p-4 rounded-lg flex-col md:flex-row shadow-lg">
|
||||
<div class="font-bold text-lg">خروجی</div>
|
||||
<div class="md:grid-cols-2 grid mt-4">
|
||||
<div>
|
||||
<div>پاداش معرفی به گرم</div>
|
||||
<div class="font-bold">{{ balance?.Gifts }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>پاداش معرفی به ریال</div>
|
||||
<div class="font-bold">{{ usePrice(balance?.GiftsPrise ?? 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-4 bg-blue-100 p-4 rounded-lg md:justify-evenly flex-col md:flex-row shadow-lg"
|
||||
>
|
||||
<div>
|
||||
<div class="font-bold text-lg">قیمت کل</div>
|
||||
<div class="flex mt-4">
|
||||
<div class="ml-4">کل درآمد :</div>
|
||||
<div class="font-bold">{{ usePrice(balance?.sumAll ?? 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</div>
|
||||
<div class="flex flex-col items-center md:items-unset md:grid md:grid-cols-7 gap-4">
|
||||
<BaseCard class="w-full md:w-none md:col-span-7">
|
||||
<div>
|
||||
<div class="font-bold text-lg mt-2 text-center md:text-right">نوسانات قیمت</div>
|
||||
<div id="chart">
|
||||
<div class="toolbar mt-2 mb-2">
|
||||
<button
|
||||
id="DAILY"
|
||||
@click="updateData('DAILY')"
|
||||
:class="{ active: selection === 'DAILY' }"
|
||||
>
|
||||
24 ساعت اخیر
|
||||
</button>
|
||||
|
||||
<button
|
||||
id="WEEKLY"
|
||||
@click="updateData('WEEKLY')"
|
||||
:class="{ active: selection === 'WEEKLY' }"
|
||||
>
|
||||
هفته گذشته
|
||||
</button>
|
||||
|
||||
<button
|
||||
id="MONTHLY"
|
||||
@click="updateData('MONTHLY')"
|
||||
:class="{ active: selection === 'MONTHLY' }"
|
||||
>
|
||||
ماه گذشته
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="chart-timeline">
|
||||
<apexchart
|
||||
type="area"
|
||||
height="350"
|
||||
ref="chart"
|
||||
:options="priceChartOptions"
|
||||
:series="priceChartSeries"
|
||||
></apexchart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { openNewTabBalance} from '@/core/composable/appInfo'
|
||||
import nothing from './assets/svgs/nothing.svg'
|
||||
import { usePrice } from '../../core/utils/usePrice'
|
||||
import DashboardItem from '@/pages/dashboard/components/dashboardItem.vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { getAllPrices, getDashboard } from '@/api/dashboard'
|
||||
import { getOthersPrices } from '@/api/othersPrices'
|
||||
import type { Charts, Dashboard } from '@/model/dashboard'
|
||||
import { getWalletTable } from '@/api/wallet'
|
||||
import type { Accounting } from '@/model/accounting'
|
||||
import { getAccountingTable, getTotalAccountingTable } from '@/api/accounting'
|
||||
import { ref } from 'vue'
|
||||
import type { OthersPrices } from '@/model/othersPrices'
|
||||
import { getNow, toJalaliNoTime } from '@core/utils/useDataTime'
|
||||
import { cols } from '@/pages/menuPages/customers/base/hooks/customerColumns'
|
||||
import type { TableInput } from '@core/type/baseTable'
|
||||
import type { PriceChart } from '@/model/priceChart'
|
||||
// import {getBalance} from "@/api/product"
|
||||
import type { Balance } from '@/model/product'
|
||||
import { getBalance } from "@/api/product";
|
||||
const tarazLoading = ref<boolean>(false)
|
||||
const main = ref(null)
|
||||
const bar = ref(null)
|
||||
const type = ref<string>('week')
|
||||
const dashboardInf = ref<Dashboard>()
|
||||
const othersPrices = ref<OthersPrices>()
|
||||
const chartDataWeekInf = reactive<Charts>({})
|
||||
const chartDataMonthInf = reactive<Charts>({})
|
||||
const chartDataYearInf = reactive<Charts>({})
|
||||
const loading = ref<boolean>(false)
|
||||
const sums = ref()
|
||||
const startDate = ref<string>('')
|
||||
const endDate = ref<string>('')
|
||||
const balance = ref<Accounting>()
|
||||
const startTaraz = ref<string>('')
|
||||
const endTaraz = ref<string>('')
|
||||
const balance_ = ref<Balance>()
|
||||
|
||||
onMounted(() => {
|
||||
startDate.value = ''
|
||||
endDate.value = ''
|
||||
startTaraz.value = getNow('YYYY-MM-DD HH:mm:ss')
|
||||
endTaraz.value = getNow('YYYY-MM-DD HH:mm:ss')
|
||||
getDate()
|
||||
getTaraz()
|
||||
})
|
||||
|
||||
async function getDate() {
|
||||
try {
|
||||
loading.value = true
|
||||
balance.value = await getAccountingTable(startDate.value, endDate.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function getTaraz() {
|
||||
try {
|
||||
loading.value = true
|
||||
balance.value = await getAccountingTable(startDate.value, endDate.value)
|
||||
balance_.value = await getBalance(startTaraz.value, endTaraz.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
//chart other prices
|
||||
function setType(val: string) {
|
||||
type.value = val
|
||||
}
|
||||
|
||||
//chart 1
|
||||
onMounted(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
dashboardInf.value = await getDashboard()
|
||||
const data = await getWalletTable()
|
||||
sums.value = data?.sums
|
||||
// chartDataWeekInf.buySellChart =
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
if (main.value !== null) {
|
||||
//circle
|
||||
const echart = echarts.init(main.value, null, {
|
||||
renderer: 'canvas'
|
||||
})
|
||||
echart.setOption({
|
||||
tooltip: {
|
||||
formatter: '{a} <br/>{b} : {c}%'
|
||||
},
|
||||
textStyle: {
|
||||
fontFamily: 'iran-sans'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'تراز',
|
||||
type: 'gauge',
|
||||
detail: {
|
||||
formatter: '{value}',
|
||||
offsetCenter: [0, '60%'],
|
||||
fontSize: 40,
|
||||
color: '#EF4444',
|
||||
valueAnimation: true
|
||||
},
|
||||
min: -50,
|
||||
max: 50,
|
||||
data: [
|
||||
{
|
||||
value: 10.25,
|
||||
name: 'گرم'
|
||||
}
|
||||
],
|
||||
axisLine: {
|
||||
roundCap: true,
|
||||
lineStyle: {
|
||||
color: [[1, '#2563EB']],
|
||||
width: 10
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: 16
|
||||
},
|
||||
title: {
|
||||
color: '#000000',
|
||||
offsetCenter: [0, '75%']
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
//chart 4
|
||||
const sumOfSellCoworkerSeries = [
|
||||
{
|
||||
name: 'series1',
|
||||
data: [31, 40, 28, 51, 42, 109, 100]
|
||||
}
|
||||
]
|
||||
|
||||
const sumOfSellCoworkerOption = {
|
||||
chart: {
|
||||
height: 350,
|
||||
type: 'area'
|
||||
},
|
||||
colors: ['#2563EB'],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth'
|
||||
},
|
||||
xaxis: {
|
||||
type: 'datetime',
|
||||
categories: [
|
||||
'2018-09-19T00:00:00.000Z',
|
||||
'2018-09-19T01:30:00.000Z',
|
||||
'2018-09-19T02:30:00.000Z',
|
||||
'2018-09-19T03:30:00.000Z',
|
||||
'2018-09-19T04:30:00.000Z',
|
||||
'2018-09-19T05:30:00.000Z',
|
||||
'2018-09-19T06:30:00.000Z'
|
||||
]
|
||||
},
|
||||
tooltip: {
|
||||
x: {
|
||||
format: 'dd/MM/yy HH:mm'
|
||||
}
|
||||
},
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
colors: ['#765DFF'],
|
||||
gradient: {
|
||||
shadeIntensity: 1,
|
||||
opacityFrom: 0.7,
|
||||
opacityTo: 0.9,
|
||||
stops: [0, 100]
|
||||
}
|
||||
}
|
||||
}
|
||||
// const priceChartSeries = ref([{name: 'قیمت', data: []}])
|
||||
// const priceChartOptions = ref({
|
||||
// chart: {
|
||||
// type: 'line',
|
||||
// height: 350,
|
||||
// zoom: {enabled: true}
|
||||
// },
|
||||
// dataLabels: {enabled: false},
|
||||
// stroke: {curve: 'smooth'},
|
||||
// title: {text: 'نمودار قیمت بر اساس تاریخ', align: 'left'},
|
||||
// xaxis: {
|
||||
// categories: [],
|
||||
// title: {text: 'تاریخ'}
|
||||
// },
|
||||
// yaxis: {
|
||||
// title: {text: 'قیمت'},
|
||||
// min: 0
|
||||
// }
|
||||
// })
|
||||
|
||||
const otherPricesSeries = ref([])
|
||||
const otherPricesOptions = ref({
|
||||
chart: {
|
||||
height: 350,
|
||||
type: 'bar',
|
||||
fontFamily: "'IranSans', sans-serif"
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 10,
|
||||
dataLabels: {
|
||||
position: 'top'
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter: (val) => `${usePrice(val)} `,
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
title: {
|
||||
text: 'قیمت',
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labels: {
|
||||
formatter: (val) => `${usePrice(val)} `,
|
||||
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['henzagold.com', 'milli.gold', 'tala.ir', 'samin.gold'],
|
||||
labels: {
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
y: {
|
||||
formatter: (val) => `${usePrice(val)} `,
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
othersPrices.value = await getOthersPrices()
|
||||
|
||||
const prices = [
|
||||
othersPrices.value?.henzagold ?? 0,
|
||||
othersPrices.value?.milli ?? 0,
|
||||
othersPrices.value?.tala_ir ?? 0,
|
||||
othersPrices.value?.price_last ?? 0
|
||||
]
|
||||
|
||||
otherPricesSeries.value = [
|
||||
{
|
||||
name: 'Prices',
|
||||
data: prices
|
||||
}
|
||||
]
|
||||
const minPrice = Math.min(...prices)
|
||||
const maxPrice = Math.max(...prices)
|
||||
const offset = (maxPrice - minPrice) * 0.05
|
||||
|
||||
otherPricesOptions.value = {
|
||||
...otherPricesOptions.value,
|
||||
yaxis: {
|
||||
...otherPricesOptions.value.yaxis,
|
||||
min: minPrice - offset,
|
||||
max: maxPrice + offset
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error fetching prices:', e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
const selection = ref('DAILY')
|
||||
const chartRef = ref<ApexCharts | null>(null)
|
||||
const priceChartSeries = ref<{ data: [number, number][] }[]>([{ data: [] }])
|
||||
|
||||
const toPersianNumber = (num) => {
|
||||
return num.toString().replace(/\d/g, (d) => '۰۱۲۳۴۵۶۷۸۹'[d])
|
||||
}
|
||||
|
||||
const priceChartOptions = ref({
|
||||
chart: {
|
||||
id: 'نوسانات قیمت',
|
||||
type: 'area',
|
||||
height: 350,
|
||||
zoom: {
|
||||
autoScaleYaxis: true
|
||||
},
|
||||
events: {
|
||||
mounted(chart) {
|
||||
chartRef.value = chart
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
formatter: (val) => toPersianNumber(usePrice(val)),
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
title: {
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labels: {
|
||||
formatter: (val) => toPersianNumber(usePrice(val)),
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
type: 'datetime',
|
||||
labels: {
|
||||
rotate: -45,
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
formatter: (val) => {
|
||||
return toPersianNumber(toJalaliNoTime(new Date(val).toString()))
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
x: {
|
||||
formatter: (val) => {
|
||||
return toPersianNumber(toJalaliNoTime(new Date(val).toString()))
|
||||
}
|
||||
},
|
||||
formatter: (val) => toPersianNumber(`${usePrice(val)} `),
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shadeIntensity: 1,
|
||||
opacityFrom: 0.7,
|
||||
opacityTo: 0.9,
|
||||
stops: [0, 100]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const fetchPrices = async () => {
|
||||
try {
|
||||
const response = await getAllPrices()
|
||||
const data = response.data.prices
|
||||
|
||||
const selectedData = data[selection.value] || []
|
||||
priceChartSeries.value[0].data = selectedData.map((item) => [item.timestamp, item.value])
|
||||
|
||||
chartRef.value?.updateOptions({ series: priceChartSeries.value })
|
||||
} catch (error) {
|
||||
console.error('خطا در دریافت دادهها', error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateData = (timeline) => {
|
||||
selection.value = timeline
|
||||
fetchPrices()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchPrices()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
/*.items-dashboard > div:not(:last-child) {
|
||||
border-left: 1px solid black;
|
||||
}*/
|
||||
.single-border {
|
||||
border-right: 1px solid black !important;
|
||||
}
|
||||
|
||||
@keyframes swingParent {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
left: 0;
|
||||
}
|
||||
to {
|
||||
left: 100%;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
|
||||
.animate.right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.animate.right.move {
|
||||
right: 100%;
|
||||
transform: translate(100%, 0);
|
||||
}
|
||||
|
||||
.dashboard-tabs-class div {
|
||||
@apply text-gray-400 w-25 text-center py-2 cursor-pointer;
|
||||
}
|
||||
|
||||
.selected_item {
|
||||
@apply ! bg- [ #0A1B37 ] ! text-white rounded-lg;
|
||||
}
|
||||
|
||||
//chart
|
||||
</style>
|
||||
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 2.2 MiB |
@@ -0,0 +1,89 @@
|
||||
<svg width="5043" height="2336" viewBox="0 0 5043 2336" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2505.15 1585.53C2468.54 1626.88 2405.34 1630.71 2363.99 1594.09L2087.2 1348.94L2608.04 760.86C2644.66 719.516 2707.86 715.685 2749.2 752.302L3026 997.454L2505.15 1585.53Z" fill="url(#paint0_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M1825.15 1585.53C1788.54 1626.88 1725.34 1630.71 1683.99 1594.09L1407.2 1348.94L1928.04 760.86C1964.66 719.516 2027.86 715.685 2069.2 752.302L2346 997.454L1825.15 1585.53Z" fill="url(#paint1_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M1118.96 1585.53C1082.34 1626.88 1019.14 1630.71 977.796 1594.09L701 1348.94L1221.85 760.86C1258.46 719.516 1321.66 715.685 1363.01 752.302L1639.81 997.454L1118.96 1585.53Z" fill="url(#paint2_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M417.958 1585.53C381.341 1626.88 318.14 1630.71 276.796 1594.09L0.000126013 1348.94L520.847 760.86C557.464 719.516 620.665 715.685 662.009 752.302L938.805 997.454L417.958 1585.53Z" fill="url(#paint3_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M2464.15 899.531C2427.54 940.875 2364.34 944.707 2322.99 908.089L2046.2 662.937L2567.04 74.8605C2603.66 33.5164 2666.86 29.6847 2708.2 66.3023L2985 311.454L2464.15 899.531Z" fill="url(#paint4_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M3092.16 922.531C3055.54 963.875 2992.34 967.707 2950.99 931.089L2674.2 685.937L3195.05 97.8605C3231.66 56.5164 3294.86 52.6847 3336.21 89.3023L3613 334.454L3092.16 922.531Z" fill="url(#paint5_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M1757.96 899.531C1721.34 940.875 1658.14 944.707 1616.8 908.089L1340 662.937L1860.85 74.8605C1897.46 33.5164 1960.66 29.6847 2002.01 66.3023L2278.81 311.454L1757.96 899.531Z" fill="url(#paint6_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M1056.96 899.531C1020.34 940.875 957.14 944.707 915.796 908.089L639 662.937L1159.85 74.8605C1196.46 33.5164 1259.66 29.6847 1301.01 66.3023L1577.81 311.454L1056.96 899.531Z" fill="url(#paint7_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M1238.15 2260.53C1201.54 2301.87 1138.34 2305.71 1096.99 2269.09L820.195 2023.94L1341.04 1435.86C1377.66 1394.52 1440.86 1390.68 1482.2 1427.3L1759 1672.45L1238.15 2260.53Z" fill="url(#paint8_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M3819.68 1588.03C3783.38 1629.65 3720.21 1633.96 3678.59 1597.66L3399.92 1354.64L3916.24 762.59C3952.54 720.967 4015.71 716.651 4057.34 752.951L4336 995.974L3819.68 1588.03Z" fill="url(#paint9_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M4525.76 1588.03C4489.46 1629.65 4426.29 1633.97 4384.67 1597.67L4106 1354.64L4622.33 762.591C4658.63 720.967 4721.79 716.651 4763.42 752.951L5042.08 995.975L4525.76 1588.03Z" fill="url(#paint10_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M1918.15 2260.53C1881.54 2301.88 1818.34 2305.71 1776.99 2269.09L1500.2 2023.94L2021.04 1435.86C2057.66 1394.52 2120.86 1390.68 2162.2 1427.3L2439 1672.45L1918.15 2260.53Z" fill="url(#paint11_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M531.958 2260.53C495.341 2301.87 432.14 2305.71 390.796 2269.09L114 2023.94L634.847 1435.86C671.464 1394.52 734.665 1390.68 776.009 1427.3L1052.81 1672.45L531.958 2260.53Z" fill="url(#paint12_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M3207.68 2255.03C3171.38 2296.65 3108.21 2300.96 3066.59 2264.66L2787.92 2021.64L3304.24 1429.59C3340.54 1387.97 3403.71 1383.65 3445.34 1419.95L3724 1662.97L3207.68 2255.03Z" fill="url(#paint13_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M3913.76 2255.03C3877.46 2296.65 3814.29 2300.97 3772.67 2264.67L3494 2021.64L4010.33 1429.59C4046.63 1387.97 4109.79 1383.65 4151.42 1419.95L4430.08 1662.97L3913.76 2255.03Z" fill="url(#paint14_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M2604.68 2212.03C2568.38 2253.65 2505.21 2257.96 2463.58 2221.66L2184.92 1978.64L2701.24 1386.59C2737.54 1344.97 2800.71 1340.65 2842.33 1376.95L3121 1619.97L2604.68 2212.03Z" fill="url(#paint15_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<path d="M3198.68 1533.03C3162.38 1574.65 3099.21 1578.96 3057.59 1542.66L2778.92 1299.64L3295.24 707.59C3331.54 665.967 3394.71 661.651 3436.34 697.951L3715 940.974L3198.68 1533.03Z" fill="url(#paint16_linear_338_9676)" fill-opacity="0.5"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_338_9676" x1="2263.02" y1="1504.66" x2="2850.17" y2="841.727" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_338_9676" x1="1583.02" y1="1504.66" x2="2170.17" y2="841.727" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_338_9676" x1="876.828" y1="1504.66" x2="1463.98" y2="841.727" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_338_9676" x1="175.828" y1="1504.66" x2="762.977" y2="841.727" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_338_9676" x1="2222.02" y1="818.664" x2="2809.17" y2="155.727" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_338_9676" x1="2850.03" y1="841.664" x2="3437.18" y2="178.727" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_338_9676" x1="1515.83" y1="818.664" x2="2102.98" y2="155.727" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_338_9676" x1="814.828" y1="818.664" x2="1401.98" y2="155.727" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_338_9676" x1="996.024" y1="2179.66" x2="1583.17" y2="1516.73" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_338_9676" x1="3576.94" y1="1509.02" x2="4158.99" y2="841.599" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_338_9676" x1="4283.02" y1="1509.02" x2="4865.07" y2="841.6" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_338_9676" x1="1676.02" y1="2179.66" x2="2263.17" y2="1516.73" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_338_9676" x1="289.828" y1="2179.66" x2="876.977" y2="1516.73" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint13_linear_338_9676" x1="2964.94" y1="2176.02" x2="3546.99" y2="1508.6" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#F5F5F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint14_linear_338_9676" x1="3671.02" y1="2176.02" x2="4253.07" y2="1508.6" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#F5F5F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint15_linear_338_9676" x1="2361.93" y1="2133.02" x2="2943.98" y2="1465.6" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#F5F5F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint16_linear_338_9676" x1="2955.94" y1="1454.02" x2="3537.99" y2="786.599" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F5F5F5"/>
|
||||
<stop offset="1" stop-color="#F5F5F5" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
@@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<div class="bg-white w-fit p-12 rounded-lg m-auto h-[35rem]" :class="[prefixCls]">
|
||||
<div class="logo flex justify-center w-full flex-col items-center">
|
||||
<img :src="getConfigApp('avatar')" class="w-[150px]" />
|
||||
</div>
|
||||
<a-tabs v-model:activeKey="activeKey" class="mt-15" centered>
|
||||
<a-tab-pane :key="1" tab="ورود با رمز یکبار مصرف">
|
||||
<a-form :model="userFormState" name="basic" @finish="onUserPassFormFinish">
|
||||
<a-form-item
|
||||
v-if="!showSMSVerify"
|
||||
label="شماره همراه"
|
||||
name="mobile"
|
||||
:rules="inputLenRules(11)"
|
||||
>
|
||||
<BasicInput v-model:value="userFormState.mobile" />
|
||||
</a-form-item>
|
||||
<AFormItem
|
||||
v-else
|
||||
class="error-token"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: 'کد ارسال شده را وارد نمایید'
|
||||
},
|
||||
{
|
||||
min: 4,
|
||||
max: 4,
|
||||
message: 'کد ارسال شده را وارد نمایید'
|
||||
}
|
||||
]"
|
||||
name="token"
|
||||
>
|
||||
<OtpInput
|
||||
style="direction: ltr"
|
||||
class="mt-5 justify-center"
|
||||
ref="refOtpInput"
|
||||
autocomplete="one-time-code"
|
||||
input-classes="otp-input"
|
||||
separator=""
|
||||
value=""
|
||||
:num-inputs="4"
|
||||
:should-auto-focus="true"
|
||||
:is-input-num="true"
|
||||
@on-change="handleOnChange"
|
||||
@on-complete="handleOnComplete"
|
||||
/>
|
||||
</AFormItem>
|
||||
<a-form-item>
|
||||
<BaseButton
|
||||
class="mt-5 w-full py-2"
|
||||
:disabled="loading"
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>ورود</div>
|
||||
</div>
|
||||
</BaseButton>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane :key="2" tab="ورود با نام کاربری" force-render>
|
||||
<a-form :model="userFormState" name="basic" @finish="onUserPassFormFinish">
|
||||
<a-form-item label="نام کاربری" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="userFormState.mobile" />
|
||||
</a-form-item>
|
||||
<a-form-item label="کلمه عبور" name="password" :rules="inputRules()">
|
||||
<BasicInput v-model:value="userFormState.password" is-password />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<BaseButton
|
||||
class="mt-5 w-full py-2"
|
||||
:disabled="loading"
|
||||
type="primary"
|
||||
html-type="submit"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>ورود</div>
|
||||
</div>
|
||||
</BaseButton>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { inputLenRules, inputRules } from '@/utils/inputRules'
|
||||
import { setToken } from '@/utils'
|
||||
import type { UserLoginState } from '@/model/login'
|
||||
import { Login, Verify } from '@/api/login'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
//import { getMyInformation } from '@/api/user'
|
||||
import OtpInput from 'vue3-otp-input'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { setupRoutes } from '@/router'
|
||||
import {getConfigApp} from "@/utils/config";
|
||||
|
||||
//define emit
|
||||
const emits = defineEmits(['enter'])
|
||||
const refOtpInput = ref<InstanceType<typeof VOtpInput> | null>(null)
|
||||
//router
|
||||
const router = useRouter()
|
||||
|
||||
//active tab
|
||||
const activeKey = ref<Number>(2)
|
||||
//const router = useRouter()
|
||||
//css style
|
||||
const { prefixCls } = usePrefix('login-panel')
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//step
|
||||
const showSMSVerify = ref<boolean>(false)
|
||||
|
||||
function handleOnChange(value: string) {
|
||||
userFormState.token = value
|
||||
// formRef.value?.validateFields()
|
||||
}
|
||||
|
||||
async function handleOnComplete(value: string) {
|
||||
userFormState.token = value
|
||||
await onUserPassFormFinish()
|
||||
}
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
//user pass form
|
||||
const userFormState = reactive<UserLoginState>({
|
||||
provider: 'user'
|
||||
})
|
||||
const onUserPassFormFinish = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
if (activeKey.value === 1) {
|
||||
if (!showSMSVerify.value) {
|
||||
userFormState.password = undefined
|
||||
const { id } = await Login(userFormState)
|
||||
userFormState.id = id
|
||||
showSMSVerify.value = true
|
||||
getcode()
|
||||
// await setToken(access_token)
|
||||
return
|
||||
} else {
|
||||
userFormState.mobile = undefined
|
||||
const { access_token } = await Verify(userFormState)
|
||||
await setToken(access_token)
|
||||
}
|
||||
} else {
|
||||
const { access_token } = await Login(userFormState)
|
||||
await setToken(access_token)
|
||||
}
|
||||
await userStore.getMyInfo()
|
||||
setupRoutes(['*'], router)
|
||||
// const info = await getMyInformation()
|
||||
// await setMyInfo(JSON.stringify(info))
|
||||
// emits('enter')
|
||||
//router.removeRoute({})
|
||||
/* if (userStore.isAdmin) {
|
||||
setupRoutes(['*'], router)
|
||||
} else {
|
||||
setupRoutes(userStore.permissions, router)
|
||||
}*/
|
||||
//router.removeRoute('usersMain')
|
||||
//router.removeRoute('users')
|
||||
await router.push({ name: 'dashboard' })
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
/* if (e?.response.status === 422) {
|
||||
message.error(e?.response?.data.message)
|
||||
} else {
|
||||
message.error('خطا در ورود به پنل کاربری')
|
||||
}*/
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/*const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo)
|
||||
}*/
|
||||
const getcode=()=>{
|
||||
if ('OTPCredential' in window) {
|
||||
console.log('run')
|
||||
const ac = new AbortController();
|
||||
navigator.credentials
|
||||
.get({
|
||||
otp: { transport: ['sms'] },
|
||||
signal: ac.signal,
|
||||
})
|
||||
.then((otp) => {
|
||||
console.log('otp recived');
|
||||
userFormState.token = otp?.code;
|
||||
refOtpInput.value.fillInput(otp?.code)
|
||||
onUserPassFormFinish();
|
||||
ac.abort();
|
||||
})
|
||||
.catch((err) => {
|
||||
ac.abort();
|
||||
console.log(err);
|
||||
});
|
||||
} else {
|
||||
console.log('not supported');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@prefix: ~'@{prefixCls}-login-panel';
|
||||
|
||||
.@{prefix} {
|
||||
.logo {
|
||||
width: 330px;
|
||||
height: 148px;
|
||||
}
|
||||
|
||||
.ant-tabs-rtl .ant-tabs-nav .ant-tabs-tab {
|
||||
//&:last-child {
|
||||
margin: 0;
|
||||
//}
|
||||
}
|
||||
|
||||
.ant-tabs > .ant-tabs-nav .ant-tabs-nav-list,
|
||||
.ant-tabs > div > .ant-tabs-nav .ant-tabs-nav-list {
|
||||
gap: 2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div
|
||||
:style="{ backgroundImage: `url(${bg1})` }"
|
||||
class="w-screen h-screen top-0 right-0 fixed bg-cover flex z-[1000]"
|
||||
>
|
||||
<LoginPanel @enter="enterTest" class="shadow-2xl" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import LoginPanel from './components/LoginPanel.vue'
|
||||
import bg1 from '../login/assets/img/loginBack.svg'
|
||||
|
||||
const emits = defineEmits(['enter'])
|
||||
|
||||
//login
|
||||
function enterTest() {
|
||||
emits('enter')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div :class="prefixCls">
|
||||
<BasicLayout>
|
||||
<transition>
|
||||
<login v-if="!loggedIn" @enter="loggedIn = true" />
|
||||
</transition>
|
||||
<!-- <Setting />-->
|
||||
<!-- <Customers />-->
|
||||
<!-- <Users />-->
|
||||
<Documents />
|
||||
</BasicLayout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BasicLayout from '../../core/layouts/BasicLayout'
|
||||
import Login from '../login'
|
||||
import { getToken } from '@/utils'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import Documents from '@/pages/dashboard/index.vue'
|
||||
|
||||
//css style
|
||||
const { prefixCls } = usePrefix('main')
|
||||
|
||||
//login
|
||||
const loggedIn = ref<Boolean>(true)
|
||||
|
||||
onBeforeMount(() => {
|
||||
loggedIn.value = !!getToken()
|
||||
console.log('sss', loggedIn.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@prefix: ~'@{prefixCls}-main';
|
||||
|
||||
.@{prefix} {
|
||||
.v-enter-active,
|
||||
.v-leave-active {
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
|
||||
.v-enter-from,
|
||||
.v-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="حسابداری">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<!-- <BaseButton v-if="!customerId" type="primary" size="small" class="flex" @click="emits('add')">-->
|
||||
<!-- <div>افزودن سفارش</div>-->
|
||||
<!-- <BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />-->
|
||||
<!-- </BaseButton>-->
|
||||
</template>
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('', record)">
|
||||
<template #title>
|
||||
<span>برداشت و واریز</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:stickynote" color="#10913A" />
|
||||
</a-tooltip>
|
||||
<a-tooltip placement="bottom" class="cursor-pointer" @click="handleOrderModal(record)">
|
||||
<template #title>
|
||||
<span>سفارشات</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:receipt-item" color="#10913A" />
|
||||
</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/accountingColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { getTotalAccountingTable } from '@/api/accounting'
|
||||
import {ref} from "vue";
|
||||
import {cloneDeep} from "lodash";
|
||||
|
||||
const showOrderModal = ref<boolean>(false)
|
||||
function handleOrderModal(record) {
|
||||
|
||||
showOrderModal.value = true
|
||||
}
|
||||
|
||||
|
||||
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'])
|
||||
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 getTotalAccountingTable(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,85 @@
|
||||
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: 'customer_to.name',
|
||||
key: 'customer_id',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'نام مشتری دعوت شده',
|
||||
dataIndex: 'customer.name',
|
||||
key: 'customer_id',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'زمان ثبت',
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
type: 'Text',
|
||||
customRender: (record: any) => {
|
||||
return toJalali(record.record.created_at)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'نقد',
|
||||
dataIndex: 'cash',
|
||||
key: 'cash',
|
||||
type: 'Number',
|
||||
// customRender(data) {
|
||||
// return usePrice(data.record?.price ?? 0, true, '')
|
||||
// }
|
||||
},
|
||||
{
|
||||
title: 'طلا',
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Number',
|
||||
},
|
||||
{
|
||||
title: 'توضیحات',
|
||||
dataIndex: 'note',
|
||||
key: 'note',
|
||||
type: 'Text',
|
||||
},
|
||||
{
|
||||
title: 'عملیات',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
slot: 'action',
|
||||
fixed: 'right',
|
||||
filterable: false
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,438 @@
|
||||
<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"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
<BasicModal
|
||||
v-model:visible="addOrderVisible"
|
||||
width="25rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} سفارش`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="stopGetPrice"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-1 gap-4">
|
||||
<div class="bg-gray-50 px-10 py-3 flex justify-center gap-4">
|
||||
<div>قیمت {{ form.direction === 1 ? 'خرید' : 'فروش' }} طلا:</div>
|
||||
<div class="font-bold">
|
||||
{{ usePrice(form.direction === 1 ? dataLast?.buy ?? 0 : dataLast?.sell ?? 0) }}
|
||||
</div>
|
||||
</div>
|
||||
<a-form-item label="نوع تراکنش" name="direction" :rules="inputRules()">
|
||||
<a-radio-group
|
||||
v-model:value="form.direction"
|
||||
button-style="solid"
|
||||
@change="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
|
||||
:label="`قیمت ${form.direction === 1 ? 'خرید' : 'فروش'} هر گرم`"
|
||||
name="price"
|
||||
:rules="inputRules()"
|
||||
>
|
||||
<BasicInput
|
||||
v-model:value="form.price"
|
||||
addon-before="ریال"
|
||||
type="price"
|
||||
@change="changePriceValue"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ سفارش" name="pay_at" :rules="inputRules()">
|
||||
<BaseDatePicker v-model:value="form.pay_at" format="YYYY-MM-DD HH:mm:ss" />
|
||||
</a-form-item>
|
||||
<a-form-item label="سود" name="difference" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.difference" addon-before="ریال" type="price" />
|
||||
</a-form-item>
|
||||
<div class="p-2 bg-orange-50 rounded-lg">
|
||||
<a-form-item label="انتخاب کاربر" name="customer_id" :rules="inputRules()">
|
||||
<BasicSelect
|
||||
v-model:value="form.customer_id"
|
||||
:items="userItems"
|
||||
valueName="name"
|
||||
keyName="id"
|
||||
@change="changeUser"
|
||||
/>
|
||||
</a-form-item>
|
||||
<BasicInfoItem
|
||||
is-line
|
||||
title="کیف پول طلا"
|
||||
class="mt-2"
|
||||
:value="selectedCustomer?.wallet[0]?.gold ?? '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
is-line
|
||||
title="کیف پول ریالی"
|
||||
class="mt-1"
|
||||
:value="selectedCustomer?.wallet[0]?.cash ?? '_'"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 bg-blue-50 p-2 rounded-lg">
|
||||
<div>مقدار {{ form.direction === 1 ? 'خرید' : 'فروش' }}:</div>
|
||||
<a-form-item name="goldCash" :rules="inputRulesNumber()">
|
||||
<BasicInput
|
||||
v-model:value="form.goldCash"
|
||||
addon-before="ریال"
|
||||
addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="ارزش کل"
|
||||
type="price"
|
||||
@onchange="calculateGold"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item name="goldValue" :rules="inputRulesNumber()">
|
||||
<BasicInput
|
||||
v-model:value="form.goldValue"
|
||||
addon-before="گرم"
|
||||
addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="مقدار طلا"
|
||||
type="tel"
|
||||
@onchange="calculateCash"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</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"
|
||||
/>
|
||||
</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 type { Order } from '@/model/order'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { getLastPrice } from '@/api/price'
|
||||
import type { last } from '@/model/price'
|
||||
import { createOrder } from '@/api/order'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
const userItems = ref<Customer[]>()
|
||||
const selectedCustomer = ref<Customer>()
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
async function getCustomers() {
|
||||
try {
|
||||
loading.value = true
|
||||
userItems.value = await getCustomersList()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCustomers()
|
||||
})
|
||||
|
||||
//form
|
||||
const form = ref<Order>({
|
||||
direction: 1,
|
||||
price: 0,
|
||||
amount: undefined,
|
||||
pay_at: '',
|
||||
difference: '',
|
||||
customer_id: undefined,
|
||||
goldCash: undefined,
|
||||
goldValue: undefined
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const dataLast = ref<last>()
|
||||
let interval: any
|
||||
|
||||
async function setIntervalGetPrice() {
|
||||
try {
|
||||
interval = setInterval(async () => {
|
||||
await getPrices()
|
||||
}, 10000)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function changePrice() {
|
||||
form.value.price = form.value.direction === 1 ? dataLast.value?.buy : dataLast.value?.sell
|
||||
}
|
||||
|
||||
async function getPrices() {
|
||||
try {
|
||||
// loading.value = true
|
||||
// const dataLast = await getLastPrice()
|
||||
dataLast.value = await getLastPrice()
|
||||
// form.value = dataLast
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
// loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function changeUser(val: Customer) {
|
||||
selectedCustomer.value = cloneDeep(val)
|
||||
console.log(selectedCustomer.value.wallet[0])
|
||||
}
|
||||
|
||||
function stopGetPrice() {
|
||||
clearInterval(interval)
|
||||
console.log('stop')
|
||||
}
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function info(val: Order) {
|
||||
infoParams.name = val.customer.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.amount ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت هر گرم طلا برای مشتری (ریال)',
|
||||
value: usePrice(val.price ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل برای مشتری (ریال)',
|
||||
value: usePrice(val.total_price ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت هر گرم طلا بدون سود (ریال)',
|
||||
value: usePrice(val.price_original ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل بدون سود (ریال)',
|
||||
value: usePrice(val.total_price_original ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود هر گرم (ریال)',
|
||||
value: usePrice(val.fee ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود کل (ریال)',
|
||||
value: usePrice(val.total_fee ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.customer.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.customer.n_code ?? '-'
|
||||
},
|
||||
/*{
|
||||
key: 'کارمزد ریالی',
|
||||
value: usePrice(val.service_charge_price ?? 0)
|
||||
},*/
|
||||
{
|
||||
key: 'کارمزد طلایی',
|
||||
value: val.service_charge ?? '-' + ' گرم'
|
||||
},
|
||||
/* {
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.customer.birth_date) ?? '-'
|
||||
},*/
|
||||
/* {
|
||||
key: 'نام فروشگاه',
|
||||
value: val.customer.shop_name ?? '-'
|
||||
},*/
|
||||
{
|
||||
key: 'شماره تلفن',
|
||||
value: val.customer.phone_number ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام استان',
|
||||
value: val.customer.province ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام شهر',
|
||||
value: val.customer.city ?? '-'
|
||||
}
|
||||
/* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*/
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
|
||||
function calculateCash(val: number) {
|
||||
// console.log(val)
|
||||
if (form.value.price) {
|
||||
if (form.value.direction === 1) {
|
||||
if (val >= 0.01) form.value.goldCash = parseFloat((val * form.value.price).toFixed(0))
|
||||
else form.value.goldCash = undefined
|
||||
} else {
|
||||
if (val >= 0.01) form.value.goldCash = parseFloat((val * form.value.price).toFixed(0))
|
||||
else form.value.goldCash = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateGold(val: number) {
|
||||
// console.log(val)
|
||||
// form.value.goldCash = usePriceWithoutType(form.value.goldCash)
|
||||
if (form.value.price) {
|
||||
if (form.value.direction === 1) {
|
||||
if (val / form.value.price >= 0.01)
|
||||
form.value.goldValue = toFixedDownTwoChar(parseFloat(val / form.value.price))
|
||||
else if (val.toString() === '') form.value.goldValue = undefined
|
||||
else form.value.goldValue = 0
|
||||
} else {
|
||||
if (val >= form.value.price)
|
||||
form.value.goldValue = toFixedDownTwoChar(parseFloat(val / form.value.price))
|
||||
else if (val.toString() === '') form.value.goldValue = undefined
|
||||
else form.value.goldValue = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function changePriceValue() {
|
||||
calculateCash(form.value.goldValue)
|
||||
}
|
||||
|
||||
function toFixedDownTwoChar(num) {
|
||||
return Math.floor(num * 100) / 100
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addOrderVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
resetData()
|
||||
addOrderVisible.value = true
|
||||
await getPrices()
|
||||
await setIntervalGetPrice()
|
||||
form.value.price = form.value.direction === 1 ? dataLast.value?.buy : dataLast.value?.sell
|
||||
updateKey.value++
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
direction: 1,
|
||||
price: 0,
|
||||
amount: undefined,
|
||||
pay_at: '',
|
||||
difference: '',
|
||||
customer_id: undefined,
|
||||
goldCash: undefined,
|
||||
goldValue: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const addOrderVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
form.value.amount = form.value.goldValue
|
||||
delete form.value.goldValue
|
||||
delete form.value.goldCash
|
||||
|
||||
await createOrder(form.value)
|
||||
message.success('سفارش با موفقیت ثبت شد')
|
||||
addOrderVisible.value = false
|
||||
resetData()
|
||||
refreshTable()
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست حساب ها">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<!-- <BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن مشتری عمده</div>
|
||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
||||
</BaseButton>-->
|
||||
</template>
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<a-tooltip
|
||||
:key="record.sts"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeAccountStsFunction(record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{ record.sts !== 2 ? 'فعال سازی' : 'غیر فعال سازی' }}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="record.sts !== 2 ? 'vuesax-linear:card-remove' : 'vuesax-linear:card-tick'"
|
||||
:color="record.sts !== 2 ? 'red' : 'green'"
|
||||
/>
|
||||
</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/cardColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { getOrderTable } from '@/api/order'
|
||||
import { getWithdrawTable } from '@/api/wallet'
|
||||
import { changeAccountSts, getAccountTable } from '@/api/card'
|
||||
import type { Card } from '@/model/card'
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'withdraw'])
|
||||
|
||||
const { prefixCls } = usePrefix('pophoverstatus')
|
||||
|
||||
//permission
|
||||
function checkPermission(temp: string) {
|
||||
const store = useUserStore()
|
||||
return store.canAccess(temp)
|
||||
}
|
||||
|
||||
async function changeAccountStsFunction(val: Card) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeAccountSts({ id: val.id, sts: val.sts !== 2 ? 2 : 3 })
|
||||
message.success(val.sts !== 2 ? 'با موفقیت تایید شد' : 'با موفقیت رد شد')
|
||||
reload()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
//define table
|
||||
const table = ref(null)
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
return getAccountTable(params)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
const loading = ref<boolean>(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,183 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { toJalaliNoTime, toTime } from '@core/utils/useDataTime'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
/*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: 'customer_id',
|
||||
key: 'customer_id',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'نام و نام خانوادگی',
|
||||
dataIndex: 'customer.name',
|
||||
key: 'customer.name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'نام بانک',
|
||||
dataIndex: 'bank_name',
|
||||
key: 'bank_name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره حساب',
|
||||
dataIndex: 'account_number',
|
||||
key: 'account_number',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'شماره کارت',
|
||||
dataIndex: 'cart_number',
|
||||
key: 'cart_number',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'شماره شبا',
|
||||
dataIndex: 'shaba_number',
|
||||
key: 'shaba_number',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'وضعیت',
|
||||
dataIndex: 'sts',
|
||||
key: 'sts',
|
||||
filterable: false,
|
||||
customRender: ({ record }) => {
|
||||
switch (record.sts) {
|
||||
case 1:
|
||||
return (
|
||||
<div class="flex justify-center font-bold">
|
||||
<CustomTag textColor="#ca8a04" bgColor="#fef3c7" class="px-2">
|
||||
{record.sts_str}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
case 2:
|
||||
return (
|
||||
<div class="flex justify-center font-bold px-2">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class="px-2">
|
||||
{record.sts_str}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
default:
|
||||
return (
|
||||
<div class="flex justify-center font-bold px-2">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class="px-2">
|
||||
{record.sts_str}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'تاریخ ثبت',
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
type: 'DateTime',
|
||||
customRender: (record: any) => {
|
||||
return toJalaliNoTime(record.record.created_at)
|
||||
}
|
||||
},
|
||||
/* {
|
||||
title: 'تاریخ تایید',
|
||||
dataIndex: 'updated_at',
|
||||
key: 'updated_at',
|
||||
type: 'DateTime',
|
||||
customRender: (record: any) => {
|
||||
return toJalaliNoTime(record.record.created_at)
|
||||
}
|
||||
},*/
|
||||
/*{
|
||||
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: 'action',
|
||||
key: 'action',
|
||||
slot: 'action',
|
||||
fixed: 'right',
|
||||
filterable: false
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicMainCard>
|
||||
<div class="flex w-full h-full">
|
||||
<tbl
|
||||
ref="table"
|
||||
class="w-full h-full"
|
||||
@edit="edit"
|
||||
@delete="deleteItem"
|
||||
@withdraw="openWithdraw"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
<!-- <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"
|
||||
/>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } from '@/utils/inputRules'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
import { ref } from 'vue'
|
||||
import { DatePicker } from 'ant-design-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, updateCustomer } from '@/api/customer'
|
||||
import type { Order } from '@/model/order'
|
||||
import type { Wallet, Withdraw } from '@/model/wallet'
|
||||
import { completeWithdraw } from '@/api/wallet'
|
||||
//import DatePicker from '@core/components/_sample/components/datePicker.vue'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//form
|
||||
const form = ref<Withdraw>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
/*
|
||||
function info(val: Order) {
|
||||
infoParams.name = val.customer.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.amount ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت هر گرم طلا برای مشتری (ریال)',
|
||||
value: val.price ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل برای مشتری (ریال)',
|
||||
value: val.total_price ?? '-'
|
||||
},
|
||||
{
|
||||
key: '/قیمت هر گرم طلا بدون سود (ریال)',
|
||||
value: val.price_original ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل بدون سود (ریال)',
|
||||
value: val.total_price_original ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود هر گرم (ریال)',
|
||||
value: val.fee ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود کل (ریال)',
|
||||
value: val.total_fee ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.customer.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.customer.n_code ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.customer.birth_date) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام فروشگاه',
|
||||
value: val.customer.shop_name ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره تلفن فروشگاه',
|
||||
value: val.customer.phone_number ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام استان',
|
||||
value: val.customer.province ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام شهر',
|
||||
value: val.customer.city ?? '-'
|
||||
}
|
||||
/!* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*!/
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
*/
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
confirmWithdrawVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
/*async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
confirmWithdrawVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}*/
|
||||
|
||||
function openWithdraw(val: number) {
|
||||
confirmWithdrawId = val
|
||||
confirmWithdrawVisible.value = true
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
tracked_number: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const confirmWithdrawVisible = ref<boolean>(false)
|
||||
let confirmWithdrawId: number
|
||||
// const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function okWithdraw() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
form.value.id = confirmWithdrawId
|
||||
await completeWithdraw(form.value)
|
||||
confirmWithdrawVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('شماره پیگیری با موفقیت تایید شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست مشتریان بایگانی شده">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<!-- <template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن مشتری عمده</div>
|
||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
||||
</BaseButton>
|
||||
</template>-->
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<a-tooltip :key="record.is_archive" placement="bottom" class="cursor-pointer">
|
||||
<template #title>
|
||||
<span>{{ record.is_archive ? 'بیرون بردن از بایگانی' : 'بایگانی کردن' }}</span>
|
||||
</template>
|
||||
<a-popconfirm
|
||||
title="آیا مشتری را از بایگانی خارج می کنید؟"
|
||||
ok-text="تایید"
|
||||
cancel-text="رد"
|
||||
placement="topLeft"
|
||||
@confirm="archiveFunction(record.id)"
|
||||
@cancel=""
|
||||
>
|
||||
<!-- <template #icon><question-circle-outlined style="color: red" /></template>-->
|
||||
<Icon class="cursor-pointer" icon="vuesax-linear:archive-slash" color="#e3bf00" />
|
||||
</a-popconfirm>
|
||||
</a-tooltip>
|
||||
|
||||
<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('delete', record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>حذف</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:trash" color="#EB3535" />
|
||||
</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,
|
||||
changeCustomerArchive,
|
||||
changeCustomerOrderActivation,
|
||||
getCustomerArchiveTable,
|
||||
getCustomerTable
|
||||
} from '@/api/customer'
|
||||
import { cols } from '../hooks/archiveColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'charge'])
|
||||
|
||||
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) => {
|
||||
return getCustomerArchiveTable(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
|
||||
}
|
||||
}
|
||||
|
||||
async function changeCustomerOrderActivationFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerOrderActivation(id)
|
||||
reload()
|
||||
message.success('تغییر وضعیت سفارش دهی با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
async function archiveFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerArchive(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,163 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { toJalaliNoTime, toTime } from '@core/utils/useDataTime'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
/*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: 'name',
|
||||
key: 'name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
},
|
||||
/* {
|
||||
title: 'نام',
|
||||
dataIndex: 'shop_name',
|
||||
key: 'shop_name',
|
||||
type: 'Text'
|
||||
},*/
|
||||
{
|
||||
title: 'وضعیت کاربر',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'وضعیت سفارش دهی',
|
||||
dataIndex: 'trade_active',
|
||||
key: 'trade_active',
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.trade_active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
/*{
|
||||
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
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <BasicMainCard>-->
|
||||
<div class="flex w-full h-full">
|
||||
<tbl ref="table" class="w-full h-full" @info="info" @edit="edit" @charge="walletCharge" />
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
<!-- </BasicMainCard>-->
|
||||
<BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="40rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} کاربر`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="نام" name="fname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام خانوادگی" name="lname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره همراه" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="form.mobile" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ تولد" name="birth_date" :rules="inputRules()">
|
||||
<BaseDatePicker v-model:value="form.birth_date" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="ایمیل" name="email" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.email" />
|
||||
</a-form-item>-->
|
||||
<!-- <a-form-item label="نام فروشگاه" name="shop_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.shop_name" />
|
||||
</a-form-item>-->
|
||||
<a-form-item label="شماره تلفن" name="phone_number" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.phone_number" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام استان" name="province" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.province" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام شهر" name="city" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.city" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره ملی" name="n_code" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.n_code" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</a-form-item>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
<BasicModal
|
||||
v-model:visible="userInfoVisible"
|
||||
width="40vw"
|
||||
title="اطلاعات کاربر"
|
||||
custom-footer
|
||||
@close="userInfoVisible = false"
|
||||
>
|
||||
<div class="grid grid-cols-4 gap-2">
|
||||
<div class="col-span-4 bg-gray-100 w-full rounded-lg flex p-3 justify-between">
|
||||
<div>
|
||||
<div class="font-bold">{{ userInfo.name }}</div>
|
||||
<div class="mt-1">{{ userInfo?.mobile }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ toJalaliNoTime(userInfo?.created_at) }}</div>
|
||||
<div class="mt-2">
|
||||
<CustomTag
|
||||
:textColor="userInfo?.active ? '#25855A' : '#C53030'"
|
||||
:bgColor="userInfo?.active ? '#E3F4E9' : '#FECACA'"
|
||||
class="font-bold px-6"
|
||||
>
|
||||
{{ userInfo?.active ? 'فعال' : 'غیرفعال' }}
|
||||
</CustomTag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
||||
<BasicInfoItem title="نوع کاربر" :value="userInfo?.type_str" />
|
||||
<BasicInfoItem
|
||||
title="تاریخ تولد"
|
||||
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="شماره ملی" :value="userInfo?.n_code ?? '_'" />
|
||||
<BasicInfoItem title="نام استان" :value="userInfo?.province ?? '_'" />
|
||||
<BasicInfoItem title="نام شهر" :value="userInfo?.city ?? '_'" />
|
||||
<BasicInfoItem title="سقف اعتبار" :value="userInfo?.gram ? `${userInfo?.gram} گرم` : '_'" />
|
||||
<BasicInfoItem title="کد معرف" :value="userInfo?.referral_id" />
|
||||
<BasicInfoItem
|
||||
title="کد معرف کاربر"
|
||||
:value="userInfo?.referral ? userInfo?.referral?.id : '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="نام معرف کاربر"
|
||||
:value="userInfo?.referral ? userInfo?.referral?.name : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="وضعیت سفارش دهی">
|
||||
<CustomTag
|
||||
:textColor="userInfo?.trade_active === 1 ? '#25855A' : '#C53030'"
|
||||
:bgColor="userInfo?.trade_active === 1 ? '#E3F4E9' : '#FECACA'"
|
||||
class="font-bold px-6"
|
||||
>
|
||||
{{ userInfo?.trade_active === 1 ? 'مجاز' : 'غیر مجاز' }}
|
||||
</CustomTag>
|
||||
</BasicInfoItem>
|
||||
<div class="col-span-4 grid grid-cols-2 gap-3">
|
||||
<div
|
||||
v-for="(item, index) in userInfo.wallet"
|
||||
:key="index"
|
||||
class="grid grid-cols-2 bg-orange-50 gap-2 rounded-lg p-2"
|
||||
>
|
||||
<BasicInfoItem
|
||||
title="نام قلک"
|
||||
:value="item?.fund ? item?.fund?.title : 'کیف پول طلایی'"
|
||||
/>
|
||||
<BasicInfoItem title="مقدار طلا" :value="`${item?.gold} گرم`" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BasicModal>
|
||||
|
||||
<BasicModal
|
||||
v-model:visible="showWalletCharge"
|
||||
width="30rem"
|
||||
title="شارژ کیف پول"
|
||||
@ok="charge"
|
||||
:loading="loading"
|
||||
@close="showWalletCharge = false"
|
||||
>
|
||||
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
|
||||
<a-form-item label="مقدار شارژ (ریال)" name="value" :rules="inputRules()">
|
||||
<BasicInput v-model:value="formCharge.value" type="number" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } 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, updateCustomer } from '@/api/customer'
|
||||
import type { Charge } from '@/model/wallet'
|
||||
import customers from '@/router/routes/customers'
|
||||
import { chargeWallet } from '@/api/wallet'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
|
||||
//wallet
|
||||
const showWalletCharge = ref<boolean>(false)
|
||||
|
||||
//form
|
||||
const form = ref<Customer>({})
|
||||
const formCharge = ref<Charge>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
const formChargeRef = ref<FormInstance>()
|
||||
const userInfo = ref<Customer>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function info(val: Customer) {
|
||||
userInfoVisible.value = true
|
||||
userInfo.value = cloneDeep(val)
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addUserVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
async function walletCharge(val: Customer) {
|
||||
showWalletCharge.value = true
|
||||
formCharge.value.customer_id = val.id
|
||||
}
|
||||
|
||||
async function charge() {
|
||||
formChargeRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await chargeMoneyWallet(formCharge.value)
|
||||
message.success('افزایش اعتبار با موفقیت انجام شد')
|
||||
showWalletCharge.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
active: false,
|
||||
avatar_id: undefined,
|
||||
sts: undefined,
|
||||
id: undefined,
|
||||
mobile: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
if (editId) {
|
||||
await updateCustomer(editId, form.value)
|
||||
} else {
|
||||
await createCustomer(form.value)
|
||||
}
|
||||
addUserVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست قلک ها">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
</BaseTable>
|
||||
</BasicShowContext>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type {TableInput} from '@core/type/baseTable'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import {
|
||||
changeCustomerActivation,
|
||||
changeCustomerArchive,
|
||||
changeCustomerOrderActivation,
|
||||
confirmUser,
|
||||
getCustomerTable
|
||||
} from '@/api/customer'
|
||||
import {cols} from '@/pages/menuPages/customers/base/hooks/fundsColumns'
|
||||
import {useUserStore} from '@/store/userStore'
|
||||
import {usePrefix} from '@core/composable/usePrefix'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {inputRules} from '@/utils/inputRules'
|
||||
import type {User} from '@/model/user'
|
||||
import {toJalaliNoTime} from '@core/utils/useDataTime'
|
||||
import type {Customer} from '@/model/customer'
|
||||
import {onMounted} from 'vue'
|
||||
import {getFundsTable} from "@/api/user";
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
|
||||
interface Prop {
|
||||
customerId?: number
|
||||
}
|
||||
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeMoney', 'chargeGold'])
|
||||
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 confirmVisible = ref<boolean>(false)
|
||||
const confirmInfo = ref<Customer>()
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
return getFundsTable(params, props.customerId)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
const refPop = ref()
|
||||
|
||||
const loading = ref<boolean>(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';
|
||||
.ant-popover,
|
||||
.ant-tooltip {
|
||||
z-index: 10 !important;
|
||||
}
|
||||
|
||||
.@{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,104 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست معرفی کرده ها">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
</BaseTable>
|
||||
</BasicShowContext>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type {TableInput} from '@core/type/baseTable'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import {
|
||||
changeCustomerActivation,
|
||||
changeCustomerArchive,
|
||||
changeCustomerOrderActivation,
|
||||
confirmUser,
|
||||
getCustomerTable
|
||||
} from '@/api/customer'
|
||||
import {cols} from '@/pages/menuPages/customers/base/hooks/referralColumns'
|
||||
import {useUserStore} from '@/store/userStore'
|
||||
import {usePrefix} from '@core/composable/usePrefix'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {inputRules} from '@/utils/inputRules'
|
||||
import type {User} from '@/model/user'
|
||||
import {toJalaliNoTime} from '@core/utils/useDataTime'
|
||||
import type {Customer} from '@/model/customer'
|
||||
import {onMounted} from 'vue'
|
||||
import {getReferralsTable} from "@/api/user";
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
|
||||
interface Prop {
|
||||
customerId?: number
|
||||
}
|
||||
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeMoney', 'chargeGold'])
|
||||
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 confirmVisible = ref<boolean>(false)
|
||||
const confirmInfo = ref<Customer>()
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
|
||||
return getReferralsTable(params, props.customerId)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
const refPop = ref()
|
||||
|
||||
const loading = ref<boolean>(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';
|
||||
.ant-popover,
|
||||
.ant-tooltip {
|
||||
z-index: 10 !important;
|
||||
}
|
||||
|
||||
.@{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,425 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title=" لیست مشتریان">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن مشتری</div>
|
||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
||||
</BaseButton>
|
||||
</template>
|
||||
<template #action="{ column, record }">
|
||||
<div class="md:hidden">
|
||||
<a-popover title="" placement="right" @cancel="">
|
||||
<template #content>
|
||||
<div class="flex flex-col gap-3">
|
||||
<a-tooltip :key="record.is_archive" placement="bottom" class="cursor-pointer">
|
||||
<template #title>
|
||||
<span>{{
|
||||
record.is_archive ? 'بیرون بردن از بایگانی' : 'بایگانی کردن'
|
||||
}}</span>
|
||||
</template>
|
||||
<a-popconfirm
|
||||
title="آیا مشتری را بایگانی می کنید؟"
|
||||
ok-text="تایید"
|
||||
cancel-text="رد"
|
||||
placement="topLeft"
|
||||
@confirm="archiveFunction(record.id)"
|
||||
@cancel=""
|
||||
>
|
||||
<!-- <template #icon><question-circle-outlined style="color: red" /></template>-->
|
||||
<Icon
|
||||
class="cursor-pointer"
|
||||
icon="vuesax-linear:archive-tick"
|
||||
color="#e3bf00"
|
||||
/>
|
||||
</a-popconfirm>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:key="record.active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>
|
||||
{{ record.active ? 'غیرفعال کردن حساب کاربری' : 'فعال کردن حساب کاربری' }}
|
||||
</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="
|
||||
record.active ? 'vuesax-linear:user-tick' : 'vuesax-linear:user-remove'
|
||||
"
|
||||
:color="record.active ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('chargeMoney', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>شارژ کیف پول ریالی</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:wallet-add" color="#9333ea" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('chargeGold', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>شارژ کیف پول طلایی</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:wallet-money" color="#ea580c" />
|
||||
</a-tooltip>
|
||||
<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('edit', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:key="record.trade_active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerOrderActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>
|
||||
{{
|
||||
record.trade_active ? 'غیر مجاز کردن سفارش دهی' : 'مجاز کردن سفارش دهی'
|
||||
}}
|
||||
</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="
|
||||
record.trade_active === 1
|
||||
? 'vuesax-linear:box-tick'
|
||||
: 'vuesax-linear:box-remove'
|
||||
"
|
||||
:color="record.trade_active === 1 ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="!record.is_legal"
|
||||
:key="record.trade_active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="openConfirmUser(record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>تایید کاربر</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:user-search" color="#0d9488" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<!-- <template #icon><question-circle-outlined style="color: red" /></template>-->
|
||||
<Icon class="cursor-pointer" icon="vuesax-linear:setting" color="#000" />
|
||||
</a-popover>
|
||||
</div>
|
||||
<div class="gap-2 hidden md:flex justify-center">
|
||||
<a-tooltip :key="record.is_archive" placement="bottom" class="cursor-pointer">
|
||||
<template #title>
|
||||
<span>{{ record.is_archive ? 'بیرون بردن از بایگانی' : 'بایگانی کردن' }}</span>
|
||||
</template>
|
||||
<a-popconfirm
|
||||
title="آیا مشتری را بایگانی می کنید؟"
|
||||
ok-text="تایید"
|
||||
cancel-text="رد"
|
||||
placement="topLeft"
|
||||
@confirm="archiveFunction(record.id)"
|
||||
@cancel=""
|
||||
>
|
||||
<!-- <template #icon><question-circle-outlined style="color: red" /></template>-->
|
||||
<Icon class="cursor-pointer" icon="vuesax-linear:archive-tick" color="#e3bf00" />
|
||||
</a-popconfirm>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:key="record.active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{
|
||||
record.active ? 'غیرفعال کردن حساب کاربری' : 'فعال کردن حساب کاربری'
|
||||
}}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="record.active ? 'vuesax-linear:user-tick' : 'vuesax-linear:user-remove'"
|
||||
:color="record.active ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('chargeMoney', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>شارژ کیف پول ریالی</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:wallet-add" color="#9333ea" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('chargeGold', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>شارژ کیف پول طلایی</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:wallet-money" color="#ea580c" />
|
||||
</a-tooltip>
|
||||
<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('edit', record)">
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:key="record.trade_active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerOrderActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{
|
||||
record.trade_active ? 'غیر مجاز کردن سفارش دهی' : 'مجاز کردن سفارش دهی'
|
||||
}}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="
|
||||
record.trade_active === 1 ? 'vuesax-linear:box-tick' : 'vuesax-linear:box-remove'
|
||||
"
|
||||
:color="record.trade_active === 1 ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="!record.is_legal"
|
||||
:key="record.trade_active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="openConfirmUser(record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>تایید کاربر</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:user-search" color="#0d9488" />
|
||||
</a-tooltip>
|
||||
<!-- <a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('delete', record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>حذف</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:trash" color="#EB3535" />
|
||||
</a-tooltip>-->
|
||||
</div>
|
||||
</template>
|
||||
</BaseTable>
|
||||
<BasicModal
|
||||
v-model:visible="confirmVisible"
|
||||
width="50vw"
|
||||
title="تایید مشتری"
|
||||
@ok="confirmUserFunction"
|
||||
ok-text="تایید"
|
||||
:loading="loading"
|
||||
@close="confirmVisible = false"
|
||||
>
|
||||
<div class="mt-[-10px] mb-10 font-bold">آیا از اطلاعات وارد شده اطمینان دارید؟</div>
|
||||
<div class="grid grid-cols-4 gap-2">
|
||||
<BasicInfoItem title="نام و نام خانوادگی" :value="confirmInfo?.name" />
|
||||
<BasicInfoItem title="شماره همراه" :value="confirmInfo?.mobile" />
|
||||
<BasicInfoItem
|
||||
title="تاریخ تولد"
|
||||
:value="confirmInfo?.birth_date ? toJalaliNoTime(confirmInfo?.birth_date) : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="شماره تلفن" :value="confirmInfo?.phone_number ?? '_'" />
|
||||
<BasicInfoItem title="نام استان" :value="confirmInfo?.province" />
|
||||
<BasicInfoItem title="نام شهر" :value="confirmInfo?.city" />
|
||||
<BasicInfoItem title="شماره ملی" :value="confirmInfo?.n_code" />
|
||||
</div>
|
||||
</BasicModal>
|
||||
</BasicShowContext>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type { TableInput } from '@core/type/baseTable'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import {
|
||||
changeCustomerActivation,
|
||||
changeCustomerArchive,
|
||||
changeCustomerOrderActivation,
|
||||
confirmUser,
|
||||
getCustomerTable
|
||||
} from '@/api/customer'
|
||||
import { cols } from '@/pages/menuPages/customers/base/hooks/customerColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { inputRules } from '@/utils/inputRules'
|
||||
import type { User } from '@/model/user'
|
||||
import { toJalaliNoTime } from '@core/utils/useDataTime'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import { onMounted } from 'vue'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeMoney', 'chargeGold'])
|
||||
|
||||
const { prefixCls } = usePrefix('pophoverstatus')
|
||||
|
||||
//permission
|
||||
function checkPermission(temp: string) {
|
||||
const store = useUserStore()
|
||||
return store.canAccess(temp)
|
||||
}
|
||||
|
||||
//define table
|
||||
const table = ref(null)
|
||||
|
||||
const confirmVisible = ref<boolean>(false)
|
||||
const confirmInfo = ref<Customer>()
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
return getCustomerTable(params)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
const refPop = ref()
|
||||
|
||||
// function edit(recordId){
|
||||
// emits('edit', recordId);
|
||||
// console.log( recordId);
|
||||
// console.log( visibleAction.value[parseInt(recordId)]);
|
||||
// visibleAction.value[recordId]=false
|
||||
// console.log('ddddd')
|
||||
// }
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
function openConfirmUser(user: Customer) {
|
||||
confirmInfo.value = user
|
||||
confirmVisible.value = true
|
||||
}
|
||||
|
||||
async function archiveFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerArchive(id)
|
||||
reload()
|
||||
message.success('مشتری با موفقیت بایگانی شد.')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmUserFunction() {
|
||||
try {
|
||||
loading.value = true
|
||||
await confirmUser(confirmInfo.value?.id)
|
||||
reload()
|
||||
confirmVisible.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function changeCustomerOrderActivationFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerOrderActivation(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';
|
||||
.ant-popover,
|
||||
.ant-tooltip {
|
||||
z-index: 10 !important;
|
||||
}
|
||||
|
||||
.@{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,214 @@
|
||||
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: 'name',
|
||||
key: 'name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'نوع کاربر',
|
||||
dataIndex: 'type_str',
|
||||
key: 'type_str',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'کد معرف',
|
||||
dataIndex: 'referral_id',
|
||||
key: 'referral_id',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'نام معرف کاربر',
|
||||
dataIndex: 'referral.name',
|
||||
key: 'referral.name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'موجودی ریالی (ریال)',
|
||||
dataIndex: 'wallet.cash',
|
||||
key: 'wallet.cash',
|
||||
type: 'Number',
|
||||
customRender(data) {
|
||||
return usePrice(data.record?.wallet[0]?.cash ?? 0, true, '')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'موجودی طلایی (گرم)',
|
||||
dataIndex: 'wallet.gold',
|
||||
key: 'wallet.gold',
|
||||
type: 'Number',
|
||||
filterable: false,
|
||||
customRender(data) {
|
||||
let sum = 0
|
||||
data.record.wallet.forEach((x) => (sum += x.gold))
|
||||
return sum.toFixed(3)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'اخرین بازدید',
|
||||
dataIndex: 'last_seen_at',
|
||||
key: 'last_seen_at',
|
||||
type: 'DateTime',
|
||||
customRender(data) {
|
||||
return toJalali(data.record.last_seen_at)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'گنج(گرم)',
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Number',
|
||||
filterable: false,
|
||||
},
|
||||
{
|
||||
title: 'وضعیت کاربر',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'وضعیت سفارش دهی',
|
||||
dataIndex: 'trade_active',
|
||||
key: 'trade_active',
|
||||
sortable: false,
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.trade_active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
/*{
|
||||
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
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { 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: 'fund.title',
|
||||
key: 'fund.title',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'موجودی طلا',
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Number'
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,163 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { 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: 'name',
|
||||
key: 'name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'نوع کاربر',
|
||||
dataIndex: 'type_str',
|
||||
key: 'type_str',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'کد معرف',
|
||||
dataIndex: 'referral_id',
|
||||
key: 'referral_id',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'وضعیت کاربر',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'وضعیت سفارش دهی',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
customRender: ({ record }) => {
|
||||
return record.trade_active === 1 ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
/*{
|
||||
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)
|
||||
}
|
||||
},*/
|
||||
]
|
||||
@@ -0,0 +1,598 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <BasicMainCard>-->
|
||||
<div class="flex w-full h-full">
|
||||
<tbl
|
||||
ref="table"
|
||||
class="w-full h-full"
|
||||
@info="info"
|
||||
@edit="edit"
|
||||
@add="add"
|
||||
@chargeMoney="walletMoneyCharge"
|
||||
@chargeGold="walletGoldCharge"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
<!-- </BasicMainCard>-->
|
||||
<BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="40rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} کاربر`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="نام" name="fname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام خانوادگی" name="lname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره همراه" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="form.mobile" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="پسورد" name="password">
|
||||
<BasicInput is-password v-model:value="form.password" />
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ تولد" name="birth_date">
|
||||
<BaseDatePicker v-model:value="form.birth_date" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="ایمیل" name="email" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.email" />
|
||||
</a-form-item>-->
|
||||
<!-- <a-form-item label="نام" name="shop_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.shop_name" />
|
||||
</a-form-item>-->
|
||||
<a-form-item label="شماره تلفن" name="phone_number">
|
||||
<BasicInput v-model:value="form.phone_number" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام استان" name="province">
|
||||
<BasicInput v-model:value="form.province" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام شهر" name="city">
|
||||
<BasicInput v-model:value="form.city" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره ملی" name="n_code">
|
||||
<BasicInput v-model:value="form.n_code" />
|
||||
</a-form-item>
|
||||
<a-form-item label="میزان پاداش" name="profit_amount">
|
||||
<BasicInput v-model:value="form.profit_amount" />
|
||||
</a-form-item>
|
||||
<a-form-item label="گنج" name="gold">
|
||||
<BasicInput v-model:value="form.gold" />
|
||||
</a-form-item>
|
||||
<a-form-item label="حداکثر معرفی" name="add_user_limit">
|
||||
<BasicInput v-model:value="form.add_user_limit" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نوع مشتری" name="n_code">
|
||||
<BasicSelect
|
||||
v-model:value="form.type"
|
||||
:items="customerItems"
|
||||
valueName="value"
|
||||
keyName="key"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="کد معرف" name="n_code">
|
||||
<BasicInput v-model:value="form.referral_to_id" :disabled="editId" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="editId" label="سقف اعتبار" name="gram" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.gram" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</a-form-item>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
<BasicModal
|
||||
v-model:visible="userInfoVisible"
|
||||
width="100vw"
|
||||
title="اطلاعات کاربر"
|
||||
:loading="loading"
|
||||
custom-footer
|
||||
@close="userInfoVisible = false"
|
||||
>
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane key="اطلاعات جامع" tab="اطلاعات جامع">
|
||||
<div class="grid grid-cols-4 gap-2">
|
||||
<div class="col-span-4 bg-gray-100 w-full rounded-lg flex p-3 justify-between">
|
||||
<div>
|
||||
<div class="font-bold">{{ userInfo.name }}</div>
|
||||
<div class="mt-1">{{ userInfo?.mobile }}</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center items-center pl-3">
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
<Icon
|
||||
:icon="
|
||||
userInfo.is_legal === 0
|
||||
? 'vuesax-linear:close-circle'
|
||||
: 'vuesax-linear:verify'
|
||||
"
|
||||
:key="userInfo.is_legal"
|
||||
:color="userInfo.is_legal === 0 ? '#ff0000' : '#008000'"
|
||||
/>
|
||||
<p
|
||||
class="text-[11px] mt-2"
|
||||
:class="userInfo.is_legal === 0 ? 'reject' : 'success'"
|
||||
>
|
||||
{{ userStatus(userInfo.is_legal).title }}
|
||||
</p>
|
||||
</div>
|
||||
<div>{{ toJalaliNoTime(userInfo?.created_at) }}</div>
|
||||
<div class="mt-2">
|
||||
<CustomTag
|
||||
:textColor="userInfo?.active ? '#25855A' : '#C53030'"
|
||||
:bgColor="userInfo?.active ? '#E3F4E9' : '#FECACA'"
|
||||
class="font-bold px-6"
|
||||
>
|
||||
{{ userInfo?.active ? 'فعال' : 'غیرفعال' }}
|
||||
</CustomTag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
||||
<BasicInfoItem title="نوع کاربر" :value="userInfo?.type_str" />
|
||||
<BasicInfoItem
|
||||
title="تاریخ تولد"
|
||||
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="شماره ملی" :value="userInfo?.n_code ?? '_'" />
|
||||
<BasicInfoItem title="نام استان" :value="userInfo?.province ?? '_'" />
|
||||
<BasicInfoItem title="نام شهر" :value="userInfo?.city ?? '_'" />
|
||||
<BasicInfoItem
|
||||
title="سقف اعتبار"
|
||||
:value="userInfo?.gram ? `${userInfo?.gram} گرم` : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="کد معرف" :value="userInfo?.referral_id" />
|
||||
<BasicInfoItem
|
||||
title="کد معرف کاربر"
|
||||
:value="userInfo?.referral ? userInfo?.referral?.id : '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="نام معرف کاربر"
|
||||
:value="userInfo?.referral ? userInfo?.referral?.name : '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="میزان سود معرفی"
|
||||
:value="userInfo?.profit_amount ? `${userInfo?.profit_amount} گرم` : '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="حداکثر معرفی"
|
||||
:value="userInfo?.add_user_limit ? `${userInfo?.add_user_limit} نفر` : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="آخرین بازدید" :value="toJalali(userInfo?.last_seen_at)" />
|
||||
<BasicInfoItem title="وضعیت سفارش دهی">
|
||||
<CustomTag
|
||||
:textColor="userInfo?.trade_active === 1 ? '#25855A' : '#C53030'"
|
||||
:bgColor="userInfo?.trade_active === 1 ? '#E3F4E9' : '#FECACA'"
|
||||
class="font-bold px-6"
|
||||
>
|
||||
{{ userInfo?.trade_active === 1 ? 'مجاز' : 'غیر مجاز' }}
|
||||
</CustomTag>
|
||||
</BasicInfoItem>
|
||||
<div class="col-span-4 grid grid-cols-2 gap-3">
|
||||
<div
|
||||
v-for="(item, index) in userInfo.wallet"
|
||||
:key="index"
|
||||
class="grid grid-cols-2 bg-orange-50 gap-2 rounded-lg p-2"
|
||||
>
|
||||
<BasicInfoItem
|
||||
title="نام قلک"
|
||||
:value="item?.fund ? item?.fund?.title : 'کیف پول طلایی'"
|
||||
/>
|
||||
<BasicInfoItem title="مقدار طلا" :value="`${item?.gold} گرم`" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="لیست سفارشات" tab="لیست سفارشات">
|
||||
<orders-tbl ref="orderTable" :customerId="userInfo?.id" @info="infoOrder" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="لیست تراکنش ها" tab="لیست تراکنش ها">
|
||||
<transactions-tbl ref="transactionTable" :customerId="userInfo?.id" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="پیامک ها" tab="پیامک ها">
|
||||
<sms-tbl ref="smsTable" :mobile="userInfo?.mobile" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="معرفی کرده ها" tab="معرفی کرده ها">
|
||||
<ReferralsTable ref="referralTable" :customerId="userInfo?.id" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="قلک ها" tab="قلک ها">
|
||||
<FundsTable ref="fundTable" :customerId="userInfo?.id" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</BasicModal>
|
||||
<BasicModal
|
||||
v-model:visible="showMoneyWalletCharge"
|
||||
width="20rem"
|
||||
title="شارژ کیف پول ریالی"
|
||||
@ok="chargeMoneyWallet"
|
||||
:loading="loading"
|
||||
@close="showMoneyWalletCharge = false"
|
||||
>
|
||||
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
|
||||
<a-form-item label="مقدار شارژ " name="value" :rules="inputRules()">
|
||||
<BasicInput addon-before="ریال" v-model:value="formCharge.value" type="price" />
|
||||
<div v-show="formCharge.value > 10">
|
||||
معادل {{ usePrice(formCharge.value / 10, true, 'تومان') }}
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item label="علت شارژ " name="value" :rules="inputRules()">
|
||||
<BasicInput v-model:value="formCharge.note" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
|
||||
<BasicModal
|
||||
v-model:visible="showGoldWalletCharge"
|
||||
width="20rem"
|
||||
title="شارژ کیف پول طلایی"
|
||||
@ok="chargeGoldWallet"
|
||||
:loading="loading"
|
||||
@close="showGoldWalletCharge = false"
|
||||
>
|
||||
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
|
||||
<a-form-item label="مقدار شارژ " name="value" :rules="inputRules()">
|
||||
<BasicInput addon-before="گرم" v-model:value="formCharge.value" type="number" />
|
||||
<!-- <div v-show="formCharge.value > 10">
|
||||
معادل {{ usePrice(formCharge.value / 10, true, 'تومان') }}
|
||||
</div>-->
|
||||
</a-form-item>
|
||||
<a-form-item label="علت شارژ " name="value" :rules="inputRules()">
|
||||
<BasicInput v-model:value="formCharge.note" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
<BasicInfoModal
|
||||
v-model:visible="userInfoOrderVisible"
|
||||
@close="userInfoOrderVisible = false"
|
||||
:title="infoParams.title"
|
||||
:date="infoParams.date"
|
||||
:time="infoParams.time"
|
||||
:type="infoParams.type"
|
||||
:name="infoParams.name"
|
||||
:items="infoParams.items"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } from '@/utils/inputRules'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
import { ref, watch } 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 { toJalali, 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, updateCustomer } from '@/api/customer'
|
||||
import type { Charge } from '@/model/wallet'
|
||||
import customers from '@/router/routes/customers'
|
||||
import { chargeWallet } from '@/api/wallet'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import jalaliday from 'jalaliday'
|
||||
import ordersTbl from '@/pages/menuPages/orders/components/table.vue'
|
||||
import transactionsTbl from '@/pages/menuPages/transactions/components/table.vue'
|
||||
import smsTbl from '@/pages/menuPages/sms/components/table.vue'
|
||||
import FundsTable from '@/pages/menuPages/customers/base/components/fundsTable.vue'
|
||||
import ReferralsTable from '@/pages/menuPages/customers/base/components/referralsTable.vue'
|
||||
import type { Order } from '@/model/order'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
|
||||
//tabs
|
||||
const activeKey = ref('اطلاعات جامع')
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const orderTable = ref(null)
|
||||
const transactionTable = ref(null)
|
||||
const smsTable = ref(null)
|
||||
const referralTable = ref(null)
|
||||
const fundTable = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
const refreshOrderTable = () => orderTable?.value?.fetch()
|
||||
const refreshTransactionTable = () => transactionTable?.value?.fetch()
|
||||
const refreshSMSTable = () => smsTable?.value?.fetch()
|
||||
const refreshReferralTable = () => referralTable?.value?.fetch()
|
||||
const refreshFundTable = () => fundTable?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
const customerItems: Array<Item> = [
|
||||
{
|
||||
value: 'همکار',
|
||||
key: 1
|
||||
},
|
||||
{
|
||||
value: 'خانگی',
|
||||
key: 2
|
||||
},
|
||||
{
|
||||
value: 'سرمایه گذار',
|
||||
key: 3
|
||||
}
|
||||
]
|
||||
|
||||
//wallet
|
||||
const showMoneyWalletCharge = ref<boolean>(false)
|
||||
const showGoldWalletCharge = ref<boolean>(false)
|
||||
const userInfoOrderVisible = ref<boolean>(false)
|
||||
|
||||
//form
|
||||
const form = ref<Partial<Customer>>({})
|
||||
const formCharge = ref<Charge>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
const formChargeRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function infoOrder(val: Order) {
|
||||
infoParams.name = val.customer.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.amount ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت هر گرم طلا برای مشتری (ریال)',
|
||||
value: usePrice(val.price ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل برای مشتری (ریال)',
|
||||
value: usePrice(val.total_price ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: '/قیمت هر گرم طلا بدون سود (ریال)',
|
||||
value: usePrice(val.price_original ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل بدون سود (ریال)',
|
||||
value: usePrice(val.total_price_original ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود هر گرم (ریال)',
|
||||
value: usePrice(val.fee ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود کل (ریال)',
|
||||
value: usePrice(val.total_fee ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.customer.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.customer.n_code ?? '-'
|
||||
},
|
||||
/*{
|
||||
key: 'کارمزد ریالی',
|
||||
value: usePrice(val.service_charge_price ?? 0)
|
||||
},*/
|
||||
{
|
||||
key: 'کارمزد طلایی',
|
||||
value: val.service_charge ?? '-' + ' گرم'
|
||||
},
|
||||
/* {
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.customer.birth_date) ?? '-'
|
||||
},*/
|
||||
/* {
|
||||
key: 'نام فروشگاه',
|
||||
value: val.customer.shop_name ?? '-'
|
||||
},*/
|
||||
{
|
||||
key: 'شماره تلفن',
|
||||
value: val.customer.phone_number ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام استان',
|
||||
value: val.customer.province ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام شهر',
|
||||
value: val.customer.city ?? '-'
|
||||
}
|
||||
/* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*/
|
||||
]
|
||||
userInfoOrderVisible.value = true
|
||||
}
|
||||
|
||||
async function info(val: Customer) {
|
||||
activeKey.value = 'اطلاعات جامع'
|
||||
userInfo.value = cloneDeep(val)
|
||||
userInfoVisible.value = true
|
||||
await nextTick(() => {
|
||||
loading.value = true
|
||||
refreshFundTable()
|
||||
refreshReferralTable()
|
||||
refreshSMSTable()
|
||||
refreshTransactionTable()
|
||||
refreshOrderTable()
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addUserVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
async function walletMoneyCharge(val: Customer) {
|
||||
showMoneyWalletCharge.value = true
|
||||
formCharge.value.customer_id = val.id
|
||||
}
|
||||
|
||||
async function walletGoldCharge(val: Customer) {
|
||||
showGoldWalletCharge.value = true
|
||||
formCharge.value.customer_id = val.id
|
||||
}
|
||||
|
||||
async function chargeMoneyWallet() {
|
||||
formChargeRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await chargeWallet(formCharge.value, 'money')
|
||||
formCharge.value.value = undefined
|
||||
message.success('افزایش اعتبار با موفقیت انجام شد')
|
||||
showMoneyWalletCharge.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function chargeGoldWallet() {
|
||||
formChargeRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await chargeWallet(formCharge.value, 'gold')
|
||||
formCharge.value.value = undefined
|
||||
message.success('افزایش اعتبار با موفقیت انجام شد')
|
||||
showMoneyWalletCharge.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
active: false,
|
||||
avatar_id: undefined,
|
||||
sts: undefined,
|
||||
id: undefined,
|
||||
mobile: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
const userInfo = ref<Customer>()
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
if (editId) {
|
||||
await updateCustomer(editId, form.value)
|
||||
} else {
|
||||
await createCustomer(form.value)
|
||||
}
|
||||
addUserVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
const result = {
|
||||
title: ''
|
||||
}
|
||||
const userStatus = (status: number) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
result.title = 'احراز هویت نشده'
|
||||
break
|
||||
case 1:
|
||||
result.title = 'احراز هویت شده توسط سامانه هوشمند'
|
||||
break
|
||||
case 2:
|
||||
result.title = 'احراز هویت شده توسط کارشناس'
|
||||
break
|
||||
}
|
||||
return result
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.reject {
|
||||
color: #ff0000 !important;
|
||||
}
|
||||
.success {
|
||||
color: #008000 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicMainCard>
|
||||
<div class="flex flex-col md:flex-row md:h-full">
|
||||
<!-- {{ menu }}-->
|
||||
<BasicMenu width="11rem" :menu="menu" mode="horizontal" class="md:hidden overflow-auto" />
|
||||
<BasicMenu
|
||||
width="13rem"
|
||||
:menu="menu"
|
||||
class="hidden md:inline overflow-auto min-w-[13.5rem]"
|
||||
/>
|
||||
<!-- <component :is="selectedComponent" class="mr-5" />-->
|
||||
<RouterView class="md:mr-5 md:mt-0 mt-5 w-full"></RouterView>
|
||||
</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 Nature from '@/pages/menuPages/setting/limitedOrder/index.vue'
|
||||
//s import test from './limitedOrder'
|
||||
//import Budget from '@/pages/menuPages/setting/budget/index.vue'
|
||||
//import ProjectType from '@/pages/menuPages/setting/projectType/index.vue'
|
||||
//import DocumentType from '@/pages/menuPages/setting/documentType/index.vue'
|
||||
// import Management from '@/pages/menuPages/setting/management/index.vue'
|
||||
//import Accessibility from '@/pages/menuPages/setting/accessibility/index.vue'
|
||||
//import SubmitProcess from '@/pages/menuPages/setting/submitProcess/index.vue'
|
||||
//import documentGroup from '@/pages/menuPages/setting/documentGroup/index.vue'
|
||||
//import userType from '@/pages/menuPages/setting/userType/index.vue'
|
||||
|
||||
const routerStore = useRouterStore()
|
||||
const menu = computed(() => {
|
||||
const item = routerStore.routes.find((item) => item.name === 'customers')
|
||||
//console.log('aaaa', get(item, 'children[0].children', []))
|
||||
return get(item, 'children[0].children', [])
|
||||
})
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,5 @@
|
||||
<template></template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست سفارشات">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<BaseButton v-if="!customerId" type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن سفارش</div>
|
||||
<BaseIcon icon="vuesax-linear:receipt-add" Size="16px" />
|
||||
</BaseButton>
|
||||
</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>
|
||||
</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'
|
||||
|
||||
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'])
|
||||
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 getOrderTable(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,239 @@
|
||||
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: 'direction',
|
||||
key: 'direction',
|
||||
filterable: false,
|
||||
customRender: ({ record }) => {
|
||||
switch (record.direction) {
|
||||
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>
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'نام و نام خانوادگی',
|
||||
dataIndex: 'customer.name',
|
||||
key: 'customer.name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'customer.mobile',
|
||||
key: 'customer.mobile',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'مقدار (گرم)',
|
||||
dataIndex: 'amount',
|
||||
key: 'amount',
|
||||
type: 'Text'
|
||||
},
|
||||
/*{
|
||||
title: 'کارمزد ریالی',
|
||||
dataIndex: 'service_charge_price',
|
||||
key: 'service_charge_price',
|
||||
type: 'Number',
|
||||
customRender(data) {
|
||||
return usePrice(data.record?.service_charge_price ?? 0, true, '')
|
||||
}
|
||||
// className: 'column-money'
|
||||
},*/
|
||||
{
|
||||
title: 'کارمزد طلایی',
|
||||
dataIndex: 'service_charge',
|
||||
key: 'service_charge',
|
||||
type: 'Number',
|
||||
customRender(data) {
|
||||
return data.record?.service_charge
|
||||
}
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'قیمت هر گرم طلا برای مشتری (ریال)',
|
||||
dataIndex: 'price',
|
||||
key: 'price',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return usePrice(data.record?.price ?? 0, true, '')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'قیمت هر گرم طلا در لیمان',
|
||||
dataIndex: 'limanPrice',
|
||||
key: 'limanPrice',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return usePrice(data.record?.total_price_liman ?? 0, true, '')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'قیمت کل برای مشتری (ریال)',
|
||||
dataIndex: 'total_price',
|
||||
key: 'total_price',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return usePrice(data.record?.total_price ?? 0, true, '')
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
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: '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
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,445 @@
|
||||
<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"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
<BasicModal
|
||||
v-model:visible="addOrderVisible"
|
||||
width="25rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} سفارش`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="stopGetPrice"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-1 gap-4">
|
||||
<div class="bg-gray-50 px-10 py-3 flex justify-center gap-4">
|
||||
<div>قیمت {{ form.direction === 1 ? 'خرید' : 'فروش' }} طلا:</div>
|
||||
<div class="font-bold">
|
||||
{{ usePrice(form.direction === 1 ? dataLast?.buy ?? 0 : dataLast?.sell ?? 0) }}
|
||||
</div>
|
||||
</div>
|
||||
<a-form-item label="نوع تراکنش" name="direction" :rules="inputRules()">
|
||||
<a-radio-group
|
||||
v-model:value="form.direction"
|
||||
button-style="solid"
|
||||
@change="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
|
||||
:label="`قیمت ${form.direction === 1 ? 'خرید' : 'فروش'} هر گرم`"
|
||||
name="price"
|
||||
:rules="inputRules()"
|
||||
>
|
||||
<BasicInput
|
||||
v-model:value="form.price"
|
||||
addon-before="ریال"
|
||||
type="price"
|
||||
@change="changePriceValue"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ سفارش" name="pay_at" :rules="inputRules()">
|
||||
<BaseDatePicker v-model:value="form.pay_at" format="YYYY-MM-DD HH:mm:ss" />
|
||||
</a-form-item>
|
||||
<a-form-item label="سود" name="difference" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.difference" addon-before="ریال" type="price" />
|
||||
</a-form-item>
|
||||
<a-form-item label="کل قیمت لیمان" name="total_price_liman">
|
||||
<BasicInput v-model:value="form.total_price_liman" addon-before="ریال" type="price" />
|
||||
</a-form-item>
|
||||
<div class="p-2 bg-orange-50 rounded-lg">
|
||||
<a-form-item label="انتخاب کاربر" name="customer_id" :rules="inputRules()">
|
||||
<BasicSelect
|
||||
v-model:value="form.customer_id"
|
||||
:items="userItems"
|
||||
valueName="name"
|
||||
keyName="id"
|
||||
@change="changeUser"
|
||||
/>
|
||||
</a-form-item>
|
||||
<BasicInfoItem
|
||||
is-line
|
||||
title="کیف پول طلا"
|
||||
class="mt-2"
|
||||
:value="selectedCustomer?.wallet[0]?.gold ?? '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
is-line
|
||||
title="کیف پول ریالی"
|
||||
class="mt-1"
|
||||
:value="selectedCustomer?.wallet[0]?.cash ?? '_'"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 bg-blue-50 p-2 rounded-lg">
|
||||
<div>مقدار {{ form.direction === 1 ? 'خرید' : 'فروش' }}:</div>
|
||||
<a-form-item name="goldCash" :rules="inputRulesNumber()">
|
||||
<BasicInput
|
||||
v-model:value="form.goldCash"
|
||||
addon-before="ریال"
|
||||
addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="ارزش کل"
|
||||
type="price"
|
||||
@onchange="calculateGold"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item name="goldValue" :rules="inputRulesNumber()">
|
||||
<BasicInput
|
||||
v-model:value="form.goldValue"
|
||||
addon-before="گرم"
|
||||
addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="مقدار طلا"
|
||||
type="tel"
|
||||
@onchange="calculateCash"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</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"
|
||||
/>
|
||||
</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 type { Order } from '@/model/order'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { getLastPrice } from '@/api/price'
|
||||
import type { last } from '@/model/price'
|
||||
import { createOrder } from '@/api/order'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
const userItems = ref<Customer[]>()
|
||||
const selectedCustomer = ref<Customer>()
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
async function getCustomers() {
|
||||
try {
|
||||
loading.value = true
|
||||
userItems.value = await getCustomersList()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCustomers()
|
||||
})
|
||||
|
||||
//form
|
||||
const form = ref<Order>({
|
||||
direction: 1,
|
||||
price: 0,
|
||||
amount: undefined,
|
||||
pay_at: '',
|
||||
difference: '',
|
||||
customer_id: undefined,
|
||||
goldCash: undefined,
|
||||
goldValue: undefined
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const dataLast = ref<last>()
|
||||
let interval: any
|
||||
|
||||
async function setIntervalGetPrice() {
|
||||
try {
|
||||
interval = setInterval(async () => {
|
||||
await getPrices()
|
||||
}, 10000)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function changePrice() {
|
||||
form.value.price = form.value.direction === 1 ? dataLast.value?.buy : dataLast.value?.sell
|
||||
}
|
||||
|
||||
async function getPrices() {
|
||||
try {
|
||||
// loading.value = true
|
||||
// const dataLast = await getLastPrice()
|
||||
dataLast.value = await getLastPrice()
|
||||
// form.value = dataLast
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
// loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function changeUser(val: Customer) {
|
||||
selectedCustomer.value = cloneDeep(val)
|
||||
console.log(selectedCustomer.value.wallet[0])
|
||||
}
|
||||
|
||||
function stopGetPrice() {
|
||||
clearInterval(interval)
|
||||
console.log('stop')
|
||||
}
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function info(val: Order) {
|
||||
infoParams.name = val.customer.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.amount ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت هر گرم طلا برای مشتری (ریال)',
|
||||
value: usePrice(val.price ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل برای مشتری (ریال)',
|
||||
value: usePrice(val.total_price ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت هر گرم طلا بدون سود (ریال)',
|
||||
value: usePrice(val.price_original ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل بدون سود (ریال)',
|
||||
value: usePrice(val.total_price_original ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل لیمان (ریال)',
|
||||
value: usePrice(val.total_price_liman ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود هر گرم (ریال)',
|
||||
value: usePrice(val.fee ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود کل (ریال)',
|
||||
value: usePrice(val.total_fee ?? 0) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.customer.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.customer.n_code ?? '-'
|
||||
},
|
||||
/*{
|
||||
key: 'کارمزد ریالی',
|
||||
value: usePrice(val.service_charge_price ?? 0)
|
||||
},*/
|
||||
{
|
||||
key: 'کارمزد طلایی',
|
||||
value: val.service_charge ?? '-' + ' گرم'
|
||||
},
|
||||
/* {
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.customer.birth_date) ?? '-'
|
||||
},*/
|
||||
/* {
|
||||
key: 'نام فروشگاه',
|
||||
value: val.customer.shop_name ?? '-'
|
||||
},*/
|
||||
{
|
||||
key: 'شماره تلفن',
|
||||
value: val.customer.phone_number ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام استان',
|
||||
value: val.customer.province ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام شهر',
|
||||
value: val.customer.city ?? '-'
|
||||
}
|
||||
/* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*/
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
|
||||
function calculateCash(val: number) {
|
||||
// console.log(val)
|
||||
if (form.value.price) {
|
||||
if (form.value.direction === 1) {
|
||||
if (val >= 0.01) form.value.goldCash = parseFloat((val * form.value.price).toFixed(0))
|
||||
else form.value.goldCash = undefined
|
||||
} else {
|
||||
if (val >= 0.01) form.value.goldCash = parseFloat((val * form.value.price).toFixed(0))
|
||||
else form.value.goldCash = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateGold(val: number) {
|
||||
// console.log(val)
|
||||
// form.value.goldCash = usePriceWithoutType(form.value.goldCash)
|
||||
if (form.value.price) {
|
||||
if (form.value.direction === 1) {
|
||||
if (val / form.value.price >= 0.01)
|
||||
form.value.goldValue = toFixedDownTwoChar(parseFloat(val / form.value.price))
|
||||
else if (val.toString() === '') form.value.goldValue = undefined
|
||||
else form.value.goldValue = 0
|
||||
} else {
|
||||
if (val >= form.value.price)
|
||||
form.value.goldValue = toFixedDownTwoChar(parseFloat(val / form.value.price))
|
||||
else if (val.toString() === '') form.value.goldValue = undefined
|
||||
else form.value.goldValue = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function changePriceValue() {
|
||||
calculateCash(form.value.goldValue)
|
||||
}
|
||||
|
||||
function toFixedDownTwoChar(num) {
|
||||
return Math.floor(num * 100) / 100
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addOrderVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
resetData()
|
||||
addOrderVisible.value = true
|
||||
await getPrices()
|
||||
await setIntervalGetPrice()
|
||||
form.value.price = form.value.direction === 1 ? dataLast.value?.buy : dataLast.value?.sell
|
||||
updateKey.value++
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
direction: 1,
|
||||
price: 0,
|
||||
amount: undefined,
|
||||
pay_at: '',
|
||||
difference: '',
|
||||
customer_id: undefined,
|
||||
goldCash: undefined,
|
||||
goldValue: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const addOrderVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
form.value.amount = form.value.goldValue
|
||||
delete form.value.goldValue
|
||||
delete form.value.goldCash
|
||||
|
||||
await createOrder(form.value)
|
||||
message.success('سفارش با موفقیت ثبت شد')
|
||||
addOrderVisible.value = false
|
||||
resetData()
|
||||
refreshTable()
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="هشدار قیمت">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<!-- <template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن مدیر</div>
|
||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
||||
</BaseButton>
|
||||
</template>-->
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<!-- <a-tooltip
|
||||
:key="record.active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeUserActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{ record.active ? 'غیرفعال کردن' : 'فعال کردن' }}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="record.active ? 'vuesax-linear:tick-circle' : 'vuesax-linear:close-circle'"
|
||||
:color="record.active ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>-->
|
||||
<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('edit', record)">
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
<!-- <a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('delete', record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>حذف</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:trash" color="#EB3535" />
|
||||
</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 { toJalali, toJalaliNoTime } from '@core/utils/useDataTime'
|
||||
import { message, Tag } from 'ant-design-vue'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import { changeUserActivation, getUserTable } from '@/api/user'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { cols } from '../hooks/priceTriggersColumns'
|
||||
import { changeCustomerActivation } from '@/api/customer'
|
||||
import {getPriceTriggersTable} from "@/api/priceTriggers";
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info'])
|
||||
|
||||
//define table
|
||||
const table = ref(null)
|
||||
|
||||
//permission
|
||||
function checkPermission(temp: string) {
|
||||
const store = useUserStore()
|
||||
return store.canAccess(temp)
|
||||
}
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
async function changeUserActivationFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeUserActivation(id)
|
||||
reload()
|
||||
message.success('تغییر وضعیت با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
return getPriceTriggersTable(params)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
|
||||
const fetch = () => {
|
||||
// console.log('sss')
|
||||
reload()
|
||||
}
|
||||
// const spinTable = (val: boolean) => {
|
||||
// // console.log('sss')
|
||||
// table?.value?.loading.value = val
|
||||
// }
|
||||
defineExpose({
|
||||
fetch
|
||||
// spinTable
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,208 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import {toJalali, toJalaliNoTime, toTime} from '@core/utils/useDataTime'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
/*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',
|
||||
customRender: (record: any) => {
|
||||
return record.index + 1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'کد مشتری',
|
||||
dataIndex: 'customer_id',
|
||||
key: 'customer_id',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'قیمت هدف',
|
||||
dataIndex: 'target_price',
|
||||
key: 'target_price',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'شرط',
|
||||
dataIndex: 'price_condition',
|
||||
key: 'price_condition',
|
||||
type: 'Text',
|
||||
customRender: ({ record }) => {
|
||||
return record.price_condition==">" ? (
|
||||
<CustomTag>بزرگتر</CustomTag>
|
||||
) : (
|
||||
<CustomTag>کوچکتر</CustomTag>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'زمان ایجاد',
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
type: 'Text',
|
||||
customRender: ({ record }) => {
|
||||
return toJalali(record.created_at)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'زمان بروزرسانی',
|
||||
dataIndex: 'updated_at',
|
||||
key: 'updated_at',
|
||||
type: 'Text',
|
||||
customRender: ({ record }) => {
|
||||
return toJalali(record.updated_at)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'زمان اعلام',
|
||||
dataIndex: 'triggered_at',
|
||||
key: 'triggered_at',
|
||||
type: 'Text',
|
||||
customRender: ({ record }) => {
|
||||
return record.triggered_at? toJalali(record.triggered_at) : '_'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'وضعیت',
|
||||
dataIndex: 'is_active',
|
||||
key: 'is_active',
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.is_active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
// customRender: ({ record }) => {
|
||||
// if(record.is_active) {
|
||||
// return (
|
||||
// <div class="flex justify-center">
|
||||
// <CustomTag textColor="#C53030" bgColor="#FECACA">
|
||||
// فروش
|
||||
// </CustomTag>
|
||||
// </div>
|
||||
// )
|
||||
// return (
|
||||
// <div class="flex justify-center">
|
||||
// <CustomTag textColor="#25855A" bgColor="#E3F4E9">
|
||||
// خرید
|
||||
// </CustomTag>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
},
|
||||
/* {
|
||||
title: 'وضعیت',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA">
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},*/
|
||||
/*{
|
||||
title: 'سمت',
|
||||
dataIndex: 'post_user',
|
||||
key: 'post_user',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
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',
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <BasicMainCard>-->
|
||||
<div class="flex w-full h-full">
|
||||
<tbl ref="table" class="w-full h-full" @info="info" @edit="edit" @add="add" />
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
<!-- </BasicMainCard>-->
|
||||
<!-- <BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="40rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} کاربر`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>-->
|
||||
<!-- <a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="نام" name="fname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام خانوادگی" name="lname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره همراه" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="form.mobile" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="editId" label="رمز عبور" name="password">
|
||||
<BasicInput v-model:value="form.password" is-password type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="editId" label="تکرار رمز عبور">
|
||||
<BasicInput v-model:value="form.repassword" is-password type="number" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form>-->
|
||||
<!-- <BasicInfoModal
|
||||
v-model:visible="userInfoVisible"
|
||||
@close="userInfoVisible = false"
|
||||
:title="infoParams.title"
|
||||
:date="infoParams.date"
|
||||
:time="infoParams.time"
|
||||
:type="infoParams.type"
|
||||
itemsTitle="اطلاعات فردی"
|
||||
:name="infoParams.name"
|
||||
:items="infoParams.items"
|
||||
/>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } from '@/utils/inputRules'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
import type { Const } from '@/model/const'
|
||||
import type { User } from '@/model/user'
|
||||
import { createUser, deleteUser, updateUser } from '@/api/user'
|
||||
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'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
|
||||
//form
|
||||
const form = ref<User>({
|
||||
active: true
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function info(val: User) {
|
||||
infoParams.name = val.name
|
||||
infoParams.type = val.mobile
|
||||
infoParams.date = toJalaliNoTime(val.created_at)
|
||||
infoParams.time = toTime(val.created_at)
|
||||
infoParams.itemsTitle = 'اطلاعات کاربری'
|
||||
infoParams.items = [
|
||||
{
|
||||
key: 'تلفن همراه',
|
||||
value: val.mobile ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.id ?? '-'
|
||||
}
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: User) {
|
||||
addUserVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
active: false,
|
||||
avatar_id: undefined,
|
||||
sts: undefined,
|
||||
id: undefined,
|
||||
mobile: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteUser, refreshTable)
|
||||
|
||||
/* Modal.confirm({
|
||||
title: 'آیا از حذف کاربر اطمینان دارید؟',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'تایید',
|
||||
okType: 'danger',
|
||||
centered: true,
|
||||
cancelText: 'انصراف',
|
||||
async onOk() {
|
||||
// console.log('OK');
|
||||
await deleteItem(id)
|
||||
},
|
||||
onCancel() {
|
||||
console.log('Cancel')
|
||||
}
|
||||
})*/
|
||||
|
||||
/*async function deleteItem(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
// table?.value?.spinTable(true)
|
||||
await deleteUser(id)
|
||||
message.success('با موفقیت حذف شد')
|
||||
table?.value?.fetch()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
message.error('خطا در حذف')
|
||||
} finally {
|
||||
loading.value = false
|
||||
// table?.value?.spinTable(false)
|
||||
}
|
||||
}*/
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
interface selectsItem {
|
||||
responsibleItems: Array<User> | undefined
|
||||
users: Array<Const> | undefined
|
||||
}
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
if (editId) {
|
||||
if (form.value.password) {
|
||||
if (form.value.password === form.value.repassword) {
|
||||
await updateUser(editId, form.value)
|
||||
} else {
|
||||
message.error('پسورد وارد شده با تکرار پسورد وارد شده یکسان نیست')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
await updateUser(editId, form.value)
|
||||
}
|
||||
} else {
|
||||
await createUser(form.value)
|
||||
}
|
||||
addUserVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<svg width="299" height="331" viewBox="0 0 299 331" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.20561 15.7673C1.88291 15.7673 0 17.6502 0 19.9729V292.811C32.2359 284.941 68.9177 280.321 110.014 280.321C166.49 280.321 213.449 285.875 252.336 295.013V19.9729C252.336 17.6502 250.453 15.7673 248.131 15.7673H4.20561Z" fill="url(#paint0_linear_220_20208)"/>
|
||||
<rect x="15.772" y="31.5352" width="220.794" height="277.518" rx="4.20561" fill="url(#paint1_linear_220_20208)"/>
|
||||
<rect x="30.8423" y="53.262" width="189.252" height="122.991" fill="url(#paint2_linear_220_20208)"/>
|
||||
<rect x="31.541" y="195.523" width="189.252" height="18.9217" fill="#F6F6F4"/>
|
||||
<rect x="31.541" y="239.674" width="189.252" height="18.9217" fill="#F6F6F4"/>
|
||||
<rect x="53.6221" y="12.6143" width="145.093" height="25.2289" fill="#D8DDE2"/>
|
||||
<path d="M91.9618 0H160.377L170.328 12.6144H82.0107L91.9618 0Z" fill="#D0D6DC"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M172.67 201.831C176.495 201.921 179.989 199.721 181.492 196.278C182.996 192.833 182.204 188.841 179.495 186.197L155.609 162.745C151.953 159.166 146.025 159.166 142.37 162.745C138.714 166.324 138.714 172.128 142.37 175.707L166.323 199.092C167.998 200.774 170.272 201.755 172.67 201.831Z" fill="#209487"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M83.3257 166.413C67.9334 151.103 65.7138 127.268 78.0229 109.479C90.3321 91.6904 113.744 84.8976 133.949 93.2538C154.153 101.61 165.525 122.789 161.113 143.845C156.701 164.9 137.734 179.972 115.806 179.846C103.59 179.769 91.9058 174.936 83.3257 166.413Z" fill="#209487"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M89.4232 108.715C74.8842 122.991 74.8978 146.115 89.4535 160.374C104.009 174.633 127.6 174.633 142.155 160.374C156.71 146.115 156.724 122.991 142.185 108.715C127.607 94.4529 104.001 94.4529 89.4232 108.715Z" fill="white"/>
|
||||
<mask id="mask0_220_20208" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="78" y="98" width="76" height="74">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M89.4232 108.715C74.8842 122.991 74.8978 146.115 89.4535 160.374C104.009 174.633 127.6 174.633 142.155 160.374C156.71 146.115 156.724 122.991 142.185 108.715C127.607 94.4529 104.001 94.4529 89.4232 108.715Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_220_20208)">
|
||||
<path d="M149.593 107.996C149.593 143.426 132.334 170.792 107.652 186.247C82.9699 201.701 153.051 176.252 153.051 176.252L166.9 127.492C166.9 127.492 149.593 72.5672 149.593 107.996Z" fill="url(#paint3_linear_220_20208)"/>
|
||||
</g>
|
||||
<path d="M226.293 307.813L280.051 328.823L292.397 311.161L238.311 298.583L226.293 307.813Z" fill="url(#paint4_linear_220_20208)"/>
|
||||
<path d="M223.369 217.847L260.302 220.759L252.1 301.094C252.1 301.094 251.382 301.897 249.639 301.585C247.897 301.273 246.069 300.304 246.069 300.304L240.576 236.439C240.576 236.439 237.399 259.022 237.621 265.375C237.788 270.162 239.425 276.001 240.301 280.996C241.055 285.295 242.641 295.568 242.641 295.568C242.641 295.568 240.767 296.424 239.77 296.617C238.773 296.811 237.495 295.748 237.495 295.748C237.495 295.748 224.546 270.611 224.38 265.838C224.213 261.064 223.369 217.847 223.369 217.847Z" fill="url(#paint5_linear_220_20208)"/>
|
||||
<path d="M236.92 295.63C236.92 295.63 235.275 298.592 233.232 300.398C231.188 302.204 227.156 304.36 226.237 305.34C225.317 306.32 226.321 307.763 226.321 307.763L236.204 307.418L244.101 300.738L242.998 294.371L236.92 295.63Z" fill="#209487"/>
|
||||
<path d="M253.03 299.06L255.337 305.459C255.337 305.459 251.548 308.393 246.313 309.21C241.078 310.027 237.471 308.772 237.471 308.772C237.471 308.772 236.526 306.868 238.307 306.054C239.125 305.68 240.959 304.126 242.569 302.136C243.296 301.238 246.034 299.304 246.034 299.304L253.03 299.06Z" fill="#209487"/>
|
||||
<path d="M269.573 175.965C269.573 175.965 272.6 180.57 274.457 179.338C276.313 178.106 287.9 166.229 287.9 166.229C287.9 166.229 291.347 163.575 291.985 164.206C292.622 164.837 290.835 166.229 290.835 166.229C290.835 166.229 294.596 166.598 295.772 166.598C296.947 166.598 299.419 168.475 297.803 169.106C296.186 169.738 289.916 169.894 289.916 169.894C289.916 169.894 280.396 187.896 275.435 189.173C270.475 190.449 263.64 183.23 263.64 183.23L269.573 175.965Z" fill="#F6F6F4"/>
|
||||
<path d="M221.208 176.294C221.208 176.294 219.223 180.358 217.424 179.383C215.626 178.408 205.534 167.766 205.534 167.766C205.534 167.766 202.174 165.708 201.352 166.078C200.53 166.448 202.556 167.766 202.556 167.766C202.556 167.766 197.612 168.167 196.681 168.541C195.751 168.915 194.668 170.061 196.074 170.582C197.481 171.104 202.864 171.474 202.864 171.474C202.864 171.474 210.348 186.263 216.018 187.992C221.688 189.721 226.518 182.908 226.518 182.908L221.208 176.294Z" fill="#F6F6F4"/>
|
||||
<path d="M239.566 163.848V156.583C239.566 156.583 235.799 156.773 234.268 154.251C232.737 151.728 232.323 144.57 232.323 144.57L233.477 141.251L244.824 140.771L250.785 145.851L248.009 150.753L247.48 151.695L250.125 162.836L239.566 163.848Z" fill="#F6F6F4"/>
|
||||
<mask id="mask1_220_20208" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="232" y="140" width="19" height="24">
|
||||
<path d="M239.566 163.848V156.583C239.566 156.583 235.799 156.773 234.268 154.251C232.737 151.728 232.323 144.57 232.323 144.57L233.477 141.251L244.824 140.771L250.785 145.851L248.009 150.753L247.48 151.695L250.125 162.836L239.566 163.848Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask1_220_20208)">
|
||||
<path d="M246.947 149.681C243.594 153.851 237.794 156.766 237.039 156.766C236.284 156.766 241.256 161.996 241.256 161.996L245.301 163.851L251.043 162.634L253.093 156.766L249.474 150.108C249.474 150.108 250.3 145.51 246.947 149.681Z" fill="url(#paint6_linear_220_20208)"/>
|
||||
</g>
|
||||
<path d="M218.796 179.214L224.372 186.725L227.928 182.969C227.928 182.969 225.223 197.799 224.372 204.911C223.52 212.023 223.362 219.107 223.362 219.107C223.362 219.107 232.29 222.422 238.946 222.979C245.602 223.537 261.096 222.101 261.096 222.101L259.096 180.358L264.899 185.745L271.713 177.877C271.713 177.877 259.983 159.852 257.765 158.801C255.547 157.751 249.381 158.801 249.381 158.801C249.381 158.801 245.005 163.98 243.231 164.052C241.457 164.124 237.521 158.801 237.521 158.801C237.521 158.801 231.233 157.797 229.404 159.852C227.576 161.906 218.796 179.214 218.796 179.214Z" fill="url(#paint7_linear_220_20208)"/>
|
||||
<path d="M232.323 144.65C232.323 144.65 233.66 141.276 235.405 141.864C237.057 142.42 238.488 143.744 240.543 144.365C242.598 144.987 242.825 142.195 244.222 142.666C245.618 143.138 244.697 147.245 245.681 148.01C246.665 148.775 246.665 142.666 248.764 144.311C250.862 145.955 246.574 150.584 246.574 150.584C246.574 150.584 247.124 153.428 247.3 153.622C247.476 153.815 247.456 151.552 247.456 151.552C247.456 151.552 249.46 150.783 250.314 147.313C251.168 143.844 251.538 142.462 250.314 139.941C249.091 137.42 248.742 135.446 245.681 134.256C242.619 133.067 240.296 133.532 238.157 134.256C236.017 134.981 234.466 136.419 233.476 137.851C231.169 141.25 232.323 144.65 232.323 144.65Z" fill="#209487"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_220_20208" x1="167.995" y1="274.038" x2="167.995" y2="190.603" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F7F7F7"/>
|
||||
<stop offset="1" stop-color="#E8EAEB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_220_20208" x1="15.772" y1="31.5352" x2="15.772" y2="309.053" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="0.746404" stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.697577"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_220_20208" x1="30.8423" y1="53.262" x2="30.8423" y2="176.253" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E8EAEB"/>
|
||||
<stop offset="1" stop-color="#F0F1F1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_220_20208" x1="138.831" y1="114.088" x2="109.601" y2="148.009" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EEEEEE" stop-opacity="0.367499"/>
|
||||
<stop offset="1" stop-color="#D8D8D8" stop-opacity="0.01"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_220_20208" x1="211.649" y1="316.125" x2="234.238" y2="353.107" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#B7BFC3"/>
|
||||
<stop offset="0.487221" stop-color="#D9E2E6"/>
|
||||
<stop offset="1" stop-color="#E6EDF3" stop-opacity="0.01"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_220_20208" x1="262.971" y1="301.24" x2="260.037" y2="217.202" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A1A7B8"/>
|
||||
<stop offset="1" stop-color="#7B8195"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_220_20208" x1="248.536" y1="158.972" x2="248.536" y2="151.932" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FBD8D6"/>
|
||||
<stop offset="1" stop-color="#EAC0BE" stop-opacity="0.7"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_220_20208" x1="192.026" y1="187.89" x2="247.661" y2="246.581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E5E9F0"/>
|
||||
<stop offset="1" stop-color="#D2DAE8"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.8 KiB |
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div class="flex items-center main">
|
||||
<div>{{ props.item.province }}</div>
|
||||
<BaseIcon icon="vuesax-linear:arrow-left-1" size=".9rem" />
|
||||
<div>{{ props.item.project }}</div>
|
||||
<BaseIcon icon="vuesax-linear:arrow-left-1" size=".9rem" />
|
||||
<div>{{ props.item.documentGroup }}</div>
|
||||
<BaseIcon icon="vuesax-linear:arrow-left-1" size=".9rem" />
|
||||
<div>{{ props.item.document }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type History from '@/pages/menuPages/customers/search/model/History'
|
||||
|
||||
//define props
|
||||
interface Prop {
|
||||
item: History
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.main {
|
||||
@apply w-full justify-center;
|
||||
background-color: #f6f6f4;
|
||||
border: solid 1px #b2b2b2;
|
||||
border-radius: @border-radius-base;
|
||||
height: 4rem;
|
||||
|
||||
div {
|
||||
@apply px-1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div :class="[prefixCls]">
|
||||
<div class="flex-row-reverse flex w-full">
|
||||
<BaseButton type="primary" size="small" iconSize="18px" icon="vuesax-linear:clipboard-export">
|
||||
افزودن پروژه
|
||||
</BaseButton>
|
||||
</div>
|
||||
<div class="md:px-14">
|
||||
<div class="colors-main">
|
||||
<p>در هر بخش یک مورد را انتخاب کنید</p>
|
||||
<div class="grid xl:grid-cols-12">
|
||||
<div class="grid xl:col-span-10 sm:grid-cols-2 md:grid-cols-4">
|
||||
<BasicSelect :items="province" title="استان" style="width: 100%" />
|
||||
<BasicSelect :items="project" title="پروژه" style="width: 100%" />
|
||||
<BasicSelect :items="documentGroup" title="گروه سندی" style="width: 100%" />
|
||||
<BasicSelect :items="documents" title="سند" style="width: 100%" />
|
||||
</div>
|
||||
<div class="relative col-span-2 flex flex-col-reverse">
|
||||
<div class="p-1">
|
||||
<BaseButton
|
||||
type="primary"
|
||||
size="small"
|
||||
iconSize="18px"
|
||||
icon="vuesax-linear:search-normal-1"
|
||||
>
|
||||
جست و جو
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-10">آخرین جست و جو</p>
|
||||
<div ref="historyElement" class="grid gap-5" :class="`grid-cols-${countHistoryElementSize}`">
|
||||
<div v-for="val in history.slice(0, countHistoryElementSize)" class="flex self-center">
|
||||
<HistoryCard :item="val" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="text-center">
|
||||
<img :src="searchIcon" class="h-[7rem] mt-8" />
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import HistoryCard from '@/pages/menuPages/customers/search/components/HistoryCard.vue'
|
||||
import type Item from '@/pages/menuPages/customers/search/model/item'
|
||||
import type History from '@/pages/menuPages/customers/search/model/History'
|
||||
import searchIcon from '@/pages/menuPages/customers/search/assets/svg/search.svg'
|
||||
import { useElementSize } from '@vueuse/core'
|
||||
|
||||
//ui historyElement
|
||||
const historyElement = ref(null)
|
||||
const historyElementSize = reactive(
|
||||
useElementSize(historyElement, { width: 0, height: 0 }, { box: 'border-box' })
|
||||
)
|
||||
const countHistoryElementSize = ref()
|
||||
watch(historyElementSize, (v) => {
|
||||
if (v.width > 1300) {
|
||||
countHistoryElementSize.value = 5
|
||||
} else if (v.width > 1100 && v.width <= 1300) {
|
||||
countHistoryElementSize.value = 4
|
||||
} else countHistoryElementSize.value = 3
|
||||
})
|
||||
|
||||
//css style
|
||||
const { prefixCls } = usePrefix('search-customers')
|
||||
|
||||
// items
|
||||
const province = ref<Array<Item>>([
|
||||
{
|
||||
value: 'تهران',
|
||||
key: 'Tehran'
|
||||
},
|
||||
{
|
||||
value: 'اصفهان',
|
||||
key: 'Esfahan'
|
||||
},
|
||||
{
|
||||
value: 'خراسان رضوی',
|
||||
key: 'Khorasan Razavi'
|
||||
},
|
||||
{
|
||||
value: 'مازندران',
|
||||
key: 'Mazandaran'
|
||||
}
|
||||
])
|
||||
const project = ref<Array<Item>>([
|
||||
{
|
||||
value: 'پروژه 1',
|
||||
key: '1'
|
||||
},
|
||||
{
|
||||
value: 'پروژه 2',
|
||||
key: '2'
|
||||
},
|
||||
{
|
||||
value: 'پروژه 3',
|
||||
key: '3'
|
||||
}
|
||||
])
|
||||
const documentGroup = ref<Array<Item>>([
|
||||
{
|
||||
value: 'گروه 1',
|
||||
key: '1'
|
||||
},
|
||||
{
|
||||
value: 'گروه 2',
|
||||
key: '2'
|
||||
},
|
||||
{
|
||||
value: 'گروه 3',
|
||||
key: '3'
|
||||
}
|
||||
])
|
||||
const documents = ref<Array<Item>>([
|
||||
{
|
||||
value: 'سند 1',
|
||||
key: '1'
|
||||
},
|
||||
{
|
||||
value: 'سند 2',
|
||||
key: '2'
|
||||
},
|
||||
{
|
||||
value: 'سند 3',
|
||||
key: '3'
|
||||
}
|
||||
])
|
||||
|
||||
//history test
|
||||
|
||||
const history = ref<Array<History>>([
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
},
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
},
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
},
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
},
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@prefix: ~'@{prefixCls}-search-projects';
|
||||
|
||||
.@{prefix} {
|
||||
.colors-main {
|
||||
@apply mt-5 p-4 border-solid border-1;
|
||||
border-radius: @border-radius-base;
|
||||
background-color: @bg-color-1;
|
||||
border-color: @border-color-1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,6 @@
|
||||
export default interface History {
|
||||
province: string
|
||||
project: string
|
||||
documentGroup: string
|
||||
document: string
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export default interface Item {
|
||||
value: String
|
||||
key: String
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="تاریخچه قیمت">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>قیمت گذاری</div>
|
||||
<BaseIcon icon="vuesax-linear:dollar-circle" Size="16px" />
|
||||
</BaseButton>
|
||||
</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>
|
||||
</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/priceColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { getOrderTable } from '@/api/order'
|
||||
import { getPriceTable } from '@/api/price'
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info'])
|
||||
|
||||
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) => {
|
||||
return getPriceTable(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,160 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { 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: 'user_id',
|
||||
key: 'user_id',
|
||||
type: 'Number'
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'نام و نام خانوادگی',
|
||||
dataIndex: 'user.name',
|
||||
key: 'user.name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'قیمت هر گرم طلا برای مشتری (ریال)',
|
||||
dataIndex: 'price',
|
||||
key: 'price',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return usePrice(data.record.price ?? 0, true, '')
|
||||
}
|
||||
},
|
||||
/* {
|
||||
title: 'قیمت کل برای مشتری (ریال)',
|
||||
dataIndex: 'price',
|
||||
key: 'price',
|
||||
type: 'Text'
|
||||
},*/
|
||||
/*
|
||||
{
|
||||
title: 'وضعیت',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA">
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
*/
|
||||
/*{
|
||||
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: 'time_at',
|
||||
key: 'time_at',
|
||||
type: 'DateTime'
|
||||
}
|
||||
/* {
|
||||
title: 'عملیات',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
slot: 'action',
|
||||
fixed: 'right',
|
||||
filterable: false
|
||||
}*/
|
||||
]
|
||||
@@ -0,0 +1,260 @@
|
||||
<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"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
|
||||
<BasicModal
|
||||
v-model:visible="priceConfirmVisible"
|
||||
width="25rem"
|
||||
@ok="ok"
|
||||
:confirm-loading="loading"
|
||||
@close="priceConfirmVisible = false"
|
||||
>
|
||||
<div class="flex items-center gap-2 font-bold">
|
||||
<BaseIcon icon="vuesax-linear:info-circle" color="orange" />
|
||||
<div>آیا مطمئن به تغییر قیمت می باشید؟</div>
|
||||
</div>
|
||||
</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"
|
||||
/>-->
|
||||
</div>
|
||||
<BasicModal
|
||||
v-model:visible="addPriceVisible"
|
||||
width="25rem"
|
||||
title="قیمت گذاری"
|
||||
@ok="confirmPrice"
|
||||
:loading="loading"
|
||||
@close="addPriceVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="gap-4">
|
||||
<a-form-item label="قیمت جدید" name="price" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.price" type="price" addon-before="ریال" />
|
||||
</a-form-item>
|
||||
<div v-show="form.price > 10">معادل {{ usePrice(form.price / 10, true, 'تومان') }}</div>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</a-form-item>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } 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 { confirmActOnApi, confirmDeleteItem } from '@/utils/confirmModal'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import type { Item } from '@/model/Item'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import { createCustomer, deleteCustomer, updateCustomer } from '@/api/customer'
|
||||
import type { Order } from '@/model/order'
|
||||
import type { Price } from '@/model/price'
|
||||
import { createPrice } from '@/api/price'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import Icon from '@core/components/BaseIcon'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
|
||||
//form
|
||||
const form = ref<Price>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
/*
|
||||
function info(val: Order) {
|
||||
infoParams.name = val.customer.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.amount ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت هر گرم طلا برای مشتری (ریال)',
|
||||
value: val.price ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل برای مشتری (ریال)',
|
||||
value: val.total_price ?? '-'
|
||||
},
|
||||
{
|
||||
key: '/قیمت هر گرم طلا بدون سود (ریال)',
|
||||
value: val.price_original ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل بدون سود (ریال)',
|
||||
value: val.total_price_original ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود هر گرم (ریال)',
|
||||
value: val.fee ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود کل (ریال)',
|
||||
value: val.total_fee ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.customer.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.customer.n_code ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.customer.birth_date) ?? '-'
|
||||
},
|
||||
/!* {
|
||||
key: 'نام فروشگاه',
|
||||
value: val.customer.shop_name ?? '-'
|
||||
},*!/
|
||||
{
|
||||
key: 'شماره تلفن',
|
||||
value: val.customer.phone_number ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام استان',
|
||||
value: val.customer.province ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام شهر',
|
||||
value: val.customer.city ?? '-'
|
||||
}
|
||||
/!* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*!/
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
*/
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
/*
|
||||
async function edit(record: Customer) {
|
||||
addPriceVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
*/
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addPriceVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {}
|
||||
}
|
||||
|
||||
//delete
|
||||
// const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
/*
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
*/
|
||||
|
||||
//add project modal
|
||||
const addPriceVisible = ref<boolean>(false)
|
||||
const priceConfirmVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
function confirmPrice() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
priceConfirmVisible.value = true
|
||||
})
|
||||
}
|
||||
async function ok() {
|
||||
loading.value = true
|
||||
try {
|
||||
await createPrice(form.value)
|
||||
refreshTable()
|
||||
priceConfirmVisible.value = false
|
||||
addPriceVisible.value = false
|
||||
// await confirmActOnApi('آیا از اعمال قیمت جدید اطمینان دارید؟', form.value, createPrice)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست محصولات بایگانی شده">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<!-- <template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن مشتری عمده</div>
|
||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
||||
</BaseButton>
|
||||
</template>-->
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<a-tooltip :key="record.is_archive" placement="bottom" class="cursor-pointer">
|
||||
<template #title>
|
||||
<span>{{ record.is_archive ? 'بیرون بردن از بایگانی' : 'بایگانی کردن' }}</span>
|
||||
</template>
|
||||
<a-popconfirm
|
||||
title="آیا مشتری را از بایگانی خارج می کنید؟"
|
||||
ok-text="تایید"
|
||||
cancel-text="رد"
|
||||
placement="topLeft"
|
||||
@confirm="archiveFunction(record.id)"
|
||||
@cancel=""
|
||||
>
|
||||
<!-- <template #icon><question-circle-outlined style="color: red" /></template>-->
|
||||
<Icon class="cursor-pointer" icon="vuesax-linear:archive-slash" color="#e3bf00" />
|
||||
</a-popconfirm>
|
||||
</a-tooltip>
|
||||
|
||||
<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('delete', record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>حذف</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:trash" color="#EB3535" />
|
||||
</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,
|
||||
changeCustomerArchive,
|
||||
changeCustomerOrderActivation,
|
||||
getCustomerArchiveTable,
|
||||
getCustomerTable
|
||||
} from '@/api/customer'
|
||||
import { cols } from '../hooks/archiveColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'charge'])
|
||||
|
||||
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) => {
|
||||
return getCustomerArchiveTable(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
|
||||
}
|
||||
}
|
||||
|
||||
async function changeCustomerOrderActivationFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerOrderActivation(id)
|
||||
reload()
|
||||
message.success('تغییر وضعیت سفارش دهی با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
async function archiveFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerArchive(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,163 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { toJalaliNoTime, toTime } from '@core/utils/useDataTime'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
/*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: 'name',
|
||||
key: 'name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
},
|
||||
/* {
|
||||
title: 'نام',
|
||||
dataIndex: 'shop_name',
|
||||
key: 'shop_name',
|
||||
type: 'Text'
|
||||
},*/
|
||||
{
|
||||
title: 'وضعیت کاربر',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'وضعیت سفارش دهی',
|
||||
dataIndex: 'trade_active',
|
||||
key: 'trade_active',
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.trade_active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
/*{
|
||||
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
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <BasicMainCard>-->
|
||||
<div class="flex w-full h-full">
|
||||
<tbl ref="table" class="w-full h-full" @info="info" @edit="edit" @charge="walletCharge" />
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
<!-- </BasicMainCard>-->
|
||||
<BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="40rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} کاربر`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="نام" name="fname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام خانوادگی" name="lname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره همراه" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="form.mobile" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ تولد" name="birth_date" :rules="inputRules()">
|
||||
<BaseDatePicker v-model:value="form.birth_date" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="ایمیل" name="email" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.email" />
|
||||
</a-form-item>-->
|
||||
<!-- <a-form-item label="نام فروشگاه" name="shop_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.shop_name" />
|
||||
</a-form-item>-->
|
||||
<a-form-item label="شماره تلفن" name="phone_number" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.phone_number" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام استان" name="province" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.province" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام شهر" name="city" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.city" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره ملی" name="n_code" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.n_code" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</a-form-item>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
<BasicModal
|
||||
v-model:visible="userInfoVisible"
|
||||
width="40vw"
|
||||
title="اطلاعات کاربر"
|
||||
custom-footer
|
||||
@close="userInfoVisible = false"
|
||||
>
|
||||
<div class="grid grid-cols-4 gap-2">
|
||||
<div class="col-span-4 bg-gray-100 w-full rounded-lg flex p-3 justify-between">
|
||||
<div>
|
||||
<div class="font-bold">{{ userInfo.name }}</div>
|
||||
<div class="mt-1">{{ userInfo?.mobile }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{{ toJalaliNoTime(userInfo?.created_at) }}</div>
|
||||
<div class="mt-2">
|
||||
<CustomTag
|
||||
:textColor="userInfo?.active ? '#25855A' : '#C53030'"
|
||||
:bgColor="userInfo?.active ? '#E3F4E9' : '#FECACA'"
|
||||
class="font-bold px-6"
|
||||
>
|
||||
{{ userInfo?.active ? 'فعال' : 'غیرفعال' }}
|
||||
</CustomTag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
||||
<BasicInfoItem title="نوع کاربر" :value="userInfo?.type_str" />
|
||||
<BasicInfoItem
|
||||
title="تاریخ تولد"
|
||||
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="شماره ملی" :value="userInfo?.n_code ?? '_'" />
|
||||
<BasicInfoItem title="نام استان" :value="userInfo?.province ?? '_'" />
|
||||
<BasicInfoItem title="نام شهر" :value="userInfo?.city ?? '_'" />
|
||||
<BasicInfoItem title="سقف اعتبار" :value="userInfo?.gram ? `${userInfo?.gram} گرم` : '_'" />
|
||||
<BasicInfoItem title="کد معرف" :value="userInfo?.referral_id" />
|
||||
<BasicInfoItem
|
||||
title="کد معرف کاربر"
|
||||
:value="userInfo?.referral ? userInfo?.referral?.id : '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="نام معرف کاربر"
|
||||
:value="userInfo?.referral ? userInfo?.referral?.name : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="وضعیت سفارش دهی">
|
||||
<CustomTag
|
||||
:textColor="userInfo?.trade_active === 1 ? '#25855A' : '#C53030'"
|
||||
:bgColor="userInfo?.trade_active === 1 ? '#E3F4E9' : '#FECACA'"
|
||||
class="font-bold px-6"
|
||||
>
|
||||
{{ userInfo?.trade_active === 1 ? 'مجاز' : 'غیر مجاز' }}
|
||||
</CustomTag>
|
||||
</BasicInfoItem>
|
||||
<div class="col-span-4 grid grid-cols-2 gap-3">
|
||||
<div
|
||||
v-for="(item, index) in userInfo.wallet"
|
||||
:key="index"
|
||||
class="grid grid-cols-2 bg-orange-50 gap-2 rounded-lg p-2"
|
||||
>
|
||||
<BasicInfoItem
|
||||
title="نام قلک"
|
||||
:value="item?.fund ? item?.fund?.title : 'کیف پول طلایی'"
|
||||
/>
|
||||
<BasicInfoItem title="مقدار طلا" :value="`${item?.gold} گرم`" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BasicModal>
|
||||
|
||||
<BasicModal
|
||||
v-model:visible="showWalletCharge"
|
||||
width="30rem"
|
||||
title="شارژ کیف پول"
|
||||
@ok="charge"
|
||||
:loading="loading"
|
||||
@close="showWalletCharge = false"
|
||||
>
|
||||
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
|
||||
<a-form-item label="مقدار شارژ (ریال)" name="value" :rules="inputRules()">
|
||||
<BasicInput v-model:value="formCharge.value" type="number" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } 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, updateCustomer } from '@/api/customer'
|
||||
import type { Charge } from '@/model/wallet'
|
||||
import customers from '@/router/routes/customers'
|
||||
import { chargeWallet } from '@/api/wallet'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
|
||||
//wallet
|
||||
const showWalletCharge = ref<boolean>(false)
|
||||
|
||||
//form
|
||||
const form = ref<Customer>({})
|
||||
const formCharge = ref<Charge>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
const formChargeRef = ref<FormInstance>()
|
||||
const userInfo = ref<Customer>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function info(val: Customer) {
|
||||
userInfoVisible.value = true
|
||||
userInfo.value = cloneDeep(val)
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addUserVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
async function walletCharge(val: Customer) {
|
||||
showWalletCharge.value = true
|
||||
formCharge.value.customer_id = val.id
|
||||
}
|
||||
|
||||
async function charge() {
|
||||
formChargeRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await chargeMoneyWallet(formCharge.value)
|
||||
message.success('افزایش اعتبار با موفقیت انجام شد')
|
||||
showWalletCharge.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
active: false,
|
||||
avatar_id: undefined,
|
||||
sts: undefined,
|
||||
id: undefined,
|
||||
mobile: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
if (editId) {
|
||||
await updateCustomer(editId, form.value)
|
||||
} else {
|
||||
await createCustomer(form.value)
|
||||
}
|
||||
addUserVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<CollapsePanel :key="activeKey">
|
||||
<template #header>
|
||||
<div class="w-full">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span>{{ props.title }}</span>
|
||||
<BaseIcon :class="[{ rotate: props.actives.includes(props.activeKey) }]" icon="vuesax-linear:arrow-left-1" size="17" />
|
||||
</div>
|
||||
<div :class="[{ open: props.actives.includes(props.activeKey) }]"></div>
|
||||
</div>
|
||||
</template>
|
||||
<slot name="content"></slot>
|
||||
</CollapsePanel>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {CollapsePanel} from "ant-design-vue";
|
||||
|
||||
interface Props {
|
||||
title: string,
|
||||
activeKey: string | number,
|
||||
actives: string[] | number[]
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
.open {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #E5E7EB;
|
||||
|
||||
}
|
||||
|
||||
.rotate {
|
||||
transform: rotate(-90deg);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.ant-collapse > .ant-collapse-item > .ant-collapse-header {
|
||||
direction: rtl !important;
|
||||
justify-content: space-between !important;
|
||||
background-color: #fff !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ant-collapse{
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.ant-collapse > .ant-collapse-item {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.ant-collapse-content {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.ant-collapse > .ant-collapse-item > .ant-collapse-header .ant-collapse-arrow {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ant-collapse > .ant-collapse-item > .ant-collapse-header {
|
||||
padding: 12px 16px 0 !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست قلک ها">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
</BaseTable>
|
||||
</BasicShowContext>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type {TableInput} from '@core/type/baseTable'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import {
|
||||
changeCustomerActivation,
|
||||
changeCustomerArchive,
|
||||
changeCustomerOrderActivation,
|
||||
confirmUser,
|
||||
getCustomerTable
|
||||
} from '@/api/customer'
|
||||
import {cols} from '@/pages/menuPages/customers/base/hooks/fundsColumns'
|
||||
import {useUserStore} from '@/store/userStore'
|
||||
import {usePrefix} from '@core/composable/usePrefix'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {inputRules} from '@/utils/inputRules'
|
||||
import type {User} from '@/model/user'
|
||||
import {toJalaliNoTime} from '@core/utils/useDataTime'
|
||||
import type {Customer} from '@/model/customer'
|
||||
import {onMounted} from 'vue'
|
||||
import {getFundsTable} from "@/api/user";
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
|
||||
interface Prop {
|
||||
customerId?: number
|
||||
}
|
||||
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeMoney', 'chargeGold'])
|
||||
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 confirmVisible = ref<boolean>(false)
|
||||
const confirmInfo = ref<Customer>()
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
return getFundsTable(params, props.customerId)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
const refPop = ref()
|
||||
|
||||
const loading = ref<boolean>(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';
|
||||
.ant-popover,
|
||||
.ant-tooltip {
|
||||
z-index: 10 !important;
|
||||
}
|
||||
|
||||
.@{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,104 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست معرفی کرده ها">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
</BaseTable>
|
||||
</BasicShowContext>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type {TableInput} from '@core/type/baseTable'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import {
|
||||
changeCustomerActivation,
|
||||
changeCustomerArchive,
|
||||
changeCustomerOrderActivation,
|
||||
confirmUser,
|
||||
getCustomerTable
|
||||
} from '@/api/customer'
|
||||
import {cols} from '@/pages/menuPages/customers/base/hooks/referralColumns'
|
||||
import {useUserStore} from '@/store/userStore'
|
||||
import {usePrefix} from '@core/composable/usePrefix'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {inputRules} from '@/utils/inputRules'
|
||||
import type {User} from '@/model/user'
|
||||
import {toJalaliNoTime} from '@core/utils/useDataTime'
|
||||
import type {Customer} from '@/model/customer'
|
||||
import {onMounted} from 'vue'
|
||||
import {getReferralsTable} from "@/api/user";
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
|
||||
interface Prop {
|
||||
customerId?: number
|
||||
}
|
||||
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeMoney', 'chargeGold'])
|
||||
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 confirmVisible = ref<boolean>(false)
|
||||
const confirmInfo = ref<Customer>()
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
|
||||
return getReferralsTable(params, props.customerId)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
const refPop = ref()
|
||||
|
||||
const loading = ref<boolean>(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';
|
||||
.ant-popover,
|
||||
.ant-tooltip {
|
||||
z-index: 10 !important;
|
||||
}
|
||||
|
||||
.@{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,611 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="md:flex pr-3">
|
||||
<div class="content-center">فعال سازی محصولات:</div>
|
||||
<div class="ml-2 content-center mt-1 md:mt-unset md:mr-4">زمان شروع </div>
|
||||
<div>
|
||||
<TimePicker
|
||||
v-model:value="startTime"
|
||||
:locale="customLocale"
|
||||
placeholder="انتخاب زمان"
|
||||
:defaultValue="dayjs('00:00:00', 'HH:mm:ss')"
|
||||
/>
|
||||
</div>
|
||||
<div class="md:mr-4 ml-2 mt-2 md:mt-unset content-center">زمان پایان </div>
|
||||
<div>
|
||||
<TimePicker
|
||||
v-model:value="endTime"
|
||||
:locale="customLocale"
|
||||
placeholder="انتخاب زمان"
|
||||
:defaultValue="dayjs('00:00:00', 'HH:mm:ss')"
|
||||
/>
|
||||
</div>
|
||||
<BaseButton @click="setTimeActive(startTime , endTime)" class="mt-2 md:mt-unset md:mr-2">ثبت</BaseButton>
|
||||
</div>
|
||||
<BasicShowContext title=" لیست محصولات">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن محصول</div>
|
||||
<BaseIcon icon="vuesax-linear:box" Size="16px" />
|
||||
</BaseButton>
|
||||
</template>
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<a-tooltip class="cursor-pointer" :key="record.open_buy">
|
||||
<template v-if="!record.open_buy" #title><span>فعال کردن خرید</span></template>
|
||||
<template v-else #title><span>غیر فعال کردن خرید</span></template>
|
||||
<BaseIcon
|
||||
icon="vuesax-linear:money-receive"
|
||||
:color="record.open_buy ? '#16A34A' : '#DC2626'"
|
||||
@click="activeBuy(record)"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip class="cursor-pointer" :key="record.open_sell">
|
||||
<template v-if="!record.open_sell" #title><span>فعال کردن فروش</span></template>
|
||||
<template v-else #title><span>غیر فعال کردن فروش</span></template>
|
||||
<BaseIcon
|
||||
icon="vuesax-linear:money-send"
|
||||
:color="record.open_sell ? '#16A34A' : '#DC2626'"
|
||||
@click="activeSell(record)"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip class="cursor-pointer" :key="record.active">
|
||||
<template v-if="!record.active" #title><span>فعال کردن محصول</span></template>
|
||||
<template v-else #title><span>غیر فعال کردن محصول</span></template>
|
||||
<BaseIcon
|
||||
v-if="!record.active"
|
||||
icon="vuesax-linear:close-circle"
|
||||
color="#DC2626"
|
||||
@click="activeProduct(record)"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
icon="vuesax-linear:tick-circle"
|
||||
color="#16A34A"
|
||||
@click="activeProduct(record)"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<!-- <a-tooltip class="cursor-pointer" :key="record.show">
|
||||
<template v-if="!record.show" #title><span>نشان دادن محصول</span></template>
|
||||
<template v-else #title><span>مخفی کردن محصول</span></template>
|
||||
<BaseIcon
|
||||
v-if="!record.show"
|
||||
icon="vuesax-linear:chart-fail"
|
||||
color="#DC2626"
|
||||
@click="visibilityProduct(record)"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
icon="vuesax-linear:chart-success"
|
||||
color="#16A34A"
|
||||
@click="visibilityProduct(record)"
|
||||
/>
|
||||
</a-tooltip>-->
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('edit', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<BaseIcon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- <div class="md:hidden">-->
|
||||
<!-- <a-popover title="" placement="right" @cancel="">
|
||||
<template #content>
|
||||
<div class="flex flex-col gap-3">
|
||||
<a-tooltip :key="record.is_archive" placement="bottom" class="cursor-pointer">
|
||||
<template #title>
|
||||
<span>{{
|
||||
record.is_archive ? 'بیرون بردن از بایگانی' : 'بایگانی کردن'
|
||||
}}</span>
|
||||
</template>
|
||||
<a-popconfirm
|
||||
title="آیا مشتری را بایگانی می کنید؟"
|
||||
ok-text="تایید"
|
||||
cancel-text="رد"
|
||||
placement="topLeft"
|
||||
@confirm="archiveFunction(record.id)"
|
||||
@cancel=""
|
||||
>
|
||||
<!– <template #icon><question-circle-outlined style="color: red" /></template>–>
|
||||
<Icon
|
||||
class="cursor-pointer"
|
||||
icon="vuesax-linear:archive-tick"
|
||||
color="#e3bf00"
|
||||
/>
|
||||
</a-popconfirm>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:key="record.active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>
|
||||
{{ record.active ? 'غیرفعال کردن حساب کاربری' : 'فعال کردن حساب کاربری' }}
|
||||
</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="
|
||||
record.active ? 'vuesax-linear:user-tick' : 'vuesax-linear:user-remove'
|
||||
"
|
||||
:color="record.active ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('chargeMoney', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>شارژ کیف پول ریالی</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:wallet-add" color="#9333ea" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('chargeGold', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>شارژ کیف پول طلایی</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:wallet-money" color="#ea580c" />
|
||||
</a-tooltip>
|
||||
<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('edit', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:key="record.trade_active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerOrderActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>
|
||||
{{
|
||||
record.trade_active ? 'غیر مجاز کردن سفارش دهی' : 'مجاز کردن سفارش دهی'
|
||||
}}
|
||||
</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="
|
||||
record.trade_active === 1
|
||||
? 'vuesax-linear:box-tick'
|
||||
: 'vuesax-linear:box-remove'
|
||||
"
|
||||
:color="record.trade_active === 1 ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="!record.is_legal"
|
||||
:key="record.trade_active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="openConfirmUser(record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>تایید کاربر</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:user-search" color="#0d9488" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<!– <template #icon><question-circle-outlined style="color: red" /></template>–>
|
||||
<Icon class="cursor-pointer" icon="vuesax-linear:setting" color="#000" />
|
||||
</a-popover>
|
||||
</div>
|
||||
<div class="gap-2 hidden md:flex justify-center">
|
||||
<a-tooltip :key="record.is_archive" placement="bottom" class="cursor-pointer">
|
||||
<template #title>
|
||||
<span>{{ record.is_archive ? 'بیرون بردن از بایگانی' : 'بایگانی کردن' }}</span>
|
||||
</template>
|
||||
<a-popconfirm
|
||||
title="آیا مشتری را بایگانی می کنید؟"
|
||||
ok-text="تایید"
|
||||
cancel-text="رد"
|
||||
placement="topLeft"
|
||||
@confirm="archiveFunction(record.id)"
|
||||
@cancel=""
|
||||
>
|
||||
<!– <template #icon><question-circle-outlined style="color: red" /></template>–>
|
||||
<Icon class="cursor-pointer" icon="vuesax-linear:archive-tick" color="#e3bf00" />
|
||||
</a-popconfirm>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:key="record.active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{
|
||||
record.active ? 'غیرفعال کردن حساب کاربری' : 'فعال کردن حساب کاربری'
|
||||
}}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="record.active ? 'vuesax-linear:user-tick' : 'vuesax-linear:user-remove'"
|
||||
:color="record.active ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('chargeMoney', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>شارژ کیف پول ریالی</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:wallet-add" color="#9333ea" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('chargeGold', record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>شارژ کیف پول طلایی</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:wallet-money" color="#ea580c" />
|
||||
</a-tooltip>
|
||||
<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('edit', record)">
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:key="record.trade_active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerOrderActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{
|
||||
record.trade_active ? 'غیر مجاز کردن سفارش دهی' : 'مجاز کردن سفارش دهی'
|
||||
}}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="
|
||||
record.trade_active === 1 ? 'vuesax-linear:box-tick' : 'vuesax-linear:box-remove'
|
||||
"
|
||||
:color="record.trade_active === 1 ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
v-if="!record.is_legal"
|
||||
:key="record.trade_active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="openConfirmUser(record)"
|
||||
>
|
||||
<template #title>
|
||||
<span>تایید کاربر</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:user-search" color="#0d9488" />
|
||||
</a-tooltip>
|
||||
<!– <a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('delete', record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>حذف</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:trash" color="#EB3535" />
|
||||
</a-tooltip>–>
|
||||
</div>-->
|
||||
</template>
|
||||
</BaseTable>
|
||||
<BasicModal
|
||||
v-model:visible="confirmVisible"
|
||||
width="50vw"
|
||||
title="تایید مشتری"
|
||||
@ok="confirmUserFunction"
|
||||
ok-text="تایید"
|
||||
:loading="loading"
|
||||
@close="confirmVisible = false"
|
||||
>
|
||||
<div class="mt-[-10px] mb-10 font-bold">آیا از اطلاعات وارد شده اطمینان دارید؟</div>
|
||||
<div class="grid grid-cols-4 gap-2">
|
||||
<BasicInfoItem title="نام و نام خانوادگی" :value="confirmInfo?.name" />
|
||||
<BasicInfoItem title="شماره همراه" :value="confirmInfo?.mobile" />
|
||||
<BasicInfoItem
|
||||
title="تاریخ تولد"
|
||||
:value="confirmInfo?.birth_date ? toJalaliNoTime(confirmInfo?.birth_date) : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="شماره تلفن" :value="confirmInfo?.phone_number ?? '_'" />
|
||||
<BasicInfoItem title="نام استان" :value="confirmInfo?.province" />
|
||||
<BasicInfoItem title="نام شهر" :value="confirmInfo?.city" />
|
||||
<BasicInfoItem title="شماره ملی" :value="confirmInfo?.n_code" />
|
||||
</div>
|
||||
</BasicModal>
|
||||
</BasicShowContext>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type { TableInput } from '@core/type/baseTable'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import {
|
||||
changeActiveProduct,
|
||||
changeBuyActiveProduct,
|
||||
changeCustomerArchive,
|
||||
changeCustomerOrderActivation,
|
||||
changeProductActivation, changeSellActiveProduct, changeVisibilityProduct,
|
||||
confirmUser,
|
||||
getCustomerTable, setActiveTime
|
||||
} from "@/api/product";
|
||||
import { cols } from '@/pages/menuPages/products/base/hooks/customerColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message, type TimePickerProps } from "ant-design-vue";
|
||||
import { inputRules } from '@/utils/inputRules'
|
||||
import type { User } from '@/model/user'
|
||||
import { toJalaliNoTime } from '@core/utils/useDataTime'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import { onMounted } from 'vue'
|
||||
import { Modal } from 'ant-design-vue'
|
||||
import type {Product} from "@/model/product";
|
||||
import {resolve} from "path";
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'chargeMoney', 'chargeGold'])
|
||||
|
||||
const { prefixCls } = usePrefix('pophoverstatus')
|
||||
|
||||
//permission
|
||||
function checkPermission(temp: string) {
|
||||
const store = useUserStore()
|
||||
return store.canAccess(temp)
|
||||
}
|
||||
|
||||
//define table
|
||||
const table = ref(null)
|
||||
const data = ref()
|
||||
const confirmVisible = ref<boolean>(false)
|
||||
const confirmInfo = ref<Customer>()
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: async (params: TableInput) => {
|
||||
const data = await getCustomerTable(params)
|
||||
startTime.value = dayjs(data?.auto_open_at, 'HH:mm:ss')
|
||||
endTime.value = dayjs(data?.auto_close_at, 'HH:mm:ss')
|
||||
return data
|
||||
},
|
||||
//bordered: true
|
||||
})
|
||||
const refPop = ref()
|
||||
|
||||
// function edit(recordId){
|
||||
// emits('edit', recordId);
|
||||
// console.log( recordId);
|
||||
// console.log( visibleAction.value[parseInt(recordId)]);
|
||||
// visibleAction.value[recordId]=false
|
||||
// console.log('ddddd')
|
||||
// }
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
function openConfirmUser(user: Customer) {
|
||||
confirmInfo.value = user
|
||||
confirmVisible.value = true
|
||||
}
|
||||
|
||||
async function archiveFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerArchive(id)
|
||||
reload()
|
||||
message.success('مشتری با موفقیت بایگانی شد.')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmUserFunction() {
|
||||
try {
|
||||
loading.value = true
|
||||
await confirmUser(confirmInfo.value?.id)
|
||||
reload()
|
||||
confirmVisible.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function changeCustomerOrderActivationFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerOrderActivation(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
|
||||
})
|
||||
|
||||
const activeSell = async (product: Product) => {
|
||||
Modal.confirm({
|
||||
title: 'وضعیت فروش محصول تغییر خواهد یافت.آیا مطمئن هستید؟',
|
||||
okText: 'بله',
|
||||
cancelText: 'انصراف',
|
||||
centered: true,
|
||||
onOk: async () => {
|
||||
await changeSellActiveProduct(product.id)
|
||||
reload()
|
||||
},
|
||||
onCancel() {
|
||||
console.log('Cancel')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const activeBuy = async (product: Product) => {
|
||||
Modal.confirm({
|
||||
title: 'وضعیت خرید محصول تغییر خواهد یافت.آیا مطمئن هستید؟',
|
||||
okText: 'بله',
|
||||
cancelText: 'انصراف',
|
||||
centered: true,
|
||||
onOk: async () => {
|
||||
await changeBuyActiveProduct(product.id)
|
||||
reload()
|
||||
},
|
||||
onCancel() {
|
||||
console.log('Cancel')
|
||||
}
|
||||
})
|
||||
}
|
||||
const activeProduct = async (product: Product) => {
|
||||
Modal.confirm({
|
||||
title: 'آیا مطمئن به انجام این عملیات هستید؟',
|
||||
okText: 'بله',
|
||||
cancelText: 'انصراف',
|
||||
centered: true,
|
||||
onOk: async () => {
|
||||
await changeActiveProduct(product.id)
|
||||
reload()
|
||||
},
|
||||
onCancel() {
|
||||
console.log('Cancel')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const visibilityProduct = async (product: Product) => {
|
||||
Modal.confirm({
|
||||
title: 'آیا مطمئن به انجام این عملیات هستید؟',
|
||||
okText: 'بله',
|
||||
cancelText: 'انصراف',
|
||||
centered: true,
|
||||
onOk: async () => {
|
||||
await changeVisibilityProduct(product.id)
|
||||
reload()
|
||||
},
|
||||
onCancel() {
|
||||
console.log('Cancel')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
import { ref } from 'vue'
|
||||
import { TimePicker } from 'ant-design-vue'
|
||||
import dayjs from 'dayjs';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat'
|
||||
import locale from "ant-design-vue/es/date-picker/locale/fa_IR"
|
||||
const startTime = ref(dayjs('00:00:00', 'HH:mm:ss'))
|
||||
const endTime = ref(dayjs('00:00:00', 'HH:mm:ss'))
|
||||
dayjs.extend(customParseFormat)
|
||||
const customLocale = ref({
|
||||
...locale,
|
||||
lang: {
|
||||
...locale.lang,
|
||||
now: "اکنون",
|
||||
ok: "ثبت",
|
||||
},
|
||||
})
|
||||
async function setTimeActive(start: string, end: string) {
|
||||
try {
|
||||
const startTimeFormatted = dayjs(start, 'HH:mm:ss').format('HH:mm:ss')
|
||||
const endTimeFormatted = dayjs(end, 'HH:mm:ss').format('HH:mm:ss')
|
||||
await setActiveTime(startTimeFormatted, endTimeFormatted)
|
||||
message.success('با موفقیت ثبت شد.')
|
||||
} catch (e) {
|
||||
message.error('زمان را وارد کنید.')
|
||||
// console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@prefix: ~'@{prefixCls}-pophoverstatus';
|
||||
.ant-popover,
|
||||
.ant-tooltip {
|
||||
z-index: 10 !important;
|
||||
}
|
||||
|
||||
.@{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,291 @@
|
||||
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: 'title',
|
||||
key: 'title',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'تصویر',
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'وزن',
|
||||
dataIndex: 'amount',
|
||||
key: 'amount',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'واحد',
|
||||
dataIndex: 'unit',
|
||||
key: 'unit',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'دسته بندی',
|
||||
dataIndex: 'group_type',
|
||||
key: 'group_type',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'قیمت',
|
||||
dataIndex: 'price',
|
||||
key: 'price',
|
||||
type: 'Text',
|
||||
},
|
||||
{
|
||||
title: 'متد',
|
||||
dataIndex: 'reading_method',
|
||||
key: 'reading_method',
|
||||
type: 'Text',
|
||||
customRender: (record) => {
|
||||
return (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag>
|
||||
{record?.record.reading_method ? record?.record.reading_method : 'دستی'}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
/*{
|
||||
title: 'کارمزد درصدی موقع خرید',
|
||||
dataIndex: 'percent_fee_buy',
|
||||
key: 'percent_fee_buy',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'کارمزد درصدی موقع فروش',
|
||||
dataIndex: 'percent_fee_sell',
|
||||
key: 'percent_fee_sell',
|
||||
type: 'Number'
|
||||
},*/
|
||||
{
|
||||
title: 'هزینه نقدی موقع خرید',
|
||||
dataIndex: 'cash_fee_buy',
|
||||
key: 'cash_fee_buy',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'هزینه نقدی موقع فروش',
|
||||
dataIndex: 'cash_fee_sell',
|
||||
key: 'cash_fee_sell',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'وضعیت محصول',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
type: 'Boolean',
|
||||
customRender: (record) => {
|
||||
return (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag
|
||||
class="px-3 font-bold py-1"
|
||||
textColor={record?.record.active ? '#65a30d' : '#dc2626'}
|
||||
bgColor={record?.record.active ? '#ecfccb' : '#fee2e2'}
|
||||
>
|
||||
{record?.record.active ? 'باز' : 'بسته'}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'عملیات',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
slot: 'action',
|
||||
filterable: false
|
||||
}
|
||||
|
||||
// {
|
||||
// title: 'کد معرف',
|
||||
// dataIndex: 'referral_id',
|
||||
// key: 'referral_id',
|
||||
// type: 'Text'
|
||||
// },
|
||||
// {
|
||||
// title: 'نام معرف کاربر',
|
||||
// dataIndex: 'referral.name',
|
||||
// key: 'referral.name',
|
||||
// type: 'Text'
|
||||
// },
|
||||
// {
|
||||
// title: 'موجودی ریالی (ریال)',
|
||||
// dataIndex: 'wallet.cash',
|
||||
// key: 'wallet.cash',
|
||||
// type: 'Number',
|
||||
// customRender(data) {
|
||||
// return usePrice(data.record?.wallet[0]?.cash ?? 0, true, '')
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// title: 'موجودی طلایی (گرم)',
|
||||
// dataIndex: 'wallet.gold',
|
||||
// key: 'wallet.gold',
|
||||
// type: 'Number',
|
||||
// filterable: false,
|
||||
// customRender(data) {
|
||||
// let sum = 0
|
||||
// data.record.wallet.forEach((x) => (sum += x.gold))
|
||||
// return sum.toFixed(3)
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// title: 'اخرین بازدید',
|
||||
// dataIndex: 'last_seen_at',
|
||||
// key: 'last_seen_at',
|
||||
// type: 'DateTime',
|
||||
// customRender(data) {
|
||||
// return toJalali(data.record.last_seen_at)
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// title: 'وضعیت کاربر',
|
||||
// dataIndex: 'active',
|
||||
// key: 'active',
|
||||
// type: 'Boolean',
|
||||
// customRender: ({ record }) => {
|
||||
// return record.active ? (
|
||||
// <div class="flex justify-center">
|
||||
// <CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
// فعال
|
||||
// </CustomTag>
|
||||
// </div>
|
||||
// ) : (
|
||||
// <div class="flex justify-center">
|
||||
// <CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
// غیر فعال
|
||||
// </CustomTag>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// title: 'وضعیت سفارش دهی',
|
||||
// dataIndex: 'trade_active',
|
||||
// key: 'trade_active',
|
||||
// sortable: false,
|
||||
// type: 'Boolean',
|
||||
// customRender: ({ record }) => {
|
||||
// return record.trade_active ? (
|
||||
// <div class="flex justify-center">
|
||||
// <CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
// مجاز
|
||||
// </CustomTag>
|
||||
// </div>
|
||||
// ) : (
|
||||
// <div class="flex justify-center">
|
||||
// <CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
// غیر مجاز
|
||||
// </CustomTag>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// },
|
||||
/*{
|
||||
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
|
||||
// }
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { 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: 'fund.title',
|
||||
key: 'fund.title',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'موجودی طلا',
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Number'
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,163 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { 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: 'name',
|
||||
key: 'name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'نوع کاربر',
|
||||
dataIndex: 'type_str',
|
||||
key: 'type_str',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'کد معرف',
|
||||
dataIndex: 'referral_id',
|
||||
key: 'referral_id',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'وضعیت کاربر',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
type: 'Boolean',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'وضعیت سفارش دهی',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
customRender: ({ record }) => {
|
||||
return record.trade_active === 1 ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class={'font-bold px-6'}>
|
||||
غیر مجاز
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
/*{
|
||||
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)
|
||||
}
|
||||
},*/
|
||||
]
|
||||
@@ -0,0 +1,842 @@
|
||||
<template xmlns="http://www.w3.org/1999/html">
|
||||
<div>
|
||||
<!-- <BasicMainCard>-->
|
||||
<div class="flex w-full h-full">
|
||||
<tbl
|
||||
ref="table"
|
||||
class="w-full h-full"
|
||||
@info="info"
|
||||
@edit="edit"
|
||||
@add="add"
|
||||
@chargeMoney="walletMoneyCharge"
|
||||
@chargeGold="walletGoldCharge"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
<!-- </BasicMainCard>-->n
|
||||
<BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="50rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} محصول`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>
|
||||
<Collapse class="grid grid-cols-1 gap-2" v-model:activeKey="activeKey_">
|
||||
<BaseCollapse title="اطلاعات محصول" active-key="0" :actives="activeKey_">
|
||||
<template #content>
|
||||
<!-- <div class="flex justify-between h-full w-full">-->
|
||||
<div
|
||||
v-if="form.group_type === '' && form.group_type !== 'آبشده'"
|
||||
class="md:flex justify-between border-1 border-solid rounded-lg border-gray-200 p-2"
|
||||
>
|
||||
<div class="items-center">
|
||||
<span class="ml-4">دریافت قیمت از :</span>
|
||||
<a-radio-group v-model:value="methodOption" name="radioGroup">
|
||||
<a-radio class="items-center" value="1">دستی</a-radio>
|
||||
<a-radio class="" value="2">اتوماتیک</a-radio>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="methodOption === '1'" class="md:flex items-center justify-between md:w-[25rem]">
|
||||
<div class=" ">قیمت وسط :</div>
|
||||
<BasicInput class="mt-1 md:mt-unset" addon-before="ریال" type="price" v-model:value="form.price" />
|
||||
<AButton
|
||||
class="border-green text-green mt-1 md:mt-unset rounded-full aspect-square"
|
||||
size="small"
|
||||
shape="circle"
|
||||
@click="addPrice()"
|
||||
>
|
||||
<template #icon>
|
||||
<div class="flex items-center justify-center">
|
||||
<Icon icon="vuesax-linear:add" size="20" />
|
||||
</div>
|
||||
</template>
|
||||
</AButton>
|
||||
<AButton
|
||||
class="border-red text-red mr-1 md:mr-unset rounded-full"
|
||||
size="small"
|
||||
shape="circle"
|
||||
@click="minusPrice()"
|
||||
>
|
||||
<template #icon>
|
||||
<div class="flex items-center justify-center">
|
||||
<Icon icon="vuesax-linear:minus" size="20" />
|
||||
</div>
|
||||
</template>
|
||||
</AButton>
|
||||
</div>
|
||||
<div v-if="methodOption === '2'" class=" md:flex justify-between items-center">
|
||||
<div class="ml-4">قیمت :</div>
|
||||
<div class="">
|
||||
<BasicSelect
|
||||
class="w-11rem method_style"
|
||||
allowClear
|
||||
:items="pricesList"
|
||||
valueName="name"
|
||||
keyName="id"
|
||||
v-model:value="form.reading_method"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="form.group_type === '' && form.group_type !== 'آبشده'"
|
||||
class="md:flex justify-between p-2 border-1 border-solid rounded-lg border-gray-200 mt-2">
|
||||
<div>
|
||||
<span class="ml-4">وزن :</span>
|
||||
<a-radio-group v-model:value="weightOption" name="radioGroup" class="">
|
||||
<a-radio value="1">دارد</a-radio>
|
||||
<a-radio value="2">ندارد</a-radio>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<div v-if="weightOption === '1'" class="flex items-center">
|
||||
<span class="ml-4 ">وزن به گرم :</span>
|
||||
<div class="">
|
||||
<BasicInput v-model:value="form.amount" type="number" />
|
||||
</div>
|
||||
<div class="mt-1 mr-4" v-if="form.amount && form.amount < 1 && 0 < form.amount">
|
||||
معادل {{ form.amount * 1000 }} سوت
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="عنوان" name="title" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.title" />
|
||||
</a-form-item>
|
||||
<a-form-item label="دسته بندی" name="group_type" :rules="inputRules()">
|
||||
<BasicSelect
|
||||
v-model:value="form.group_type"
|
||||
:items="categoryItems"
|
||||
valueName="value"
|
||||
keyName="value"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="واحد" name="unit" :rules="inputRules()">
|
||||
<BasicSelect
|
||||
v-model:value="form.unit"
|
||||
:items="unitItems"
|
||||
valueName="value"
|
||||
keyName="value"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item v-if="weightOption === '1'" label="وزن به گرم" name="amount" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.amount" type="number" />
|
||||
</a-form-item>-->
|
||||
<a-form-item v-if="form.group_type === '' && form.group_type !== 'آبشده'"
|
||||
label="کارمزد درصدی موقع خرید" name="percent_fee_buy" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.percent_fee_buy" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="form.group_type === '' && form.group_type !== 'آبشده'"
|
||||
label="هزینه نقدی موقع خرید" name="cash_fee_buy" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.cash_fee_buy" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="form.group_type === '' && form.group_type !== 'آبشده'"
|
||||
label="کارمزد درصدی موقع فروش" name="percent_fee_sell" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.percent_fee_sell" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="form.group_type === '' && form.group_type !== 'آبشده'"
|
||||
label="هزینه نقدی موقع فروش" name="cash_fee_sell" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.cash_fee_sell" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="زمان شروع فعال سازی" name="auto_open_at">
|
||||
<TimePicker
|
||||
v-model:value="form.auto_open_at"
|
||||
:locale="customLocale"
|
||||
placeholder="انتخاب زمان"
|
||||
:defaultValue="dayjs('00:00:00', 'HH:mm:ss')"
|
||||
/>
|
||||
<!-- <a-time-picker v-model:value="form.auto_open_at"/>-->
|
||||
</a-form-item>
|
||||
<a-form-item label="زمان پایان فعال سازی" name="auto_close_at">
|
||||
<TimePicker
|
||||
v-model:value="form.auto_close_at"
|
||||
:locale="customLocale"
|
||||
placeholder="انتخاب زمان"
|
||||
:defaultValue="dayjs('00:00:00', 'HH:mm:ss')"
|
||||
/>
|
||||
<!-- <a-time-picker v-model:value="form.auto_close_at"/>-->
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form>
|
||||
</template>
|
||||
</BaseCollapse>
|
||||
<BaseCollapse title="تصاویر محصول" active-key="1" :actives="activeKey_">
|
||||
<template #content>
|
||||
<div class="flex gap-2">
|
||||
<IndexImageUploader
|
||||
v-model:file-list="ProductIndexImage"
|
||||
@ok="uploadedIndexFile"
|
||||
@delete="deleteIndexFile"
|
||||
/>
|
||||
<ProductImageUploader
|
||||
v-model:file-list="ImageFileList"
|
||||
@ok="uploadedFile"
|
||||
@delete="deleteFile"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</BaseCollapse>
|
||||
</Collapse>
|
||||
</BasicModal>
|
||||
|
||||
<BasicModal
|
||||
v-model:visible="userInfoVisible"
|
||||
width="100vw"
|
||||
title="اطلاعات کاربر"
|
||||
:loading="loading"
|
||||
custom-footer
|
||||
@close="userInfoVisible = false"
|
||||
>
|
||||
<a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane key="اطلاعات جامع" tab="اطلاعات جامع">
|
||||
<div class="grid grid-cols-4 gap-2">
|
||||
<div class="col-span-4 bg-gray-100 w-full rounded-lg flex p-3 justify-between">
|
||||
<div>
|
||||
<div class="font-bold">{{ userInfo.name }}</div>
|
||||
<div class="mt-1">{{ userInfo?.mobile }}</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center items-center pl-3">
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
<Icon
|
||||
:icon="
|
||||
userInfo.is_legal === 0
|
||||
? 'vuesax-linear:close-circle'
|
||||
: 'vuesax-linear:verify'
|
||||
"
|
||||
:key="userInfo.is_legal"
|
||||
:color="userInfo.is_legal === 0 ? '#ff0000' : '#008000'"
|
||||
/>
|
||||
<p
|
||||
class="text-[11px] mt-2"
|
||||
:class="userInfo.is_legal === 0 ? 'reject' : 'success'"
|
||||
>
|
||||
{{ userStatus(userInfo.is_legal).title }}
|
||||
</p>
|
||||
</div>
|
||||
<div>{{ toJalaliNoTime(userInfo?.created_at) }}</div>
|
||||
<div class="mt-2">
|
||||
<CustomTag
|
||||
:textColor="userInfo?.active ? '#25855A' : '#C53030'"
|
||||
:bgColor="userInfo?.active ? '#E3F4E9' : '#FECACA'"
|
||||
class="font-bold px-6"
|
||||
>
|
||||
{{ userInfo?.active ? "فعال" : "غیرفعال" }}
|
||||
</CustomTag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BasicInfoItem title="کد کاربری" :value="userInfo?.id" />
|
||||
<BasicInfoItem title="نوع کاربر" :value="userInfo?.type_str" />
|
||||
<BasicInfoItem
|
||||
title="تاریخ تولد"
|
||||
:value="userInfo?.birth_date ? toJalaliNoTime(userInfo?.birth_date) : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="شماره ملی" :value="userInfo?.n_code ?? '_'" />
|
||||
<BasicInfoItem title="نام استان" :value="userInfo?.province ?? '_'" />
|
||||
<BasicInfoItem title="نام شهر" :value="userInfo?.city ?? '_'" />
|
||||
<BasicInfoItem
|
||||
title="سقف اعتبار"
|
||||
:value="userInfo?.gram ? `${userInfo?.gram} گرم` : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="کد معرف" :value="userInfo?.referral_id" />
|
||||
<BasicInfoItem
|
||||
title="کد معرف کاربر"
|
||||
:value="userInfo?.referral ? userInfo?.referral?.id : '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="نام معرف کاربر"
|
||||
:value="userInfo?.referral ? userInfo?.referral?.name : '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="میزان سود معرفی"
|
||||
:value="userInfo?.profit_amount ? `${userInfo?.profit_amount} گرم` : '_'"
|
||||
/>
|
||||
<BasicInfoItem
|
||||
title="حداکثر معرفی"
|
||||
:value="userInfo?.add_user_limit ? `${userInfo?.add_user_limit} نفر` : '_'"
|
||||
/>
|
||||
<BasicInfoItem title="آخرین بازدید" :value="toJalali(userInfo?.last_seen_at)" />
|
||||
<BasicInfoItem title="وضعیت سفارش دهی">
|
||||
<CustomTag
|
||||
:textColor="userInfo?.trade_active === 1 ? '#25855A' : '#C53030'"
|
||||
:bgColor="userInfo?.trade_active === 1 ? '#E3F4E9' : '#FECACA'"
|
||||
class="font-bold px-6"
|
||||
>
|
||||
{{ userInfo?.trade_active === 1 ? "مجاز" : "غیر مجاز" }}
|
||||
</CustomTag>
|
||||
</BasicInfoItem>
|
||||
<div class="col-span-4 grid grid-cols-2 gap-3">
|
||||
<div
|
||||
v-for="(item, index) in userInfo.wallet"
|
||||
:key="index"
|
||||
class="grid grid-cols-2 bg-orange-50 gap-2 rounded-lg p-2"
|
||||
>
|
||||
<BasicInfoItem
|
||||
title="نام قلک"
|
||||
:value="item?.fund ? item?.fund?.title : 'کیف پول طلایی'"
|
||||
/>
|
||||
<BasicInfoItem title="مقدار طلا" :value="`${item?.gold} گرم`" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="لیست سفارشات" tab="لیست سفارشات">
|
||||
<orders-tbl ref="orderTable" :customerId="userInfo?.id" @info="infoOrder" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="لیست تراکنش ها" tab="لیست تراکنش ها">
|
||||
<transactions-tbl ref="transactionTable" :customerId="userInfo?.id" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="پیامک ها" tab="پیامک ها">
|
||||
<sms-tbl ref="smsTable" :mobile="userInfo?.mobile" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="معرفی کرده ها" tab="معرفی کرده ها">
|
||||
<ReferralsTable ref="referralTable" :customerId="userInfo?.id" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="قلک ها" tab="قلک ها">
|
||||
<FundsTable ref="fundTable" :customerId="userInfo?.id" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</BasicModal>
|
||||
<BasicModal
|
||||
v-model:visible="showMoneyWalletCharge"
|
||||
width="20rem"
|
||||
title="شارژ کیف پول ریالی"
|
||||
@ok="chargeMoneyWallet"
|
||||
:loading="loading"
|
||||
@close="showMoneyWalletCharge = false"
|
||||
>
|
||||
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
|
||||
<a-form-item label="مقدار شارژ " name="value" :rules="inputRules()">
|
||||
<BasicInput addon-before="ریال" v-model:value="formCharge.value" type="price" />
|
||||
<div v-show="formCharge.value > 10">
|
||||
معادل {{ usePrice(formCharge.value / 10, true, "تومان") }}
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item label="علت شارژ " name="value" :rules="inputRules()">
|
||||
<BasicInput v-model:value="formCharge.note" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
<BasicModal
|
||||
v-model:visible="showGoldWalletCharge"
|
||||
width="20rem"
|
||||
title="شارژ کیف پول طلایی"
|
||||
@ok="chargeGoldWallet"
|
||||
:loading="loading"
|
||||
@close="showGoldWalletCharge = false"
|
||||
>
|
||||
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
|
||||
<a-form-item label="مقدار شارژ " name="value" :rules="inputRules()">
|
||||
<BasicInput addon-before="گرم" v-model:value="formCharge.value" type="number" />
|
||||
<!-- <div v-show="formCharge.value > 10">
|
||||
معادل {{ usePrice(formCharge.value / 10, true, 'تومان') }}
|
||||
</div>-->
|
||||
</a-form-item>
|
||||
<a-form-item label="علت شارژ " name="value" :rules="inputRules()">
|
||||
<BasicInput v-model:value="formCharge.note" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
<BasicInfoModal
|
||||
v-model:visible="userInfoOrderVisible"
|
||||
@close="userInfoOrderVisible = false"
|
||||
:title="infoParams.title"
|
||||
:date="infoParams.date"
|
||||
:time="infoParams.time"
|
||||
:type="infoParams.type"
|
||||
:name="infoParams.name"
|
||||
:items="infoParams.items"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { Collapse, FormItem, message, Textarea, Form, TimePicker } from "ant-design-vue";
|
||||
import { inputLenRules, inputRules } from "@/utils/inputRules";
|
||||
import { useStaticApiListsStore } from "@/store/staticApisStore";
|
||||
import { ref, watch } from "vue";
|
||||
import tbl from "./components/table.vue";
|
||||
import type { FormInstance } from "ant-design-vue";
|
||||
import BasicInfoModal from "@/components/BasicInfoModal/index.vue";
|
||||
import type { Info } from "@/components/BasicInfoModal/model/Info";
|
||||
import { toJalali, 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 { createProduct, deleteCustomer, updateCustomer } from "@/api/product";
|
||||
import type { Charge } from "@/model/wallet";
|
||||
import customers from "@/router/routes/products";
|
||||
import { chargeWallet } from "@/api/wallet";
|
||||
import { usePrice } from "@core/utils/usePrice";
|
||||
import jalaliday from "jalaliday";
|
||||
import ordersTbl from "@/pages/menuPages/orders/components/table.vue";
|
||||
import transactionsTbl from "@/pages/menuPages/transactions/components/table.vue";
|
||||
import smsTbl from "@/pages/menuPages/sms/components/table.vue";
|
||||
import FundsTable from "@/pages/menuPages/customers/base/components/fundsTable.vue";
|
||||
import ReferralsTable from "@/pages/menuPages/customers/base/components/referralsTable.vue";
|
||||
import type { Order } from "@/model/order";
|
||||
import Icon from "@core/components/BaseIcon/src/Icon.vue";
|
||||
import type { MethodePrices, Product } from "@/model/product";
|
||||
import IndexImageUploader from "@/components/ProductUploader/IndexImageUploader.vue";
|
||||
import ProductImageUploader from "@/components/ProductUploader/ProductImageUploader.vue";
|
||||
|
||||
//tabs
|
||||
const activeKey = ref("اطلاعات جامع");
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false);
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore();
|
||||
|
||||
//define tbl
|
||||
const table = ref(null);
|
||||
const orderTable = ref(null);
|
||||
const transactionTable = ref(null);
|
||||
const smsTable = ref(null);
|
||||
const referralTable = ref(null);
|
||||
const fundTable = ref(null);
|
||||
const refreshTable = () => table?.value?.fetch();
|
||||
const refreshOrderTable = () => orderTable?.value?.fetch();
|
||||
const refreshTransactionTable = () => transactionTable?.value?.fetch();
|
||||
const refreshSMSTable = () => smsTable?.value?.fetch();
|
||||
const refreshReferralTable = () => referralTable?.value?.fetch();
|
||||
const refreshFundTable = () => fundTable?.value?.fetch();
|
||||
const methodOption = ref<string>("1");
|
||||
const weightOption = ref<string>("1");
|
||||
|
||||
const activeKey_ = ref(["0"]);
|
||||
const ImageFileList = ref<Array<FileList>>([]);
|
||||
|
||||
function uploadedFile(id: number) {
|
||||
// console.log(id)
|
||||
let arr: number[] | undefined = form.value.image_ids;
|
||||
arr?.push(id);
|
||||
form.value.image_ids = arr;
|
||||
}
|
||||
|
||||
function deleteFile() {
|
||||
form.value.image_ids = ImageFileList?.value.map((x: FileList) => x.uid);
|
||||
}
|
||||
|
||||
import BaseCollapse from "@/pages/menuPages/products/base/components/BaseCollapse.vue";
|
||||
import { methodePrices } from "@/api/price";
|
||||
import { getAllPrices } from "@/api/dashboard";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const ProductIndexImage = ref<Array<FileList>>([]);
|
||||
|
||||
function uploadedIndexFile(id: number) {
|
||||
// console.log(id)
|
||||
form.value.original_image_id = id;
|
||||
}
|
||||
|
||||
function deleteIndexFile() {
|
||||
form.value.original_image_id = null;
|
||||
form.value.original_image = null;
|
||||
ProductIndexImage.value = [];
|
||||
}
|
||||
|
||||
let updateKey = ref<number>(0);
|
||||
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: "بله",
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: "خیر",
|
||||
key: false
|
||||
}
|
||||
];
|
||||
const customerItems: Array<Item> = [
|
||||
{
|
||||
value: "همکار",
|
||||
key: 1
|
||||
},
|
||||
{
|
||||
value: "خانگی",
|
||||
key: 2
|
||||
},
|
||||
{
|
||||
value: "سرمایه گذار",
|
||||
key: 3
|
||||
}
|
||||
];
|
||||
|
||||
//wallet
|
||||
const showMoneyWalletCharge = ref<boolean>(false);
|
||||
const showGoldWalletCharge = ref<boolean>(false);
|
||||
const userInfoOrderVisible = ref<boolean>(false);
|
||||
|
||||
//form
|
||||
const form = ref<Partial<Product>>({
|
||||
auto_close_at: dayjs("00:00:00", "HH:mm:ss"),
|
||||
auto_open_at: dayjs("00:00:00", "HH:mm:ss")
|
||||
});
|
||||
|
||||
// const form = ref<Order>({
|
||||
// direction: 1,
|
||||
// price: 0,
|
||||
// amount: undefined,
|
||||
// pay_at: '',
|
||||
// difference: '',
|
||||
// customer_id: undefined,
|
||||
// goldCash: undefined,
|
||||
// goldValue: undefined
|
||||
// })
|
||||
const formCharge = ref<Charge>({});
|
||||
const formRef = ref<FormInstance>();
|
||||
const formChargeRef = ref<FormInstance>();
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({});
|
||||
|
||||
function infoOrder(val: Order) {
|
||||
infoParams.name = val.customer.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.amount ?? "-"
|
||||
},
|
||||
{
|
||||
key: "قیمت هر گرم طلا برای مشتری (ریال)",
|
||||
value: usePrice(val.price ?? 0) ?? "-"
|
||||
},
|
||||
{
|
||||
key: "قیمت کل برای مشتری (ریال)",
|
||||
value: usePrice(val.total_price ?? 0) ?? "-"
|
||||
},
|
||||
{
|
||||
key: "/قیمت هر گرم طلا بدون سود (ریال)",
|
||||
value: usePrice(val.price_original ?? 0) ?? "-"
|
||||
},
|
||||
{
|
||||
key: "قیمت کل بدون سود (ریال)",
|
||||
value: usePrice(val.total_price_original ?? 0) ?? "-"
|
||||
},
|
||||
{
|
||||
key: "سود هر گرم (ریال)",
|
||||
value: usePrice(val.fee ?? 0) ?? "-"
|
||||
},
|
||||
{
|
||||
key: "سود کل (ریال)",
|
||||
value: usePrice(val.total_fee ?? 0) ?? "-"
|
||||
},
|
||||
{
|
||||
key: "کد کاربری",
|
||||
value: val.customer.id ?? "-"
|
||||
},
|
||||
{
|
||||
key: "شماره ملی",
|
||||
value: val.customer.n_code ?? "-"
|
||||
},
|
||||
/* {
|
||||
key: "کارمزد ریالی",
|
||||
value: usePrice(val.service_charge_price ?? 0)
|
||||
},*/
|
||||
{
|
||||
key: "کارمزد طلایی",
|
||||
value: val.service_charge ?? "-" + " گرم"
|
||||
},
|
||||
/* {
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.customer.birth_date) ?? '-'
|
||||
},*/
|
||||
/* {
|
||||
key: 'نام فروشگاه',
|
||||
value: val.customer.shop_name ?? '-'
|
||||
},*/
|
||||
{
|
||||
key: "شماره تلفن",
|
||||
value: val.customer.phone_number ?? "-"
|
||||
},
|
||||
{
|
||||
key: "نام استان",
|
||||
value: val.customer.province ?? "-"
|
||||
},
|
||||
{
|
||||
key: "نام شهر",
|
||||
value: val.customer.city ?? "-"
|
||||
}
|
||||
/* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*/
|
||||
];
|
||||
userInfoOrderVisible.value = true;
|
||||
}
|
||||
|
||||
async function info(val: Customer) {
|
||||
activeKey.value = "اطلاعات جامع";
|
||||
userInfo.value = cloneDeep(val);
|
||||
userInfoVisible.value = true;
|
||||
await nextTick(() => {
|
||||
loading.value = true;
|
||||
refreshFundTable();
|
||||
refreshReferralTable();
|
||||
refreshSMSTable();
|
||||
refreshTransactionTable();
|
||||
refreshOrderTable();
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined;
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addUserVisible.value = true;
|
||||
editId = record.id;
|
||||
console.log(record);
|
||||
const customForm = cloneDeep(record);
|
||||
const start = dayjs(customForm.auto_open_at, "HH:mm:ss");
|
||||
const close = dayjs(customForm.auto_close_at, "HH:mm:ss");
|
||||
delete customForm.auto_open_at;
|
||||
delete customForm.auto_close_at;
|
||||
form.value.auto_open_at = start;
|
||||
form.value.auto_close_at = close;
|
||||
console.log(form.value);
|
||||
form.value = cloneDeep(customForm);
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true;
|
||||
editId = undefined;
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true;
|
||||
updateKey.value++;
|
||||
resetData();
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
async function walletMoneyCharge(val: Customer) {
|
||||
showMoneyWalletCharge.value = true;
|
||||
formCharge.value.customer_id = val.id;
|
||||
}
|
||||
|
||||
async function walletGoldCharge(val: Customer) {
|
||||
showGoldWalletCharge.value = true;
|
||||
formCharge.value.customer_id = val.id;
|
||||
}
|
||||
|
||||
async function chargeMoneyWallet() {
|
||||
formChargeRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
await chargeWallet(formCharge.value, "money");
|
||||
formCharge.value.value = undefined;
|
||||
message.success("افزایش اعتبار با موفقیت انجام شد");
|
||||
showMoneyWalletCharge.value = false;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function chargeGoldWallet() {
|
||||
formChargeRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
await chargeWallet(formCharge.value, "gold");
|
||||
formCharge.value.value = undefined;
|
||||
message.success("افزایش اعتبار با موفقیت انجام شد");
|
||||
showMoneyWalletCharge.value = false;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields();
|
||||
form.value = {
|
||||
unit: "",
|
||||
group_type: "",
|
||||
amount: undefined,
|
||||
percent_fee_buy: 0,
|
||||
cash_fee_buy: 0,
|
||||
percent_fee_sell: 0,
|
||||
cash_fee_sell: 0
|
||||
};
|
||||
};
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem("کاربر", id, deleteCustomer, refreshTable);
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true;
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false);
|
||||
const userInfoVisible = ref<boolean>(false);
|
||||
const userInfo = ref<Customer>();
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true;
|
||||
try {
|
||||
if (methodOption.value === "1") delete form.value.reading_method;
|
||||
else delete form.value.price;
|
||||
if (weightOption.value === "2")
|
||||
form.value.amount = 1;
|
||||
form.value.auto_open_at = dayjs(form.value.auto_open_at).format("HH:mm:ss");
|
||||
form.value.auto_close_at = dayjs(form.value.auto_close_at).format("HH:mm:ss");
|
||||
await methodePrices(form.value);
|
||||
if (editId) {
|
||||
await updateCustomer(editId, form.value);
|
||||
} else {
|
||||
await createProduct(form.value);
|
||||
}
|
||||
addUserVisible.value = false;
|
||||
refreshTable();
|
||||
resetData();
|
||||
message.success("عملیات با موفقیت انجام شد");
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const result = {
|
||||
title: ""
|
||||
};
|
||||
const userStatus = (status: number) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
result.title = "احراز هویت نشده";
|
||||
break;
|
||||
case 1:
|
||||
result.title = "احراز هویت شده توسط سامانه هوشمند";
|
||||
break;
|
||||
case 2:
|
||||
result.title = "احراز هویت شده توسط کارشناس";
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const unitItems: Array<Item> = [
|
||||
{
|
||||
value: "عدد"
|
||||
},
|
||||
{
|
||||
value: "گرم"
|
||||
}
|
||||
];
|
||||
|
||||
const categoryItems: Array<Item> = [
|
||||
{
|
||||
value: "آبشده"
|
||||
},
|
||||
{
|
||||
value: "مکعب"
|
||||
},
|
||||
{
|
||||
value: "گوی"
|
||||
},
|
||||
{
|
||||
value: "سکه"
|
||||
},
|
||||
{
|
||||
value: "سکه پارسیان"
|
||||
}
|
||||
];
|
||||
|
||||
const data = ref<MethodePrices[]>([]);
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
data.value = await methodePrices();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const pricesList = computed(() => {
|
||||
return data.value.map((x) => {
|
||||
return {
|
||||
id: `${x.name}`,
|
||||
// id: x.id,
|
||||
name: `${x.name}(${usePrice(x.price)})`
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
});
|
||||
|
||||
const addPrice = () => {
|
||||
if (form.value.price) form.value.price = parseInt(form.value.price) + 10000;
|
||||
else form.value.price = 0 + 10000;
|
||||
};
|
||||
|
||||
const minusPrice = () => {
|
||||
if (form.value.price) form.value.price = parseInt(form.value.price) - 10000;
|
||||
else form.value.price = 0 - 10000;
|
||||
};
|
||||
|
||||
import customParseFormat from "dayjs/plugin/customParseFormat";
|
||||
import locale from "ant-design-vue/es/date-picker/locale/fa_IR";
|
||||
|
||||
dayjs.extend(customParseFormat);
|
||||
const customLocale = ref({
|
||||
...locale,
|
||||
lang: {
|
||||
...locale.lang,
|
||||
now: "اکنون",
|
||||
ok: "ثبت"
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.reject {
|
||||
color: #ff0000 !important;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #008000 !important;
|
||||
}
|
||||
|
||||
.method_style .ant-select-selector {
|
||||
width: 15rem !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicMainCard>
|
||||
<div class="flex flex-col md:flex-row md:h-full">
|
||||
<!-- {{ menu }}-->
|
||||
<BasicMenu width="11rem" :menu="menu" mode="horizontal" class="md:hidden overflow-auto" />
|
||||
<BasicMenu
|
||||
width="13rem"
|
||||
:menu="menu"
|
||||
class="hidden md:inline overflow-auto min-w-[13.5rem]"
|
||||
/>
|
||||
<!-- <component :is="selectedComponent" class="mr-5" />-->
|
||||
<RouterView class="md:mr-5 md:mt-0 mt-5 w-full"></RouterView>
|
||||
</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 Nature from '@/pages/menuPages/setting/limitedOrder/index.vue'
|
||||
//s import test from './limitedOrder'
|
||||
//import Budget from '@/pages/menuPages/setting/budget/index.vue'
|
||||
//import ProjectType from '@/pages/menuPages/setting/projectType/index.vue'
|
||||
//import DocumentType from '@/pages/menuPages/setting/documentType/index.vue'
|
||||
// import Management from '@/pages/menuPages/setting/management/index.vue'
|
||||
//import Accessibility from '@/pages/menuPages/setting/accessibility/index.vue'
|
||||
//import SubmitProcess from '@/pages/menuPages/setting/submitProcess/index.vue'
|
||||
//import documentGroup from '@/pages/menuPages/setting/documentGroup/index.vue'
|
||||
//import userType from '@/pages/menuPages/setting/userType/index.vue'
|
||||
|
||||
const routerStore = useRouterStore()
|
||||
const menu = computed(() => {
|
||||
const item = routerStore.routes.find((item) => item.name === 'products')
|
||||
//console.log('aaaa', get(item, 'children[0].children', []))
|
||||
return get(item, 'children[0].children', [])
|
||||
})
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,5 @@
|
||||
<template></template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicMainCard>
|
||||
<div class="flex h-full">
|
||||
<!-- {{ menu }}-->
|
||||
<BasicMenu width="13rem" :menu="menu" class="overflow-auto min-w-[13.5rem]" />
|
||||
<!-- <component :is="selectedComponent" class="mr-5" />-->
|
||||
<RouterView class="mr-5 w-full"></RouterView>
|
||||
</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 Nature from '@/pages/menuPages/setting/limitedOrder/index.vue'
|
||||
//s import test from './limitedOrder'
|
||||
//import Budget from '@/pages/menuPages/setting/budget/index.vue'
|
||||
//import ProjectType from '@/pages/menuPages/setting/projectType/index.vue'
|
||||
//import DocumentType from '@/pages/menuPages/setting/documentType/index.vue'
|
||||
// import Management from '@/pages/menuPages/setting/management/index.vue'
|
||||
//import Accessibility from '@/pages/menuPages/setting/accessibility/index.vue'
|
||||
//import SubmitProcess from '@/pages/menuPages/setting/submitProcess/index.vue'
|
||||
//import documentGroup from '@/pages/menuPages/setting/documentGroup/index.vue'
|
||||
//import userType from '@/pages/menuPages/setting/userType/index.vue'
|
||||
|
||||
const routerStore = useRouterStore()
|
||||
const menu = computed(() => {
|
||||
const item = routerStore.routes.find((item) => item.name === 'settings')
|
||||
//console.log('aaaa', get(item, 'children[0].children', []))
|
||||
return get(item, 'children[0].children', [])
|
||||
})
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
:style="{ backgroundImage: `url(${bg1})` }"
|
||||
class="w-[80vw] h-full bg-cover flex items-center justify-center"
|
||||
>
|
||||
<div class="shadow-2xl h-[25vh] w-1/3 rounded-lg p-10 bg-white">
|
||||
<a-form :model="form" ref="formRef" autocomplete="off" @finish="ok">
|
||||
<div class="gap-4">
|
||||
<a-form-item label="سقف واریز اولیه (ریال)" name="value" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.value" type="number" />
|
||||
</a-form-item>
|
||||
<div v-show="form.value > 10">معادل {{ usePrice(form.value / 10, true, 'تومان') }}</div>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</a-form-item>-->
|
||||
<a-form-item>
|
||||
<BaseButton
|
||||
class="mt-10 w-full"
|
||||
:disabled="loading"
|
||||
type="primary"
|
||||
size="middle"
|
||||
html-type="submit"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>ثبت</div>
|
||||
</div>
|
||||
</BaseButton>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <BasicShowContent>-->
|
||||
<!-- <!– <BasicTags-->
|
||||
<!-- :items="items"-->
|
||||
<!-- color="green"-->
|
||||
<!-- @add="add"-->
|
||||
<!-- @edit="edit"-->
|
||||
<!-- :key="refresh"-->
|
||||
<!-- :loading="loading"-->
|
||||
<!-- @delete="deleteTag"-->
|
||||
<!-- />–>-->
|
||||
<!-- </BasicShowContent>-->
|
||||
<!-- <a-modal
|
||||
v-model:visible="addNatureVisible"
|
||||
title="Vertically centered modal dialog"
|
||||
centered
|
||||
@ok="addNatureVisible = false"
|
||||
>
|
||||
<BaseInput title="عنوان" size="large" />
|
||||
</a-modal>-->
|
||||
<!-- <BasicModal
|
||||
v-model:visible="addNatureVisible"
|
||||
:title="editId ? `ویرایش` : 'افزودن'"
|
||||
@close="addNatureVisible = false"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
>
|
||||
<a-form ref="formRef" :model="form" autocomplete="off">
|
||||
<a-form-item name="value" label="حروف اختصاری" :rules="valueValidation">
|
||||
<BasicInput v-model:value="form.value" placeHolder="حروف اختصاری" />
|
||||
</a-form-item>
|
||||
<a-form-item name="title_fa" label="عنوان">
|
||||
<BasicInput v-model:value="form.title_fa" placeHolder="نام" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicModal>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BasicShowContent from '@/components/BasicShowContext.vue'
|
||||
import { inputRules, valueValidation } from '@/utils/inputRules'
|
||||
import type { Const } from '../../../../model/const'
|
||||
import type { TagItem } from '@/components/BasicTags/model'
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
import { createAddConst, deleteConst, updateEditConst } from '@/api/consts'
|
||||
import bg1 from '@/pages/login/assets/img/loginBack.svg'
|
||||
import { usePrice } from '../../../../core/utils/usePrice'
|
||||
//data Arrays
|
||||
const items = ref<Array<TagItem>>()
|
||||
const baseData = ref<Array<Const>>()
|
||||
|
||||
//limitedOrder modal
|
||||
const addNatureVisible = ref<boolean>()
|
||||
const loading = ref<boolean>()
|
||||
|
||||
//refresh
|
||||
let refresh = 0
|
||||
|
||||
const form = ref<Const>({
|
||||
title_fa: '',
|
||||
value: ''
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//get limitedOrder
|
||||
/*onMounted(() => {
|
||||
setTypes()
|
||||
})
|
||||
const getTypes = async () =>
|
||||
(baseData.value = store.natureListData ?? (await store.getNatureConst()))*/
|
||||
/*async function setTypes() {
|
||||
try {
|
||||
loading.value = true
|
||||
await getTypes()
|
||||
// console.log('set', baseData.value)
|
||||
items.value = baseData.value?.map((x: Const) => {
|
||||
return {
|
||||
id: x.id,
|
||||
name: `${x.title_fa ?? ''}(${x.value})`
|
||||
}
|
||||
})
|
||||
refresh++
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در دریافت اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
// console.log(items.value)
|
||||
}*/
|
||||
|
||||
//delete limitedOrder item
|
||||
/*
|
||||
async function deleteTag(id: number) {
|
||||
// console.log(id)
|
||||
try {
|
||||
await deleteConst(id)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در حذف مورد')
|
||||
await resetData()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//edit limitedOrder
|
||||
// let editId: number | undefined = undefined
|
||||
|
||||
// function edit(id: number) {
|
||||
// const obj: Const = baseData.value?.find((x: Const) => x.id === id) ?? ({} as Const)
|
||||
// addNatureVisible.value = true
|
||||
// editId = id
|
||||
// form.value = obj
|
||||
// }
|
||||
|
||||
//resetData
|
||||
// async function resetData() {
|
||||
// await store.getNatureConst()
|
||||
// formRef.value?.resetFields()
|
||||
// form.value = {
|
||||
// title_fa: '',
|
||||
// value: ''
|
||||
// }
|
||||
// await setTypes()
|
||||
// }
|
||||
|
||||
//add
|
||||
|
||||
// function add() {
|
||||
// editId = undefined
|
||||
// addNatureVisible.value = true
|
||||
// resetData()
|
||||
// }
|
||||
|
||||
//submit
|
||||
async function ok() {
|
||||
let obj: Const = {
|
||||
key: 'limited_price',
|
||||
// title_fa: form.value.title_fa,
|
||||
value: form.value.value
|
||||
// id: editId
|
||||
}
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await updateEditConst(obj)
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در ثبت اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
// addNatureVisible.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <BaseTableOld v-bind="tblProps" @register="submit" ref="tbl"></BaseTableOld>-->
|
||||
<BaseTable v-bind="tblProps" ref="table" @register="register" :showPaginate="true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type { TableInput } from '@core/type/baseTable'
|
||||
import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable'
|
||||
import { cols } from '../hooks/numberColumns'
|
||||
import { getNumbersTable, getSMSTable } from '@/api/sms'
|
||||
|
||||
const [register, reload] = useBaseTable()
|
||||
const _selectedRows = ref([])
|
||||
interface Props {
|
||||
type: number | null
|
||||
items: number[]
|
||||
filter: string[]
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {})
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:items', value: number[]): void
|
||||
}>()
|
||||
|
||||
//define table
|
||||
const table = ref(null)
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
params.functions = props.filter
|
||||
return getNumbersTable(params)
|
||||
},
|
||||
rowSelection: {
|
||||
selectedRowKeys: _selectedRows,
|
||||
onSelect: (record: any, selected: any, selectedRows: any, nativeEvent: any) => {
|
||||
_selectedRows.value = selectedRows.map((item: any) => item.id)
|
||||
emit('update:items', _selectedRows.value)
|
||||
},
|
||||
onSelectAll: (selected: any, selectedRows: any, changeRows: any) => {
|
||||
_selectedRows.value = selectedRows.map((item: any) => item.id)
|
||||
emit('update:items', _selectedRows.value)
|
||||
}
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
|
||||
const fetch = () => {
|
||||
// console.log('sss')
|
||||
reload()
|
||||
}
|
||||
|
||||
const changeCheckItem = () => {
|
||||
emit('update:items', JSON.parse(JSON.stringify(_selectedRows.value)))
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
fetch
|
||||
})
|
||||
</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,113 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست پیامک ها">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<BaseButton v-if="!mobile" type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>ارسال پیامک</div>
|
||||
<BaseIcon icon="vuesax-linear:sms" Size="16px"/>
|
||||
</BaseButton>
|
||||
</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>
|
||||
</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/smsColumns'
|
||||
import {useUserStore} from '@/store/userStore'
|
||||
import {usePrefix} from '@core/composable/usePrefix'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {getOrderTable} from '@/api/order'
|
||||
import {getPriceTable} from '@/api/price'
|
||||
import {getSMSTable} from '@/api/sms'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
|
||||
interface Prop {
|
||||
mobile: number
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info'])
|
||||
|
||||
// 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.mobile) {
|
||||
params.filters = []
|
||||
params.filters?.push({
|
||||
field: "receiver",
|
||||
type: "text",
|
||||
value: props.mobile,
|
||||
cr: "and",
|
||||
op: "eq",
|
||||
hidden: false
|
||||
})
|
||||
}
|
||||
|
||||
return getSMSTable(params)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
// const loading = ref<boolean>(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,57 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { 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,
|
||||
width: 100,
|
||||
customRender: (record: any) => {
|
||||
return record.index + 1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'کد',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
type: 'Number',
|
||||
width: 100
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'نام کاربر',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
// className: 'column-money'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,84 @@
|
||||
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,
|
||||
width: 100,
|
||||
customRender: (record: any) => {
|
||||
return record.index + 1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'کد',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
type: 'Number',
|
||||
width: 100
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'تاریخ و ساعت',
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
type: 'DateTime',
|
||||
width: 200,
|
||||
customRender(data) {
|
||||
return toJalali(data.record.created_at)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'شماره تلفن',
|
||||
dataIndex: 'receiver',
|
||||
key: 'receiver',
|
||||
type: 'Text',
|
||||
width: 200,
|
||||
customRender(data){
|
||||
return data.record.person.mobile
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'نام دریافت کننده',
|
||||
dataIndex: 'receiver',
|
||||
key: 'receiver',
|
||||
type: 'Text',
|
||||
width: 200,
|
||||
customRender(data){
|
||||
if (data.record.person.name)
|
||||
return data.record.person.name
|
||||
return data.record.person.mobile
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'پیام',
|
||||
dataIndex: 'sms',
|
||||
key: 'sms',
|
||||
type: 'Number'
|
||||
// className: 'column-money'
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicMainCard>
|
||||
<div class="flex w-full h-full">
|
||||
<tbl ref="table" class="w-full h-full" @add="add" />
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
|
||||
<BasicModal
|
||||
v-model:visible="priceConfirmVisible"
|
||||
width="25rem"
|
||||
@ok="ok"
|
||||
:confirm-loading="loading"
|
||||
@close="priceConfirmVisible = false"
|
||||
>
|
||||
<div class="flex items-center gap-2 font-bold">
|
||||
<BaseIcon icon="vuesax-linear:info-circle" color="orange" />
|
||||
<div>آیا مطمئن به تغییر قیمت می باشید؟</div>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</div>
|
||||
<BasicModal
|
||||
v-model:visible="addSMSVisible"
|
||||
width="80vw"
|
||||
title=""
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addSMSVisible = false"
|
||||
>
|
||||
<!-- <a-tabs v-model:activeKey="activeKey">
|
||||
<a-tab-pane :key="1" tab="ارسال تکی" />
|
||||
<a-tab-pane :key="2" tab="ارسال گروهی" />
|
||||
</a-tabs>-->
|
||||
<a-form :model="form" ref="formRef" autocomplete="off" class="md:grid md:grid-cols-4 gap-2">
|
||||
<a-form-item label="انتخاب گروه">
|
||||
<BasicSelect
|
||||
v-model:value="selectedGroup"
|
||||
:items="groupItems"
|
||||
valueName="name"
|
||||
keyName="function"
|
||||
mode="multiple"
|
||||
class="w-full"
|
||||
@change="getGroupNumbers"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره های تکی" name="numbers" class="md:col-span-3">
|
||||
<BasicSelect
|
||||
v-model:value="form.single"
|
||||
mode="tags"
|
||||
valueName="name"
|
||||
keyName="mobile"
|
||||
type="tel"
|
||||
noData="لطفا شماره موبایل را وارد کنید و سپس روی کیبورد خود کلید تایید را بزنید"
|
||||
class="w-full smsSelector"
|
||||
>
|
||||
<template #notFoundContent>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else class="w-full text-center font-bold">لطفا شماره را وارد کنید</div>
|
||||
</template>
|
||||
</BasicSelect>
|
||||
</a-form-item>
|
||||
<a-form-item label="انتخاب کاربر" class="md:col-span-4">
|
||||
<BasicInput
|
||||
place-holder="جستجو"
|
||||
class="mb-2"
|
||||
@onchange="filterNumbers"
|
||||
:disabled="selectedGroup.length === 0"
|
||||
/>
|
||||
<a-table
|
||||
rowKey="mobile"
|
||||
:row-selection="{ selectedRowKeys: form.numbers, onChange: onSelectChange }"
|
||||
:columns="columns"
|
||||
:scroll="{ y: '20vh', x: 500 }"
|
||||
:pagination="false"
|
||||
:data-source="groupNumbers"
|
||||
>
|
||||
</a-table>
|
||||
</a-form-item>
|
||||
<a-form-item label="متن پیام" name="message" class="md:col-span-4">
|
||||
<BasicTextArea v-model:value="form.message" />
|
||||
<div class="md:flex items-center justify-between mt-2 md:flex-row-reverse">
|
||||
<BaseButton @click="addName()" type="primary" class="w-full md:w-10rem"
|
||||
>افزودن نام کاربر</BaseButton
|
||||
>
|
||||
<div class="text-gray-500">
|
||||
برای استفاده از نام اشخاص در پیام از گزینه افزودن نام کاربر استفاده کنید این متغیر با
|
||||
عنوان( name% )به متن پیام اضافه میگردد
|
||||
</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item class="col-span-4">
|
||||
<!-- <NumbersTable
|
||||
v-if="selectedGroup.length > 0"
|
||||
type="check"
|
||||
:items="form.numbers"
|
||||
:filter="selectedGroup"
|
||||
/>-->
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { ref } from 'vue'
|
||||
import tbl from './components/table.vue'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import { message } from 'ant-design-vue/es'
|
||||
import type { FunctionItem } from '@/model/Item'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import { createSMS, getCustomerList, getGroupsList } from '@/api/sms'
|
||||
import type { Sms } from '@/model/sms'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
const selectedGroup = ref<string[]>([])
|
||||
const groupItems = ref<FunctionItem[]>()
|
||||
const groupNumbers = ref<Customer[]>()
|
||||
let baseGroupNumbers: Customer[] = []
|
||||
|
||||
onMounted(() => getGroups())
|
||||
|
||||
async function getGroups() {
|
||||
try {
|
||||
loading.value = true
|
||||
groupItems.value = await getGroupsList()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const addName = () => {
|
||||
form.value.message = form.value.message.concat('', '%name')
|
||||
}
|
||||
|
||||
function filterNumbers(val: string) {
|
||||
// console.log(val)
|
||||
if (val !== '') {
|
||||
groupNumbers.value = baseGroupNumbers?.filter((v) => v.name.includes(val))
|
||||
} else groupNumbers.value = baseGroupNumbers
|
||||
}
|
||||
|
||||
// const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
async function getGroupNumbers(val: string[]) {
|
||||
if (val) {
|
||||
try {
|
||||
loading.value = true
|
||||
const { customers } = await getCustomerList(val)
|
||||
groupNumbers.value = customers
|
||||
baseGroupNumbers = customers
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch(selectedGroup, (val) => {
|
||||
console.log(val)
|
||||
if (val) {
|
||||
getGroupNumbers(val)
|
||||
}
|
||||
})
|
||||
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
const activeKey = ref(1)
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
/*
|
||||
function onselected(val) {
|
||||
console.log()
|
||||
}
|
||||
*/
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'کد کاربر',
|
||||
dataIndex: 'id'
|
||||
},
|
||||
{
|
||||
title: 'نام و نام خانوادگی',
|
||||
dataIndex: 'name'
|
||||
},
|
||||
{
|
||||
title: 'شماره همراه',
|
||||
dataIndex: 'mobile'
|
||||
}
|
||||
]
|
||||
const onSelectChange = (changableRowKeys: string[]) => {
|
||||
console.log('selectedRowKeys changed: ', changableRowKeys)
|
||||
// if (changableRowKeys !== undefined) {
|
||||
form.value.numbers = changableRowKeys
|
||||
// }
|
||||
}
|
||||
//role confirm items
|
||||
|
||||
//form
|
||||
const form = ref<Sms>({
|
||||
message: '',
|
||||
numbers: [],
|
||||
single: []
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addSMSVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
message: '',
|
||||
numbers: [],
|
||||
single: []
|
||||
}
|
||||
groupNumbers.value = []
|
||||
selectedGroup.value = []
|
||||
}
|
||||
//add project modal
|
||||
const addSMSVisible = ref<boolean>(false)
|
||||
const priceConfirmVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
if (!form.value.numbers) form.value.numbers = []
|
||||
form.value.numbers?.push(...(form.value.single ?? []))
|
||||
// console.log(form.value.numbers)
|
||||
// delete form.value.single
|
||||
await createSMS(form.value)
|
||||
// form.value.single = []
|
||||
resetData()
|
||||
addSMSVisible.value = false
|
||||
message.success('با موفقیت ارسال شد')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*async function ok() {
|
||||
loading.value = true
|
||||
try {
|
||||
await createPrice(form.value)
|
||||
refreshTable()
|
||||
priceConfirmVisible.value = false
|
||||
addSMSVisible.value = false
|
||||
// await confirmActOnApi('آیا از اعمال قیمت جدید اطمینان دارید؟', form.value, createPrice)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}*/
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.smsSelector .ant-select-selector {
|
||||
max-height: 5vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست گزارشات">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<!-- <template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن کیف پول</div>
|
||||
<BaseIcon icon="vuesax-linear:wallet-add" Size="16px" />
|
||||
</BaseButton>
|
||||
</template>-->
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<!-- <a-tooltip
|
||||
:key="record.active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{ record.active ? 'غیرفعال کردن' : 'فعال کردن' }}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="record.active ? 'vuesax-linear:tick-circle' : 'vuesax-linear:close-circle'"
|
||||
:color="record.active ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>-->
|
||||
<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('edit', record)">
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>-->
|
||||
<!-- <a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('delete', record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>حذف</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:trash" color="#EB3535" />
|
||||
</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/transactionsColumns'
|
||||
import {useUserStore} from '@/store/userStore'
|
||||
import {usePrefix} from '@core/composable/usePrefix'
|
||||
import {message} from 'ant-design-vue'
|
||||
import {getWalletTable} from '@/api/wallet'
|
||||
import {getTransactionTable} from '@/api/transaction'
|
||||
import {getSMSTable} from "@/api/sms";
|
||||
|
||||
|
||||
interface Prop {
|
||||
customerId: number
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info'])
|
||||
|
||||
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) => {
|
||||
// console.log(props.customerId)
|
||||
if (props.customerId) {
|
||||
params.filters = []
|
||||
params.filters?.push({
|
||||
field: "customer_id",
|
||||
type: "text",
|
||||
value: props.customerId,
|
||||
cr: "and",
|
||||
op: "eq",
|
||||
hidden: false
|
||||
})
|
||||
}
|
||||
return getTransactionTable(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,203 @@
|
||||
import type {BaseTableColumn} from '@core/type/baseTable'
|
||||
import {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: 'type_str',
|
||||
key: 'type_str',
|
||||
type: 'Text'
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'علت تراکنش',
|
||||
dataIndex: 'note',
|
||||
key: 'note',
|
||||
type: 'Text',
|
||||
|
||||
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'نوع تراکنش',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
customRender: ({record}) => {
|
||||
return record.type === 4 || record.type === 3 ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class={'font-bold px-6'}>
|
||||
پول
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
{/*<CustomTag textColor="rgb(255 120 0)" bgColor="rgb(255 221 0)">*/}
|
||||
<CustomTag textColor="#ca8a04" bgColor="#fef3c7" class={'font-bold px-6'}>
|
||||
طلا
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'نام مشتری',
|
||||
dataIndex: 'customer.name',
|
||||
key: 'customer.name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'مقدار طلا طی تراکنش (گرم)',
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Number',
|
||||
customRender: ({record}) => {
|
||||
return record.gold > 0 ? (
|
||||
<div class="flex justify-center">
|
||||
<div class={'font-bold px-6 text-green'}>{record.gold}</div>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
{/*<CustomTag textColor="rgb(255 120 0)" bgColor="rgb(255 221 0)">*/}
|
||||
<div class={'font-bold px-6 text-red'}>{record.gold}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'مقدار پول طی تراکنش (ریال)',
|
||||
dataIndex: 'cash',
|
||||
key: 'cash',
|
||||
type: 'Number',
|
||||
customRender: ({record}) => {
|
||||
return record.cash > 0 ? (
|
||||
<div class="flex justify-center">
|
||||
<div class={'font-bold px-6 text-green'}>{usePrice(record?.cash ?? 0, true, '')}</div>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
{/*<CustomTag textColor="rgb(255 120 0)" bgColor="rgb(255 221 0)">*/}
|
||||
<div class={'font-bold px-6 text-red'}>{usePrice(record?.cash ?? 0, true, '')}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
/* {
|
||||
title: 'شماره سفارش',
|
||||
dataIndex: 'order_id',
|
||||
key: 'order_id',
|
||||
type: 'Text'
|
||||
},*/
|
||||
/* {
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
},*/
|
||||
/* {
|
||||
title: 'نام فروشگاه',
|
||||
dataIndex: 'shop_name',
|
||||
key: 'shop_name',
|
||||
type: 'Text'
|
||||
},*/
|
||||
{
|
||||
title: 'تاریخ تراکنش',
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
type: 'DateTime',
|
||||
customRender: (record: any) => {
|
||||
return toJalaliNoTime(record.record.created_at)
|
||||
}
|
||||
}
|
||||
/*{
|
||||
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: 'action',
|
||||
key: 'action',
|
||||
slot: 'action',
|
||||
fixed: 'right',
|
||||
filterable: false
|
||||
}*/
|
||||
]
|
||||
@@ -0,0 +1,226 @@
|
||||
<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"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
<BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="40rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} کاربر`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="نام" name="fname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام خانوادگی" name="lname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره همراه" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="form.mobile" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ تولد" name="birth_date" :rules="inputRules()">
|
||||
<BaseDatePicker v-model:value="form.birth_date" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="ایمیل" name="email" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.email" />
|
||||
</a-form-item>-->
|
||||
<!-- <a-form-item label="نام فروشگاه" name="shop_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.shop_name" />
|
||||
</a-form-item>-->
|
||||
<a-form-item label="شماره تلفن" name="phone_number" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.phone_number" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام استان" name="province" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.province" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام شهر" name="city" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.city" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره ملی" name="n_code" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.n_code" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</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"
|
||||
itemsTitle="اطلاعات فردی"
|
||||
:name="infoParams.name"
|
||||
:items="infoParams.items"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } 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, updateCustomer } from '@/api/customer'
|
||||
import type { Transaction } from '@/model/transaction'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
|
||||
//form
|
||||
const form = ref<Customer>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function info(val: Transaction) {
|
||||
infoParams.name = val.customer.name
|
||||
infoParams.type = val.transaction_type === '1' ? 'نقدی' : 'طلا'
|
||||
infoParams.date = toJalaliNoTime(val.created_at)
|
||||
infoParams.time = toTime(val.created_at)
|
||||
infoParams.itemsTitle = 'اطلاعات کاربری'
|
||||
infoParams.items = [
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.n_code ?? '-'
|
||||
}
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addUserVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
active: false,
|
||||
avatar_id: undefined,
|
||||
sts: undefined,
|
||||
id: undefined,
|
||||
mobile: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
if (editId) {
|
||||
await updateCustomer(editId, form.value)
|
||||
} else {
|
||||
await createCustomer(form.value)
|
||||
}
|
||||
addUserVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست مدیران">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن مدیر</div>
|
||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
||||
</BaseButton>
|
||||
</template>
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<!-- <a-tooltip
|
||||
:key="record.active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeUserActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{ record.active ? 'غیرفعال کردن' : 'فعال کردن' }}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="record.active ? 'vuesax-linear:tick-circle' : 'vuesax-linear:close-circle'"
|
||||
:color="record.active ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>-->
|
||||
<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('edit', record)">
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
<!-- <a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('delete', record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>حذف</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:trash" color="#EB3535" />
|
||||
</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 { toJalali, toJalaliNoTime } from '@core/utils/useDataTime'
|
||||
import { message, Tag } from 'ant-design-vue'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import { changeUserActivation, getUserTable } from '@/api/user'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { cols } from '../hooks/usersColumns'
|
||||
import { changeCustomerActivation } from '@/api/customer'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info'])
|
||||
|
||||
//define table
|
||||
const table = ref(null)
|
||||
|
||||
//permission
|
||||
function checkPermission(temp: string) {
|
||||
const store = useUserStore()
|
||||
return store.canAccess(temp)
|
||||
}
|
||||
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
async function changeUserActivationFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeUserActivation(id)
|
||||
reload()
|
||||
message.success('تغییر وضعیت با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: (params: TableInput) => {
|
||||
return getUserTable(params)
|
||||
}
|
||||
//bordered: true
|
||||
})
|
||||
|
||||
const fetch = () => {
|
||||
// console.log('sss')
|
||||
reload()
|
||||
}
|
||||
// const spinTable = (val: boolean) => {
|
||||
// // console.log('sss')
|
||||
// table?.value?.loading.value = val
|
||||
// }
|
||||
defineExpose({
|
||||
fetch
|
||||
// spinTable
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,141 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { toJalaliNoTime, toTime } from '@core/utils/useDataTime'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
/*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: 'name',
|
||||
key: 'name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
},
|
||||
/* {
|
||||
title: 'وضعیت',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA">
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},*/
|
||||
/*{
|
||||
title: 'سمت',
|
||||
dataIndex: 'post_user',
|
||||
key: 'post_user',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
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
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- <BasicMainCard>-->
|
||||
<div class="flex w-full h-full">
|
||||
<tbl ref="table" class="w-full h-full" @info="info" @edit="edit" @add="add" />
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
<!-- </BasicMainCard>-->
|
||||
<BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="40rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} کاربر`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="نام" name="fname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام خانوادگی" name="lname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره همراه" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="form.mobile" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="editId" label="رمز عبور" name="password">
|
||||
<BasicInput v-model:value="form.password" is-password type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="editId" label="تکرار رمز عبور">
|
||||
<BasicInput v-model:value="form.repassword" is-password type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item v-if="editId" label="ارسال پیامک">
|
||||
<a-switch v-model:checked="form.send_sms" >
|
||||
<template #checkedChildren>فعال</template>
|
||||
<template #unCheckedChildren>غیر فعال</template>
|
||||
</a-switch>
|
||||
</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"
|
||||
itemsTitle="اطلاعات فردی"
|
||||
:name="infoParams.name"
|
||||
:items="infoParams.items"
|
||||
/>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } from '@/utils/inputRules'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
import type { Const } from '@/model/const'
|
||||
import type { User } from '@/model/user'
|
||||
import { createUser, deleteUser, updateUser } from '@/api/user'
|
||||
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'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
|
||||
//form
|
||||
const form = ref<User>({
|
||||
active: true
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function info(val: User) {
|
||||
infoParams.name = val.name
|
||||
infoParams.type = val.mobile
|
||||
infoParams.date = toJalaliNoTime(val.created_at)
|
||||
infoParams.time = toTime(val.created_at)
|
||||
infoParams.itemsTitle = 'اطلاعات کاربری'
|
||||
infoParams.items = [
|
||||
{
|
||||
key: 'تلفن همراه',
|
||||
value: val.mobile ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.id ?? '-'
|
||||
}
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: User) {
|
||||
addUserVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
active: false,
|
||||
avatar_id: undefined,
|
||||
sts: undefined,
|
||||
id: undefined,
|
||||
mobile: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteUser, refreshTable)
|
||||
|
||||
/* Modal.confirm({
|
||||
title: 'آیا از حذف کاربر اطمینان دارید؟',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'تایید',
|
||||
okType: 'danger',
|
||||
centered: true,
|
||||
cancelText: 'انصراف',
|
||||
async onOk() {
|
||||
// console.log('OK');
|
||||
await deleteItem(id)
|
||||
},
|
||||
onCancel() {
|
||||
console.log('Cancel')
|
||||
}
|
||||
})*/
|
||||
|
||||
/*async function deleteItem(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
// table?.value?.spinTable(true)
|
||||
await deleteUser(id)
|
||||
message.success('با موفقیت حذف شد')
|
||||
table?.value?.fetch()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
message.error('خطا در حذف')
|
||||
} finally {
|
||||
loading.value = false
|
||||
// table?.value?.spinTable(false)
|
||||
}
|
||||
}*/
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
interface selectsItem {
|
||||
responsibleItems: Array<User> | undefined
|
||||
users: Array<Const> | undefined
|
||||
}
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
if (editId) {
|
||||
if (form.value.password) {
|
||||
if (form.value.password === form.value.repassword) {
|
||||
await updateUser(editId, form.value)
|
||||
} else {
|
||||
message.error('پسورد وارد شده با تکرار پسورد وارد شده یکسان نیست')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
await updateUser(editId, form.value)
|
||||
}
|
||||
} else {
|
||||
await createUser(form.value)
|
||||
}
|
||||
addUserVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<svg width="299" height="331" viewBox="0 0 299 331" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.20561 15.7673C1.88291 15.7673 0 17.6502 0 19.9729V292.811C32.2359 284.941 68.9177 280.321 110.014 280.321C166.49 280.321 213.449 285.875 252.336 295.013V19.9729C252.336 17.6502 250.453 15.7673 248.131 15.7673H4.20561Z" fill="url(#paint0_linear_220_20208)"/>
|
||||
<rect x="15.772" y="31.5352" width="220.794" height="277.518" rx="4.20561" fill="url(#paint1_linear_220_20208)"/>
|
||||
<rect x="30.8423" y="53.262" width="189.252" height="122.991" fill="url(#paint2_linear_220_20208)"/>
|
||||
<rect x="31.541" y="195.523" width="189.252" height="18.9217" fill="#F6F6F4"/>
|
||||
<rect x="31.541" y="239.674" width="189.252" height="18.9217" fill="#F6F6F4"/>
|
||||
<rect x="53.6221" y="12.6143" width="145.093" height="25.2289" fill="#D8DDE2"/>
|
||||
<path d="M91.9618 0H160.377L170.328 12.6144H82.0107L91.9618 0Z" fill="#D0D6DC"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M172.67 201.831C176.495 201.921 179.989 199.721 181.492 196.278C182.996 192.833 182.204 188.841 179.495 186.197L155.609 162.745C151.953 159.166 146.025 159.166 142.37 162.745C138.714 166.324 138.714 172.128 142.37 175.707L166.323 199.092C167.998 200.774 170.272 201.755 172.67 201.831Z" fill="#209487"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M83.3257 166.413C67.9334 151.103 65.7138 127.268 78.0229 109.479C90.3321 91.6904 113.744 84.8976 133.949 93.2538C154.153 101.61 165.525 122.789 161.113 143.845C156.701 164.9 137.734 179.972 115.806 179.846C103.59 179.769 91.9058 174.936 83.3257 166.413Z" fill="#209487"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M89.4232 108.715C74.8842 122.991 74.8978 146.115 89.4535 160.374C104.009 174.633 127.6 174.633 142.155 160.374C156.71 146.115 156.724 122.991 142.185 108.715C127.607 94.4529 104.001 94.4529 89.4232 108.715Z" fill="white"/>
|
||||
<mask id="mask0_220_20208" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="78" y="98" width="76" height="74">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M89.4232 108.715C74.8842 122.991 74.8978 146.115 89.4535 160.374C104.009 174.633 127.6 174.633 142.155 160.374C156.71 146.115 156.724 122.991 142.185 108.715C127.607 94.4529 104.001 94.4529 89.4232 108.715Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_220_20208)">
|
||||
<path d="M149.593 107.996C149.593 143.426 132.334 170.792 107.652 186.247C82.9699 201.701 153.051 176.252 153.051 176.252L166.9 127.492C166.9 127.492 149.593 72.5672 149.593 107.996Z" fill="url(#paint3_linear_220_20208)"/>
|
||||
</g>
|
||||
<path d="M226.293 307.813L280.051 328.823L292.397 311.161L238.311 298.583L226.293 307.813Z" fill="url(#paint4_linear_220_20208)"/>
|
||||
<path d="M223.369 217.847L260.302 220.759L252.1 301.094C252.1 301.094 251.382 301.897 249.639 301.585C247.897 301.273 246.069 300.304 246.069 300.304L240.576 236.439C240.576 236.439 237.399 259.022 237.621 265.375C237.788 270.162 239.425 276.001 240.301 280.996C241.055 285.295 242.641 295.568 242.641 295.568C242.641 295.568 240.767 296.424 239.77 296.617C238.773 296.811 237.495 295.748 237.495 295.748C237.495 295.748 224.546 270.611 224.38 265.838C224.213 261.064 223.369 217.847 223.369 217.847Z" fill="url(#paint5_linear_220_20208)"/>
|
||||
<path d="M236.92 295.63C236.92 295.63 235.275 298.592 233.232 300.398C231.188 302.204 227.156 304.36 226.237 305.34C225.317 306.32 226.321 307.763 226.321 307.763L236.204 307.418L244.101 300.738L242.998 294.371L236.92 295.63Z" fill="#209487"/>
|
||||
<path d="M253.03 299.06L255.337 305.459C255.337 305.459 251.548 308.393 246.313 309.21C241.078 310.027 237.471 308.772 237.471 308.772C237.471 308.772 236.526 306.868 238.307 306.054C239.125 305.68 240.959 304.126 242.569 302.136C243.296 301.238 246.034 299.304 246.034 299.304L253.03 299.06Z" fill="#209487"/>
|
||||
<path d="M269.573 175.965C269.573 175.965 272.6 180.57 274.457 179.338C276.313 178.106 287.9 166.229 287.9 166.229C287.9 166.229 291.347 163.575 291.985 164.206C292.622 164.837 290.835 166.229 290.835 166.229C290.835 166.229 294.596 166.598 295.772 166.598C296.947 166.598 299.419 168.475 297.803 169.106C296.186 169.738 289.916 169.894 289.916 169.894C289.916 169.894 280.396 187.896 275.435 189.173C270.475 190.449 263.64 183.23 263.64 183.23L269.573 175.965Z" fill="#F6F6F4"/>
|
||||
<path d="M221.208 176.294C221.208 176.294 219.223 180.358 217.424 179.383C215.626 178.408 205.534 167.766 205.534 167.766C205.534 167.766 202.174 165.708 201.352 166.078C200.53 166.448 202.556 167.766 202.556 167.766C202.556 167.766 197.612 168.167 196.681 168.541C195.751 168.915 194.668 170.061 196.074 170.582C197.481 171.104 202.864 171.474 202.864 171.474C202.864 171.474 210.348 186.263 216.018 187.992C221.688 189.721 226.518 182.908 226.518 182.908L221.208 176.294Z" fill="#F6F6F4"/>
|
||||
<path d="M239.566 163.848V156.583C239.566 156.583 235.799 156.773 234.268 154.251C232.737 151.728 232.323 144.57 232.323 144.57L233.477 141.251L244.824 140.771L250.785 145.851L248.009 150.753L247.48 151.695L250.125 162.836L239.566 163.848Z" fill="#F6F6F4"/>
|
||||
<mask id="mask1_220_20208" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="232" y="140" width="19" height="24">
|
||||
<path d="M239.566 163.848V156.583C239.566 156.583 235.799 156.773 234.268 154.251C232.737 151.728 232.323 144.57 232.323 144.57L233.477 141.251L244.824 140.771L250.785 145.851L248.009 150.753L247.48 151.695L250.125 162.836L239.566 163.848Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask1_220_20208)">
|
||||
<path d="M246.947 149.681C243.594 153.851 237.794 156.766 237.039 156.766C236.284 156.766 241.256 161.996 241.256 161.996L245.301 163.851L251.043 162.634L253.093 156.766L249.474 150.108C249.474 150.108 250.3 145.51 246.947 149.681Z" fill="url(#paint6_linear_220_20208)"/>
|
||||
</g>
|
||||
<path d="M218.796 179.214L224.372 186.725L227.928 182.969C227.928 182.969 225.223 197.799 224.372 204.911C223.52 212.023 223.362 219.107 223.362 219.107C223.362 219.107 232.29 222.422 238.946 222.979C245.602 223.537 261.096 222.101 261.096 222.101L259.096 180.358L264.899 185.745L271.713 177.877C271.713 177.877 259.983 159.852 257.765 158.801C255.547 157.751 249.381 158.801 249.381 158.801C249.381 158.801 245.005 163.98 243.231 164.052C241.457 164.124 237.521 158.801 237.521 158.801C237.521 158.801 231.233 157.797 229.404 159.852C227.576 161.906 218.796 179.214 218.796 179.214Z" fill="url(#paint7_linear_220_20208)"/>
|
||||
<path d="M232.323 144.65C232.323 144.65 233.66 141.276 235.405 141.864C237.057 142.42 238.488 143.744 240.543 144.365C242.598 144.987 242.825 142.195 244.222 142.666C245.618 143.138 244.697 147.245 245.681 148.01C246.665 148.775 246.665 142.666 248.764 144.311C250.862 145.955 246.574 150.584 246.574 150.584C246.574 150.584 247.124 153.428 247.3 153.622C247.476 153.815 247.456 151.552 247.456 151.552C247.456 151.552 249.46 150.783 250.314 147.313C251.168 143.844 251.538 142.462 250.314 139.941C249.091 137.42 248.742 135.446 245.681 134.256C242.619 133.067 240.296 133.532 238.157 134.256C236.017 134.981 234.466 136.419 233.476 137.851C231.169 141.25 232.323 144.65 232.323 144.65Z" fill="#209487"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_220_20208" x1="167.995" y1="274.038" x2="167.995" y2="190.603" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#F7F7F7"/>
|
||||
<stop offset="1" stop-color="#E8EAEB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_220_20208" x1="15.772" y1="31.5352" x2="15.772" y2="309.053" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="0.746404" stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.697577"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_220_20208" x1="30.8423" y1="53.262" x2="30.8423" y2="176.253" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E8EAEB"/>
|
||||
<stop offset="1" stop-color="#F0F1F1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_220_20208" x1="138.831" y1="114.088" x2="109.601" y2="148.009" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EEEEEE" stop-opacity="0.367499"/>
|
||||
<stop offset="1" stop-color="#D8D8D8" stop-opacity="0.01"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_220_20208" x1="211.649" y1="316.125" x2="234.238" y2="353.107" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#B7BFC3"/>
|
||||
<stop offset="0.487221" stop-color="#D9E2E6"/>
|
||||
<stop offset="1" stop-color="#E6EDF3" stop-opacity="0.01"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_220_20208" x1="262.971" y1="301.24" x2="260.037" y2="217.202" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#A1A7B8"/>
|
||||
<stop offset="1" stop-color="#7B8195"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_220_20208" x1="248.536" y1="158.972" x2="248.536" y2="151.932" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FBD8D6"/>
|
||||
<stop offset="1" stop-color="#EAC0BE" stop-opacity="0.7"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_220_20208" x1="192.026" y1="187.89" x2="247.661" y2="246.581" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E5E9F0"/>
|
||||
<stop offset="1" stop-color="#D2DAE8"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.8 KiB |
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div class="flex items-center main">
|
||||
<div>{{ props.item.province }}</div>
|
||||
<BaseIcon icon="vuesax-linear:arrow-left-1" size=".9rem" />
|
||||
<div>{{ props.item.project }}</div>
|
||||
<BaseIcon icon="vuesax-linear:arrow-left-1" size=".9rem" />
|
||||
<div>{{ props.item.documentGroup }}</div>
|
||||
<BaseIcon icon="vuesax-linear:arrow-left-1" size=".9rem" />
|
||||
<div>{{ props.item.document }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type History from '@/pages/menuPages/customers/search/model/History'
|
||||
|
||||
//define props
|
||||
interface Prop {
|
||||
item: History
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.main {
|
||||
@apply w-full justify-center;
|
||||
background-color: #f6f6f4;
|
||||
border: solid 1px #b2b2b2;
|
||||
border-radius: @border-radius-base;
|
||||
height: 4rem;
|
||||
|
||||
div {
|
||||
@apply px-1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div :class="[prefixCls]">
|
||||
<div class="flex-row-reverse flex w-full">
|
||||
<BaseButton type="primary" size="small" iconSize="18px" icon="vuesax-linear:clipboard-export">
|
||||
افزودن پروژه
|
||||
</BaseButton>
|
||||
</div>
|
||||
<div class="md:px-14">
|
||||
<div class="colors-main">
|
||||
<p>در هر بخش یک مورد را انتخاب کنید</p>
|
||||
<div class="grid xl:grid-cols-12">
|
||||
<div class="grid xl:col-span-10 sm:grid-cols-2 md:grid-cols-4">
|
||||
<BasicSelect :items="province" title="استان" style="width: 100%" />
|
||||
<BasicSelect :items="project" title="پروژه" style="width: 100%" />
|
||||
<BasicSelect :items="documentGroup" title="گروه سندی" style="width: 100%" />
|
||||
<BasicSelect :items="documents" title="سند" style="width: 100%" />
|
||||
</div>
|
||||
<div class="relative col-span-2 flex flex-col-reverse">
|
||||
<div class="p-1">
|
||||
<BaseButton
|
||||
type="primary"
|
||||
size="small"
|
||||
iconSize="18px"
|
||||
icon="vuesax-linear:search-normal-1"
|
||||
>
|
||||
جست و جو
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-10">آخرین جست و جو</p>
|
||||
<div ref="historyElement" class="grid gap-5" :class="`grid-cols-${countHistoryElementSize}`">
|
||||
<div v-for="val in history.slice(0, countHistoryElementSize)" class="flex self-center">
|
||||
<HistoryCard :item="val" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="text-center">
|
||||
<img :src="searchIcon" class="h-[7rem] mt-8" />
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import HistoryCard from '@/pages/menuPages/customers/search/components/HistoryCard.vue'
|
||||
import type Item from '@/pages/menuPages/customers/search/model/item'
|
||||
import type History from '@/pages/menuPages/customers/search/model/History'
|
||||
import searchIcon from '@/pages/menuPages/customers/search/assets/svg/search.svg'
|
||||
import { useElementSize } from '@vueuse/core'
|
||||
|
||||
//ui historyElement
|
||||
const historyElement = ref(null)
|
||||
const historyElementSize = reactive(
|
||||
useElementSize(historyElement, { width: 0, height: 0 }, { box: 'border-box' })
|
||||
)
|
||||
const countHistoryElementSize = ref()
|
||||
watch(historyElementSize, (v) => {
|
||||
if (v.width > 1300) {
|
||||
countHistoryElementSize.value = 5
|
||||
} else if (v.width > 1100 && v.width <= 1300) {
|
||||
countHistoryElementSize.value = 4
|
||||
} else countHistoryElementSize.value = 3
|
||||
})
|
||||
|
||||
//css style
|
||||
const { prefixCls } = usePrefix('search-customers')
|
||||
|
||||
// items
|
||||
const province = ref<Array<Item>>([
|
||||
{
|
||||
value: 'تهران',
|
||||
key: 'Tehran'
|
||||
},
|
||||
{
|
||||
value: 'اصفهان',
|
||||
key: 'Esfahan'
|
||||
},
|
||||
{
|
||||
value: 'خراسان رضوی',
|
||||
key: 'Khorasan Razavi'
|
||||
},
|
||||
{
|
||||
value: 'مازندران',
|
||||
key: 'Mazandaran'
|
||||
}
|
||||
])
|
||||
const project = ref<Array<Item>>([
|
||||
{
|
||||
value: 'پروژه 1',
|
||||
key: '1'
|
||||
},
|
||||
{
|
||||
value: 'پروژه 2',
|
||||
key: '2'
|
||||
},
|
||||
{
|
||||
value: 'پروژه 3',
|
||||
key: '3'
|
||||
}
|
||||
])
|
||||
const documentGroup = ref<Array<Item>>([
|
||||
{
|
||||
value: 'گروه 1',
|
||||
key: '1'
|
||||
},
|
||||
{
|
||||
value: 'گروه 2',
|
||||
key: '2'
|
||||
},
|
||||
{
|
||||
value: 'گروه 3',
|
||||
key: '3'
|
||||
}
|
||||
])
|
||||
const documents = ref<Array<Item>>([
|
||||
{
|
||||
value: 'سند 1',
|
||||
key: '1'
|
||||
},
|
||||
{
|
||||
value: 'سند 2',
|
||||
key: '2'
|
||||
},
|
||||
{
|
||||
value: 'سند 3',
|
||||
key: '3'
|
||||
}
|
||||
])
|
||||
|
||||
//history test
|
||||
|
||||
const history = ref<Array<History>>([
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
},
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
},
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
},
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
},
|
||||
{
|
||||
province: 'اصفهان',
|
||||
project: 'پروژه 1',
|
||||
document: 'گروه 1',
|
||||
documentGroup: 'سند 1'
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@prefix: ~'@{prefixCls}-search-projects';
|
||||
|
||||
.@{prefix} {
|
||||
.colors-main {
|
||||
@apply mt-5 p-4 border-solid border-1;
|
||||
border-radius: @border-radius-base;
|
||||
background-color: @bg-color-1;
|
||||
border-color: @border-color-1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,6 @@
|
||||
export default interface History {
|
||||
province: string
|
||||
project: string
|
||||
documentGroup: string
|
||||
document: string
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export default interface Item {
|
||||
value: String
|
||||
key: String
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست کیف پول">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<!-- <template #extraHeader>
|
||||
<BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن کیف پول</div>
|
||||
<BaseIcon icon="vuesax-linear:wallet-add" Size="16px" />
|
||||
</BaseButton>
|
||||
</template>-->
|
||||
<template #extraHeader>
|
||||
<div class="w-60vw hidden md:block">
|
||||
<div class="grid grid-cols-2 gap-3 w-full py-2 px-5">
|
||||
<div
|
||||
:class="
|
||||
sums?.cash >= 0
|
||||
? sums?.cash === 0
|
||||
? 'bg-amber-100'
|
||||
: 'bg-green-100'
|
||||
: 'bg-red-100'
|
||||
"
|
||||
class="rounded-lg p-2"
|
||||
>
|
||||
<div class="mb-1">مجموع موجودی کیف پول:</div>
|
||||
<div class="flex gap-2">
|
||||
<div
|
||||
class="gap-5 rounded-lg border-1 border-solid border-gray flex-1 p-1 text-center"
|
||||
>
|
||||
<div class="font-bold">{{ usePrice(sums?.cash ?? 0) }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="gap-5 rounded-lg border-1 border-solid border-gray flex-1 p-1 text-center"
|
||||
>
|
||||
<div class="font-bold">
|
||||
{{ usePrice(sums?.cashToGold.toFixed(2) ?? 0, true, 'گرم') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
:class="
|
||||
sums?.gold >= 0
|
||||
? sums?.gold === 0
|
||||
? 'bg-amber-100'
|
||||
: 'bg-green-100'
|
||||
: 'bg-red-100'
|
||||
"
|
||||
class="rounded-lg p-2"
|
||||
>
|
||||
<div class="mb-1">مجموع موجودی کیف طلا:</div>
|
||||
<div class="flex gap-2">
|
||||
<div
|
||||
class="gap-5 rounded-lg border-1 border-solid border-gray flex-1 p-1 text-center"
|
||||
>
|
||||
<div class="font-bold">{{ usePrice(sums?.gold ?? 0, true, 'گرم') }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="gap-5 rounded-lg border-1 border-solid border-gray flex-1 p-1 text-center"
|
||||
>
|
||||
<div class="font-bold">{{ usePrice(sums?.goldToCash ?? 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<!-- <a-tooltip
|
||||
:key="record.active"
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="changeCustomerActivationFunction(record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{ record.active ? 'غیرفعال کردن' : 'فعال کردن' }}</span>
|
||||
</template>
|
||||
<Icon
|
||||
:icon="record.active ? 'vuesax-linear:tick-circle' : 'vuesax-linear:close-circle'"
|
||||
:color="record.active ? '#54AD06' : '#ad0627'"
|
||||
/>
|
||||
</a-tooltip>-->
|
||||
<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('edit', record)">
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
<!-- <a-tooltip
|
||||
placement="bottom"
|
||||
class="cursor-pointer"
|
||||
@click="emits('delete', record.id)"
|
||||
>
|
||||
<template #title>
|
||||
<span>حذف</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:trash" color="#EB3535" />
|
||||
</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/walletColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { getWalletTable } from '@/api/wallet'
|
||||
import { usePrice } from '../../../../core/utils/usePrice'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'sums'])
|
||||
|
||||
const { prefixCls } = usePrefix('pophoverstatus')
|
||||
|
||||
//permission
|
||||
/*function checkPermission(temp: string) {
|
||||
const store = useUserStore()
|
||||
return store.canAccess(temp)
|
||||
}*/
|
||||
|
||||
//define table
|
||||
const table = ref(null)
|
||||
const sums = ref<any>()
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
api: async (params: TableInput) => {
|
||||
const data = await getWalletTable(params)
|
||||
sums.value = data?.sums
|
||||
emits('sums', data?.sums)
|
||||
console.log(sums.value)
|
||||
return data
|
||||
}
|
||||
//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,157 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { 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: 'customer.name',
|
||||
key: 'customer.name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'موجودی کیف پول (ریال)',
|
||||
dataIndex: 'cash',
|
||||
key: 'cash',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return usePrice(data.record.cash, true, '')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'موجودی کیف طلا (گرم)',
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Text'
|
||||
}
|
||||
/* {
|
||||
title: 'شماره موبایل',
|
||||
dataIndex: 'mobile',
|
||||
key: 'mobile',
|
||||
type: 'Number'
|
||||
},*/
|
||||
/* {
|
||||
title: 'نام فروشگاه',
|
||||
dataIndex: 'shop_name',
|
||||
key: 'shop_name',
|
||||
type: 'Text'
|
||||
},*/
|
||||
/* {
|
||||
title: 'وضعیت',
|
||||
dataIndex: 'active',
|
||||
key: 'active',
|
||||
customRender: ({ record }) => {
|
||||
return record.active ? (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
|
||||
فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex justify-center">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA">
|
||||
غیر فعال
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},*/
|
||||
/*{
|
||||
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
|
||||
}*/
|
||||
]
|
||||
@@ -0,0 +1,330 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicMainCard>
|
||||
<div class="md:hidden">
|
||||
<!-- <div class="bg-gray-100 grid grid-cols-2 gap-3 w-full py-2 px-5">
|
||||
<div class="gap-5 text-xs">
|
||||
<div>مجموع موجودی کیف پول:</div>
|
||||
<div class="font-bold">{{ usePrice(sums?.cash ?? 0) }}</div>
|
||||
</div>
|
||||
<div class="gap-5 text-xs">
|
||||
<div>مجموع موجودی کیف پول:</div>
|
||||
<div class="font-bold">
|
||||
{{ usePrice(sums?.cashToGold.toFixed(2) ?? 0, true, 'گرم') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-5 text-xs">
|
||||
<div>مجموع موجودی کیف طلا:</div>
|
||||
<div class="font-bold">{{ usePrice(sums?.gold ?? 0, true, 'گرم') }}</div>
|
||||
</div>
|
||||
<div class="gap-5 text-xs">
|
||||
<div>مجموع موجودی کیف طلا:</div>
|
||||
<div class="font-bold">{{ usePrice(sums?.goldToCash ?? 0) }}</div>
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="grid grid-cols-3 gap-1 text-xs">
|
||||
<div class="bg-blue-600 text-white rounded p-1">مجموع</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">ریال</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">گرم</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">کیف طلا</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="
|
||||
sums?.goldToCash >= 0
|
||||
? sums?.goldToCash === 0
|
||||
? 'bg-amber-600'
|
||||
: 'bg-green-600'
|
||||
: 'bg-red-600'
|
||||
"
|
||||
>
|
||||
{{ usePrice(sums?.goldToCash ?? 0, true, '') }}
|
||||
</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="
|
||||
sums?.gold >= 0 ? (sums?.gold === 0 ? 'bg-amber-600' : 'bg-green-600') : 'bg-red-600'
|
||||
"
|
||||
>
|
||||
{{ usePrice(sums?.gold ?? 0, true, '') }}
|
||||
</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">کیف پول</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="
|
||||
sums?.cash >= 0 ? (sums?.cash === 0 ? 'bg-amber-600' : 'bg-green-600') : 'bg-red-600'
|
||||
"
|
||||
>
|
||||
{{ usePrice(sums?.cash ?? 0, true, '') }}
|
||||
</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="
|
||||
sums?.cashToGold >= 0
|
||||
? sums?.cashToGold === 0
|
||||
? 'bg-amber-600'
|
||||
: 'bg-green-600'
|
||||
: 'bg-red-600'
|
||||
"
|
||||
>
|
||||
{{ usePrice(sums?.cashToGold ?? 0, true, '') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-full h-full">
|
||||
<tbl
|
||||
ref="table"
|
||||
class="w-full h-full"
|
||||
@info="info"
|
||||
@edit="edit"
|
||||
@sums="setSums"
|
||||
@delete="deleteItem"
|
||||
@add="add"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
<BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="40rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} کاربر`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="نام" name="fname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام خانوادگی" name="lname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره همراه" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="form.mobile" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ تولد" name="birth_date" :rules="inputRules()">
|
||||
<BaseDatePicker v-model:value="form.birth_date" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="ایمیل" name="email" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.email" />
|
||||
</a-form-item>-->
|
||||
<!-- <a-form-item label="نام فروشگاه" name="shop_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.shop_name" />
|
||||
</a-form-item>-->
|
||||
<a-form-item label="شماره تلفن" name="phone_number" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.phone_number" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام استان" name="province" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.province" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام شهر" name="city" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.city" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره ملی" name="n_code" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.n_code" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</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"
|
||||
itemsTitle="اطلاعات فردی"
|
||||
:name="infoParams.name"
|
||||
:items="infoParams.items"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } 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, sum } from 'lodash'
|
||||
import type { Item } from '@/model/Item'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import { createCustomer, deleteCustomer, updateCustomer } from '@/api/customer'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
const sums = ref()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
|
||||
//form
|
||||
const form = ref<Customer>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function setSums(val) {
|
||||
sums.value = val
|
||||
}
|
||||
|
||||
function info(val: Customer) {
|
||||
infoParams.name = val.name
|
||||
infoParams.type = val.mobile
|
||||
infoParams.date = toJalaliNoTime(val.created_at)
|
||||
infoParams.time = toTime(val.created_at)
|
||||
infoParams.itemsTitle = 'اطلاعات کاربری'
|
||||
infoParams.items = [
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.n_code ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.birth_date) ?? '-'
|
||||
},
|
||||
/* {
|
||||
key: 'ایمیل',
|
||||
value: val.email ?? '-'
|
||||
},*/
|
||||
/* {
|
||||
key: 'نام فروشگاه',
|
||||
value: val.shop_name ?? '-'
|
||||
},*/
|
||||
{
|
||||
key: 'شماره تلفن',
|
||||
value: val.phone_number ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام استان',
|
||||
value: val.province ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام شهر',
|
||||
value: val.city ?? '-'
|
||||
}
|
||||
/* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*/
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addUserVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
active: false,
|
||||
avatar_id: undefined,
|
||||
sts: undefined,
|
||||
id: undefined,
|
||||
mobile: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
if (editId) {
|
||||
await updateCustomer(editId, form.value)
|
||||
} else {
|
||||
await createCustomer(form.value)
|
||||
}
|
||||
addUserVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<ADropdown :trigger="['click']" v-if="props.more">
|
||||
<span class="mr-2 mb-1 cursor-pointer">...</span>
|
||||
<template #overlay>
|
||||
<a-menu class="flex flex-col">
|
||||
<a-menu-item
|
||||
v-for="(item, index) in statusList"
|
||||
:key="index"
|
||||
class="border-none px-2 py-1 rounded m-1"
|
||||
:style="{ color: item[1].color }"
|
||||
@click="changeHandler(item)"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<!-- <BaseIcon :icon="item[1].icon" size="18" />-->
|
||||
<span class="font-normal pr-1">{{ item[1].title }}</span>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</ADropdown>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
||||
import { toNumber } from 'lodash'
|
||||
|
||||
interface Props {
|
||||
sts: number
|
||||
more?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
more: false
|
||||
})
|
||||
|
||||
const statusList = computed(() => {
|
||||
return Object.entries(status).filter((item) => toNumber(item[0]) !== props.sts)
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'change-sts', value: any): void
|
||||
}>()
|
||||
|
||||
const changeHandler = (item: any) => {
|
||||
emit('change-sts', item)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex justify-center border-none flex-inline items-center px-2 py-1 rounded w-fit"
|
||||
:style="{ background: currentStatus?.bgColor, color: currentStatus?.color }"
|
||||
>
|
||||
<!-- <BaseIcon :icon="currentStatus?.icon" size="18" />-->
|
||||
<span class="font-normal pr-1">{{ currentStatus?.title }}</span>
|
||||
<WithdrawSelector :more="props.more" :sts="props.sts" @change-sts="changeStatusHandler" />
|
||||
<!-- <ADropdown :trigger="['click']" v-if="props.more">-->
|
||||
<!-- <span class="mr-2 mb-1 cursor-pointer">...</span>-->
|
||||
<!-- <template #overlay>-->
|
||||
<!-- <a-menu class="flex flex-col">-->
|
||||
<!-- <a-menu-item-->
|
||||
<!-- v-for="(item, index) in Object.entries(status)"-->
|
||||
<!-- :key="index"-->
|
||||
<!-- class="border-none px-2 py-1 rounded m-1"-->
|
||||
<!-- :style="{ color: item[1].color }"-->
|
||||
<!-- @click="changeHandler(item)"-->
|
||||
<!-- >-->
|
||||
<!-- <div class="flex items-center">-->
|
||||
<!-- <BaseIcon :icon="item[1].icon" size="18" />-->
|
||||
<!-- <span class="font-normal pr-1">{{ item[1].title }}</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </a-menu-item>-->
|
||||
<!-- </a-menu>-->
|
||||
<!-- </template>-->
|
||||
<!-- </ADropdown>-->
|
||||
</div>
|
||||
<!-- <ATag :color="currentStatus.color" > 1111 </ATag>-->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { get } from 'lodash'
|
||||
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
||||
import type { WithdrawStatus } from '@/model/wallet'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import WithdrawSelector from '@/pages/menuPages/withdraw/components/WithdrawSelector.vue'
|
||||
|
||||
interface Props {
|
||||
sts: number
|
||||
more?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
more: false
|
||||
})
|
||||
const emit = defineEmits<{
|
||||
(e: 'change-sts', value: any): void
|
||||
}>()
|
||||
|
||||
const currentStatus = computed<WithdrawStatus>(() => {
|
||||
return get(status, props.sts)
|
||||
})
|
||||
|
||||
const changeStatusHandler = (item) => {
|
||||
emit('change-sts', item)
|
||||
}
|
||||
|
||||
// onMounted(() => {
|
||||
// console.log(currentStatus.value, 'current')
|
||||
// })
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicShowContext title="لیست برداشت و واریز">
|
||||
<BaseTable v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<!-- <BaseButton type="primary" size="small" class="flex" @click="emits('add')">
|
||||
<div>افزودن مشتری عمده</div>
|
||||
<BaseIcon icon="vuesax-linear:user-add" Size="16px" />
|
||||
</BaseButton>-->
|
||||
</template>
|
||||
<template #tracked="{ column, record }">
|
||||
<div v-if="record.tracked_number">{{ record.tracked_number }}</div>
|
||||
<div v-else>
|
||||
<BaseButton @click="emits('withdraw', record.id)">تایید برداشت</BaseButton>
|
||||
</div>
|
||||
</template>
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<div class="flex gap-2" v-if="record.sts <= 70 && record.sts >= 50">
|
||||
<a-tooltip class="cursor-pointer">
|
||||
<template #title><span>دریافت فاکتور</span></template>
|
||||
<Icon
|
||||
icon="vuesax-linear:document-download"
|
||||
color="#1D4ED8"
|
||||
@click="$router.push({ name: 'factor', params: { id: record.id } })"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip class="cursor-pointer">
|
||||
<template #title><span>وضعیت</span></template>
|
||||
<ADropdown :trigger="['click']">
|
||||
<Icon icon="vuesax-linear:status-up" color="#CA8A04" @click="test(record)" />
|
||||
<template #overlay>
|
||||
<a-menu class="flex flex-col">
|
||||
<a-menu-item
|
||||
v-for="(item, index) in statusList"
|
||||
:key="index"
|
||||
class="border-none px-2 py-1 rounded m-1"
|
||||
:style="{ color: item[1].color }"
|
||||
@click="changeStatusHandler(item)"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<BaseIcon :icon="item[1].icon" size="18" />
|
||||
<span class="font-normal pr-1">{{ item[1].title }}</span>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</ADropdown>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- <div v-if="record.sts == 53">-->
|
||||
<a-tooltip class="cursor-pointer">
|
||||
<template #title><span>تعیین وزن</span></template>
|
||||
<Icon
|
||||
icon="vuesax-linear:3d-cube-scan"
|
||||
color="#1D4ED8"
|
||||
@click="emits('weight', record)"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<!-- </div>-->
|
||||
</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/withdrawColumns'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { getOrderTable } from '@/api/order'
|
||||
import {getWithdrawTable, updateSts} from '@/api/wallet'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
/*const select = (val) => {
|
||||
val.sts === 1 ? return ['1'] : ['2']
|
||||
}*/
|
||||
//emits
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'withdraw', 'weight'])
|
||||
|
||||
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) => {
|
||||
return getWithdrawTable(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
|
||||
})
|
||||
|
||||
import { status } from '@/pages/menuPages/withdraw/information/hooks/status'
|
||||
import {toNumber} from "lodash";
|
||||
const withdrawId = ref(null)
|
||||
const sts = ref()
|
||||
const statusList = computed(() => {
|
||||
return Object.entries(status).filter((item) => toNumber(item[0]) !== sts.value)
|
||||
})
|
||||
const test = (record: any) => {
|
||||
sts.value = record.sts
|
||||
withdrawId.value = record.id
|
||||
}
|
||||
const changeStatusHandler = async (status: any) => {
|
||||
try {
|
||||
await changeStatus(withdrawId.value as number, status)
|
||||
reload()
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
const changeStatus = async (id: number, status: any) => {
|
||||
try {
|
||||
await updateSts(id, { sts: status[0] })
|
||||
message.success(`وضعیت ثبت شد `)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
message.error('خطا در ثبت اطلاعات')
|
||||
}
|
||||
}
|
||||
</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,163 @@
|
||||
<template>
|
||||
<div :class="[prefixCls]">
|
||||
<ACard v-if="withdraw" class="my-4 mx-auto !p-3 h-print max-w-[700px]">
|
||||
<div class="h-16 flex justify-center items-center mt-[4rem]">
|
||||
<!-- <img class="h-16" src="@/assets/img/logo.svg" alt="logo" />-->
|
||||
<div class="logo flex justify-center w-full flex-col items-center">
|
||||
<img :src="getConfigApp('avatar')" class="w-[150px]" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-[6rem] p-2 flex bg-gray-50 border border-solid rounded-lg border-gray-300">
|
||||
<div class="w-3/5 flex justify-center items-center">
|
||||
<span class="text-sm font-medium">فاکتور فروش</span>
|
||||
</div>
|
||||
<div class="w-2/5 flex flex-col gap-2">
|
||||
<!-- <div class="flex items-center justify-between">
|
||||
<span class="text-gray-500 text-xs font-medium">وضعیت سفارش :</span>
|
||||
<span class="text-gray-700 text-sm font-medium">{{ withdraw?.transaction?.sts_str }}</span>
|
||||
</div>-->
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-500 text-xs font-medium">تاریخ سفارش :</span>
|
||||
<span class="text-gray-700 text-sm font-medium">{{ toJalaliNoTime(withdraw?.created_at) }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-500 text-xs font-medium">شماره سفارش :</span>
|
||||
<span class="text-gray-700 text-sm font-medium">{{ withdraw?.id }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-2 p-2 flex flex-col gap-2 bg-gray-50 border border-solid rounded-lg border-gray-300"
|
||||
>
|
||||
<div class="grid grid-cols-3">
|
||||
<div class="col-span-1 flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-gray-500">خریدار</span>
|
||||
<span class="text-sm font-medium text-gray-700">{{ withdraw?.customer?.name }}</span>
|
||||
</div>
|
||||
<div class="col-span-1 flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-gray-500">شماره تلفن همراه</span>
|
||||
<span class="text-sm font-medium text-gray-700">{{ withdraw?.customer?.mobile }}</span>
|
||||
</div>
|
||||
<!-- <div class="col-span-1 flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-gray-500">تلفن ثابت</span>
|
||||
<span class="text-sm font-medium text-gray-700">{{ withdraw?.address?.phone }}</span>
|
||||
</div>-->
|
||||
</div>
|
||||
<div class="grid grid-cols-3">
|
||||
<!-- <div class="col-span-1 flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-gray-500">کد پستی</span>
|
||||
<span class="text-sm font-medium text-gray-700">{{ withdraw?.address?.zip }}</span>
|
||||
</div>-->
|
||||
<div class="col-span-1 flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-gray-500">استان</span>
|
||||
<span class="text-sm font-medium text-gray-700">{{ withdraw?.address?.province }}</span>
|
||||
</div>
|
||||
<div class="col-span-1 flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-gray-500">شهر</span>
|
||||
<span class="text-sm font-medium text-gray-700">{{ withdraw?.address?.city }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-xs font-medium text-gray-500">آدرس</span>
|
||||
<span class="text-sm font-medium text-gray-700">{{ withdraw?.address?.address }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<ADivider class="!my-4" />
|
||||
<div class="h-7 grid grid grid-cols-10 bg-[#091A38] rounded-t-lg">
|
||||
<span class="col-span-2 text-white flex justify-center">ردیف</span>
|
||||
<span class="col-span-6 text-white flex justify-center">عنوان</span>
|
||||
<!-- <span class="col-span-1 text-white flex justify-center">کد محصول</span>-->
|
||||
<!-- <span class="col-span-1 text-white flex justify-center">قیمت</span>-->
|
||||
<span class="col-span-2 text-white flex justify-center">تعداد</span>
|
||||
<!-- <span class="col-span-2 text-white flex justify-center">قیمت کل</span>-->
|
||||
</div>
|
||||
<div class="flex flex-col" >
|
||||
<div v-for="(item, index) in withdraw?.transaction">
|
||||
<div class="grid grid-cols-10">
|
||||
<span class="col-span-2 text-xs font-medium py-[8px] px-[10px] flex justify-center">{{
|
||||
index + 1
|
||||
}}</span>
|
||||
<span class="col-span-6 text-xs font-medium py-[8px] px-[10px] flex justify-center">{{
|
||||
item?.title
|
||||
}}</span>
|
||||
<!-- <span class="col-span-1 text-xs font-medium py-[8px] px-[10px] flex justify-center">{{-->
|
||||
<!-- item.product.code-->
|
||||
<!-- }}</span>-->
|
||||
<!-- <span class="col-span-1 text-xs font-medium py-[8px] px-[10px] flex justify-center">{{
|
||||
usePrice(item.price?? 0, true, '')
|
||||
}}</span>-->
|
||||
<span class="col-span-2 text-xs font-medium py-[8px] px-[10px] flex justify-center">{{
|
||||
item.gold * -1
|
||||
}}</span>
|
||||
<!-- <span class="col-span-2 text-xs font-medium py-[8px] px-[10px] flex justify-center">{{
|
||||
usePrice(item.total_price?? 0, true, '')
|
||||
}}</span>-->
|
||||
</div>
|
||||
<ADivider class="!my-0" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="h-7 flex justify-between items-center bg-gray-100 rounded-b-lg px-2">
|
||||
<span class="text-xs font-medium">جمع سفارش ها</span>
|
||||
<span class="w-1/10 ml-4 text-xs font-bold"></span>
|
||||
</div>-->
|
||||
<div class="mt-4 flex gap-2 no-print">
|
||||
<AButton class="flex gap-2 items-center" type="primary" @click="printFactor">
|
||||
<Icon icon="vuesax-linear:printer" size="15" color="#fff" />
|
||||
<span>چاپ فاکتور</span>
|
||||
</AButton>
|
||||
<AButton type="primary" danger @click="$router.push({ name: 'withdrawMain' })"
|
||||
>بازگشت</AButton
|
||||
>
|
||||
</div>
|
||||
</ACard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import type { Withdraw } from '@/model/wallet'
|
||||
import { getWithdrawById , getWithdrawTable } from '@/api/wallet'
|
||||
import { onMounted } from 'vue'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import {toJalaliNoTime} from "../../../../core/utils/useDataTime";
|
||||
import {forEach} from "lodash";
|
||||
import {getConfigApp} from "@/utils/config";
|
||||
|
||||
const { prefixCls } = usePrefix('factor')
|
||||
const router = useRouter()
|
||||
const withdraw = ref<null | Withdraw>(null)
|
||||
const id = computed(() => {
|
||||
return parseInt(router.currentRoute.value.params.id as string)
|
||||
})
|
||||
|
||||
const getWithdraw = async () => {
|
||||
withdraw.value = await getWithdrawById(id.value)
|
||||
console.log('hello')
|
||||
console.log(withdraw.value)
|
||||
// totalPrice.value = usePrice(withdraw.value.total_price as number, true, '')
|
||||
}
|
||||
const printFactor = () => {
|
||||
window.print()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getWithdraw()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@prefix: ~'@{prefixCls}-factor';
|
||||
|
||||
.@{prefix} {
|
||||
}
|
||||
|
||||
@media print {
|
||||
.h-print {
|
||||
height: calc(100vh - 32px);
|
||||
}
|
||||
.no-print {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,226 @@
|
||||
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 WithdrawStatus from "@/pages/menuPages/withdraw/components/WithdrawStatus.vue";
|
||||
/*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: 'note',
|
||||
key: 'note',
|
||||
type: 'Number'
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'شماره پیگیری',
|
||||
dataIndex: 'tracked_number',
|
||||
key: 'tracked_number',
|
||||
type: 'Number',
|
||||
slot: 'tracked',
|
||||
customRender: (record: any) => record.record.tracked_number ?? '__'
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'کد سفارش',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
type: 'Number'
|
||||
// className: 'column-money'
|
||||
},
|
||||
{
|
||||
title: 'کد کاربر',
|
||||
dataIndex: 'customer_id',
|
||||
key: 'customer_id',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'نام و نام خانوادگی',
|
||||
dataIndex: 'customer.name',
|
||||
key: 'customer.name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'مقدار (ریال)',
|
||||
dataIndex: 'cash',
|
||||
key: 'cash',
|
||||
type: 'Number',
|
||||
customRender: ({ record }) => {
|
||||
return (
|
||||
<div class="flex justify-center">
|
||||
<div class={'font-bold px-6 text-red'}>{usePrice(record.cash ?? 0, true, '')}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'طلا',
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Number',
|
||||
},
|
||||
{
|
||||
title: 'شماره کارت',
|
||||
dataIndex: 'bank_account.cart_number',
|
||||
key: 'bank_account.cart_number',
|
||||
type: 'Number',
|
||||
customRender: (data) => {
|
||||
return data.record.bank_account?.cart_number ?? '_'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'وضعیت',
|
||||
dataIndex: 'sts',
|
||||
key: 'sts',
|
||||
filterable: false,
|
||||
/*customRender: ({ record }) => {
|
||||
switch (record.sts) {
|
||||
case 1:
|
||||
return (
|
||||
<div class="flex justify-center font-bold">
|
||||
<CustomTag textColor="#ca8a04" bgColor="#fef3c7" class="px-2">
|
||||
{record.sts_str}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
case 2:
|
||||
return (
|
||||
<div class="flex justify-center font-bold px-2">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class="px-2">
|
||||
{record.sts_str}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
case 4:
|
||||
return (
|
||||
<div class="flex justify-center font-bold px-2">
|
||||
<CustomTag textColor="#25855A" bgColor="#E3F4E9" class="px-2">
|
||||
{record.sts_str}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
default:
|
||||
return (
|
||||
<div class="flex justify-center font-bold px-2">
|
||||
<CustomTag textColor="#C53030" bgColor="#FECACA" class="px-2">
|
||||
{record.sts_str}
|
||||
</CustomTag>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}*/
|
||||
customRender: ({ record }) => {
|
||||
return (
|
||||
<CustomTag textColor='#ca8a04' bgColor='#fef3c7'>{record?.sts_str}</CustomTag>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'تاریخ ثبت',
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
type: 'DateTime',
|
||||
customRender: (record: any) => {
|
||||
return toJalali(record.record.created_at)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'عملیات',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
slot: 'action',
|
||||
filterable: false
|
||||
}
|
||||
/* {
|
||||
title: 'تاریخ تایید',
|
||||
dataIndex: 'updated_at',
|
||||
key: 'updated_at',
|
||||
type: 'DateTime',
|
||||
customRender: (record: any) => {
|
||||
return toJalaliNoTime(record.record.created_at)
|
||||
}
|
||||
},*/
|
||||
/*{
|
||||
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: 'action',
|
||||
key: 'action',
|
||||
slot: 'action',
|
||||
fixed: 'right',
|
||||
filterable: false
|
||||
}*/
|
||||
]
|
||||
@@ -0,0 +1,291 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicMainCard>
|
||||
<div class="flex w-full h-full">
|
||||
<tbl
|
||||
ref="table"
|
||||
class="w-full h-full"
|
||||
@edit="edit"
|
||||
@delete="deleteItem"
|
||||
@withdraw="openWithdraw"
|
||||
@weight="openWeight"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
<BasicModal
|
||||
v-model:visible="confirmWithdrawVisible"
|
||||
width="15rem"
|
||||
title="تایید برداشت"
|
||||
@ok="okWithdraw"
|
||||
:loading="loading"
|
||||
@close="confirmWithdrawVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="">
|
||||
<a-form-item label="شماره پیگیری" name="tracked_number" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.tracked_number" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ" name="date_at">
|
||||
<BaseDatePicker v-model:value="form.date_at" show-time format="YYYY-MM-DD HH:mm" />
|
||||
<!-- format="YYYY-MM-DD HH:mm"-->
|
||||
<!-- <DatePicker show-time />-->
|
||||
</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="confirmWeightVisible"
|
||||
width="40rem"
|
||||
title="ثبت اطلاعات"
|
||||
:loading="loading"
|
||||
@close="confirmWeightVisible = false"
|
||||
>
|
||||
<div v-for="(item, index) in confirmWithdraw?.transaction">
|
||||
<div class="bg-gray-100 rounded-lg p-4 mt-2">
|
||||
<div class="mb-4">{{ item?.title }} ({{ (item.gold * -1) }} عدد)</div>
|
||||
<ADivider class="!my-0 "/>
|
||||
<div v-if="item.gold && item.gold * -1 > 0">
|
||||
<div class="h-7 grid grid grid-cols-3">
|
||||
<span class="col-span-1 flex "></span>
|
||||
<span class="col-span-1 flex justify-center">وزن جدید</span>
|
||||
</div>
|
||||
<div v-for="i in Math.abs(item.gold * -1)" class="grid grid-cols-3 gap-2 mb-2" >
|
||||
<!-- <span class="col-span-1 text-xs font-medium py-[8px] px-[10px]">{{
|
||||
i
|
||||
}}</span>-->
|
||||
<span class="col-span-1 text-xs font-medium py-[8px] px-[10px]">{{ item?.title }} {{ i }}</span>
|
||||
<BasicInput class="col-span-1 text-xs font-medium w-10rem" v-model:value="newWeightArray[i]" />
|
||||
<BaseButton class="col-span-1 text-xs font-medium w-4rem mr-4" @click="ok(i)">ثبت</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } from '@/utils/inputRules'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
import { ref } from 'vue'
|
||||
import { DatePicker } from 'ant-design-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, updateCustomer } from '@/api/customer'
|
||||
import type { Order } from '@/model/order'
|
||||
import type { Wallet, Withdraw } from '@/model/wallet'
|
||||
import {completeWithdraw, sendWeights} from '@/api/wallet'
|
||||
import Button from "@core/components/BaseButton";
|
||||
//import DatePicker from '@core/components/_sample/components/datePicker.vue'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//form
|
||||
const form = ref<Withdraw>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
/*
|
||||
function info(val: Order) {
|
||||
infoParams.name = val.customer.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.amount ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت هر گرم طلا برای مشتری (ریال)',
|
||||
value: val.price ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل برای مشتری (ریال)',
|
||||
value: val.total_price ?? '-'
|
||||
},
|
||||
{
|
||||
key: '/قیمت هر گرم طلا بدون سود (ریال)',
|
||||
value: val.price_original ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'قیمت کل بدون سود (ریال)',
|
||||
value: val.total_price_original ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود هر گرم (ریال)',
|
||||
value: val.fee ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'سود کل (ریال)',
|
||||
value: val.total_fee ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.customer.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.customer.n_code ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.customer.birth_date) ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام فروشگاه',
|
||||
value: val.customer.shop_name ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره تلفن فروشگاه',
|
||||
value: val.customer.phone_number ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام استان',
|
||||
value: val.customer.province ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام شهر',
|
||||
value: val.customer.city ?? '-'
|
||||
}
|
||||
/!* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*!/
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
*/
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
confirmWithdrawVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
/*async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
confirmWithdrawVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}*/
|
||||
|
||||
function openWithdraw(val: Withdraw) {
|
||||
confirmWithdraw = val
|
||||
confirmWithdrawVisible.value = true
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
tracked_number: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const confirmWithdrawVisible = ref<boolean>(false)
|
||||
const confirmWeightVisible = ref<boolean>(false)
|
||||
let confirmWithdraw: Withdraw
|
||||
// const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit weight
|
||||
async function okWithdraw() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
form.value.id = confirmWithdraw
|
||||
await completeWithdraw(form.value)
|
||||
confirmWithdrawVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('شماره پیگیری با موفقیت تایید شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const newWeightArray = ref([])
|
||||
function openWeight(val) {
|
||||
confirmWithdraw = val
|
||||
confirmWeightVisible.value = true
|
||||
}
|
||||
function ok(i) {
|
||||
try {
|
||||
// await sendWeights()
|
||||
message.success('با موفقیت ثبت شد')
|
||||
} catch (e) {
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
console.error(e)
|
||||
} finally {
|
||||
console.log()
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,132 @@
|
||||
<svg width="264" height="259" viewBox="0 0 264 259" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="264" height="259" fill="white"/>
|
||||
<g id="میز کار" clip-path="url(#clip0_508_4188)">
|
||||
<rect width="1920" height="1080" transform="translate(-1159 -659)" fill="#F6F7F9"/>
|
||||
<rect id="Rectangle 5" x="-1127" y="-563" width="1856" height="952" rx="10" fill="white"/>
|
||||
<g id="Rectangle 7" opacity="0.25" filter="url(#filter0_dd_508_4188)">
|
||||
<rect x="-1159" y="-595" width="1920" height="1016" fill="black"/>
|
||||
</g>
|
||||
<g id="Frame 35660" filter="url(#filter1_dd_508_4188)">
|
||||
<rect x="-767" y="-518" width="1135.05" height="863" rx="8" fill="white" shape-rendering="crispEdges"/>
|
||||
<g id="Frame 35659">
|
||||
<g id="Frame 35658">
|
||||
<g id="Frame 35657">
|
||||
<g id="Frame 35640">
|
||||
<g id="16" opacity="0.5">
|
||||
<g id="Group">
|
||||
<path id="Vector" d="M250 120C250 146.93 240.983 171.902 225.873 191.978C217.587 202.75 207.595 212.298 196.141 219.642C177.619 231.883 155.442 238.983 131.559 238.983C66.0019 238.983 12.874 185.612 12.874 120C12.874 54.1429 66.0019 1.0166 131.315 1.0166C155.198 1.0166 177.376 8.11643 195.897 20.1127C207.351 27.4573 217.343 37.0054 225.629 47.7775C240.983 68.0977 250 92.8247 250 120Z" fill="#EAEEF9"/>
|
||||
<path id="Vector_2" d="M20.8227 222.892C23.016 222.892 24.9657 221.179 24.9657 218.73C24.9657 216.527 23.2597 214.568 20.8227 214.568C18.6293 214.568 16.6797 216.282 16.6797 218.73C16.6797 220.934 18.3856 222.892 20.8227 222.892Z" fill="url(#paint0_linear_508_4188)"/>
|
||||
<path id="Vector_3" d="M56.6754 35.2923C58.8688 35.2923 60.5747 33.5785 60.5747 31.3752C60.5747 29.1718 58.8688 27.458 56.6754 27.458C54.4821 27.458 52.7761 29.1718 52.7761 31.3752C52.7761 33.5785 54.4821 35.2923 56.6754 35.2923Z" fill="url(#paint1_linear_508_4188)"/>
|
||||
</g>
|
||||
<g id="Recipt 1">
|
||||
<g id="Vector_4" filter="url(#filter2_d_508_4188)">
|
||||
<path d="M241.714 19.3782V217.684C241.714 221.111 237.815 222.825 235.377 220.377L231.234 216.46C229.772 214.991 227.335 214.991 225.873 216.46L218.074 224.049C216.612 225.518 214.175 225.518 212.713 224.049L204.914 216.46C203.452 214.991 201.015 214.991 199.553 216.46L191.754 224.049C190.292 225.518 187.855 225.518 186.393 224.049L178.594 216.46C177.132 214.991 174.695 214.991 173.232 216.46L165.678 224.049C164.215 225.518 161.778 225.518 160.316 224.049L152.517 216.46C151.055 214.991 148.618 214.991 147.156 216.46L139.357 224.049C137.895 225.518 135.458 225.518 133.996 224.049L126.197 216.46C124.735 214.991 122.298 214.991 120.836 216.46L113.037 224.049C111.575 225.518 109.138 225.518 107.676 224.049L97.4399 213.767L96.7088 214.501L90.6161 220.377C88.1791 222.825 84.2798 221.111 84.2798 217.684V19.3782C84.2798 15.9507 88.1791 14.2369 90.6161 16.6852L94.7591 20.6023C96.2214 22.0712 98.6584 22.0712 100.121 20.6023L107.919 13.0128C109.382 11.5439 111.819 11.5439 113.281 13.0128L121.079 20.6023C122.542 22.0712 124.979 22.0712 126.441 20.6023L134.24 13.0128C135.702 11.5439 138.139 11.5439 139.601 13.0128L147.4 20.6023C148.862 22.0712 151.299 22.0712 152.761 20.6023L160.56 13.0128C162.022 11.5439 164.459 11.5439 165.921 13.0128L173.476 20.6023C174.938 22.0712 177.375 22.0712 178.838 20.6023L186.636 13.0128C188.099 11.5439 190.536 11.5439 191.998 13.0128L199.796 20.6023C201.259 22.0712 203.696 22.0712 205.158 20.6023L212.957 13.0128C214.419 11.5439 216.856 11.5439 218.318 13.0128L226.117 20.6023C227.579 22.0712 230.016 22.0712 231.478 20.6023L235.621 16.6852C237.815 14.2369 241.714 15.9507 241.714 19.3782Z" fill="white"/>
|
||||
</g>
|
||||
<g id="Group_2">
|
||||
<path id="Vector_5" d="M212.226 63.9347H195.166C193.46 63.9347 191.998 62.4658 191.998 60.752C191.998 59.0383 193.46 57.5693 195.166 57.5693H212.226C213.932 57.5693 215.394 59.0383 215.394 60.752C215.394 62.4658 213.932 63.9347 212.226 63.9347Z" fill="#C5CCDE"/>
|
||||
<path id="Vector_6" d="M179.569 63.9347H112.306C110.6 63.9347 109.138 62.4658 109.138 60.752C109.138 59.0383 110.6 57.5693 112.306 57.5693H179.569C181.275 57.5693 182.737 59.0383 182.737 60.752C182.737 62.4658 181.275 63.9347 179.569 63.9347Z" fill="#C5CCDE"/>
|
||||
<path id="Vector_7" d="M212.226 94.2931H182.981C181.275 94.2931 179.813 92.8242 179.813 91.1104C179.813 89.3967 181.275 87.9277 182.981 87.9277H212.226C213.932 87.9277 215.394 89.3967 215.394 91.1104C215.394 92.8242 213.932 94.2931 212.226 94.2931Z" fill="#C5CCDE"/>
|
||||
<path id="Vector_8" d="M167.384 94.2931H137.408C135.702 94.2931 134.24 92.8242 134.24 91.1104C134.24 89.3967 135.702 87.9277 137.408 87.9277H167.627C169.333 87.9277 170.795 89.3967 170.795 91.1104C170.795 92.8242 169.089 94.2931 167.384 94.2931Z" fill="#C5CCDE"/>
|
||||
<path id="Vector_9" d="M125.71 94.2931H112.306C110.6 94.2931 109.138 92.8242 109.138 91.1104C109.138 89.3967 110.6 87.9277 112.306 87.9277H125.71C127.416 87.9277 128.878 89.3967 128.878 91.1104C128.878 92.8242 127.416 94.2931 125.71 94.2931Z" fill="#4988FD"/>
|
||||
<path id="Vector_10" d="M162.266 124.896H139.113C137.408 124.896 135.945 123.427 135.945 121.713C135.945 119.999 137.408 118.53 139.113 118.53H162.266C163.971 118.53 165.434 119.999 165.434 121.713C165.434 123.427 163.971 124.896 162.266 124.896Z" fill="#C5CCDE"/>
|
||||
<path id="Vector_11" d="M126.685 124.896H112.306C110.6 124.896 109.138 123.427 109.138 121.713C109.138 119.999 110.6 118.53 112.306 118.53H126.685C128.391 118.53 129.853 119.999 129.853 121.713C129.853 123.427 128.391 124.896 126.685 124.896Z" fill="#4988FD"/>
|
||||
<path id="Vector_12" d="M162.266 155.254H112.306C110.6 155.254 109.138 153.785 109.138 152.071C109.138 150.358 110.6 148.889 112.306 148.889H162.266C163.972 148.889 165.434 150.358 165.434 152.071C165.434 153.785 163.972 155.254 162.266 155.254Z" fill="#C5CCDE"/>
|
||||
<path id="Vector_13" d="M162.266 179.491C144.719 179.491 129.853 179.491 112.306 179.491C108.163 179.491 108.163 185.612 112.306 185.612C131.559 185.612 143.257 185.612 162.266 185.612C163.972 185.612 165.434 184.143 165.434 182.429C165.434 180.715 163.972 179.491 162.266 179.491Z" fill="#C5CCDE"/>
|
||||
</g>
|
||||
<g id="Group_3">
|
||||
<path id="Vector_14" d="M202.964 189.041C200.527 189.041 198.578 187.082 198.578 184.634V179.982C194.922 179.737 191.51 178.758 188.586 177.534C186.392 176.555 185.418 174.106 186.149 171.658C186.88 169.7 188.586 168.475 190.535 168.475C191.267 168.475 191.754 168.72 192.485 168.965C194.435 169.944 197.603 170.924 201.502 170.924C206.864 170.924 210.519 167.986 210.519 163.824C210.519 159.907 207.839 157.459 201.502 154.765C193.46 151.583 186.149 147.421 186.149 138.118C186.149 130.528 191.267 124.408 199.309 122.694V117.797C199.309 115.349 201.258 113.391 203.696 113.391C206.133 113.391 208.082 115.349 208.082 117.797V122.204C211.007 122.449 213.444 122.939 215.881 123.918C218.074 124.897 219.293 127.59 218.318 129.794C217.587 131.507 215.881 132.732 213.931 132.732C213.2 132.732 212.713 132.732 212.225 132.487C209.788 131.507 207.351 131.018 204.67 131.018C198.821 131.018 196.872 134.2 196.872 137.138C196.872 140.566 199.065 142.524 206.864 145.707C217.099 149.869 221.486 155.255 221.486 163.334C221.486 171.413 215.881 177.779 207.595 179.492V184.634C207.351 187.082 205.402 189.041 202.964 189.041Z" fill="#C5CCDE"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Vector_15" filter="url(#filter3_d_508_4188)">
|
||||
<path d="M140.332 86.2151V157.213C140.332 161.62 136.92 165.048 132.534 165.048H15.7986C11.4119 165.048 8 161.62 8 157.213V86.2151C8 81.8084 11.4119 78.3809 15.7986 78.3809H132.534C136.92 78.3809 140.332 82.0532 140.332 86.2151Z" fill="url(#paint2_linear_508_4188)"/>
|
||||
</g>
|
||||
<g id="Group_4">
|
||||
<path id="Vector_16" d="M39.6816 127.59H21.6474C20.1851 127.59 18.7229 126.365 18.7229 124.652C18.7229 123.183 19.9414 121.714 21.6474 121.714H39.6816C41.1439 121.714 42.6061 122.938 42.6061 124.652C42.3624 126.365 41.1439 127.59 39.6816 127.59Z" fill="#4260FF"/>
|
||||
<path id="Vector_17" d="M68.9262 127.59H50.892C49.4298 127.59 47.9675 126.365 47.9675 124.652C47.9675 123.183 49.1861 121.714 50.892 121.714H68.9262C70.3885 121.714 71.8507 122.938 71.8507 124.652C71.607 126.365 70.3885 127.59 68.9262 127.59Z" fill="#4260FF"/>
|
||||
<path id="Vector_18" d="M98.1709 127.59H80.1366C78.6744 127.59 77.2122 126.365 77.2122 124.652C77.2122 123.183 78.4307 121.714 80.1366 121.714H98.1709C99.6331 121.714 101.095 122.938 101.095 124.652C100.852 126.365 99.6331 127.59 98.1709 127.59Z" fill="#4260FF"/>
|
||||
<path id="Vector_19" d="M127.416 149.623H94.0282C92.566 149.623 91.1038 148.399 91.1038 146.685C91.1038 145.216 92.3223 143.747 94.0282 143.747H127.172C128.634 143.747 130.097 144.971 130.097 146.685C130.097 148.399 128.878 149.623 127.416 149.623Z" fill="#4260FF"/>
|
||||
<path id="Vector_20" d="M127.416 127.59H109.382C107.92 127.59 106.457 126.365 106.457 124.652C106.457 123.183 107.676 121.714 109.382 121.714H127.416C128.878 121.714 130.34 122.938 130.34 124.652C130.097 126.365 128.878 127.59 127.416 127.59Z" fill="#4260FF"/>
|
||||
</g>
|
||||
<path id="Vector_21" d="M37.7322 154.764C42.0392 154.764 45.5308 151.257 45.5308 146.93C45.5308 142.603 42.0392 139.096 37.7322 139.096C33.4251 139.096 29.9336 142.603 29.9336 146.93C29.9336 151.257 33.4251 154.764 37.7322 154.764Z" fill="#4260FF"/>
|
||||
<path id="Vector_22" d="M27.2527 154.764C31.5597 154.764 35.0513 151.257 35.0513 146.93C35.0513 142.603 31.5597 139.096 27.2527 139.096C22.9456 139.096 19.4541 142.603 19.4541 146.93C19.4541 151.257 22.9456 154.764 27.2527 154.764Z" fill="#B3C6FF"/>
|
||||
<path id="Vector_23" d="M140.332 92.8242H8V109.472H140.332V92.8242Z" fill="#4260FF"/>
|
||||
</g>
|
||||
<rect x="-133.5" y="-441.5" width="485" height="770" rx="3.5" stroke="#E5E7EB"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_dd_508_4188" x="-1171" y="-597" width="1944" height="1040" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect1_dropShadow_508_4188"/>
|
||||
<feOffset dy="4"/>
|
||||
<feGaussianBlur stdDeviation="3"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_508_4188"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="3" operator="erode" in="SourceAlpha" result="effect2_dropShadow_508_4188"/>
|
||||
<feOffset dy="10"/>
|
||||
<feGaussianBlur stdDeviation="7.5"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="effect1_dropShadow_508_4188" result="effect2_dropShadow_508_4188"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_508_4188" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_dd_508_4188" x="-779" y="-520" width="1159.05" height="887" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect1_dropShadow_508_4188"/>
|
||||
<feOffset dy="4"/>
|
||||
<feGaussianBlur stdDeviation="3"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_508_4188"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feMorphology radius="3" operator="erode" in="SourceAlpha" result="effect2_dropShadow_508_4188"/>
|
||||
<feOffset dy="10"/>
|
||||
<feGaussianBlur stdDeviation="7.5"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
|
||||
<feBlend mode="normal" in2="effect1_dropShadow_508_4188" result="effect2_dropShadow_508_4188"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_508_4188" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter2_d_508_4188" x="62.2798" y="0.911133" width="201.434" height="257.239" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="11"/>
|
||||
<feGaussianBlur stdDeviation="11"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.397708 0 0 0 0 0.47749 0 0 0 0 0.575 0 0 0 0.18 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_508_4188"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_508_4188" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter3_d_508_4188" x="0" y="75.3809" width="148.332" height="102.667" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="5"/>
|
||||
<feGaussianBlur stdDeviation="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.1125 0 0 0 0 0.295916 0 0 0 0 1 0 0 0 0.22 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_508_4188"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_508_4188" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_508_4188" x1="16.5729" y1="218.813" x2="25.1056" y2="218.813" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF66A9"/>
|
||||
<stop offset="1" stop-color="#F53689"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_508_4188" x1="52.6756" y1="31.4532" x2="60.7064" y2="31.4532" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF66A9"/>
|
||||
<stop offset="1" stop-color="#F53689"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_508_4188" x1="41.3173" y1="90.7679" x2="114.71" y2="159.233" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#83A6FF"/>
|
||||
<stop offset="1" stop-color="#5A78FF"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_508_4188">
|
||||
<rect width="1920" height="1080" fill="white" transform="translate(-1159 -659)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="mx-3 relative">
|
||||
<div class="absolute z-10 w-full">
|
||||
<div class="flex justify-between items-center bg-gray-50 rounded p-3 w-full">
|
||||
<span class="text-base font-bold">اقلام سفارش</span>
|
||||
<Button type="primary" size="small" v-if="edit" @click="updateOrders"
|
||||
>ثبت اطلاعات
|
||||
</Button>
|
||||
<span v-else>
|
||||
<BaseIcon
|
||||
icon="vuesax-linear:edit-2"
|
||||
class="cursor-pointer"
|
||||
size="21"
|
||||
@click="emit('update:edit', true)"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="border-t border-t-solid border-t-gray-200 border-1 mt-4"></div>
|
||||
</div>
|
||||
<div class="h-18"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="grid grid-cols-1 md:grid-cols-4 border border-solid border-gray-200 p-6 rounded-lg mb-4 mt-4"
|
||||
v-for="(item, index) in _withdraw?.items"
|
||||
>
|
||||
<div class="col-span-1 w-25 mb-5 md:mb-0">
|
||||
<img
|
||||
v-if="item.product?.original_image?.src"
|
||||
class="w-25 h-25 object-contain"
|
||||
:src="item.product?.original_image?.src"
|
||||
:alt="item?.product?.title_fa"
|
||||
/>
|
||||
<img :src="Logo" class="w-25 h-25 object-contain" :alt="item?.product?.title_fa" v-else />
|
||||
</div>
|
||||
|
||||
<div class="col-span-3 mr-3 text-sm">
|
||||
<div class="mb-6">
|
||||
<span class="text-gray-400 font-normal">نام محصول:</span>
|
||||
<span class="font-bold text-gray-800 mr-2">{{ item?.product?.title_fa }}</span>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<span class="text-gray-400 font-normal">قیمت:</span>
|
||||
<span v-if="item?.price === null || undefined" class="font-bold text-gray-800 mr-2"
|
||||
>0</span
|
||||
>
|
||||
<span class="font-bold text-gray-800 mr-2">{{ usePrice(item?.price, true, '') }}</span>
|
||||
<span class="mr-1 text-xs">تومان</span>
|
||||
</div>
|
||||
<div class="flex justify-between mb-6">
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal">جمع قیمت اقلام:</span>
|
||||
<span class="font-bold text-gray-800 mr-2">{{
|
||||
usePrice(item.price * item.qty, true, '')
|
||||
}}</span>
|
||||
<span class="mr-1 text-xs">تومان</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal">تعداد:</span>
|
||||
<BasicInput
|
||||
place-holder="تعداد"
|
||||
v-if="props.edit === true"
|
||||
type="number"
|
||||
v-model:value="(_withdraw as Withdraw).items[index].qty"
|
||||
/>
|
||||
<span v-else class="font-bold text-gray-800 mr-2">{{ item?.qty }} عدد</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-6">
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal">کد محصول:</span>
|
||||
<span class="font-bold text-gray-800 mr-2">{{ item?.product.code }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal">رنگ:</span>
|
||||
<span class="font-bold text-gray-800 mr-2">{{
|
||||
item?.product?.color ? item?.product?.color : '---'
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div>-->
|
||||
<!-- <div class="mb-2">توضیحات:</div>-->
|
||||
|
||||
<!-- <div>-->
|
||||
<!-- {{ item?.product?.body }}-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BaseIcon from '@core/components/BaseIcon'
|
||||
import Button from '@core/components/BaseButton/src/button.vue'
|
||||
import Logo from '@/assets/img/saminLogo_.png'
|
||||
import { ref } from 'vue'
|
||||
import type { Withdraw } from '@/model/wallet'
|
||||
import { cloneDeep } from 'lodash'
|
||||
// import { updateOrder, getOrderById } from '@/api/orders'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
|
||||
const _withdraw = ref<Withdraw | null>(null)
|
||||
interface Props {
|
||||
edit: boolean
|
||||
order: Withdraw
|
||||
loading: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
edit: false,
|
||||
loading: false
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:edit', value: boolean): void
|
||||
(e: 'update:loading', value: boolean): void
|
||||
(e: 'update'): void
|
||||
}>()
|
||||
|
||||
watch(
|
||||
() => props.order,
|
||||
() => {
|
||||
// console.log('watch')
|
||||
// console.log(props.order, 'fhkldakfdghajkg')
|
||||
_withdraw.value = cloneDeep(props.order)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const updateOrders = async () => {
|
||||
try {
|
||||
emit('update:loading', true)
|
||||
let id = _withdraw.value?.id
|
||||
await updateOrder(id as number, _withdraw.value as Withdraw)
|
||||
message.success('سفارش به روز شد.')
|
||||
// _order.value = await getOrderById(id as number)
|
||||
emit('update')
|
||||
} catch (e) {
|
||||
message.error('خطا در ثبت اطلاعات')
|
||||
console.log(e)
|
||||
} finally {
|
||||
emit('update:loading', false)
|
||||
emit('update:edit', false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,46 @@
|
||||
import { message } from 'ant-design-vue'
|
||||
import { updateSts } from '@/api/wallet'
|
||||
|
||||
export const status = {
|
||||
'50': {
|
||||
icon: 'vuesax-linear:truck-tick',
|
||||
color: '#16A34A',
|
||||
bgColor: '#DCFCE7',
|
||||
title: 'در انتظار ارسال'
|
||||
},
|
||||
'51': {
|
||||
icon: 'vuesax-linear:profile-tick',
|
||||
color: '#2563EB',
|
||||
bgColor: '#DBEAFE',
|
||||
title: 'ارسال شده'
|
||||
},
|
||||
'52': {
|
||||
icon: 'vuesax-linear:empty-wallet-time',
|
||||
color: '#EA580C',
|
||||
bgColor: '#FFEDD5',
|
||||
title: 'لغو شده'
|
||||
},
|
||||
'53': {
|
||||
icon: 'vuesax-linear:3d-cube-scan',
|
||||
color: '#c62050',
|
||||
bgColor: '#FFEDD5',
|
||||
title: 'در انتظار تعیین مجدد قیمت'
|
||||
},
|
||||
}
|
||||
|
||||
export const changeStatus = async (id: number, status: any) => {
|
||||
try {
|
||||
await updateSts(id, { sts: status[0] })
|
||||
message.success(`وضعیت ثبت شد `)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
message.error('خطا در ثبت اطلاعات')
|
||||
}
|
||||
}
|
||||
|
||||
const statusArray = Object.entries(status).map(([key, value]) => {
|
||||
return {
|
||||
key: key,
|
||||
value: value.title
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
:visible="props.visible"
|
||||
width="70rem"
|
||||
height="90rem"
|
||||
title="جزئیات سفارش"
|
||||
:custom-footer="true"
|
||||
@close="handleCancel"
|
||||
:destroyOnClose="true"
|
||||
>
|
||||
<ASpin tip="در حال دریافت اطلاعات..." :indicator="indicator" :spinning="loading">
|
||||
<div class="grid grid-cols-1 md:grid-cols-5 md:gap-3 relative p-2" :class="[prefixCls]">
|
||||
<div class="col-span-2 border border-solid border-gray-200 rounded-lg mb-2">
|
||||
<div class="flex justify-between m-3">
|
||||
<WithdrawStatus :sts="orderInfo?.sts" :more="true" @change-sts="changeSts" />
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="$router.push({ name: 'factor', params: { id: orderInfo?.id } })"
|
||||
>
|
||||
<span class="text-xs"> دریافت فاکتور </span>
|
||||
<BaseIcon icon="vuesax-linear:document-download" size="18" />
|
||||
</Button>
|
||||
</div>
|
||||
<div class="mx-3">
|
||||
<ADivider class="divider" />
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mx-3">
|
||||
<div class="col-span-1 grid justify-start gap-4">
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal text-sm">شماره سفارش:</span>
|
||||
<span class="text-gray-800 font-bold text-sm mr-2">{{ orderInfo?.id }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal text-sm">مبلغ سفارش:</span>
|
||||
<span class="text-gray-800 font-bold text-sm mr-2">
|
||||
{{ usePrice(orderInfo?.total_price, true, '') }}
|
||||
</span>
|
||||
<span class="text-gray-800 font-normal text-xs"> تومان</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-1 grid justify-start gap-4">
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal text-sm">تاریخ سفارش:</span>
|
||||
<span class="text-gray-600 font-bold text-sm mr-2">{{ orderInfo?.caj }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal text-sm"> تعداد آیتم:</span>
|
||||
<span class="text-gray-800 font-bold text-sm mr-2">
|
||||
{{ orderInfo?.items?.length }}
|
||||
</span>
|
||||
<span class="text-gray-800 font-normal text-xs"> عدد</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-3">
|
||||
<ADivider class="divider" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mx-3">
|
||||
<div class="grid-cols-1 grid justify-start gap-4">
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal text-sm"> تحویل گیرنده:</span>
|
||||
<span class="text-gray-600 font-bold text-sm mr-2">
|
||||
{{ orderInfo?.customer?.name }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal text-sm"> شماره همراه:</span>
|
||||
<span class="text-gray-600 font-bold text-sm mr-2">
|
||||
{{ orderInfo?.customer?.mobile }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-1 grid justify-start gap-4">
|
||||
<!-- <div>-->
|
||||
<!-- <span class="text-gray-400 font-normal text-sm"> نام فروشگاه:</span>-->
|
||||
<!-- <span class="text-gray-600 font-bold text-sm mr-2">-->
|
||||
<!-- {{ orderInfo?.customer?.shop_name }}</span-->
|
||||
<!-- >-->
|
||||
<!-- </div>-->
|
||||
<div>
|
||||
<span class="text-gray-400 font-normal text-sm"> تلفن ثابت:</span>
|
||||
<span class="text-gray-600 font-bold text-sm mr-2">
|
||||
{{ orderInfo?.customer?.phone_number }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-3">
|
||||
<ADivider class="divider" />
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mx-3">
|
||||
<div>
|
||||
<span class="text-sm font-normal text-gray-400">استان:</span>
|
||||
<span class="text-sm font-bold text-gray-600 mr-2">
|
||||
{{ orderInfo?.customer?.province }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-sm font-normal text-gray-400">شهر:</span>
|
||||
<span class="text-sm font-bold text-gray-600 mr-2">{{
|
||||
orderInfo?.customer?.city
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-3 my-4">
|
||||
<span class="text-sm font-normal text-gray-400">کد پستی:</span>
|
||||
<span class="text-sm font-bold text-gray-600 mr-2">{{
|
||||
orderInfo?.address?.zip
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="mr-3">
|
||||
<span class="text-sm font-normal text-gray-400">آدرس:</span>
|
||||
<span class="text-sm font-bold text-gray-600 mr-2">{{
|
||||
orderInfo?.address?.address
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center mt-3">
|
||||
<img :src="detail" width="150" height="150" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<WithdrawItems
|
||||
class="col-span-3"
|
||||
:order="orderInfo as Orders"
|
||||
v-model:edit="edit"
|
||||
v-model:loading="loading"
|
||||
@update="updateTable"
|
||||
/>
|
||||
</div>
|
||||
</ASpin>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { ref } from 'vue'
|
||||
import detail from './assets/order1.svg'
|
||||
import type { Withdraw } from '@/model/wallet'
|
||||
import WithdrawStatus from '@/pages/menuPages/withdraw/components/WithdrawStatus.vue'
|
||||
import WithdrawItems from '@/pages/menuPages/withdraw/information/components/WithdrawItems.vue'
|
||||
import Button from '@core/components/BaseButton/src/button.vue'
|
||||
import { changeStatus } from '@/pages/menuPages/withdraw/information/hooks/status'
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { getWithdrawById } from '@/api/wallet'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
|
||||
const indicator = h(LoadingOutlined, {
|
||||
style: {
|
||||
fontSize: '24px'
|
||||
},
|
||||
spin: true
|
||||
})
|
||||
|
||||
interface Props {
|
||||
visible?: boolean
|
||||
order?: Withdraw
|
||||
}
|
||||
|
||||
const edit = ref<boolean>(false)
|
||||
const loading = ref<boolean>(false)
|
||||
const orderInfo = ref<Withdraw | null>(null)
|
||||
const { prefixCls } = usePrefix('informationIndex')
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
visible: false
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.order,
|
||||
() => {
|
||||
// console.log('watch')
|
||||
orderInfo.value = cloneDeep(props.order)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', value: boolean): void
|
||||
(e: 'update'): void
|
||||
}>()
|
||||
|
||||
const handleCancel = () => {
|
||||
emit('update:visible', false)
|
||||
edit.value = false
|
||||
}
|
||||
|
||||
const changeSts = async (status: any) => {
|
||||
try {
|
||||
let orderId = props.order?.id
|
||||
loading.value = true
|
||||
await changeStatus(orderId as number, status)
|
||||
orderInfo.value = await getWithdrawById(orderId as number)
|
||||
updateTable()
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const updateTable = () => {
|
||||
emit('update')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@prefix: ~'@{prefixCls}-AppHeader';
|
||||
|
||||
.@{prefix} {
|
||||
}
|
||||
|
||||
.classOne {
|
||||
color: #9ca3af;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<div class="fixed py-5 shadow-lg top-0 right-0 left-0">
|
||||
<div class="flex items-center justify-center relative">
|
||||
<img :src="getConfigApp('avatar')" class="w10rem" />
|
||||
<BaseIcon
|
||||
icon="vuesax-linear:row-vertical"
|
||||
class="absolute p-3 right-0.5rem"
|
||||
@click="showDrawer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ADrawer
|
||||
title="Basic Drawer"
|
||||
:placement="placement"
|
||||
:closable="true"
|
||||
:visible="open"
|
||||
@close="onClose"
|
||||
>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
</ADrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Logo from '@/assets/img/logo_full_.png'
|
||||
import type { DrawerProps } from 'ant-design-vue'
|
||||
import {useConfigStore} from "@/store/configStore";
|
||||
import {getConfigApp} from "@/utils/config";
|
||||
|
||||
const placement = ref<DrawerProps['placement']>('right')
|
||||
const open = ref<boolean>(false)
|
||||
|
||||
const showDrawer = () => {
|
||||
open.value = true
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
open.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||