1404/10/28-base
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="text-center">صفحه مورد نظر یافت نشد</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,9 @@
|
||||
<svg width="428" height="331" viewBox="0 0 428 331" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="428" height="331" transform="matrix(1 0 0 -1 0 331)" fill="url(#paint0_linear_455_10939)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_455_10939" x1="214" y1="0" x2="214" y2="331" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 438 B |
@@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-white wrap-fix z-200001 py-3 px-3 text-primary font-bold drop-shadow flex">
|
||||
<div @click="router.back()" class="cursor-pointer">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1" />
|
||||
</div>
|
||||
<div class="mr-2">درباره ما</div>
|
||||
</div>
|
||||
<div class="pt-20">
|
||||
<div>
|
||||
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0" />
|
||||
</div>
|
||||
<div class="text-justify text-base z-200000 relative">
|
||||
<div class="px-10">
|
||||
<!-- <img :src="logoFull" class="mb-20 mt-5" />-->
|
||||
<div class="overflow-y-auto h-65vh">
|
||||
<div class="bg-primary text-white rounded-[12px] p-4 text-xs leading-5">
|
||||
<div class="w-full h-1px my-3 bg-tertiary"></div>
|
||||
<div>
|
||||
طلا علاوه بر کاربرد در ساخت زیورآلات، از دوران کهن به عنوان یک فلز ارزشمند و دارایی
|
||||
مقاوم در برابر تورم شناخته میشود، به طوری که سرمایهگذاران حرفهای همواره بخشی از
|
||||
سبد سرمایهگذاریشان را به طلا اختصاص میدهند.
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
با وجود گسترش فناوریهای نوین در همه حوزهها، ما در شرکت پخش طلای حاجی ابوالفتح با
|
||||
تلفیق تجربه سنتی خود در بازار طلا و با دانش تخصصی خود و با بهرهگیری از سوابق موفق
|
||||
قبلی در حوزه فینتک، اقدام به ایجاد گلد نمودیم.
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
مهمترین ارزش پیشنهادی گلد، امکان پس انداز تدریجی طلا با سرمایههای خرد و بدون
|
||||
پرداخت هزینههای جانبی است و در این راستا گلد دات آی آر تمام تلاش خود را نموده است تا از
|
||||
ابتدای سال 1401 با رونمایی محصول اولیه، برای همه افراد با هر سطحی از دارایی، بستری
|
||||
امن و مطمئن ایجاد نماید.
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
علاوه بر این گلد به عنوان یک واحد فناور از سال 1403 با رونمایی نسخه کاملا آنلاین
|
||||
و نرم افزاری وارد فاز جدیدی از خرید و فروش طلای آب شده، شده است.
|
||||
</div>
|
||||
<div class="w-full h-1px my-3 bg-tertiary"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap-fix bottom-0 px-10 py-6 flex gap-2 bg-white">
|
||||
<a class="w-full" href="tel:09123113112">
|
||||
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
|
||||
</a>
|
||||
<a href="https://t.me/saminn_gold">
|
||||
<img src="@/assets/img/telegram.png" alt="" class="h-10 w-10"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <ActionSheet v-model:show="editPassVisible">salam</ActionSheet>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import img from '@/assets/img/user_ly1.svg'
|
||||
import gr_bottom from './assets/img/gr_bottom_white.svg'
|
||||
import { loading } from '@/utils'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import { lengthValidation, required } from '@/utils/inputRules'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { User } from '@/models/login'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import router from '@/router'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { updateMe } from '@/api/me'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker'
|
||||
import img_pattern from "@/views/login/assets/img/pattern.svg";
|
||||
|
||||
const userFormState = ref<User>({
|
||||
fname: '',
|
||||
lname: '',
|
||||
mobile: undefined,
|
||||
birth_date: '',
|
||||
phone_number: '',
|
||||
province: '',
|
||||
city: '',
|
||||
n_code: undefined
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// const editPassVisible = ref<boolean>(false)
|
||||
const editPassVisible = ref<boolean>(false)
|
||||
|
||||
function setForm() {
|
||||
userFormState.value = userStore.userInfo
|
||||
}
|
||||
|
||||
function copyCode() {
|
||||
// nextTick(() => {
|
||||
const val = userStore.userInfo?.referral_id
|
||||
navigator.clipboard.writeText(val)
|
||||
message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
function shareCode() {
|
||||
// nextTick(() => {
|
||||
const val = `⭐️الان طلا بخر؛ آخر ماه سودشو ببر!
|
||||
با خرید طلای آبشده در مقدارهای کم ولی مستمر، سود بیشتری ببر!
|
||||
|
||||
این دعوت نامه از طرف "${userStore.userInfo?.name}" عزیز برای شما ارسال شده تا شما هم از بازار طلای گلد دات آی آر جا نمونید.
|
||||
روی لینک زیر کلیک کنید و ثبت نام خود را تکمیل کنید.
|
||||
|
||||
gold.ir/login?id=${userStore.userInfo?.referral_id}`
|
||||
navigator.share({
|
||||
title: 'گلد دات آی آر',
|
||||
text: val
|
||||
})
|
||||
// message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
userFormState.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
mobile: undefined,
|
||||
birth_date: '',
|
||||
phone_number: '',
|
||||
province: '',
|
||||
city: '',
|
||||
n_code: undefined
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setForm()
|
||||
})
|
||||
|
||||
function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await updateMe(userFormState.value)
|
||||
await userStore.getMyInfo()
|
||||
editPassVisible.value = false
|
||||
message.success('اطلاعات شما با موفقیت به روز رسانی شد')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.trans{
|
||||
transition: height 1s;
|
||||
}*/
|
||||
</style>
|
||||
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<div @click="infoVisible = true" class="shadow mb-2 p-2 rounded-lg">
|
||||
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<div class="font-semibold text-base mb-2">{{item.address }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 mt-2">
|
||||
<BasicInfoItem is-line title="استان" :value="item.province"/>
|
||||
<BasicInfoItem is-line title="شهر" :value="item.city"/>
|
||||
<BasicInfoItem is-line title="کد پستی" :value="item.zip"/>
|
||||
<BasicInfoItem is-line title="شماره تلفن" :value="item.phone"/>
|
||||
</div>
|
||||
<a-divider class="!my-3" />
|
||||
|
||||
<div class="flex justify-between mt-1">
|
||||
<div class="mb-2">{{toJalali(item.created_at)}}</div>
|
||||
<div class="flex gap-2 ">
|
||||
<BasicIcon color="red" icon="vuesax-linear:trash" @click.stop="deleteConfirmVisible = true" class="p-1"/>
|
||||
<BasicIcon color="green" icon="vuesax-linear:edit" @click.stop="emits('edit',item)" class="p-1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- <teleport to="app">-->
|
||||
<DialogVant v-model:show="deleteConfirmVisible" teleport="body" :closeOnClickOverlay="false" :timeOut="-1">
|
||||
<!-- <template v-slot:img>
|
||||
<img :src="registerDelayImage" alt="" class="opacity-80">
|
||||
</template>-->
|
||||
|
||||
<template v-slot:title>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="p-5 text-sm">
|
||||
آیا از حذف آدرس اطمینان دارید؟
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:button>
|
||||
<div class="text-center text-red flex items-center justify-center" @click="deleteItem">
|
||||
<a-spin :spinning="deleteLoading" size="small">
|
||||
تایید
|
||||
</a-spin>
|
||||
</div>
|
||||
<div class="text-center" @click="deleteConfirmVisible = false">
|
||||
انصراف
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</DialogVant>
|
||||
<!-- </teleport>-->
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { toJalali } from '../../../../utils/useDateTime'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import BasicInfoItem from '@/components/BasicPacks/BasicInfoItem.vue'
|
||||
import DialogVant from '@/components/DialogVant.vue'
|
||||
import { updatePriceTrigger } from '@/api/triggerPrice'
|
||||
import { loading } from '@/utils'
|
||||
import type { Address } from '@/models/address'
|
||||
import { deleteAddress } from '@/api/address'
|
||||
|
||||
const infoVisible = ref<boolean>(false)
|
||||
|
||||
const isActive = ref<boolean>(false)
|
||||
|
||||
const deleteLoading = ref(false)
|
||||
const deleteConfirmVisible = ref(false)
|
||||
|
||||
interface Prop {
|
||||
item: Address
|
||||
}
|
||||
function changeActive(val: boolean) {
|
||||
console.log(val)
|
||||
try {
|
||||
loading.value = true
|
||||
updatePriceTrigger(props?.item.id, {is_active: val})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
isActive.value = !isActive.value
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function returnPriceCondition(val: string) {
|
||||
switch (val) {
|
||||
case '==': return 'مساوی'
|
||||
case '<': return 'کوچکتر'
|
||||
// case '==': return 'مساوی'
|
||||
}
|
||||
/* if (val === '=='){
|
||||
return 'مساوی'
|
||||
} else if (val === '<'){
|
||||
return 'کوچکتر'
|
||||
}*/
|
||||
}
|
||||
|
||||
async function deleteItem() {
|
||||
try {
|
||||
deleteLoading.value = true
|
||||
await deleteAddress(props.item.id)
|
||||
deleteConfirmVisible.value = false
|
||||
emits('refresh')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
deleteLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function returnAction(val: string) {
|
||||
switch (val) {
|
||||
case 'sms': return 'پیامک'
|
||||
case 'email': return 'ایمیل'
|
||||
case 'notify': return 'نوتیفیکیشن'
|
||||
// case '==': return 'مساوی'
|
||||
}
|
||||
/* if (val === '=='){
|
||||
return 'مساوی'
|
||||
} else if (val === '<'){
|
||||
return 'کوچکتر'
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const emits = defineEmits(['edit','refresh'])
|
||||
|
||||
/*const title = computed(() => {
|
||||
if (isUp.value) {
|
||||
if (isGold.value) {
|
||||
return 'واریز ریالی'
|
||||
} else {
|
||||
return 'خرید طلا'
|
||||
}
|
||||
} else {
|
||||
if (isGold.value) {
|
||||
return 'برداشت ریالی'
|
||||
} else {
|
||||
return 'فروش طلا'
|
||||
}
|
||||
}
|
||||
})*/
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div >
|
||||
<a-form ref="formRef" :model="address" class="!mt-5" name="basic"
|
||||
@finish="ok()">
|
||||
<div class="font-bold text-lg mb-2">آدرس</div>
|
||||
<div class="flex flex-col gap-4 pb-30 w-full h-65vh overflow-y-auto">
|
||||
<a-form-item label="استان" name="province" :rules="[required()]">
|
||||
<BasicSelect
|
||||
v-model:value="address.province"
|
||||
:items="provinceList"
|
||||
@change="changeProvince"
|
||||
valueName="title"
|
||||
keyName="title"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="شهر" name="city" :rules="[required()]">
|
||||
<BasicSelect
|
||||
:disabled="!cityList"
|
||||
v-model:value="address.city"
|
||||
valueName="title"
|
||||
:items="cityList"
|
||||
keyName="title"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="کد پستی" name="zip" :rules="[required()]">
|
||||
<BasicInput placeholder="کد پستی را وارد نمایید" v-model:value="address.zip" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="تلفن تماس" name="phone" :rules="[required()]"
|
||||
>
|
||||
<BasicInput placeholder="تلفن تماس را وارد نمایید" v-model:value="address.phone" />
|
||||
</a-form-item>
|
||||
<!-- <FormItem label="کد پستی" name="">
|
||||
<Input placeholder="کد پستی را وارد نمایید" />
|
||||
</FormItem>-->
|
||||
<a-form-item
|
||||
label="آدرس کامل"
|
||||
name="address"
|
||||
:rules="[required()]"
|
||||
>
|
||||
<BasicTextArea placeholder="آدرس کامل را وارد نمایید" v-model:value="address.address" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
</a-form>
|
||||
<div class="absolute bottom-18 right-0 w-full p-4 bg-white flex justify-center !text-white ">
|
||||
<BasicButton class=" w-full !text-white " type="primary" @click="handleOk">ثبت آدرس
|
||||
</BasicButton>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {required} from "@/utils/inputRules";
|
||||
import BasicSelect from "@/components/BasicPacks/BasicSelect.vue";
|
||||
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
|
||||
import BasicInput from "@/components/BasicPacks/BasicInput.vue";
|
||||
import BasicTextArea from "@/components/BasicPacks/BasicTextArea.vue";
|
||||
import {loading} from "@/utils";
|
||||
import {createAddress, getCity, getProvince, updateAddress} from "@/api/address";
|
||||
import {FormInstance, message} from "ant-design-vue";
|
||||
|
||||
import {Address} from "@/models/address";
|
||||
import {createPriceTrigger, updatePriceTrigger} from "@/api/triggerPrice";
|
||||
import {onMounted, ref} from "vue";
|
||||
const formRef = ref<FormInstance>()
|
||||
const provinceList = ref<any[]>([])
|
||||
const cityList = ref<any[]>()
|
||||
const emits = defineEmits([ 'onOk'])
|
||||
const addAddressVisible=ref<boolean>(false)
|
||||
const editId = ref<number | undefined>(undefined)
|
||||
const address = ref<Address>({
|
||||
city: '',
|
||||
province: '',
|
||||
phone: '',
|
||||
address: '',
|
||||
zip: '',
|
||||
default_address: false
|
||||
})
|
||||
function resetFields() {
|
||||
editId.value = undefined
|
||||
address.value = {
|
||||
city: '',
|
||||
province: '',
|
||||
phone: '',
|
||||
address: '',
|
||||
zip: '',
|
||||
default_address: false
|
||||
}
|
||||
}
|
||||
onMounted(async () => {
|
||||
resetFields()
|
||||
provinceList.value = await getProvince()
|
||||
})
|
||||
|
||||
|
||||
const handleOk = (e: MouseEvent) => {
|
||||
formRef.value?.validate().then(async () => {
|
||||
editId.value ? await updateAddress(editId.value, address.value) : await createAddress(address.value)
|
||||
addAddressVisible.value = false
|
||||
message.success('آدرس با موفقیت ثبت شد')
|
||||
emits('onOk')
|
||||
resetFields()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('error', error)
|
||||
})
|
||||
}
|
||||
const changeProvince = async (obj: any) => {
|
||||
try {
|
||||
loading.value = true
|
||||
cityList.value = undefined
|
||||
address.value.city = undefined
|
||||
cityList.value = await getCity(obj.id)
|
||||
} catch (e) {
|
||||
message.error('خطا در دریافت شهرها')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
editId.value ? await updatePriceTrigger(editId.value, address.value) : await createPriceTrigger(address.value)
|
||||
message.success('آدرس با موفقیت ایجاد شد')
|
||||
addAddressVisible.value = false
|
||||
emits('onOk')
|
||||
//
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,242 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-white py-3 px-3 text-primary font-bold drop-shadow wrap-fix flex z-10">
|
||||
<div @click="router.back()">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1" />
|
||||
</div>
|
||||
<div class="mr-2">آدرس ها</div>
|
||||
</div>
|
||||
<div>
|
||||
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0" />
|
||||
</div>
|
||||
<!-- <a-spin :spinning="loading">-->
|
||||
<div ref="el" :class="loading? 'h-screen': ''" class="px-3 pt-16 pb-2 overflow-y-scroll"
|
||||
style="max-height: calc(100vh - 50px)">
|
||||
|
||||
<list-anim v-if="!loading" class="pb-12vh">
|
||||
<Item v-for="item in items" :key="item.id" :item="item" @edit="openEdit" @refresh="initItems" />
|
||||
<!-- <TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />-->
|
||||
</list-anim>
|
||||
<div v-if="loading">
|
||||
<TransactionSkeleton v-for="i in 13" :key="i" class="mt-1" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- </a-spin>-->
|
||||
<BasicActionSheet v-model:show="addAddressVisible" teleport="body">
|
||||
<a-form ref="formRef" :model="address" class="!mt-5" name="basic"
|
||||
@finish="ok()">
|
||||
<div class="font-bold text-lg mb-2">آدرس</div>
|
||||
<div class="flex flex-col gap-4 pb-20 w-full h-65vh overflow-y-auto">
|
||||
<a-form-item label="استان" name="province" :rules="[required()]">
|
||||
<BasicSelect
|
||||
v-model:value="address.province"
|
||||
:items="provinceList"
|
||||
@change="changeProvince"
|
||||
valueName="title"
|
||||
keyName="title"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="شهر" name="city" :rules="[required()]">
|
||||
<BasicSelect
|
||||
:disabled="!cityList"
|
||||
v-model:value="address.city"
|
||||
valueName="title"
|
||||
:items="cityList"
|
||||
keyName="title"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="کد پستی" name="zip" :rules="[required()]">
|
||||
<BasicInput placeholder="کد پستی را وارد نمایید" v-model:value="address.zip" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="تلفن تماس" name="phone" :rules="[required()]"
|
||||
>
|
||||
<BasicInput placeholder="تلفن تماس را وارد نمایید" v-model:value="address.phone" />
|
||||
</a-form-item>
|
||||
<!-- <FormItem label="کد پستی" name="">
|
||||
<Input placeholder="کد پستی را وارد نمایید" />
|
||||
</FormItem>-->
|
||||
<a-form-item
|
||||
label="آدرس کامل"
|
||||
name="address"
|
||||
:rules="[required()]"
|
||||
>
|
||||
<BasicTextArea placeholder="آدرس کامل را وارد نمایید" v-model:value="address.address" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<BasicButton class="absolute bottom-20 w-full !text-white" type="primary" @click="handleOk">ثبت آدرس
|
||||
</BasicButton>
|
||||
</a-form>
|
||||
</BasicActionSheet>
|
||||
<!-- <div class="bg-primary w-3rem h-3rem flex items-center justify-center rounded-lg fixed bottom-12vh left-8vw"
|
||||
@click="openAdd()">
|
||||
<BasicIcon icon="vuesax-linear:add" color="white" />
|
||||
</div>-->
|
||||
<Transition mode="out-in" name="fade">
|
||||
<div
|
||||
class="wrap-fix bottom-0 h-[16vh] bg-[#FBFBFC] shadow-lg rounded-3xl flex justify-center pt-3 z-200"
|
||||
style="box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 26px 11px"
|
||||
@click="openAdd()">
|
||||
<BasicIcon icon="vuesax-linear:add" />
|
||||
<div>افزودن آدرس جدید</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { createPriceTrigger, getPriceTriggers, updatePriceTrigger } from '@/api/triggerPrice'
|
||||
|
||||
const radioStyle = reactive({
|
||||
display: '',
|
||||
height: '30px',
|
||||
lineHeight: '30px'
|
||||
})
|
||||
import type { SelectItem } from '@/models/SelectItem'
|
||||
|
||||
// import Item from "./components/Item.vue";
|
||||
/*import {lengthValidation, required} from "@/utils/inputRules";
|
||||
import {loading} from "@/utils";
|
||||
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
|
||||
import BasicActionSheet from "@/components/BasicPacks/BasicActionSheet.vue";
|
||||
import BasicInput from "@/components/BasicPacks/BasicInput.vue";*/
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import type { TableEngineInput, TableOutput } from '@/models/table'
|
||||
import { loading, loadingMore } from '@/utils'
|
||||
// import {getOrders} from "@/api/order";
|
||||
import { getTransactionTable } from '@/api/transaction'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue'
|
||||
import { useInfiniteScroll, useScroll } from '@vueuse/core'
|
||||
import ListAnim from '@/components/ListAnim.vue'
|
||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
import { mobileValidation, required } from '@/utils/inputRules'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { User } from '@/models/login'
|
||||
import { type FormInstance, message } from 'ant-design-vue'
|
||||
import type { PriceTrigger } from '@/models/PriceTrigger'
|
||||
import BasicSelect from '@/components/BasicPacks/BasicSelect.vue'
|
||||
import Item from './components/Item.vue'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import router from '@/router'
|
||||
import type { Address } from '@/models/address'
|
||||
import { createAddress, getCity, getProvince, tableAddress, updateAddress } from '@/api/address'
|
||||
import BasicTextArea from '@/components/BasicPacks/BasicTextArea.vue'
|
||||
import img from "@/assets/img/user_ly1.svg";
|
||||
|
||||
const provinceList = ref<any[]>([])
|
||||
const cityList = ref<any[]>()
|
||||
const items = ref<PriceTrigger[]>([])
|
||||
const addAddressVisible = ref<boolean>(false)
|
||||
const editId = ref<number | undefined>(undefined)
|
||||
const el = ref()
|
||||
|
||||
const address = ref<Address>({
|
||||
city: '',
|
||||
province: '',
|
||||
phone: '',
|
||||
address: '',
|
||||
zip: '',
|
||||
default_address: false
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
onMounted(async () => {
|
||||
await initItems()
|
||||
provinceList.value = await getProvince()
|
||||
})
|
||||
|
||||
function resetFields() {
|
||||
editId.value = undefined
|
||||
address.value = {
|
||||
city: '',
|
||||
province: '',
|
||||
phone: '',
|
||||
address: '',
|
||||
zip: '',
|
||||
default_address: false
|
||||
}
|
||||
}
|
||||
|
||||
function openAdd() {
|
||||
resetFields()
|
||||
editId.value = undefined
|
||||
addAddressVisible.value = true
|
||||
}
|
||||
|
||||
const handleOk = (e: MouseEvent) => {
|
||||
formRef.value?.validate().then(async () => {
|
||||
editId.value ? await updateAddress(editId.value, address.value) : await createAddress(address.value)
|
||||
await initItems()
|
||||
addAddressVisible.value = false
|
||||
message.success('آدرس با موفقیت ثبت شد')
|
||||
resetFields()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('error', error)
|
||||
})
|
||||
}
|
||||
|
||||
async function initItems() {
|
||||
try {
|
||||
items.value = []
|
||||
const data = await tableAddress({ page: 0, limit: 150 })
|
||||
items.value = data.rows
|
||||
|
||||
// console.log(items.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const changeProvince = async (obj: any) => {
|
||||
try {
|
||||
loading.value = true
|
||||
cityList.value = undefined
|
||||
address.value.city = undefined
|
||||
cityList.value = await getCity(obj.id)
|
||||
} catch (e) {
|
||||
message.error('خطا در دریافت شهرها')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function openEdit(val: PriceTrigger) {
|
||||
address.value = cloneDeep(val)
|
||||
editId.value = address.value.id
|
||||
addAddressVisible.value = true
|
||||
}
|
||||
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
editId.value ? await updatePriceTrigger(editId.value, address.value) : await createPriceTrigger(address.value)
|
||||
message.success('آدرس با موفقیت ایجاد شد')
|
||||
await initItems()
|
||||
addAddressVisible.value = false
|
||||
//
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<div class="border-solid border-1 border-[#E5E7EB] p-2 mt-3 rounded-[8px]">
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="font-bold">{{item.name}}</div>
|
||||
<div class="flex text-[#9CA3AF]">
|
||||
<div>{{toJalaliNotime(item.created_at)}}</div>
|
||||
<BasicIcon icon="vuesax-linear:calendar" class="w-4 h-4 content-center mr-1" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="mt-2 rounded-[8px] p-2 text-xs" :class="item.is_legal === 0? 'bg-red-100 text-red-600':'bg-green-100 test-green-600'">{{item.is_legal === 0? 'احراز هویت نشده':'احراز هویت شده'}}</div>
|
||||
<div class="flex text-[#9CA3AF]">
|
||||
<div>{{toJalali(item.created_at, 'HH:mm')}}</div>
|
||||
<BasicIcon icon="vuesax-linear:clock" class="w-4 h-4 mr-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import type { User } from '@/models/login'
|
||||
import { toJalali, toJalaliNotime } from '../../../../utils/useDateTime'
|
||||
|
||||
interface Prop {
|
||||
item: User
|
||||
}
|
||||
const props = defineProps<Prop>()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="border-solid border-1 border-[#E5E7EB] p-2 mt-3 rounded-[8px]">
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="font-bold">{{item.customer.name}}</div>
|
||||
<div class="flex text-[#9CA3AF]">
|
||||
<div>{{toJalaliNotime(item.created_at)}}</div>
|
||||
<BasicIcon icon="vuesax-linear:calendar" class="w-4 h-4 content-center mr-1" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div>مبلغ پاداش :</div>
|
||||
<div class="mr-4">{{item.gold}}</div>
|
||||
</div>
|
||||
<!-- <div class="mt-2 rounded-[8px] p-2 text-xs" :class="item.is_legal === 0? 'bg-red-100 text-red-600':'bg-green-100 test-green-600'">{{item.is_legal === 0? 'احراز هویت نشده':'احراز هویت شده'}}</div>-->
|
||||
<div class="flex text-[#9CA3AF]">
|
||||
<div>{{toJalali(item.created_at, 'HH:mm')}}</div>
|
||||
<BasicIcon icon="vuesax-linear:clock" class="w-4 h-4 mr-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import { toJalali, toJalaliNotime } from '../../../../utils/useDateTime'
|
||||
import type { Gifts } from '@/models/gifts'
|
||||
|
||||
interface Prop {
|
||||
item: Gifts
|
||||
}
|
||||
const props = defineProps<Prop>()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-white w-full py-3 px-3 text-primary font-bold drop-shadow flex">
|
||||
<div @click="router.back()">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1" />
|
||||
</div>
|
||||
<div class="mr-2">کسب درآمد</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="text-center p-3 border-solid border-1 rounded-[8px] border-[#0A1B37] ">
|
||||
<div class="flex items-center">
|
||||
<div class=" bg-[#DBEAFE] h-10 w-10 rounded-100% flex justify-center items-center">
|
||||
<img :src="coin" />
|
||||
</div>
|
||||
<div class="mr-4">
|
||||
<div class="flex ">
|
||||
<div class="font-bold">دعوت دوستان</div>
|
||||
<!-- <div class="text-xs ">راهنمای کسب درآمد</div>-->
|
||||
</div>
|
||||
<div class="text-center mt-2 text-xs">هر دعوت موفق 10 سوت طلا هدیه</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-4">
|
||||
<div class="text-[10px] content-center ">کد بازاریابی</div>
|
||||
<div class="mr-2 font-bold">{{userStore.userInfo.referral_id}}</div>
|
||||
</div>
|
||||
<div class="flex mt-4 gap-2">
|
||||
<BasicButton icon="vuesax-linear:share" size="small" class="flex-1" icon-size="18" @click.stop="shareCode()">
|
||||
اشتراک گذاری
|
||||
</BasicButton>
|
||||
<BasicButton icon="vuesax-linear:copy" size="small" class="flex-1" icon-size="18" @click.stop="copyCode()">
|
||||
رونوشت
|
||||
</BasicButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4 mt-4 ">
|
||||
<div class="text-center bg-[#DBEAFE] p-2 rounded-[8px]">
|
||||
<div class="font-bold text-[#2563EB] text-md">
|
||||
{{data?.usersSum}} عدد
|
||||
</div>
|
||||
<div class="text-xs text-[#2563EB] mt-2">تعداد زیر مجموعه</div>
|
||||
</div>
|
||||
<div class="text-center bg-[#FEF9C3] p-2 rounded-[8px]">
|
||||
<div class="font-bold text-[#CA8A04] text-md">
|
||||
{{data?.giftsSum}} سوت
|
||||
</div>
|
||||
<div class="text-xs text-[#CA8A04] mt-2">میزان کل پاداش ها</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-evenly w-full px-2 h-11 items-center bg-gray-50 relative rounded-lg mt-6 ">
|
||||
<div :class="isTransaction?'text-primary bg-white h-8 w-1/2 rounded-lg':'text-gray-400'" class="w-full text-center z-2 flex items-center justify-center"
|
||||
@click.stop="setIsTransaction(true) ">
|
||||
پاداش ها
|
||||
</div>
|
||||
<div :class="!isTransaction?'text-primary bg-white h-8 w-1/2 rounded-lg':'text-gray-400'" class="w-full text-center z-2 flex items-center justify-center"
|
||||
@click.stop="setIsTransaction(false) ">
|
||||
فهرست زیر مجموعه
|
||||
</div>
|
||||
</div>
|
||||
<!-- //**************************************-->
|
||||
<!-- <div class="flex mt-6">-->
|
||||
<!-- <div class="bg-[#0A1B37] p-2 rounded-[8px] w-full">-->
|
||||
<!-- <div class="text-white text-center">فهرست زیرمجموعه</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="bg-[#0A1B37] p-2 rounded-[8px] w-full mr-2">-->
|
||||
<!-- <div class="text-white text-center">پاداش ها</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<div class="border-solid border-1 border-[#E5E7EB] mt-6 "></div>
|
||||
<div v-if="isTransaction">
|
||||
<GiftCard v-for="(val,i) in data?.gifts" :key="i" :item="val"/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<EarnCard v-for="(val,i) in data?.users" :key="i" :item="val"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import router from '@/router'
|
||||
import coin from '@/assets/img/coin.png'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { type FormInstance, message } from 'ant-design-vue'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import type { EarnMoney } from '@/models/earnMoney'
|
||||
import { loading } from '@/utils'
|
||||
import { getEarnMoney } from '@/api/earnMoney'
|
||||
import EarnCard from '@/views/base/earnMoney/components/EarnCard.vue'
|
||||
import TransactionCard from '@/views/base/transactions/components/Item.vue'
|
||||
import GiftCard from '@/views/base/earnMoney/components/GiftCard.vue'
|
||||
|
||||
const data = ref<EarnMoney>()
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
const isTransaction = ref<boolean>(false)
|
||||
|
||||
function setIsTransaction(value: boolean) {
|
||||
isTransaction.value = value
|
||||
}
|
||||
|
||||
function copyCode() {
|
||||
// nextTick(() => {
|
||||
const val = userStore.userInfo?.referral_id
|
||||
navigator.clipboard.writeText(val)
|
||||
message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
function shareCode() {
|
||||
// nextTick(() => {
|
||||
const val = `⭐️الان طلا بخر؛ آخر ماه سودشو ببر!
|
||||
با خرید طلای آبشده در مقدارهای کم ولی مستمر، سود بیشتری ببر!
|
||||
|
||||
این دعوت نامه از طرف "${userStore.userInfo?.name}" عزیز برای شما ارسال شده تا شما هم از بازار طلای گلد دات آی آر جا نمونید.
|
||||
روی لینک زیر کلیک کنید و ثبت نام خود را تکمیل کنید.
|
||||
|
||||
gold.ir/login?id=${userStore.userInfo?.referral_id}`
|
||||
navigator.share({
|
||||
title: ' گلد',
|
||||
text: val
|
||||
})
|
||||
// message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
async function earnMoney() {
|
||||
try {
|
||||
loading.value = true
|
||||
data.value = await getEarnMoney()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function subsetList(){
|
||||
|
||||
}
|
||||
onMounted(async () => {
|
||||
earnMoney()
|
||||
})
|
||||
|
||||
function useStyle() {
|
||||
if (data.value?.User) return 'right: 2%;'
|
||||
// if (isbuy.value) return 'animation-direction: normal'
|
||||
// else return 'animation-direction: reverse'
|
||||
else return ' right: 98%; transform: translate(100%, 0);'
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<div v-if="item" class="bg-white flex flex-col items-center p-3 rounded-xl">
|
||||
<!-- <img v-lazy="{ src: itemImg, loading: logo,error: logo}" alt="" class="w-[87px] ">-->
|
||||
<img v-if="props.item.group_type=='گوی'" :src="goyImg">
|
||||
<img v-if="props.item.group_type=='مکعب'" :src="mokaabImg">
|
||||
<img v-if="props.item.group_type=='سکه'" :src="sekkeImg">
|
||||
<!-- <img :src="props.item.img" alt="image">-->
|
||||
<img v-if="props.item.group_type=='آبشده'|| props.item.group_type== null" :src="defaultImg">
|
||||
<div class="mt-3">{{props.item?.title?? '-'}}</div>
|
||||
<div class="mt-1 flex gap-1"> <div class="font-bold"> {{props.item?.wallet?.gold?? '-'}} </div> {{props.item?.unit}} </div>
|
||||
<!-- {{props.item?.wallet[0]?.cash}}-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import homeImg from '@/assets/img/cash_home.svg'
|
||||
import giftImg from '@/assets/img/cash_gift.svg'
|
||||
import circulationImg from '@/assets/img/cash_circulation.svg'
|
||||
import loveImg from '@/assets/img/cash_love.svg'
|
||||
import repairsImg from '@/assets/img/cash_repairs.svg'
|
||||
import savingImg from '@/assets/img/cash_saving.svg'
|
||||
import {computed} from "vue"
|
||||
import type {Fund} from "@/models/fund"
|
||||
import defaultImg from "@/assets/img/defaultAbshodeh.svg"
|
||||
import goyImg from "@/assets/img/goyImg.svg"
|
||||
import mokaabImg from "@/assets/img/mokaabImg.svg"
|
||||
import sekkeImg from "@/assets/img/sekkeImg.svg"
|
||||
import type { Product } from '@/models/products'
|
||||
/*function itemImg() {
|
||||
|
||||
}*/
|
||||
interface Prop {
|
||||
item: Product
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
|
||||
const itemImg = computed(() => {
|
||||
switch (props.item?.title) {
|
||||
case 'خرید لوازم منزل':
|
||||
return homeImg
|
||||
case 'هدیه':
|
||||
return giftImg
|
||||
case 'گردش':
|
||||
return circulationImg
|
||||
case 'ازدواج':
|
||||
return loveImg
|
||||
case 'تعمیرات':
|
||||
return repairsImg
|
||||
case 'پس انداز':
|
||||
return savingImg
|
||||
default: return savingImg
|
||||
}
|
||||
})
|
||||
|
||||
/*const itemName = computed(() => {
|
||||
switch (props.type) {
|
||||
case 'home':
|
||||
return 'خرید لوازم منزل'
|
||||
case 'gift':
|
||||
return 'هدیه'
|
||||
case 'circulation':
|
||||
return 'گردش'
|
||||
case 'love':
|
||||
return 'ازدواج'
|
||||
case 'repairs':
|
||||
return 'تعمیرات'
|
||||
case 'saving':
|
||||
return 'پس انداز'
|
||||
default: return null
|
||||
}
|
||||
})*/
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-white w-full py-3 px-3 text-primary font-bold drop-shadow fixed md:absolute top-0 flex h-12 z-20">
|
||||
<div @click="router.back()">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1"/>
|
||||
</div>
|
||||
<div class="mr-2">دارایی ها</div>
|
||||
</div>
|
||||
<div class="bg-[#EFCED9] w-screen md:w-full h-[70vh] fixed md:absolute">
|
||||
<div class="pt-15 flex flex-col">
|
||||
<div class="text-gray-500 font-bold mr-5 z-20">موجودی دارایی ها</div>
|
||||
<div class="flex justify-center mt-2 w-full z-20">
|
||||
محصولات:
|
||||
<div class="text-l mr-4 font-bold">{{ walletStore.walletInfo?.count_product ?? 0}}عدد</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-2 w-full z-20">
|
||||
دارایی طلایی:
|
||||
<div class="text-l mr-4 font-bold">{{ walletStore.walletInfo?.count_gold ?? 0}}گرم</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-2 w-full z-20">
|
||||
دارایی ریالی:
|
||||
<div class="text-l mr-4 font-bold">{{ usePriceWithoutType(walletStore.walletInfo?.count_cash ?? 0) }}ریال</div>
|
||||
</div>
|
||||
<!-- <div class="flex items-baseline justify-center mt-2 w-full z-20">
|
||||
<div class="text-3xl font-bold">{{ inventory }}</div>
|
||||
/عدد
|
||||
</div>
|
||||
<div class="flex items-baseline justify-center mt-2 w-full z-20">
|
||||
<div class="text-3xl font-bold">{{ (weight + ((userInfo?.gold) ?? 0)).toFixed(3)}}</div>
|
||||
/گرم
|
||||
</div>-->
|
||||
<img :src="img" alt="" class="mt-[-4rem] mr-10 max-w-[22rem] self-end">
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-[20rem] ">
|
||||
<div class="bg-gray-100 w-screen md:w-full z-20 relative rounded-t-3xl h-[calc(100vh-20rem-70px)] overflow-y-auto pb-15"
|
||||
style="box-shadow: 0px -2px 4px -2px #0000001A;">
|
||||
|
||||
<div v-if="items.length === 0 && !loading" class="w-full h-full flex justify-center items-center">
|
||||
<div>
|
||||
<img :src="empty" alt="" class="w-70 ">
|
||||
<div class="text-center text-lg">یک گنج جدید بساز!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-spin :spinning="loading">
|
||||
<div :class="loading? 'h-[40vh]':''" class="grid grid-cols-2 gap-3 p-5">
|
||||
<Item v-for="item in items.filter(x => x.title !== 'آبشده نقدی')" :item="item"
|
||||
@click="router.push({name: 'fund_info', params:{id:item.id}})"
|
||||
/>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="fixed w-full flex justify-center bottom-23 z-200 md:right-0">
|
||||
<div class="rounded-3xl bg-[#0A1B37] text-white px-5 py-2" @click="router.push({name: 'fund_add'})">افزودن گنج
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import router from "@/router";
|
||||
import BasicIcon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import BasicModal from "@/components/BasicPacks/BasicModal.vue";
|
||||
import img from '@/assets/img/cash_img.svg'
|
||||
import empty from '@/assets/img/cash_empty.svg'
|
||||
import Item from './components/Item.vue'
|
||||
import {onMounted, ref} from "vue";
|
||||
import {loading} from "@/utils";
|
||||
import type {TableOutput} from "@/models/table";
|
||||
import type {Fund} from "@/models/fund";
|
||||
import {useFundUserStore} from "@/store/fundStore";
|
||||
import goyImg from '@/assets/img/goyImg.svg'
|
||||
import mokaabImg from '@/assets/img/mokaabImg.svg'
|
||||
import defaultImg from '@/assets/img/defaultAbshodeh.svg'
|
||||
import { getMe } from '@/api/me'
|
||||
import type { User } from '@/models/login'
|
||||
import {usePriceWithoutType} from "../../../utils/usePrice";
|
||||
import {useWalletStore} from "@/store/walletStore";
|
||||
const openModal = ref<boolean>(false)
|
||||
|
||||
|
||||
const items = ref<Fund[]>([])
|
||||
const tableOutput = ref<TableOutput<Fund> | null>(null)
|
||||
const inventory = ref<number>(0)
|
||||
const fundStore = useFundUserStore()
|
||||
const walletStore = useWalletStore()
|
||||
const userInfo = ref<User>()
|
||||
const weight = ref<number>(0)
|
||||
const total = ref<number>(0)
|
||||
onMounted(() => {
|
||||
initTable()
|
||||
})
|
||||
|
||||
async function initTable() {
|
||||
try {
|
||||
userInfo.value = await getMe()
|
||||
loading.value = true
|
||||
tableOutput.value = fundStore.myFunds ?? await fundStore.getMyFund() ?? null
|
||||
console.log(tableOutput.value)
|
||||
items.value.push(...tableOutput.value?.rows ?? [])
|
||||
items.value.forEach(x => {
|
||||
console.log(x.wallet)
|
||||
if (x.title !== 'آبشده نقدی')
|
||||
inventory.value += x?.wallet?.gold ?? 0
|
||||
total.value += ((x?.wallet?.gold) ?? 0) * ((x?.price) ?? 0)
|
||||
if (x.title !== 'آبشده نقدی' && x.title !== 'سکه')
|
||||
weight.value += ((x?.wallet?.gold) ?? 0) * ((x?.amount) ?? 0)
|
||||
// console.log(inventory.value)
|
||||
})
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/*watch(()=> router.currentRoute.value.name, () =>{
|
||||
console.log('salammmmmmmmmmmmmmmmmmmmmmmmmmm')
|
||||
})*/
|
||||
/*
|
||||
const items = [
|
||||
{
|
||||
type: 'home',
|
||||
amount: 2.7
|
||||
},
|
||||
{
|
||||
type: 'gift',
|
||||
amount: 13.1
|
||||
},
|
||||
{
|
||||
type: 'saving',
|
||||
amount: 6.4
|
||||
},
|
||||
{
|
||||
type: 'repairs',
|
||||
amount: 16.6
|
||||
},
|
||||
{
|
||||
type: 'circulation',
|
||||
amount: 5.4
|
||||
},
|
||||
{
|
||||
type: 'love',
|
||||
amount: 3.7
|
||||
},
|
||||
]
|
||||
*/
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
|
||||
<div @click="infoVisible = true">
|
||||
<div class="flex">
|
||||
<div :class="isUp? 'bg-green-50':'bg-red-50'"
|
||||
class="rounded-lg p-3 h-fit w-fit flex justify-center items-center ">
|
||||
<Icon :class="isUp? 'text-green-600':'text-red-600'"
|
||||
:icon="`vuesax-linear:${isUp? 'arrow-up-2':'arrow-down-2'}`"/>
|
||||
</div>
|
||||
<div class="w-full mr-3">
|
||||
<div class="flex justify-between w-full">
|
||||
<div>{{ item.title }}</div>
|
||||
<div>{{ toJalaliNotime(item.expire_at) }}</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-2">
|
||||
<div :class="item.gold >= 0? 'text-green-600':'text-red-600'" class="text-gray-500 text-xs number-ltr">
|
||||
</div>
|
||||
<div class="text-gray-500 flex gap-1 text-xs items-center">
|
||||
<div :class="item.gold > 0 ? 'text-green-600':'text-red-600'" class="text-base number-ltr">
|
||||
{{ item.gold }}
|
||||
</div>
|
||||
{{item.unit}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div v-if="isGold" class="flex w-full justify-between mt-2">
|
||||
<div class="text-gray-500">قیمت معامله</div>
|
||||
<div class="text-gray-500 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(Math.abs(item.cash) / Math.abs(item.gold)) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- <div v-else class="h-8"></div>-->
|
||||
<a-divider class="!my-3"/>
|
||||
<BasicActionSheet v-model:show="infoVisible">
|
||||
<div class="font-bold text-lg">{{ props.item.title }}</div>
|
||||
<div class="pb-20 mt-5">
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">مقدار {{props.title}} مبادله شده:</div>
|
||||
<div :class="item.gold >= 0? 'text-green-600' : 'text-red-600'" class="flex text-xs items-center">
|
||||
<div class="text-base ml-1 number-ltr">{{ item.gold }}</div>
|
||||
{{item.unit}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">موجودی {{ props.title }}:</div>
|
||||
<div class="flex text-xs text-yellow-700 items-center">
|
||||
<div class="text-base ml-1">{{ item.balance_gold }}</div>
|
||||
{{item.unit}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex justify-between mb-3">
|
||||
<div class="text-primary">موجودی کیف پول:</div>
|
||||
<div class="flex text-xs items-center" :class="isUp? 'text-green-600' : 'text-red-600'"><div class="text-base">{{usePriceWithoutType(12000000)}}</div>ریال</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">موجودی کیف طلا:</div>
|
||||
<div class="flex items-center" :class="isUp? 'text-red-600' : 'text-green-600'">60 گرم</div>
|
||||
</div>-->
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">وضعیت:</div>
|
||||
<div class="flex text-xs items-center">
|
||||
<ATag :color="item.active? 'blue': 'red'" class="!py-1 !px-6 !ml-0">{{
|
||||
item.active ? 'موفق' : 'نا موفق'
|
||||
}}
|
||||
</ATag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">تاریخ:</div>
|
||||
<div>{{ toJalaliNotime(item.expire_at) }}</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">زمان:</div>
|
||||
<div>{{ toTime(item.expire_at) }}</div>
|
||||
</div>
|
||||
<BasicButton class="w-full mt-5" @click="infoVisible = false">بازگشت</BasicButton>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Icon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import BasicActionSheet from "@/components/BasicPacks/BasicActionSheet.vue";
|
||||
import {computed, ref} from "vue";
|
||||
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
|
||||
import type {Transaction} from "@/models/transaction";
|
||||
import {toJalaliNotime, toTime} from "../../../../../utils/useDateTime";
|
||||
|
||||
const infoVisible = ref<boolean>(false)
|
||||
|
||||
interface Prop {
|
||||
item: Transaction
|
||||
title?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const isUp = computed(() => props.item.type === 3 || props.item.type === 1)
|
||||
// const isGold = computed(() => props.item.type === 1 || props.item.type === 2 || props.item.type === 10)
|
||||
/*const title = computed(() => {
|
||||
if (isUp.value) {
|
||||
if (isGold.value) {
|
||||
return 'واریز ریالی'
|
||||
} else {
|
||||
return 'خرید طلا'
|
||||
}
|
||||
} else {
|
||||
if (isGold.value) {
|
||||
return 'برداشت ریالی'
|
||||
} else {
|
||||
return 'فروش طلا'
|
||||
}
|
||||
}
|
||||
})*/
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,300 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-white wrap-fix py-3 px-3 text-primary font-bold drop-shadow flex h-12 z-20 justify-between">
|
||||
<div class="flex ">
|
||||
<div @click="router.back()" class="cursor-pointer">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1" />
|
||||
</div>
|
||||
<div class="mr-2">{{ info?.title }}</div>
|
||||
</div>
|
||||
<!-- <div @click="editShow = true">
|
||||
<BasicIcon icon="vuesax-linear:setting-4" />
|
||||
</div>-->
|
||||
</div>
|
||||
<div class="pt-20 flex flex-col justify-center items-center">
|
||||
<a-spin :spinning="loading">
|
||||
<div class="bg-sky-100 w-[120px] aspect-square flex justify-center rounded-xl">
|
||||
<!-- <img v-if="!loading" :src="itemImg" alt="">-->
|
||||
<img v-if="info?.group_type=='گوی'" :src="goyImg">
|
||||
<img v-if="info?.group_type=='مکعب'" :src="mokaabImg">
|
||||
<img v-if="info?.group_type=='سکه'" :src="sekkeImg">
|
||||
<img v-if="info?.group_type=='آبشده'|| info?.group_type== null" :src="defaultImg">
|
||||
</div>
|
||||
</a-spin>
|
||||
<div class="mt-2 font-bold flex text-xs items-center text-gray-500">
|
||||
<div class="ml-1 text-base text-primary">{{ info?.wallet?.gold?? 0 }}</div>
|
||||
{{info?.unit}}
|
||||
</div>
|
||||
<div class="text-gray-400">موجودی گنج {{ info?.title }}</div>
|
||||
<div class="w-full p-5">
|
||||
<!-- <div class="w-full flex gap-3">
|
||||
<BasicButton class="w-full !bg-[#F3F0E9] !border-0 !rounded" icon="vuesax-linear:add-square" icon-size="18"
|
||||
@click="()=> {transactionShow = true; isDeposit= false}">برداشت
|
||||
</BasicButton>
|
||||
<BasicButton class="w-full !bg-[#F3F0E9] !border-0 !rounded" icon="vuesax-linear:arrow-up" icon-size="18"
|
||||
@click="()=> {transactionShow = true; isDeposit= true}">واریز
|
||||
</BasicButton>
|
||||
</div>-->
|
||||
<div class=" font-bold mt-5">تراکنش ها</div>
|
||||
<!-- <a-spin :spinning="loading">-->
|
||||
<div class="mt-5 pb-17 overflow-y-scroll h-[54vh]">
|
||||
<list-anim v-if="!loading">
|
||||
<Item v-for="item in items" :key="item.id" :item="item" :title="info?.title"/>
|
||||
</list-anim>
|
||||
<TransactionSkeleton v-for="i in 8" v-else :key="i" class="mt-1" />
|
||||
<empty v-if="items.length === 0 && !loading" text="هیچ تراکنشی یافت نشد" />
|
||||
</div>
|
||||
<!-- </a-spin>-->
|
||||
</div>
|
||||
</div>
|
||||
<BasicActionSheet v-model:show="transactionShow">
|
||||
<div class="font-bold text-lg">{{ isDeposit ? 'واریز' : 'برداشت' }}</div>
|
||||
<a-form ref="formRef" :model="userFormState" class="!mt-5" name="basic" @finish="transaction()">
|
||||
<a-form-item :rules="[required()]" label="مقدار گرم طلا" name="value" class="!block">
|
||||
<BasicInput v-model:value="userFormState.value"
|
||||
addon-before="گرم" place-holder="گرم"
|
||||
type="text" inputmode="decimal"
|
||||
size="large" />
|
||||
<div v-if="isDeposit" class="mt-2 text-xs font-bold leading-5">
|
||||
<div>موجودی کیف طلا: {{ walletStore?.walletInfo?.gold }} گرم</div>
|
||||
<div v-if="info?.wallet?.gold !== 0">
|
||||
{{ `موجودی قابل برداشت گنج: ${info?.wallet?.gold ?? 0} گرم` }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="mt-2 text-xs font-bold">موجودی گنج {{ info.title }}: {{ info?.wallet?.gold }} گرم
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<BasicButton
|
||||
:disabled="transButtonDisable"
|
||||
class=" w-full py-2 mt-2"
|
||||
html-type="submit"
|
||||
type="primary"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>{{ isDeposit ? 'واریز' : 'برداشت' }}</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton class="mb-20 mt-2 w-full" @click="transactionShow = false">بازگشت</BasicButton>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</BasicActionSheet>
|
||||
<BasicActionSheet v-model:show="editShow">
|
||||
<div class="font-bold text-lg">گنج {{ info?.title }}</div>
|
||||
|
||||
<BasicButton class="mt-12 w-full" icon="vuesax-linear:edit"
|
||||
icon-size="16" @click="$router.push({name: 'fund_add', query:{id:infoId}})">
|
||||
<div class="flex w-full justify-right">ویرایش</div>
|
||||
</BasicButton>
|
||||
<BasicButton :loading="loading" class="mb-10 mt-2 w-full !text-red-600"
|
||||
icon="vuesax-linear:trash"
|
||||
icon-size="16"
|
||||
@click="deleteFundConfirm">
|
||||
<div class="flex w-full justify-right">حذف</div>
|
||||
</BasicButton>
|
||||
|
||||
<BasicButton class="mb-20 mt-2 w-full" type="primary" @click="transactionShow = false">بازگشت</BasicButton>
|
||||
</BasicActionSheet>
|
||||
<DialogVant v-model:show="showDeleteConfirm" :closeOnClickOverlay="true" :timeOut="-1">
|
||||
<!-- <template v-slot:img>
|
||||
<img :src="registerDelayImage" alt="" class="opacity-80">
|
||||
</template>-->
|
||||
|
||||
<template v-slot:title>
|
||||
<div class="p-5 text-sm">
|
||||
آیا از حذف گنج خود اطمینان دارید؟
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:button>
|
||||
<div class="text-center text-red" @click="deleteFundFunction">
|
||||
حذف
|
||||
</div>
|
||||
<div class="text-center" @click="showDeleteConfirm = false">
|
||||
انصراف
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</DialogVant>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import router from '@/router'
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||
import Item from './components/Item.vue'
|
||||
import homeImg from '@/assets/img/cash_home.svg'
|
||||
import giftImg from '@/assets/img/cash_gift.svg'
|
||||
import circulationImg from '@/assets/img/cash_circulation.svg'
|
||||
import loveImg from '@/assets/img/cash_love.svg'
|
||||
import repairsImg from '@/assets/img/cash_repairs.svg'
|
||||
import savingImg from '@/assets/img/cash_saving.svg'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import { loading } from '@/utils'
|
||||
import { deleteFund, fundDeposit, fundWithdraw, getFundById, getFundTransactionTable } from '@/api/fund'
|
||||
import type { Fund, FundTransaction } from '@/models/fund'
|
||||
import type { TableInput, TableOutput } from '@/models/table'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import Empty from '@/components/empty.vue'
|
||||
import { required } from '@/utils/inputRules'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import { useWalletStore } from '@/store/walletStore'
|
||||
import ListAnim from '@/components/ListAnim.vue'
|
||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
||||
import DialogVant from '@/components/DialogVant.vue'
|
||||
import { useFundUserStore } from '@/store/fundStore'
|
||||
import { getOneProductWallet } from '@/api/products'
|
||||
import goyImg from '@/assets/img/goyImg.svg'
|
||||
import mokaabImg from '@/assets/img/mokaabImg.svg'
|
||||
import sekkeImg from "@/assets/img/sekkeImg.svg"
|
||||
import defaultImg from '@/assets/img/defaultAbshodeh.svg'
|
||||
import type { Product } from '@/models/products'
|
||||
|
||||
const info = ref<Product>()
|
||||
const items = ref<Transaction[]>([])
|
||||
const tableOutput = ref<TableOutput<Transaction> | null>(null)
|
||||
const pagination = ref<TableInput>({/*limit: 100, page: 0*/ })
|
||||
const transactionShow = ref<boolean>()
|
||||
const editShow = ref<boolean>()
|
||||
const showDeleteConfirm = ref<boolean>()
|
||||
const isDeposit = ref<boolean>()
|
||||
const formRef = ref<FormInstance>()
|
||||
let fundStore = useFundUserStore()
|
||||
let walletStore = useWalletStore()
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
initInfo()
|
||||
// initTable()
|
||||
})
|
||||
|
||||
function deleteFundConfirm() {
|
||||
if (info.value?.wallet === undefined || info.value?.wallet?.gold === 0) {
|
||||
showDeleteConfirm.value = true
|
||||
} else {
|
||||
message.error('ابتدا گنج خود را خالی کنید')
|
||||
editShow.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteFundFunction() {
|
||||
try {
|
||||
loading.value = true
|
||||
showDeleteConfirm.value = false
|
||||
await deleteFund(infoId)
|
||||
await fundStore.getMyFund()
|
||||
router.back()
|
||||
message.success('گنج با موفقیت حذف شد')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const infoId: number = parseInt(<string>router.currentRoute.value.params.id)
|
||||
const userFormState = reactive<FundTransaction>({
|
||||
value: undefined,
|
||||
fund_id: infoId
|
||||
})
|
||||
|
||||
watch(transactionShow, (n) => !n ? userFormState.value = undefined : '')
|
||||
|
||||
const transButtonDisable = computed(() => {
|
||||
if (!loading.value) {
|
||||
if (userFormState.value !== undefined) {
|
||||
if (isDeposit.value) {
|
||||
return userFormState.value > walletStore?.walletInfo?.gold
|
||||
} else {
|
||||
return userFormState.value > info.value?.wallet?.gold
|
||||
}
|
||||
// return isDeposit.value ? userFormState.value > walletStore?.walletInfo?.gold : userFormState.value > info.value?.wallet?.gold
|
||||
} else return true
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
async function initInfo() {
|
||||
try {
|
||||
loading.value = true
|
||||
info.value = await getOneProductWallet(infoId)
|
||||
//pagination.value.page=0
|
||||
await initTable()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initTable() {
|
||||
if (info.value?.wallet)
|
||||
try {
|
||||
loading.value = true
|
||||
items.value = []
|
||||
Object.assign(pagination.value, { wallet_id: info.value?.wallet?.id })
|
||||
// pagination.value.fund_id = infoId
|
||||
tableOutput.value = await getFundTransactionTable(pagination.value)
|
||||
items.value.push(...tableOutput.value.rows)
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function transaction() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
userFormState.fund_id = infoId
|
||||
isDeposit.value ? await fundDeposit(userFormState) : await fundWithdraw(userFormState)
|
||||
await initInfo()
|
||||
// await initTable()
|
||||
await fundStore.getMyFund()
|
||||
await walletStore.getMyWallet()
|
||||
fundStore = useWalletStore()
|
||||
walletStore = useWalletStore()
|
||||
message.success(` با موفقیت${isDeposit.value ? ' واریز' : ' برداشت'} شد`)
|
||||
transactionShow.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const itemImg = computed(() => {
|
||||
switch (info.value?.title) {
|
||||
case 'خرید لوازم منزل':
|
||||
return homeImg
|
||||
case 'هدیه':
|
||||
return giftImg
|
||||
case 'گردش':
|
||||
return circulationImg
|
||||
case 'ازدواج':
|
||||
return loveImg
|
||||
case 'تعمیرات':
|
||||
return repairsImg
|
||||
case 'پس انداز':
|
||||
return savingImg
|
||||
default:
|
||||
return savingImg
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-white wrap-fix py-3 px-3 text-primary font-bold drop-shadow flex h-12 z-20 justify-between">
|
||||
<div class="flex ">
|
||||
<div @click="router.back()" class="cursor-pointer">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1"/>
|
||||
</div>
|
||||
<div class="mr-2">{{edit_id? `ویرایش گنج ${name}`: 'صندوق جدید'}}</div>
|
||||
</div>
|
||||
<div @click="router.back()">
|
||||
<!-- <BasicIcon icon="vuesax-linear:setting-4"/>-->
|
||||
</div>
|
||||
</div>
|
||||
<a-spin :spinning="loading">
|
||||
<div class="pt-20 flex flex-col justify-center items-center">
|
||||
<div class="bg-sky-100 w-[120px] aspect-square flex justify-center rounded-xl"><img :src="itemImg" alt=""></div>
|
||||
<!-- <div class="mt-1 text-xs">تغییر عکس</div>-->
|
||||
<div class="flex mt-3 w-full relative px-5" :class="[prefixCls]">
|
||||
<!-- <div class="text-primary font-bold mx-auto items-center">پس انداز</div>
|
||||
<div class="absolute left-5 text-gray-400 text-xs">7/25</div>-->
|
||||
<van-field
|
||||
v-model="name"
|
||||
label=""
|
||||
class="font-bold"
|
||||
placeholder="عنوان را وارد کنید"
|
||||
input-align="center"
|
||||
:show-word-limit="true"
|
||||
maxlength="25"
|
||||
rows="1"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex overflow-x-scroll gap-2 whitespace-nowrap max-w-[320px] mt-2 px-3">
|
||||
<!-- <BasicTags
|
||||
:items="types"
|
||||
color="green"
|
||||
:has-add="false"
|
||||
/>-->
|
||||
<!-- <BasicButton v-for="item in types" size="small">{{item.name}}</BasicButton>-->
|
||||
<div v-for="item in types"
|
||||
class="border-1 px-3 py-2 flex-nowrap rounded text-xs color-transition background-color-transition"
|
||||
:key="item.name"
|
||||
:class="item.name === name? 'bg-[#0A1B37] text-white':'bg-gray-200 text-gray-600'"
|
||||
@click="name = item.name">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="mt-2 font-bold flex text-xs items-center text-gray-500">
|
||||
<div class="ml-1 text-base text-primary">{{ router.currentRoute.value.query.amount }}</div>
|
||||
گرم
|
||||
</div>
|
||||
<div class="text-gray-400">موجودی صندوق {{itemName}}</div>
|
||||
<div class="w-full p-5">
|
||||
<div class="w-full flex gap-3">
|
||||
<BasicButton class="w-full !bg-light" icon="vuesax-linear:add-square" icon-size="18">برداشت</BasicButton>
|
||||
<BasicButton class="w-full !bg-light" icon="vuesax-linear:arrow-up" icon-size="18">واریز</BasicButton>
|
||||
</div>
|
||||
<div class="text-lg font-bold mt-5">تراکنش ها</div>
|
||||
<div class="mt-5 pb-17">
|
||||
<Item v-for="item in items" :is-up="item.isUp" :has-transition="item.hasTransition" :key="item"/>
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="wrap-fix flex justify-center bottom-23 px-5 z-200" @click="ok()">
|
||||
<BasicButton class="rounded w-full px-5 py-2 text-center" type="primary" :disabled="loading">
|
||||
<a-spin v-if="loading" size="small"/>
|
||||
<div v-else>{{edit_id? 'ویرایش گنج':'ساخت گنج'}}</div>
|
||||
</BasicButton>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import router from "@/router";
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import homeImg from "@/assets/img/cash_home.svg";
|
||||
import giftImg from "@/assets/img/cash_gift.svg";
|
||||
import circulationImg from "@/assets/img/cash_circulation.svg";
|
||||
import loveImg from "@/assets/img/cash_love.svg";
|
||||
import repairsImg from "@/assets/img/cash_repairs.svg";
|
||||
import savingImg from "@/assets/img/cash_saving.svg";
|
||||
import {usePrefix} from "@/utils/usePrefix";
|
||||
import {loading} from "@/utils";
|
||||
import {createFund, editFund, getFundById} from "@/api/fund";
|
||||
import {message} from "ant-design-vue/es";
|
||||
import {useFundUserStore} from "@/store/fundStore";
|
||||
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
|
||||
import type {Fund} from "@/models/fund";
|
||||
|
||||
const fundStore = useFundUserStore()
|
||||
|
||||
|
||||
const types = [
|
||||
{
|
||||
name: 'خرید لوازم منزل'
|
||||
},
|
||||
{
|
||||
name: 'پس انداز'
|
||||
},
|
||||
{
|
||||
name: 'گردش'
|
||||
},
|
||||
{
|
||||
name: 'ازدواج'
|
||||
},
|
||||
{
|
||||
name: 'تعمیرات'
|
||||
},
|
||||
{
|
||||
name: 'هدیه'
|
||||
},
|
||||
]
|
||||
|
||||
const edit_id = computed(() => {
|
||||
return parseInt(router.currentRoute.value.query.id as string)
|
||||
})
|
||||
const name = ref<string>('پس انداز')
|
||||
const {prefixCls} = usePrefix('input_name')
|
||||
const info = ref<Fund>()
|
||||
|
||||
async function getEditInfo() {
|
||||
try {
|
||||
loading.value = true
|
||||
info.value = await getFundById(edit_id.value)
|
||||
name.value = info.value?.title?? ''
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (edit_id.value) {
|
||||
getEditInfo()
|
||||
}
|
||||
})
|
||||
|
||||
const itemImg = computed(() => {
|
||||
switch (name.value) {
|
||||
case 'خرید لوازم منزل':
|
||||
return homeImg
|
||||
case 'هدیه':
|
||||
return giftImg
|
||||
case 'گردش':
|
||||
return circulationImg
|
||||
case 'ازدواج':
|
||||
return loveImg
|
||||
case 'تعمیرات':
|
||||
return repairsImg
|
||||
case 'پس انداز':
|
||||
return savingImg
|
||||
default:
|
||||
return savingImg
|
||||
}
|
||||
})
|
||||
|
||||
async function ok() {
|
||||
try {
|
||||
loading.value = true
|
||||
// console.log(name.value)
|
||||
name.value ? edit_id.value? await editFund(edit_id.value,{title: name.value}) :await createFund({title: name.value}) : () => {
|
||||
message.error('ابتدا نام گنج را وارد کنید')
|
||||
return
|
||||
}
|
||||
await fundStore.getMyFund()
|
||||
message.success(`گنج با موفقیت ${edit_id.value? 'ویرایش':'ساخته'} شد`)
|
||||
router.back()
|
||||
// name.value? message.warn('ss'): message.error('ابتدا نام صندوق را وارد کنید')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@prefix: ~'@{prefixCls}-input_name';
|
||||
|
||||
.@{prefix} {
|
||||
.van-field__value {
|
||||
@apply flex;
|
||||
}
|
||||
|
||||
.van-field__body {
|
||||
@apply w-full mr-5;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<div ref="skeletonRatio" class="h-fit">
|
||||
<content-loader :width="skeletonSize.width" class="bg-white" height="100vh">
|
||||
<rect :width="skeletonSize.width" height="88" rx="3" ry="3" x="0" y="0"/>
|
||||
</content-loader>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import {reactive, ref, watch} from "vue";
|
||||
import {useElementSize} from "@vueuse/core";
|
||||
import {ContentLoader} from "vue-content-loader";
|
||||
|
||||
const skeletonRatio = ref(null)
|
||||
const skeletonSize = reactive(
|
||||
useElementSize(skeletonRatio, {width: 0, height: 0}, {box: 'border-box'})
|
||||
)
|
||||
watch(skeletonSize, () => {
|
||||
console.log(skeletonSize)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,651 @@
|
||||
<template>
|
||||
<div class="h-35rem overflow-y-auto">
|
||||
<div class=" !overflow-y-scroll bg-white py-3 text-primary font-bold flex justify-evenly">
|
||||
<!-- <div @click="isBuy = false" class="w-full text-center" :class="!isBuy?'text-primary':'text-gray-400'">خرید طلا</div>
|
||||
<div @click="isBuy = true" class="w-full text-center" :class="isBuy?'text-primary':'text-gray-400'">فروش طلا</div>-->
|
||||
<div class="flex justify-evenly w-full px-2 h-11 items-center bg-gray-50 relative rounded ">
|
||||
<div :class="isBuy?'text-secondary':'text-gray-400'" class="w-full text-center z-2"
|
||||
@click.stop="setIsBuy(true) ">
|
||||
خرید طلا {{ props?.ProductItem?.title }}
|
||||
</div>
|
||||
<div :class="!isBuy?'text-secondary':'text-gray-400'" class="w-full text-center z-2"
|
||||
@click.stop="setIsBuy(false) ">
|
||||
فروش طلا {{ props?.ProductItem?.title }}
|
||||
</div>
|
||||
<!-- <div ref="bganim" class="absolute bg-white h-8 w-1/2 rounded-lg " :style="`transform: translateX(${isbuy? '0':'-100%'}); left: ${isbuy? '0':'100%'}`"></div>-->
|
||||
<div ref="bganim" :style="useStyle()"
|
||||
class="absolute bg-white h-8 w-1/2 rounded-lg animate right"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="userStore" class=" mt-5 mb-25vh pb-2">
|
||||
<a-spin :spinning="!price">
|
||||
<div v-if="!loading" :class="!isBuy? ' bg-red-100' : ' bg-green-100'"
|
||||
class="w-full relative rounded-lg h-[88px] flex flex-col justify-center background-color-transition">
|
||||
<img :src="img1" alt="" class="h-[88px] absolute">
|
||||
<div class="w-full items-center flex flex-col">
|
||||
<div class="text-gray-700 font-bold">{{ !isBuy ? 'قیمت فروش' : 'قیمت خرید' }}</div>
|
||||
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
|
||||
<div :class="!isBuy? 'text-red-700' : 'text-green-700'" class="font-bold text-2xl color-transition">
|
||||
{{ usePriceWithoutType(goldPriceValue) }}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="w-full h-[88px]">
|
||||
<GoldSkeleton class="w-full" />
|
||||
</div>
|
||||
<div v-if="limitedPrice !== undefined && userStore?.userInfo.trade_active !== 1"
|
||||
class="text-red text-xs flex gap-1 items-center justify-center my-2">
|
||||
<Icon icon="vuesax-linear:info-circle" size="16" />
|
||||
حداقل مبلغ اولیه برای ثبت سفارش {{ usePriceWithoutType(limitedPrice.value as number ?? 0) }} ریال می باشد.
|
||||
</div>
|
||||
</a-spin>
|
||||
<a-form :model="form" class="!mt-5" name="basic" @finish="okConfirm()">
|
||||
<div class="border-gray-200 border-1 rounded-xl p-5 h-58 relative">
|
||||
<bg_main />
|
||||
<div class="z-100 relative">
|
||||
<a-form-item>
|
||||
<BasicInput v-model:value="form.goldCash" addon-before="ریال" addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="ارزش کل"
|
||||
size="large"
|
||||
type="price" @onchange="calculateGold" />
|
||||
</a-form-item>
|
||||
<a-form-item :rules="[justNumber()]">
|
||||
<BasicInput v-model:value="form.goldValue" addon-before="گرم" addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="مقدار طلا"
|
||||
size="large" type="text" inputmode="decimal" @onchange="calculateCash" />
|
||||
</a-form-item>
|
||||
<!-- {{walletStore?.walletInfo?.gold}}-->
|
||||
<Transition mode="out-in" name="fade">
|
||||
<div v-if="!isBuy" class="font-bold text-xs">
|
||||
<div> {{ `موجودی کیف طلا: ${walletStore?.walletInfo?.gold ?? 0} گرم` }}</div>
|
||||
<!-- <div v-if="walletStore?.walletInfo?.gold_block !== 0">
|
||||
{{ `موجودی قابل برداشت طلا: ${walletStore?.walletInfo?.gold_block ?? 0} گرم` }}
|
||||
</div>-->
|
||||
</div>
|
||||
<div v-else class="font-bold text-xs">
|
||||
{{ `موجودی کیف پول: ${usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)} ریال` }}
|
||||
</div>
|
||||
</Transition>
|
||||
<Transition mode="out-in" name="fade">
|
||||
<a-form-item v-if="walletStore?.walletInfo" class="!mt-3 ">
|
||||
<!-- {{ isBuy }}-->
|
||||
<a-slider v-model:value="form.percentWallet"
|
||||
:disabled="isBuy? walletStore?.walletInfo?.cash <= 0: false"
|
||||
:max="100"
|
||||
:min="0"
|
||||
:step="10"
|
||||
:tip-formatter="null"
|
||||
class="!my-1"
|
||||
@change="percentChange" />
|
||||
</a-form-item>
|
||||
</Transition>
|
||||
<!-- <Transition mode="out-in" name="fade">
|
||||
<div v-if="priceErrorVisible" class="flex gap-1 items-center text-xs mt-[-15px] text-orange-600">
|
||||
<BasicIcon icon="vuesax-linear:danger" />
|
||||
ارزش کل وارد شده بر حسب گرم طلا محاسبه خواهد شد و قیمت وارد شده معادل {{ usePrice(finalPrice) }} می
|
||||
باشد!
|
||||
</div>
|
||||
</Transition>-->
|
||||
<Transition mode="out-in" name="fade">
|
||||
<div v-if="priceErrorVisible" class="flex gap-1 items-center text-xs mt-[-15px] text-blue-600">
|
||||
<BasicIcon icon="vuesax-linear:info-circle" />
|
||||
ارزش کل وارد شده بر حسب گرم طلا محاسبه خواهد شد و قیمت وارد شده معادل {{ usePrice(parseInt(finalPrice.toFixed(0))) }} می
|
||||
باشد!
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
<GoldLoading v-model:show="infoVisible" />
|
||||
<a-form-item>
|
||||
<BasicButton
|
||||
v-if="walletStore"
|
||||
:disabled="disableTransaction"
|
||||
class=" w-full py-2 mt-5"
|
||||
html-type="submit"
|
||||
type="primary"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>{{ !isBuy ? 'فروش' : 'خرید' }}</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<div v-if="!isBuy && form.goldValue > walletStore?.walletInfo?.gold"
|
||||
class="text-red-700 text-xs font-bold mt-2">
|
||||
مقدار گرم طلای وارد شده جهت فروش ({{ form.goldValue }}گرم) بیشتر از مقدار موجودی شما
|
||||
({{ walletStore?.walletInfo?.gold }}گرم) می باشد.
|
||||
</div>
|
||||
<!-- <div>{{form?.goldValue? true: false}}</div>-->
|
||||
<div v-if="isBuy? ((form?.goldValue || form.goldValue === 0)? form?.goldCash < 500000: false) : false"
|
||||
class="text-red-700 text-xs font-bold mt-2">
|
||||
حداقل مقدار طلا جهت خرید 500,000 ریال می باشد.
|
||||
</div>
|
||||
</a-form-item>
|
||||
<div class=" w-full bottom-18 px-6 rounded-xl py-1 border-1 bg-white">
|
||||
<!-- <BasicInfoItem is-line title="کارمزد" :value="parseFloat(((form.goldValue?? 0)*0.005).toFixed(3))" />-->
|
||||
<!-- <BasicInfoItem is-line title="کارمزد" :value="parseFloat(((form.goldValue?? 0)*0.005).toFixed(3))" />-->
|
||||
<div class="flex justify-between items-center">
|
||||
<div>کارمزد:</div>
|
||||
<div class="flex gap-2 items-center">
|
||||
<div class="">{{ parseFloat(((form.goldValue ?? 0) * 0.01).toFixed(4)) }}</div>
|
||||
<!-- <div class="font-bold text-2xl">{{ 0 }}</div>-->
|
||||
<div>
|
||||
گرم
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-form>
|
||||
<!-- <div ref="el" :class="loading? 'h-screen': ''"
|
||||
class="px-3 overflow-y-scroll w-full h-[49vh] pb-25 max-h-[35vh]">
|
||||
<!– <div v-for="item in items">ss</div>–>
|
||||
<list-anim v-if="!loading" :numberItemsAnim="4">
|
||||
<Item v-for="item in isBuy? buyItems: sellItems" :key="item.id" :item="item" />
|
||||
<TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />
|
||||
</list-anim>
|
||||
<TransactionSkeleton v-for="i in 13" v-else :key="i" class="mt-1" />
|
||||
</div>-->
|
||||
</div>
|
||||
|
||||
<BasicActionSheet v-model:show="confirmAction">
|
||||
<div class="font-bold text-lg"></div>
|
||||
<div class="w-full rounded-lg bg-gray-50 p-3">
|
||||
<div class="flex justify-between ">
|
||||
<div>وزن:</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">{{ form.goldValue }}</div>
|
||||
<div class="text-xs mr-1">گرم</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>مظنه:</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">{{ usePriceWithoutType(isBuy ? price.buy ?? 0 : price.sell ?? 0) }}</div>
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>کارمزد:</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="font-bold text-xl">{{ parseFloat(((form.goldValue ?? 0) * 0.01).toFixed(4)) }}</div>
|
||||
<div class="text-xs mr-1">گرم</div>
|
||||
</div>
|
||||
</div>
|
||||
<div >(معادل {{ equivalentPrice }} ریال)</div>
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>{{ isBuy ? 'قیمت قابل پرداخت:' : 'مبلغ دریافتی:' }}</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">{{ usePriceWithoutType(payablePrice.toFixed(0)) }}</div>
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<BasicButton class="mb-20 mt-5 w-full" type="primary" @click="ok(); confirmAction= false">ثبت نهایی</BasicButton>
|
||||
</BasicActionSheet>
|
||||
<van-dialog v-model:show="noCompleteVisible" class="completeButtonStyle" confirm-button-text="تکمیل اطلاعات"
|
||||
show-confirm-button @confirm="router.push({name: 'user',query:{showEdit: true}})">
|
||||
<div class="flex flex-col items-center p-2">
|
||||
<BasicIcon class="home_appear_fade_in_up text-center" color="orange"
|
||||
icon="vuesax-linear:info-circle"
|
||||
size="50" />
|
||||
<!-- <div class="home_appear_fade_in_up delay-100">به روز رسانی</div>-->
|
||||
<div class="home_appear_fade_in_up mt-2 text-justify text-center">برای ثبت سفارش، لطفا اطلاعات خود را تکمیل کنید
|
||||
یا در صورت تکمیل اطلاعات، منتظر تایید اطلاعات خود بمانید.
|
||||
</div>
|
||||
</div>
|
||||
</van-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import img1 from '@/assets/img/home_ly2.svg'
|
||||
import { usePrice, usePriceWithoutType } from '@/utils/usePrice'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { Gold } from '@/models/gold'
|
||||
import { isIphone, loading, loadingMore, toFixedDownThreeChar } from '@/utils'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import router from '@/router'
|
||||
import { useWalletStore } from '@/store/walletStore'
|
||||
import { createOrder } from '@/api/order'
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { Price } from '@/models/home'
|
||||
import { getLastPrice } from '@/api/home'
|
||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import { justNumber } from '@/utils/inputRules'
|
||||
import GoldSkeleton from '@/views/base/gold/components/GoldSkeleton.vue'
|
||||
import GoldLoading from '@/components/GoldLoading.vue'
|
||||
import { update } from 'lodash'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
||||
import ListAnim from '@/components/ListAnim.vue'
|
||||
import Item from '@/views/base/wallet/components/Item.vue'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import type { TableEngineInput, TableOutput } from '@/models/table'
|
||||
import { useInfiniteScroll } from '@vueuse/core'
|
||||
import { getTransactionTable } from '@/api/transaction'
|
||||
import { getLastPrices, getUpPrice, lastPrice, setIntervalGetAllPrice, stopPriceInterval } from '@/utils/price'
|
||||
import type { Product } from '@/models/products'
|
||||
import { useFundUserStore } from '@/store/fundStore'
|
||||
// import Bg_main from "@/components/bg_main.vue";
|
||||
|
||||
const infoVisible = ref(false)
|
||||
const walletStore = useWalletStore()
|
||||
const userStore = useUserStore()
|
||||
const fundStore = useFundUserStore()
|
||||
const confirmAction = ref<boolean>(false)
|
||||
const noCompleteVisible = ref<boolean>(false)
|
||||
const buyItems = ref<Transaction[]>([])
|
||||
const sellItems = ref<Transaction[]>([])
|
||||
const priceErrorVisible = ref<boolean>(false)
|
||||
const buyTableOutput = ref<TableOutput<Transaction> | null>(null)
|
||||
const sellTableOutput = ref<TableOutput<Transaction> | null>(null)
|
||||
const el = ref()
|
||||
|
||||
interface Prop {
|
||||
ProductItem?: Product
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const isBuy = ref<boolean>(true)
|
||||
|
||||
const buyPagination = ref<TableEngineInput>({
|
||||
filters: [{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 1
|
||||
}], limit: 6, page: 0
|
||||
})
|
||||
const sellPagination = ref<TableEngineInput>({
|
||||
filters: [{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 2
|
||||
}], limit: 6, page: 0
|
||||
})
|
||||
|
||||
const finalPrice = computed(() => (form.value?.goldValue * (isBuy.value ? price.value?.buy ?? 0 : price.value?.sell ?? 0)))
|
||||
// const payablePrice = computed(() => finalPrice.value + finalPrice.value * 0.007)
|
||||
const payablePrice = computed(() => finalPrice.value)
|
||||
const equivalentPrice = computed(() => usePriceWithoutType(((isBuy ? price.value?.buy ?? 0 : price.value?.sell ?? 0) * (parseFloat(((form.value?.goldValue ?? 0) * 0.01).toFixed(4))) ).toFixed(0)) )
|
||||
|
||||
const disableTransaction = computed(() =>
|
||||
loading.value ||
|
||||
form.value?.goldValue === undefined ||
|
||||
form.value?.goldValue === '' ||
|
||||
form.value?.goldCash === '' ||
|
||||
form.value?.goldCash === undefined ||
|
||||
(isBuy.value ? (form.value?.goldCash ?? 0) < 500000 : (form.value?.goldValue ?? 0) < 0.001) ||
|
||||
(!isBuy.value && form.value.goldValue > walletStore?.walletInfo?.gold) ||
|
||||
price.value?.buy === undefined)
|
||||
|
||||
function refreshTable() {
|
||||
sellItems.value = []
|
||||
buyItems.value = []
|
||||
sellPagination.value = {
|
||||
filters: [{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 2
|
||||
}], limit: 6, page: 0
|
||||
}
|
||||
buyPagination.value = {
|
||||
filters: [{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 1
|
||||
}], limit: 6, page: 0
|
||||
}
|
||||
initSellTable()
|
||||
initBuyTable()
|
||||
}
|
||||
|
||||
|
||||
async function initBuyTable() {
|
||||
try {
|
||||
buyPagination.value.page === 0 ? loading.value = true : loadingMore.value = true
|
||||
buyTableOutput.value = await getTransactionTable(buyPagination.value)
|
||||
buyItems.value.push(...buyTableOutput.value.rows)
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initSellTable() {
|
||||
try {
|
||||
sellPagination.value.page === 0 ? loading.value = true : loadingMore.value = true
|
||||
sellTableOutput.value = await getTransactionTable(sellPagination.value)
|
||||
sellItems.value.push(...sellTableOutput.value.rows)
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// if (!userStore.isSingle) {
|
||||
/*useInfiniteScroll(
|
||||
el,
|
||||
async () => {
|
||||
// load more
|
||||
// console.log('salamss')
|
||||
if (!userStore.isSingle) {
|
||||
if (isbuy.value) {
|
||||
// console.log((buyeTableOutput.value.query.page))
|
||||
// console.log(buyeTableOutput.value.query.total)
|
||||
// console.log((buyeTableOutput.value.query.page + 1) * buyPagination.value.limit < buyeTableOutput.value.query.total)
|
||||
if (
|
||||
buyeTableOutput.value &&
|
||||
(buyPagination.value.page + 1) * buyPagination.value.limit < buyeTableOutput.value.query.total
|
||||
) {
|
||||
// console.log('gfgf')
|
||||
buyPagination.value.page++
|
||||
await initbuyTable()
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
sellTableOutput.value &&
|
||||
(sellPagination.value.page + 1) * sellPagination.value.limit < sellTableOutput.value.query.total
|
||||
) {
|
||||
// console.log('gfgf')
|
||||
sellPagination.value.page++
|
||||
await initsellTable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{ distance: 12 }
|
||||
)*/
|
||||
// }
|
||||
|
||||
onMounted(async () => {
|
||||
switch (router.currentRoute.value.query.state) {
|
||||
case 'sell':
|
||||
isBuy.value = false
|
||||
break
|
||||
case 'buy':
|
||||
isBuy.value = true
|
||||
break
|
||||
}
|
||||
await initPrice()
|
||||
/* await initSellTable()
|
||||
await initBuyTable()*/
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
stopPriceInterval()
|
||||
})
|
||||
|
||||
const form = ref<Gold>({
|
||||
goldCash: undefined,
|
||||
goldValue: undefined,
|
||||
percentWallet: undefined
|
||||
})
|
||||
const allowedAsciiCodeFloat = [46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
|
||||
const allowedAsciiCodeInt = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
|
||||
watch(form.value, () => {
|
||||
if (form.value.goldValue) {
|
||||
const lastCharGoldStr: string = form.value.goldValue.toString()
|
||||
if (!allowedAsciiCodeFloat.includes(lastCharGoldStr.slice(-1).charCodeAt(0))) {
|
||||
form.value.goldValue = isNaN(parseFloat(lastCharGoldStr.slice(0, -1))) ? null : parseFloat(lastCharGoldStr.slice(0, -1))
|
||||
calculateCash(form.value.goldValue)
|
||||
}
|
||||
}
|
||||
if (form.value.goldCash) {
|
||||
const lastCharCashStr: string = form.value.goldCash.toString()
|
||||
if (!allowedAsciiCodeInt.includes(lastCharCashStr.slice(-1).charCodeAt(0))) {
|
||||
form.value.goldCash = isNaN(parseFloat(lastCharCashStr.slice(0, -1))) ? null : parseFloat(lastCharCashStr.slice(0, -1))
|
||||
calculateGold(form.value.goldCash)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
console.log(userStore.userInfo?.is_legal === 2)
|
||||
if (userStore.userInfo?.is_legal === 0) {
|
||||
noCompleteVisible.value = true
|
||||
}
|
||||
})
|
||||
|
||||
function percentChange(val: number) {
|
||||
if (val !== 0)
|
||||
if (isBuy.value) {
|
||||
form.value.goldCash = unitCashCalculator.value * val
|
||||
calculateGold(form.value.goldCash)
|
||||
calculateCash(form.value.goldValue)
|
||||
} else {
|
||||
// console.log((unitGoldCalculator.value * val).toFixed(2))
|
||||
// form.value.goldValue = parseFloat((unitGoldCalculator.value * val).toFixed(2))
|
||||
form.value.goldValue = toFixedDownThreeChar(parseFloat(unitGoldCalculator.value * val))
|
||||
calculateCash(form.value.goldValue)
|
||||
}
|
||||
else {
|
||||
form.value.goldValue = undefined
|
||||
form.value.goldCash = undefined
|
||||
}
|
||||
}
|
||||
|
||||
const unitGoldCalculator = computed(() => {
|
||||
// console.log(walletStore?.walletInfo?.gold / 100)
|
||||
return (walletStore?.walletInfo?.gold ?? 0) / 100
|
||||
})
|
||||
|
||||
const unitCashCalculator = computed(() => {
|
||||
return (walletStore?.walletInfo?.cash ?? 0) / 100
|
||||
})
|
||||
|
||||
const limitedPrice = computed(() => {
|
||||
if (walletStore.limitedPrice)
|
||||
return walletStore?.limitedPrice[0]
|
||||
})
|
||||
|
||||
function calculateCash(val: number) {
|
||||
priceErrorVisible.value = false
|
||||
// console.log(val)
|
||||
if (price.value) {
|
||||
if (isBuy.value) {
|
||||
if (val) form.value.goldCash = parseFloat((val * price?.value?.buy).toFixed(0))
|
||||
else form.value.goldCash = undefined
|
||||
} else {
|
||||
if (val) form.value.goldCash = parseFloat((val * price?.value?.sell).toFixed(0))
|
||||
else form.value.goldCash = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateGold(val: number) {
|
||||
// console.log(val)
|
||||
// form.value.goldCash = usePriceWithoutType(form.value.goldCash)
|
||||
if (price.value) {
|
||||
if (isBuy.value) {
|
||||
if (val) {
|
||||
form.value.goldValue = toFixedDownThreeChar(parseFloat(val / price?.value?.buy))
|
||||
if (parseInt(finalPrice.value) > 0) priceErrorVisible.value = true
|
||||
if (parseInt(finalPrice.value) === 0) priceErrorVisible.value = false
|
||||
} else if (val.toString() === '') {
|
||||
form.value.goldValue = undefined
|
||||
priceErrorVisible.value = false
|
||||
} else {
|
||||
form.value.goldValue = 0
|
||||
priceErrorVisible.value = false
|
||||
}
|
||||
} else {
|
||||
if (val) {
|
||||
form.value.goldValue = toFixedDownThreeChar(parseFloat((val / price?.value?.sell)))
|
||||
if (parseInt(finalPrice.value) > 0) priceErrorVisible.value = true
|
||||
if (parseInt(finalPrice.value) === 0) priceErrorVisible.value = false
|
||||
} else if (val.toString() === '') {
|
||||
// console.log('sasasasasasa')
|
||||
form.value.goldValue = undefined
|
||||
priceErrorVisible.value = false
|
||||
} else {
|
||||
form.value.goldValue = 0
|
||||
priceErrorVisible.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*watch(form.value?.goldValue, (n)=>{
|
||||
console.log('salammmm', n)
|
||||
})*/
|
||||
|
||||
const bganim = ref(null)
|
||||
|
||||
function useStyle() {
|
||||
if (isBuy.value) return 'right: 2%;'
|
||||
// if (isbuy.value) return 'animation-direction: normal'
|
||||
// else return 'animation-direction: reverse'
|
||||
else return ' right: 98%; transform: translate(100%, 0);'
|
||||
}
|
||||
|
||||
|
||||
function setIsBuy(val: boolean) {
|
||||
isBuy.value = val
|
||||
form.value.goldValue = undefined
|
||||
form.value.goldCash = undefined
|
||||
form.value.percentWallet = 0
|
||||
priceErrorVisible.value = false
|
||||
// console.log(bganim.value.classList)
|
||||
// bganim?.value?.classList.add(val?'right':'left')
|
||||
// bganim?.value?.style.transform = `translateX(${val ? '0' : '-100'});`
|
||||
// bganim?.value?.style.animationDirection = val? 'normal':'reverse'
|
||||
// val? bganim?.value?.classList?.add("move") : bganim?.value?.classList?.remove("move")
|
||||
// const el = bganim.value?.
|
||||
// el.
|
||||
}
|
||||
|
||||
const formatter = (value: number) => {
|
||||
return `${value}%`
|
||||
}
|
||||
|
||||
|
||||
const price = computed((): Price => <Price>lastPrice.value ?? 0)
|
||||
|
||||
const goldPriceValue = computed(() => {
|
||||
if (!price.value) return 0
|
||||
return isBuy.value
|
||||
? (price.value.buy ?? 0)
|
||||
: (price.value.sell ?? 0)
|
||||
})
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
// chartLoading.value = true
|
||||
await getLastPrices()
|
||||
await getUpPrice()
|
||||
await setIntervalGetAllPrice()
|
||||
loading.value = true
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
// chartLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function okConfirm() {
|
||||
confirmAction.value = true
|
||||
}
|
||||
|
||||
async function ok() {
|
||||
try {
|
||||
loading.value = true
|
||||
infoVisible.value = true
|
||||
await createOrder({
|
||||
direction: isBuy.value ? 1 : 2,
|
||||
price: isBuy.value ? price.value?.buy : price.value?.sell,
|
||||
amount: form.value.goldValue ?? 0
|
||||
})
|
||||
await walletStore.getMyWallet()
|
||||
await router.push({ name: 'transactions' })
|
||||
form.value = {
|
||||
goldValue: undefined,
|
||||
goldCash: undefined,
|
||||
percentWallet: undefined
|
||||
}
|
||||
// refreshTable()
|
||||
message.success('سفارش شما با موفقیت انجام شد')
|
||||
await fundStore.getMyFund()
|
||||
} catch (e) {
|
||||
// console.log(e)
|
||||
// await initPrice()
|
||||
} finally {
|
||||
loading.value = false
|
||||
infoVisible.value = false
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.completeButtonStyle{
|
||||
background: blue;
|
||||
}*/
|
||||
.completeButtonStyle .van-dialog__confirm .van-button__content {
|
||||
background: #0A1B37;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.left {
|
||||
transform: translateX(0);
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.toggle-transe-parent {
|
||||
animation: ease-in-out infinite alternate swingParent;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div ref="skeletonRatio" class="h-fit">
|
||||
<content-loader :width="skeletonSize.width" class="bg-white" height="100vh">
|
||||
<rect :width="skeletonSize.width" height="5" rx="3" ry="3" x="0" y="0"/>
|
||||
<rect :width="skeletonSize.width" height="5" rx="3" ry="3" x="0" y="84"/>
|
||||
<rect :width="5" height="85" rx="3" ry="3" x="0" y="0"/>
|
||||
<rect :width="5" :x="skeletonSize.width-5" height="85" rx="3" ry="3" y="0"/>
|
||||
<rect :width="2" :x="skeletonSize.width/2" height="60" rx="3" ry="3" y="15"/>
|
||||
<rect :width="skeletonSize.width/2-20" :x="10" height="20" rx="10" ry="10" y="15"/>
|
||||
<rect :width="skeletonSize.width/2-20" :x="skeletonSize.width/2 + 10" height="20" rx="10" ry="10" y="15"/>
|
||||
<rect :width="skeletonSize.width/2-40" :x="20" height="10" rx="5" ry="5" y="40"/>
|
||||
<rect :width="skeletonSize.width/2-40" :x="skeletonSize.width/2 + 20" height="10" rx="5" ry="5" y="40"/>
|
||||
<rect :width="skeletonSize.width/2-30" :x="15" height="18" rx="10" ry="10" y="60"/>
|
||||
<rect :width="skeletonSize.width/2-30" :x="skeletonSize.width/2 + 15" height="18" rx="10" ry="10" y="60"/>
|
||||
<circle :cx="skeletonSize.width/4-skeletonSize.width/8" cy="145" r="20"/>
|
||||
<circle :cx="skeletonSize.width/4+skeletonSize.width/8" cy="145" r="20"/>
|
||||
<circle :cx="skeletonSize.width/2+ skeletonSize.width/8" cy="145" r="20"/>
|
||||
<circle :cx="skeletonSize.width - skeletonSize.width/8" cy="145" r="20"/>
|
||||
<rect :width="50" :x="skeletonSize.width/4-skeletonSize.width/8 - 25" height="15" rx="3" ry="3" y="170"/>
|
||||
<rect :width="50" :x="skeletonSize.width/4+skeletonSize.width/8 - 25" height="15" rx="3" ry="3" y="170"/>
|
||||
<rect :width="50" :x="skeletonSize.width/2+ skeletonSize.width/8 - 25" height="15" rx="3" ry="3" y="170"/>
|
||||
<rect :width="50" :x="skeletonSize.width - skeletonSize.width/8 - 25" height="15" rx="3" ry="3" y="170"/>
|
||||
<rect :width="skeletonSize.width - 45" :x="45" height="20" rx="3" ry="3" y="230"/>
|
||||
<rect :width="skeletonSize.width" :x="0" height="80" rx="3" ry="3" y="260"/>
|
||||
<rect :width="skeletonSize.width/2 - 5" :x="0" height="50" rx="3" ry="3" y="360"/>
|
||||
<rect :width="skeletonSize.width/2 - 5" :x="skeletonSize.width/2 + 5" height="50" rx="3" ry="3" y="360"/>
|
||||
<rect :width="skeletonSize.width" :x="0" height="170" rx="3" ry="3" y="440"/>
|
||||
<!-- <rect height="20" rx="3" ry="3" width="100" x="0" y="0"/>
|
||||
<rect :width="skeletonSize.width/4 + 40" :x="skeletonSize.width/2" height="20" rx="3" ry="3" y="0"/>
|
||||
<rect height="20" rx="3" ry="3" width="80" x="0" y="30"/>
|
||||
<rect :x="skeletonSize.width - 40" height="40" rx="12" ry="12" width="40" y="0"/>
|
||||
<rect :width="skeletonSize.width" :x="0" :y="skeletonSize.height-5" height="2" rx="12" ry="12"/>-->
|
||||
<!-- <circle :cx="skeletonSize.width - 20" :cy="skeletonSize.height/2 - 10" r="20" />-->
|
||||
<!-- <rect :x="10" y="20" rx="3" ry="3" :width="skeletonSize.width - 20" height="150"/>
|
||||
<circle :cx="skeletonSize.width/2" cy="170" r="15" />
|
||||
<rect :x="skeletonSize.width/2 - skeletonSize.width/3 -10" y="190" rx="3" ry="3" :width="skeletonSize.width/3 + skeletonSize.width/3 + 20" height="20"/>
|
||||
<rect :x="skeletonSize.width/2 - skeletonSize.width/3 +20" y="220" rx="3" ry="3" :width="skeletonSize.width/3 + skeletonSize.width/3 - 40" height="20"/>-->
|
||||
<!-- <rect x="90" y="0" rx="3" ry="3" width="80" height="20" />
|
||||
<rect x="180" y="0" rx="3" ry="3" width="80" height="20" />
|
||||
<rect x="270" y="0" rx="3" ry="3" width="80" height="20" ♥/>-->
|
||||
</content-loader>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {reactive, ref, watch} from "vue";
|
||||
import {useElementSize} from "@vueuse/core";
|
||||
import {ContentLoader} from "vue-content-loader";
|
||||
|
||||
const skeletonRatio = ref(null)
|
||||
const skeletonSize = reactive(
|
||||
useElementSize(skeletonRatio, {width: 0, height: 0}, {box: 'border-box'})
|
||||
)
|
||||
/*watch(skeletonSize, () => {
|
||||
console.log(skeletonSize)
|
||||
})*/
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div v-if="props.ProductItem.wallet" class="bg-gradient-to-l from-primary rounded-lg p-px to-transparent ">
|
||||
<div class="flex flex-col gap-7 rounded-lg p-4 w-56 bg-white ">
|
||||
<div class="flex justify-between items-center font-medium text-sm">
|
||||
<div class="text-primary">موجودی {{ props.ProductItem.title }}</div>
|
||||
<BasicIcon v-if="props.ProductItem.group_type=='گوی'" stroke-width="1" size="50" color="#0A1B37" class="rotate-310" icon="vuesax-linear:grammerly"/>
|
||||
<BasicIcon v-else-if="props.ProductItem.group_type=='سکه'" stroke-width="1" size="50" color="#0A1B37" class="rotate-310" icon="vuesax-linear:coin"/>
|
||||
<BasicIcon v-else-if="props.ProductItem.group_type=='شمش'" stroke-width="1" size="50" color="#0A1B37" class="rotate-310" icon="vuesax-linear:slider-vertical"/>
|
||||
<BasicIcon v-else-if="props.ProductItem.group_type=='مکعب'" stroke-width="1" size="50" color="#0A1B37" class="rotate-310" icon="vuesax-linear:keyboard"/>
|
||||
<BasicIcon v-else-if="props.ProductItem.group_type=='آبشده'" stroke-width="1" size="50" color="#0A1B37" class="rotate-310" icon="vuesax-linear:slider-vertical"/>
|
||||
<BasicIcon v-else stroke-width="1" size="50" color="#0A1B37" class="rotate-310" icon="vuesax-linear:slider-vertical"/>
|
||||
</div>
|
||||
<div class="flex justify-between px-2 items-center ">
|
||||
<BasicIcon v-if="props.ProductItem.group_type=='گوی'" stroke-width="1" size="26" color="#0A1B37" class="rotate-310" icon="vuesax-linear:grammerly"/>
|
||||
<BasicIcon v-else-if="props.ProductItem.group_type=='سکه'" stroke-width="1" size="26" color="#0A1B37" class="rotate-310" icon="vuesax-linear:coin"/>
|
||||
<BasicIcon v-else-if="props.ProductItem.group_type=='شمش'" stroke-width="1" size="26" color="#0A1B37" class="rotate-310" icon="vuesax-linear:slider-vertical"/>
|
||||
<BasicIcon v-else-if="props.ProductItem.group_type=='مکعب'" stroke-width="1" size="26" color="#0A1B37" class="rotate-310" icon="vuesax-linear:keyboard"/>
|
||||
<BasicIcon v-else stroke-width="1" size="26" color="#0A1B37" class="rotate-310" icon="vuesax-linear:slider-vertical"/> <div class="flex justify-between gap-2 items-center">
|
||||
<span v-if="props.ProductItem.group_type=='آبشده'" class="font-bold text-secondary">{{userWallet.walletInfo?.gold??0}}</span>
|
||||
<span v-else class="font-bold text-secondary">{{props?.ProductItem.wallet?.gold??0}}</span>
|
||||
<span class="text-gray-400">{{props?.ProductItem?.unit}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import BasicIcon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import type {PInventory} from "@/models/products";
|
||||
import {useWalletStore} from "../../../../store/walletStore";
|
||||
interface Prop {
|
||||
ProductItem: PInventory
|
||||
}
|
||||
const userWallet=useWalletStore()
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.text-secondary{
|
||||
font-size: large;
|
||||
--un-text-opacity: 1;
|
||||
color: #ac842f !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,364 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<!-- <div class="bg-primary h-30 mt-[-3rem] z-100000000000"></div>-->
|
||||
<div class="fixed h-[60vh] bg-[#0A1B37] w-screen">
|
||||
<div class="flex w-full justify-around mt-18">
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">موجودی کیف طلا</div>
|
||||
<div class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs">
|
||||
<div class="text-white text-lg">{{ walletStore?.walletInfo?.gold ?? 0 }}</div>
|
||||
گرم
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">سقف اعتبار خرید طلا</div>
|
||||
<div class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs">
|
||||
<div class="text-white text-lg">{{ userStore?.userInfo?.gram ?? 0 }}</div>
|
||||
گرم
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">موجودی کیف پول</div>
|
||||
<div class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs">
|
||||
<div class="text-white text-lg">
|
||||
{{ walletStore?.walletInfo?.cash === undefined ? 0 : usePriceWithoutType(walletStore.walletInfo?.cash) }}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-[9rem] relative">
|
||||
<img :src="img" alt="" class="w-screen h-[8rem]">
|
||||
<!-- <div class="w-screen bg-white w-screen h-[calc(100vh-16rem-70px)] px-5">-->
|
||||
<div v-if="userStore.userInfo && !loading" class="bg-white w-screen h-fit px-5 m-[-1px]">
|
||||
<!-- <a-alert :message="``" type="warning" show-icon/>-->
|
||||
<!-- {{limitedPrice === undefined}}-->
|
||||
<div v-if="limitedPrice !== undefined && userStore?.userInfo.trade_active !== 1"
|
||||
class="text-red text-xs flex gap-1 items-center justify-center mb-2">
|
||||
<Icon icon="vuesax-linear:info-circle" size="16"/>
|
||||
حداقل مبلغ اولیه برای ثبت سفارش {{ usePriceWithoutType(limitedPrice.value as number ?? 0) }} ریال می باشد.
|
||||
</div>
|
||||
<div class="bg-gray-50 w-full flex justify-evenly rounded-lg py-2">
|
||||
<div class="text-center w-full">
|
||||
<div>قیمت خرید از گلد دات آی آر</div>
|
||||
<div class="text-[10px] text-gray-500">(هر گرم طلای 18 عیار)</div>
|
||||
<div class="flex w-full mt-3 justify-evenly">
|
||||
<!-- <div class="text-[10px] gap-1 flex bg-green-100 rounded-xl px-1 text-green-600 items-center">
|
||||
<Icon icon="vuesax-linear:received" size="10"/>
|
||||
<div>2%</div>
|
||||
</div>-->
|
||||
<div v-if="price" class="flex text-gray-500 text-xs items-center gap-1">
|
||||
<div class="text-primary font-bold text-base">{{ usePriceWithoutType(price.buy ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-divider class="bg-gray-200 !h-auto !my-2" type="vertical"/>
|
||||
<div class="text-center w-full">
|
||||
<div>قیمت فروش به گنج طل</div>
|
||||
<div class="text-[10px] text-gray-500">(هر گرم طلای 18 عیار)</div>
|
||||
<div class="flex w-full mt-3 justify-evenly">
|
||||
<!-- <div class="text-[10px] gap-1 flex bg-red-100 rounded-xl px-1 text-red-600 items-center">
|
||||
<Icon icon="vuesax-linear:send" size="10"/>
|
||||
<div>3%</div>
|
||||
</div>-->
|
||||
<div v-if="price" class="flex text-gray-500 text-xs items-center gap-1">
|
||||
<div class="text-primary font-bold text-base">{{ usePriceWithoutType(price.sell ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-8">
|
||||
<div class="text-center w-full flex-flex-col items-center" style="text-align: -webkit-center"
|
||||
@click="isSingle?router.push({name:'single_gold', query:{state: 'sell'}}): router.push({name:'gold', query:{state: 'sell'}})">
|
||||
<div class="rounded-full w-[42px] h-[42px] bg-orange-100 flex items-center justify-center">
|
||||
<Icon class="text-orange-600" icon="vuesax-linear:money-send"/>
|
||||
</div>
|
||||
<div class="text-primary">فروش</div>
|
||||
</div>
|
||||
<div class="text-center w-full flex-flex-col items-center" style="text-align: -webkit-center"
|
||||
@click="router.push({name:'wallet', query:{state: 'deposit'}})">
|
||||
<div class="rounded-full w-[42px] h-[42px] bg-green-100 flex items-center justify-center">
|
||||
<Icon class="text-green-600" icon="vuesax-linear:card-add"/>
|
||||
</div>
|
||||
<div class="text-primary">واریز نقدی</div>
|
||||
</div>
|
||||
<div class="text-center w-full flex-flex-col items-center" style="text-align: -webkit-center"
|
||||
@click="router.push({name:'gold', query:{state: 'buy'}})">
|
||||
<div class="rounded-full w-[42px] h-[42px] bg-blue-100 flex items-center justify-center">
|
||||
<Icon class="text-blue-600" icon="vuesax-linear:money-receive"/>
|
||||
</div>
|
||||
<div class="text-primary">خرید</div>
|
||||
</div>
|
||||
<div class="text-center w-full flex-flex-col items-center" style="text-align: -webkit-center"
|
||||
@click="router.push({name: 'fund'})">
|
||||
<div class="rounded-full w-[42px] h-[42px] bg-yellow-100 flex items-center justify-center">
|
||||
<Icon class="text-yellow-600" icon="vuesax-linear:archive-1"/>
|
||||
</div>
|
||||
<div class="text-primary">گنج</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-10 font-bold">نمودار نوسانات قیمت هر گرم طلای 18 عیار</div>
|
||||
<div class="w-full mt-2 relative bg-gray-100 rounded-lg h-[88px] flex flex-col justify-center">
|
||||
<img :src="img1" alt="" class="h-[88px] absolute">
|
||||
<div class="w-full items-center flex flex-col">
|
||||
<div class="text-gray-600">قیمت لحظه ای طلا</div>
|
||||
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
|
||||
<div class="font-bold text-2xl">{{ usePriceWithoutType(price.price_last ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-around mt-8">
|
||||
<div v-if="lastPrice" class="flex flex-col items-center">
|
||||
<div class="text-xs">بالاترین قیمت خرید امروز</div>
|
||||
<div class="text-green-600 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(lastPrice.buy ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="lastPrice" class="flex flex-col items-center">
|
||||
<div class="text-xs">بالاترین قیمت فروش امروز</div>
|
||||
<div class="text-red-600 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(lastPrice.sell ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<a-spin :spinning="chartLoading">
|
||||
<div id="chart" class="pb-20 mt-7 overflow-x-auto">
|
||||
<apexchart :options="chartOptions" :series="series" :style="`width: ${chartWidth}`" height="350"
|
||||
type="candlestick"></apexchart>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
<div v-else class="bg-white w-screen h-[40vh] px-5 m-[-1px] flex justify-center">
|
||||
<a-spin :spinning="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="y>130? 'bg-white shadow opacity-95': ''"
|
||||
class=" px-4 py-2 top-0 fixed w-screen background-color-transition ">
|
||||
<div class="flex justify-between my-2">
|
||||
<div class="flex items-center gap-2" @click.stop="router.push({name: 'user'})">
|
||||
<!-- <img :src="testimg" alt="" class="w-[24px] h-[24px]">-->
|
||||
<div :class="y>130? 'text-primary': 'text-white'" class="color-transition font-bold">
|
||||
{{ userStore.userInfo?.mobile }}
|
||||
</div>
|
||||
</div>
|
||||
<Icon :color="y>130? 'primary': 'white'" class="color-transition" icon="vuesax-linear:logout"
|
||||
@click="showLogoutConfirm = true"/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogVant v-model:show="showLogoutConfirm" :closeOnClickOverlay="false" :timeOut="-1">
|
||||
<!-- <template v-slot:img>
|
||||
<img :src="registerDelayImage" alt="" class="opacity-80">
|
||||
</template>-->
|
||||
|
||||
<template v-slot:title>
|
||||
<div class="p-5 text-sm">
|
||||
آیا از خروج خود اطمینان دارید؟
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:button>
|
||||
<div class="text-center text-red" @click="logout">
|
||||
خروج
|
||||
</div>
|
||||
<div class="text-center" @click="showLogoutConfirm = false">
|
||||
انصراف
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</DialogVant>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import img from '@/assets/img/home_ly1.svg'
|
||||
import img1 from '@/assets/img/home_ly2.svg'
|
||||
import Icon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import {usePriceWithoutType} from "../../../utils/usePrice";
|
||||
import {computed, onMounted, ref, watch} from "vue";
|
||||
import router from "@/router";
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
import {useWindowScroll} from '@vueuse/core'
|
||||
import {loading, removeToken} from "@/utils";
|
||||
import {useUserStore} from "@/store/userStore";
|
||||
import {useWalletStore} from "@/store/walletStore";
|
||||
import DialogVant from "@/components/DialogVant.vue";
|
||||
import type {Price} from "@/models/home";
|
||||
import {getChart, getLastPrice, getPrice} from "@/api/home";
|
||||
import {toJalali} from "@/utils/useDateTime";
|
||||
|
||||
|
||||
const userStore = useUserStore()
|
||||
const walletStore = useWalletStore()
|
||||
const chartLoading = ref<boolean>(false)
|
||||
const {x, y} = useWindowScroll()
|
||||
const series = ref<Chart[]>([{data: []}])
|
||||
const price = ref<Price>()
|
||||
const lastPrice = ref<Price>()
|
||||
const main = ref(null)
|
||||
|
||||
const upColor = '#ec0000';
|
||||
const upBorderColor = '#8A0000';
|
||||
const downColor = '#00da3c';
|
||||
const downBorderColor = '#008F28';
|
||||
|
||||
// const limitedPrice: Const = walletStore?.limitedPrice
|
||||
watch(main, (n) => {
|
||||
if (main.value !== null) {
|
||||
// console.log('saaaa')
|
||||
const echart = echarts.init(main.value, null, {
|
||||
renderer: 'canvas'
|
||||
})
|
||||
echart.setOption({
|
||||
xAxis: {
|
||||
data: dates.value.values,
|
||||
show: true,
|
||||
},
|
||||
yAxis: {
|
||||
show: false,
|
||||
scale: true,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'candlestick',
|
||||
data: series.value
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
const limitedPrice = computed(() => {
|
||||
if (walletStore.limitedPrice)
|
||||
return walletStore?.limitedPrice[0]
|
||||
})
|
||||
|
||||
const limitedBuyGold = computed(() => {
|
||||
if (walletStore.limitedBuyGold)
|
||||
return walletStore?.limitedBuyGold[0]
|
||||
})
|
||||
|
||||
const chartWidth = computed(() => {
|
||||
if (series.value.length < 30)
|
||||
return '100vw'
|
||||
else if (series.value.length < 60)
|
||||
return '200vw'
|
||||
else if (series.value.length < 90)
|
||||
return '300vw'
|
||||
else if (series.value.length < 120)
|
||||
return '400vw'
|
||||
else if (series.value.length < 160)
|
||||
return '500vw'
|
||||
else if (series.value.length < 190)
|
||||
return '600vw'
|
||||
else if (series.value.length < 210)
|
||||
return '700vw'
|
||||
else if (series.value.length < 240)
|
||||
return '800vw'
|
||||
else if (series.value.length < 270)
|
||||
return '900vw'
|
||||
else if (series.value.length < 300)
|
||||
return '1000vw'
|
||||
else if (series.value.length < 330)
|
||||
return '1100vw'
|
||||
else if (series.value.length < 360)
|
||||
return '1200vw'
|
||||
else if (series.value.length < 390)
|
||||
return '1300vw'
|
||||
})
|
||||
|
||||
async function initChart() {
|
||||
try {
|
||||
chartLoading.value = true
|
||||
const data = await getChart()
|
||||
data.forEach(item => {
|
||||
series.value[0].data.push({
|
||||
x: toJalali(item[0]),
|
||||
y: item[1]
|
||||
})
|
||||
// console.log(x)
|
||||
})
|
||||
console.log(series.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
chartLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
loading.value = true
|
||||
const data = await getPrice()
|
||||
const dataLast = await getLastPrice()
|
||||
price.value = data
|
||||
lastPrice.value = dataLast
|
||||
console.log(series.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initChart()
|
||||
initPrice()
|
||||
})
|
||||
|
||||
const chartOptions = ref(
|
||||
{
|
||||
chart: {
|
||||
type: 'candlestick',
|
||||
height: 600,
|
||||
toolbar: {
|
||||
autoSelected: 'pan',
|
||||
show: false
|
||||
},
|
||||
},
|
||||
title: {
|
||||
// text: 'CandleStick Chart',
|
||||
align: 'left'
|
||||
},
|
||||
xaxis: {
|
||||
type: 'datetime',
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
show: false,
|
||||
showAlways: false,
|
||||
showForNullSeries: false,
|
||||
tooltip: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
const showLogoutConfirm = ref<boolean>()
|
||||
|
||||
async function logout() {
|
||||
// baseConfirm('آیا از حساب کاربری خارج می شوید؟',async () => {
|
||||
removeToken()
|
||||
await router.push({name: 'login'})
|
||||
// console.log('salam')
|
||||
// })
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,891 @@
|
||||
<template>
|
||||
<div class=" mt-20">
|
||||
|
||||
<!-- <div class="flex gap-7 overflow-x-scroll px-5">
|
||||
<ProductInventory v-for="item in productInventorys" :ProductItem="item" class="shadow-lg my-5" :key="item.id"></ProductInventory>
|
||||
</div>-->
|
||||
<div>
|
||||
<div
|
||||
v-if="userStore.userInfo && !loading"
|
||||
class="bg-white w-screen md:w-auto h-fit px-5 m-[-1px]"
|
||||
>
|
||||
<div
|
||||
v-if="limitedPrice !== undefined && userStore?.userInfo.trade_active !== 1"
|
||||
class="text-red text-xs flex gap-1 items-center justify-center mb-2"
|
||||
>
|
||||
<Icon icon="vuesax-linear:info-circle" size="16" />
|
||||
حداقل مبلغ اولیه برای ثبت سفارش
|
||||
{{ usePriceWithoutType(limitedPrice.value as number ?? 0) }} ریال می باشد.
|
||||
</div>
|
||||
|
||||
<!-- <div class="bg-white">
|
||||
<MySlider v-if="cardItems.length > 0" :items="cardItems" class=" pb-[20vh] "
|
||||
style="touch-action: none" />
|
||||
</div>-->
|
||||
<!-- <div class="bg-gradient-to-l mt-3 p-1 shadow-lg from-primary rounded-lg p-px to-transparent ">-->
|
||||
<div class="mt-3 p-1 shadow-lg from-primary rounded-lg p-px to-transparent">
|
||||
<div class=" p-2 py-6 rounded-lg bg-tertiary">
|
||||
<div class="flex justify-between ">
|
||||
<!-- <div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_up"
|
||||
style="text-align: -webkit-center"
|
||||
@click="router.push({ name: 'buyProduct', query: { state: 'sell' } })"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[42px] h-[42px] bg-primary flex items-center justify-center"
|
||||
style="border: solid 1px #0A1B37"
|
||||
|
||||
>
|
||||
<Icon class="text-tertiary" icon="vuesax-linear:money-send" />
|
||||
</div>
|
||||
<div class="text-primary">فروش</div>
|
||||
</div>-->
|
||||
<div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_up"
|
||||
style="text-align: -webkit-center"
|
||||
@click="router.push({ name: 'buyProduct' })"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[50px] h-[50px] bg-primary flex items-center justify-center"
|
||||
style="border: solid 1px #0A1B37"
|
||||
|
||||
>
|
||||
<Icon class="text-tertiary" icon="vuesax-linear:money-receive" />
|
||||
</div>
|
||||
<div class="text-primary">خرید و فروش</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_down"
|
||||
style="text-align: -webkit-center"
|
||||
@click="router.push({ name: 'wallet', query: { state: 'deposit' } })"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[50px] h-[50px] bg-primary flex items-center justify-center"
|
||||
style="border: solid 1px #0A1B37"
|
||||
|
||||
>
|
||||
<Icon class="text-tertiary" icon="vuesax-linear:card-add" />
|
||||
</div>
|
||||
<div class="text-primary">واریز نقدی</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_up"
|
||||
style="text-align: -webkit-center"
|
||||
@click="openWholeBalanceVisible()"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[50px] h-[50px] bg-primary flex items-center justify-center "
|
||||
style="border: solid 1px #0A1B37"
|
||||
>
|
||||
<Icon class="text-tertiary" icon="vuesax-linear:receipt-item" />
|
||||
</div>
|
||||
<div class="text-primary">موجودی</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_down"
|
||||
style="text-align: -webkit-center"
|
||||
@click="router.push({ name: 'fund' })"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[50px] h-[50px] bg-primary flex items-center justify-center"
|
||||
style=" border: solid 1px #0A1B37"
|
||||
|
||||
>
|
||||
<Icon class="text-tertiary font-bold" icon="vuesax-linear:cup" />
|
||||
</div>
|
||||
<div class="text-primary">دارایی ها</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <ADivider></ADivider>-->
|
||||
<div>
|
||||
<!-- <div @click="router.push({ name: 'fund' })">-->
|
||||
<div class="bg-primary rounded-lg p-2 py-6 mt-2">
|
||||
<div class="flex justify-center text-tertiary w-full z-20">
|
||||
محصولات:
|
||||
<div class="text-l mr-2 font-bold">{{ userStore?.userInfo?.wallet?.count_product ?? 0}}عدد</div>
|
||||
</div>
|
||||
<div class="flex mt-2 justify-center text-tertiary w-full z-20">
|
||||
دارایی طلایی:
|
||||
<div class="text-l mr-2 font-bold">{{ (userStore?.userInfo?.wallet?.count_gold ?? 0).toFixed(3)}}گرم</div>
|
||||
<BasicIcon @click="openGoldModal" icon="vuesax-linear:info-circle" size="18" color="orange" />
|
||||
</div>
|
||||
<div class="flex mt-2 justify-center text-tertiary w-full z-20">
|
||||
دارایی ریالی:
|
||||
<div class="text-l mr-2 font-bold">{{ usePriceWithoutType(userStore?.userInfo?.wallet?.count_cash ?? 0) }}ریال</div>
|
||||
<BasicIcon @click="openRialModal" icon="vuesax-linear:info-circle" size="18" color="orange" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex justify-center mt-2 w-full z-20">
|
||||
دارایی ریالی:
|
||||
<div class="text-l mr-4 font-bold">{{ usePriceWithoutType(walletStore.walletInfo?.count_cash ?? 0) }}ریال</div>
|
||||
</div>-->
|
||||
<!-- <div class="flex justify-center mt-2 w-full z-20">
|
||||
<BasicInfoItem
|
||||
title="دارایی ریالی"
|
||||
is-line
|
||||
:info="`در این قسمت مجموع کیف پول ریالی (${usePrice(walletStore?.walletInfo?.count_cash_wallet ?? 0) }) + معادل ریالی محصولات (${ usePrice(walletStore?.walletInfo?.count_cash_wallets ?? 0)} ) را مشاهده میفرمایید.`"
|
||||
infoHead="مجموع کل دارایی ریالی"
|
||||
:value="usePriceWithoutType(walletStore.walletInfo?.count_cash ?? 0) + ' ریال'"
|
||||
/>
|
||||
</div>-->
|
||||
</div>
|
||||
<!-- <div class="flex justify-between">
|
||||
<div class="text-center font-bold">دارایی شما</div>
|
||||
<div class="flex items-center gap-2 mr-4">
|
||||
<span class="text-base font-bold">{{ usePriceWithoutType(walletStore.walletInfo?.cash ?? 0) }}</span>
|
||||
<span class="text-xs text-base">ریال</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 ml-4">
|
||||
<span class="text-base font-bold">{{ walletStore.walletInfo?.gold_sum.toFixed(3) }}</span>
|
||||
<span class="text-xs text-base">گرم</span>
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- <div class="flex justify-between items-center ">
|
||||
<div class="text-sm">
|
||||
موجودی کیف پول شما:
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-base font-bold">{{ usePrice(walletStore.walletInfo?.cash ?? 0) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-center ">
|
||||
<div class="text-sm">
|
||||
موجودی کیف طلای شما:
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-base font-bold">{{ walletStore.walletInfo?.gold }}</span>
|
||||
<span class="text-xs text-gray-500">گرم</span>
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- <div class="flex justify-between items-center ">
|
||||
<div class="text-sm">
|
||||
ارزش کل طلا های شما:
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-base font-bold">{{ walletStore.walletInfo?.gold_sum }}</span>
|
||||
<span class="text-xs text-gray-500">گرم</span>
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- <div class="flex justify-between items-center ">
|
||||
<div class="text-sm">
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div v-if="walletStore.walletInfo?.gold_sum*goldVal">
|
||||
<Vue3Odometer
|
||||
:value="walletStore.walletInfo?.gold_sum*goldVal"
|
||||
class="o-text !text-base font-bold"
|
||||
style="font-family: iran-sans; direction: ltr"
|
||||
v-if="key % 2 === 0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<span class="text-xs text-gray-500">ریال</span>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
<div
|
||||
class="w-full relative mt-5 border-gray-200 border-1 rounded-lg h-[88px] flex flex-col justify-center home_appear_fade_in"
|
||||
>
|
||||
|
||||
<div class="w-full items-center flex flex-col">
|
||||
<div class="text-gray-600">قیمت خرید از گلد دات آی آر</div>
|
||||
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
|
||||
<!-- <div id="odometer" class="font-bold text-2xl odometer animated fadeIn">
|
||||
<!– {{ usePriceWithoutType(useCounterAnim(price.price_last) ?? 0) }}–>
|
||||
</div>-->
|
||||
<!-- <div id="odometer" class="odometer animated fadeIn"></div>-->
|
||||
<div v-if="percentPriceChanged()!=0"
|
||||
class="bg-green-100 text-green-600 flex flex-row-reverse rounded-lg justify-between items-center gap-2 px-3"
|
||||
:class="percentPriceChanged()>=0?'bg-green-100 text-green-600':'bg-red-100 text-red-600'">
|
||||
<div dir="ltr">{{ useTowDecimal(percentPriceChanged()) }}%</div>
|
||||
<div>
|
||||
<icon v-if="percentPriceChanged()<0" size="15px" icon="vuesax-linear:received" color="red-600"></icon>
|
||||
<icon v-else size="15px" icon="vuesax-linear:send" color="green-600"></icon>
|
||||
</div>
|
||||
</div>
|
||||
<Vue3Odometer
|
||||
:value="goldVal"
|
||||
class="o-text !text-2xl font-bold"
|
||||
style="font-family: iran-sans; direction: ltr"
|
||||
v-if="key % 2 === 0"
|
||||
/>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex mt-5 gap-1 bg-primary text-[#CEA34C] font-bold justify-center rounded-lg py-5"
|
||||
@click="router.push({ name: 'buyProduct', query: { cat: 'coin'} })">
|
||||
<div>خرید و فروش</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- <div class="mt-10 font-bold home_appear_fade_in" @click="update">
|
||||
نوسانات قیمت هر گرم طلای 18 عیار
|
||||
</div>-->
|
||||
|
||||
<!-- <a-spin :spinning="chartLoading" class="relative">
|
||||
<div ref="target" class="absolute"></div>
|
||||
<div v-if="!chartLoading" id="chart" class="pb-20 mt-7 overflow-x-auto">
|
||||
<!– <apexchart v-if="targetIsVisible" :options="chartOptions" :series="test_series"
|
||||
:style="`width: ${chartWidth}`"
|
||||
height="350"
|
||||
type="candlestick"></apexchart>–>
|
||||
</div>
|
||||
</a-spin>-->
|
||||
<!-- <a-spin :spinning="chartLoading" >-->
|
||||
<!-- <div ref="target" class="absolute"></div>-->
|
||||
<!-- <div id="chart" class="mt-7">-->
|
||||
<div class="bg-gray-50 w-full flex justify-evenly rounded-lg py-4 mt-4 h-[15rem]">
|
||||
<div class="w-full text-center pt-2">
|
||||
<a-radio-group v-model:value="value" button-style="solid">
|
||||
<a-radio-button value="a" @click="updateData('DAILY')">24 ساعت اخیر</a-radio-button>
|
||||
<a-radio-button value="b" @click="updateData('WEEKLY')">هفته گذشته</a-radio-button>
|
||||
<a-radio-button value="c" @click="updateData('MONTHLY')">ماه گذشته</a-radio-button>
|
||||
</a-radio-group>
|
||||
<div id="chart-timeline">
|
||||
<apexchart
|
||||
type="area"
|
||||
height="200"
|
||||
ref="chart"
|
||||
:options="priceChartOptions"
|
||||
:series="priceChartSeries"
|
||||
></apexchart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" w-full flex justify-evenly rounded-lg py-2 home_appear_fade_in mt-6 pb-25">
|
||||
<div class="text-center w-full">
|
||||
<div>بالاترین قیمت امروز</div>
|
||||
<div v-if="lastPrice" class="flex flex-col items-center mt-3">
|
||||
<div class="text-green-600 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(price?.buy ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-divider class="bg-gray-200 !h-auto !my-2" type="vertical" />
|
||||
<div class="text-center w-full">
|
||||
<div>پایین ترین قیمت امروز</div>
|
||||
<div class="flex w-full mt-3 justify-evenly">
|
||||
<div v-if="lastPrice" class="flex flex-col items-center">
|
||||
<div class="text-red-600 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(price?.sell ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else class="bg-white w-screen md:w-auto h-[80vh] px-5 m-[-1px] flex justify-center ">
|
||||
<HomeSkeleton class="w-full" />
|
||||
</div>
|
||||
<!-- <div class="relative pt-15 overflow-hidden ">-->
|
||||
<!-- <div class="absolute left--12 top-0">-->
|
||||
<!-- <img :src="image">-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="bg-primary pb-30"-->
|
||||
<!-- style="background: linear-gradient(to bottom, #fff,#fff, #0A1B37, #0A1B37);"-->
|
||||
<!-- >-->
|
||||
<!-- <div class=" text-tertiary text-2xl pt-6 pr-5 pl-50" style="font-size: 26px;font-weight: 600; color: #0A1B37" >ارسال کالا بعد از ثبت سفارش</div>-->
|
||||
<!-- <div class="pr-5 pl-8 pt-10 text-tertiary ">میتوانید با خرید محصولات بعد از ثبت سفارش درخواست ارسال را-->
|
||||
<!-- ثبت کرده و زیر 24 ساعت خرید خود را دریافت کنید-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<div
|
||||
:class="y > 50 ? 'bg-white shadow opacity-95' : ''"
|
||||
class="px-4 py-2 top-0 z-5 wrap-fix background-color-transition"
|
||||
>
|
||||
<div class="flex justify-between my-2">
|
||||
<div class="flex items-center gap-2" @click.stop="router.push({ name: 'user' })">
|
||||
<!-- <img :src="testimg" alt="" class="w-[24px] h-[24px]">-->
|
||||
<div
|
||||
class="z-100000 rounded-full border-1"
|
||||
:class="y > 50 ? 'text-primary border-primary' : 'text-primary border-primary'"
|
||||
>
|
||||
<Icon icon="vuesax-linear:user" size="20" />
|
||||
</div>
|
||||
<div :class="y > 50 ? 'text-primary' : 'text-primary'" class="color-transition font-bold">
|
||||
{{ userStore.userInfo?.name }}
|
||||
</div>
|
||||
</div>
|
||||
<Icon
|
||||
:color="y > 50 ? '#0A1B37' : '#0A1B37'"
|
||||
class="color-transition"
|
||||
icon="vuesax-linear:logout"
|
||||
@click="showLogoutConfirm = true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogVant v-model:show="showLogoutConfirm" :closeOnClickOverlay="false" :timeOut="-1">
|
||||
<!-- <template v-slot:img>
|
||||
<img :src="registerDelayImage" alt="" class="opacity-80">
|
||||
</template>-->
|
||||
|
||||
<template v-slot:title>
|
||||
<div class="flex flex-col items-center">
|
||||
<DotLottieVue
|
||||
class="w-11rem h-11rem"
|
||||
autoplay
|
||||
src="https://lottie.host/129cf3a1-df84-4758-a856-58c133ae6013/R5RqclXA8G.json"
|
||||
/>
|
||||
<div class="p-5 text-sm">آیا از خروج خود اطمینان دارید؟</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:button>
|
||||
<div class="text-center text-red flex items-center justify-center" @click="logout">
|
||||
<a-spin :spinning="logoutLoading" size="small"> خروج</a-spin>
|
||||
</div>
|
||||
<div class="text-center" @click="showLogoutConfirm = false">انصراف</div>
|
||||
</template>
|
||||
</DialogVant>
|
||||
</div>
|
||||
<BasicActionSheet v-model:show="wholeBalanceVisible">
|
||||
<div class="pb-20">
|
||||
<div>
|
||||
<div class="w-full text-center font-bold">موجودی ها</div>
|
||||
<div class="h-30vh overflow-y-auto">
|
||||
<div class="mt-5">
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="مجموعه کل دارایی طلایی"
|
||||
is-line
|
||||
:info="`در این قسمت مجموع کل وزن طلای آبشده (${(walletStore.walletInfo?.gold ?? 0)?.toFixed(3)}) + ارزش دارایی ها (${(walletStore.walletInfo?.treasure_sum ?? 0)?.toFixed(3)} ) را مشاهده میفرمایید.`"
|
||||
infoHead="مجموع کل دارایی طلایی"
|
||||
:value="parseFloat((walletStore.walletInfo?.gold_sum ?? 0).toFixed(2)) + ' گرم'"
|
||||
/>
|
||||
<!-- <a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="میزان طلای آبشده"
|
||||
is-line
|
||||
:value="parseFloat((walletStore.walletInfo?.gold ?? 0)?.toFixed(3)) + ' گرم'"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="ارزش گنج ها"
|
||||
is-line
|
||||
:value="parseFloat((walletStore.walletInfo?.treasure_sum ?? 0)?.toFixed(3)) + ' گرم'"
|
||||
/>-->
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="دارایی کیف پول ریالی"
|
||||
is-line
|
||||
:value="usePrice(walletStore.walletInfo?.cash ?? 0)"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="دارایی کیف پول طلایی"
|
||||
is-line
|
||||
:value="(walletStore.walletInfo?.count_gold_wallet ?? 0) + ' گرم'"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<!-- <BasicInfoItem class="flex justify-between" title="دارایی کیف پول(به گرم)" is-line
|
||||
:value="((walletStore.walletInfo?.cash?? 0) / (goldVal?? 0)).toFixed(2)+ ' گرم'" />
|
||||
<a-divider class="!my-1" />-->
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="ارزش کل دارایی شما"
|
||||
is-line
|
||||
:value="
|
||||
usePrice(
|
||||
(
|
||||
(walletStore.walletInfo?.gold_sum ?? 0) * (goldVal ?? 0) +
|
||||
(walletStore.walletInfo?.cash ?? 0)
|
||||
).toFixed(0)
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import img from '@/assets/img/home_ly1.svg'
|
||||
import img1 from '@/assets/img/home_ly2.svg'
|
||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import { usePrice, usePriceWithoutType, useTowDecimal } from '../../../utils/usePrice'
|
||||
import {computed, createVNode, onMounted, onUnmounted, ref, watch, watchEffect} from 'vue'
|
||||
import router from '@/router'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
import { useIntersectionObserver, useWindowScroll } from '@vueuse/core'
|
||||
import { loading, removeToken } from '@/utils'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { useWalletStore } from '@/store/walletStore'
|
||||
import DialogVant from '@/components/DialogVant.vue'
|
||||
import type { Price } from '@/models/home'
|
||||
import { getAllPrices, getChart, getLastPrice, getPrice } from '@/api/home'
|
||||
// import odometer from 'odometer/odometer'
|
||||
import Vue3Odometer from 'vue3-odometer'
|
||||
import 'odometer/themes/odometer-theme-default.css'
|
||||
import HomeSkeleton from '@/views/base/home/components/HomeSkeleton.vue'
|
||||
import { toJalaliNotime } from '@/utils/useDateTime'
|
||||
import {
|
||||
getLastPrices,
|
||||
getUpPrice,
|
||||
lastPrice,
|
||||
percentPriceChanged,
|
||||
price,
|
||||
setIntervalGetAllPrice,
|
||||
stopPriceInterval
|
||||
} from '@/utils/price'
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import BasicInfoItem from '@/components/BasicPacks/BasicInfoItem.vue'
|
||||
import MySlider from '@/views/base/wallet/components/mySlider/MySlider.vue'
|
||||
import type { Card, PWallet, Wallet } from '@/models/wallet'
|
||||
import { getActivatedCards } from '@/api/wallet'
|
||||
import banner1 from '@/assets/img/banner/banner1.png'
|
||||
import banner2 from '@/assets/img/banner/banner2.png'
|
||||
import image from '@/assets/img/image.svg'
|
||||
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import ProductInventory from '@/views/base/home/components/ProductInventory.vue'
|
||||
import type { PInventory, Product } from '@/models/products'
|
||||
import { getProductInventory } from '@/api/products'
|
||||
import type { Fund } from '@/models/fund'
|
||||
import type { TableOutput } from '@/models/table'
|
||||
import { useFundUserStore } from '@/store/fundStore'
|
||||
import {Modal} from "ant-design-vue";
|
||||
import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
|
||||
import {message} from "ant-design-vue/es";
|
||||
|
||||
const userStore = useUserStore()
|
||||
const walletStore = useWalletStore()
|
||||
const chartLoading = ref<boolean>(false)
|
||||
const wholeBalanceVisible = ref<boolean>(false)
|
||||
const { x, y } = useWindowScroll()
|
||||
const series = ref<Chart[]>([{ data: [] }])
|
||||
const key = ref<number>(0)
|
||||
const cardItems = [banner1, banner2]
|
||||
const main = ref(null)
|
||||
const logoutLoading = ref(false)
|
||||
const productInventorys = ref<PInventory[] | undefined>()
|
||||
const value = ref<string>('a')
|
||||
const items = ref<Fund[]>([])
|
||||
const tableOutput = ref<TableOutput<Fund> | null>(null)
|
||||
const inventory = ref<number>(0)
|
||||
const sumGold = ref<number>(0)
|
||||
const fundStore = useFundUserStore()
|
||||
|
||||
async function initTable() {
|
||||
try {
|
||||
loading.value = true
|
||||
tableOutput.value = fundStore.myFunds ?? await fundStore.getMyFund() ?? null
|
||||
items.value.push(...tableOutput.value?.rows ?? [])
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
stopPriceInterval()
|
||||
})
|
||||
|
||||
/*
|
||||
onMounted(() => {
|
||||
animateNum(2)
|
||||
})
|
||||
*/
|
||||
|
||||
const goldVal = ref<number | undefined>()
|
||||
|
||||
function openWholeBalanceVisible() {
|
||||
items.value.forEach(x => {
|
||||
if (x.title !== 'آبشده نقدی')
|
||||
inventory.value += x?.wallet?.gold ?? 0
|
||||
})
|
||||
wholeBalanceVisible.value = true
|
||||
}
|
||||
|
||||
function sumOfGold() {
|
||||
items.value.forEach(x => {
|
||||
if (x.title !== 'آبشده نقدی')
|
||||
return sumGold.value += x?.wallet?.gold ?? 0
|
||||
})
|
||||
}
|
||||
|
||||
function update() {
|
||||
setInterval(() => {
|
||||
goldVal.value = lastPrice?.value.price_last
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const target = ref(null)
|
||||
const targetIsVisible = ref(false)
|
||||
|
||||
const isHidden = ref<boolean>(false)
|
||||
|
||||
const { stop } = useIntersectionObserver(target, ([{ isIntersecting }], observerElement) => {
|
||||
targetIsVisible.value = isIntersecting
|
||||
console.log('saaaaa', targetIsVisible.value)
|
||||
})
|
||||
|
||||
watch(main, (n) => {
|
||||
if (main.value !== null) {
|
||||
// console.log('saaaa')
|
||||
const echart = echarts.init(main.value, null, {
|
||||
renderer: 'candlestick'
|
||||
})
|
||||
echart.setOption({
|
||||
xAxis: {
|
||||
data: dates.value.values,
|
||||
show: true
|
||||
},
|
||||
yAxis: {
|
||||
show: false,
|
||||
scale: true
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'candlestick',
|
||||
data: series.value
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
//whole prices
|
||||
const priceChartSeries = ref<{ data: [number, number][] }[]>([
|
||||
{
|
||||
name: 'قیمت',
|
||||
data: []
|
||||
}
|
||||
])
|
||||
const selection = ref('DAILY')
|
||||
const chartRef = ref<ApexCharts | null>(null)
|
||||
const priceChartOptions = ref({
|
||||
chart: {
|
||||
id: 'نوسانات قیمت',
|
||||
type: 'candlestick',
|
||||
height: 200,
|
||||
toolbar: {
|
||||
show: false // Disable the toolbar to remove download and other options
|
||||
},
|
||||
zoom: {
|
||||
autoScaleYaxis: true
|
||||
},
|
||||
events: {
|
||||
mounted(chart) {
|
||||
chartRef.value = chart
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
padding: {
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0
|
||||
},
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
width: 2
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
// formatter: (val) => toPersianNumber(val),
|
||||
style: {
|
||||
fontFamily: '\'IranSans\', sans-serif'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
tickAmount: 8,
|
||||
show: false,
|
||||
title: {
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
fontFamily: '\'IranSans\', sans-serif',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labels: {
|
||||
formatter: (val) => toPersianNumber(usePrice(val)),
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
fontFamily: '\'IranSans\', sans-serif'
|
||||
}
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
show: false,
|
||||
type: 'datetime',
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
labels: {
|
||||
show: false,
|
||||
rotate: -45,
|
||||
style: {
|
||||
fontFamily: '\'IranSans\', sans-serif'
|
||||
}
|
||||
// formatter: (val) => toPersianNumber(toJalaliNotime(new Date(val).toString()))
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
x: {
|
||||
// formatter: (val) => toPersianNumber(toJalaliNotime(new Date(val).toString()))
|
||||
formatter: (value) => {
|
||||
const date = new Date(value)
|
||||
return `${date.toLocaleDateString('fa-IR')} - ${date.toLocaleTimeString('fa-IR', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})}`
|
||||
}
|
||||
},
|
||||
formatter: (val) => toPersianNumber(usePrice(val)),
|
||||
style: {
|
||||
fontFamily: '\'IranSans\', sans-serif'
|
||||
// fontWeight: 'bold'
|
||||
},
|
||||
markers: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
colors: ['#0A1B37'],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shadeIntensity: 1,
|
||||
opacityFrom: 0.7,
|
||||
opacityTo: 0.9,
|
||||
stops: [0, 100]
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
const toPersianNumber = (num) => {
|
||||
return num.toString().replace(/\d/g, (d) => '۰۱۲۳۴۵۶۷۸۹'[d])
|
||||
}
|
||||
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 - 1])
|
||||
// console.log(priceChartSeries.value[0].data)
|
||||
chartRef.value?.updateOptions({
|
||||
series: priceChartSeries.value
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('خطا در دریافت دادهها', error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateData = (timeline) => {
|
||||
selection.value = timeline
|
||||
fetchPrices()
|
||||
}
|
||||
|
||||
const limitedPrice = computed(() => {
|
||||
if (walletStore.limitedPrice) return walletStore?.limitedPrice[0]
|
||||
})
|
||||
|
||||
const test_series = [
|
||||
{
|
||||
name: 'candle',
|
||||
data: []
|
||||
}
|
||||
]
|
||||
|
||||
async function initChart() {
|
||||
try {
|
||||
// chartLoading.value = true
|
||||
const data = await getChart()
|
||||
/* data.forEach(item => {
|
||||
test_series[0].data.push({
|
||||
x: toJalali(item[0]),
|
||||
y: item[1]
|
||||
})
|
||||
// console.log(x)
|
||||
})*/
|
||||
data.forEach((item) => {
|
||||
test_series[0].data.push({
|
||||
x: item[0],
|
||||
y: item[1]
|
||||
})
|
||||
// console.log(x)
|
||||
})
|
||||
// console.log(test_series)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
// chartLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
// loading.value = true
|
||||
const val = price?.value?.price_last
|
||||
await getLastPrices()
|
||||
await getUpPrice()
|
||||
await setIntervalGetAllPrice()
|
||||
// console.log('runhome')
|
||||
if (val !== price?.value?.price_last) {
|
||||
update()
|
||||
/* key.value++
|
||||
key.value++*/
|
||||
}
|
||||
/* price.value = data
|
||||
lastPrice.value = dataLast*/
|
||||
goldVal.value = 0
|
||||
// console.log(price?.value.price_last)
|
||||
if (userStore.isFirst) {
|
||||
const timer = setInterval(function() {
|
||||
update()
|
||||
// if (current == end) {
|
||||
userStore.isFirst = false
|
||||
clearInterval(timer)
|
||||
// }
|
||||
}, 100)
|
||||
} else {
|
||||
goldVal.value = price.value?.price_last
|
||||
}
|
||||
// console.log(series.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
// loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initProductInventory() {
|
||||
try {
|
||||
// loading.value = true
|
||||
|
||||
// let { rows } = await getProductInventory()
|
||||
// fundStore.myFunds
|
||||
// productInventorys.value = fundStore.myFunds?.rows
|
||||
productInventorys.value = items.value.sort((a, b) => {
|
||||
if (a.wallet?.gold ?? 0 < b.wallet?.gold ?? 0)
|
||||
return -1
|
||||
if (a.wallet?.gold ?? 0 > b.wallet?.gold ?? 0)
|
||||
return 1
|
||||
return 0
|
||||
})
|
||||
// console.log(productInventorys.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
// loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await initTable()
|
||||
await initProductInventory()
|
||||
// await initChart()
|
||||
await initPrice()
|
||||
await fetchPrices()
|
||||
update()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
stopPriceInterval()
|
||||
// console.log('okhome')
|
||||
})
|
||||
|
||||
|
||||
const showLogoutConfirm = ref<boolean>()
|
||||
|
||||
async function logout() {
|
||||
logoutLoading.value = true
|
||||
// baseConfirm('آیا از حساب کاربری خارج می شوید؟',async () => {
|
||||
userStore.userInfo = undefined
|
||||
walletStore.walletInfo = undefined
|
||||
/* userStore.$reset()
|
||||
walletStore.$reset()*/
|
||||
removeToken()
|
||||
await router.push({ name: 'login' })
|
||||
logoutLoading.value = true
|
||||
window.location.reload()
|
||||
// console.log('salam')
|
||||
// })
|
||||
}
|
||||
|
||||
async function openGoldModal() {
|
||||
Modal.confirm({
|
||||
title: `در این قسمت مجموع کل وزن طلای آبشده (${(walletStore.walletInfo?.gold ?? 0)?.toFixed(3)}) + ارزش دارایی ها (${(walletStore.walletInfo?.count_gold_wallets ?? 0)?.toFixed(3)} ) را مشاهده میفرمایید.`,
|
||||
okText: 'متوجه شدم',
|
||||
centered: true,
|
||||
cancelButtonProps: { style: { display: 'none' } },
|
||||
})
|
||||
}
|
||||
|
||||
async function openRialModal() {
|
||||
Modal.confirm({
|
||||
title: `در این قسمت مجموع کیف پول ریالی (${usePrice(walletStore?.walletInfo?.count_cash_wallet ?? 0) }) + معادل ریالی محصولات (${ usePrice(walletStore?.walletInfo?.count_cash_wallets ?? 0)} ) را مشاهده میفرمایید.`,
|
||||
okText: 'متوجه شدم',
|
||||
centered: true,
|
||||
cancelButtonProps: { style: { display: 'none' } },
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
.odometer {
|
||||
font-size: 60px;
|
||||
//margin: 200px 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
animation-duration: 3s;
|
||||
}
|
||||
|
||||
label:focus-within {
|
||||
box-shadow: none !important
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
apexchart {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
@@ -0,0 +1,389 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<!-- <div class="bg-primary h-30 mt-[-3rem] z-100000000000"></div>-->
|
||||
<div class="fixed h-[60vh] bg-[#0A1B37] w-screen">
|
||||
<div class="flex w-full justify-around mt-18">
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">موجودی کیف طلا</div>
|
||||
<div class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs">
|
||||
<div class="text-white text-lg">{{ walletStore?.walletInfo?.gold ?? 0 }}</div>
|
||||
گرم
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">سقف اعتبار خرید طلا</div>
|
||||
<div class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs">
|
||||
<div class="text-white text-lg">{{ userStore?.userInfo?.gram ?? 0 }}</div>
|
||||
گرم
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">موجودی کیف پول</div>
|
||||
<div class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs">
|
||||
<div class="text-white text-lg">
|
||||
{{ walletStore?.walletInfo?.cash === undefined ? 0 : usePriceWithoutType(walletStore.walletInfo?.cash) }}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-[9rem] relative">
|
||||
<img :src="img" alt="" class="w-screen h-[8rem]">
|
||||
<!-- <div class="w-screen bg-white w-screen h-[calc(100vh-16rem-70px)] px-5">-->
|
||||
<div v-if="userStore.userInfo && !loading" class="bg-white w-screen h-fit px-5 m-[-1px]">
|
||||
<!-- <a-alert :message="``" type="warning" show-icon/>-->
|
||||
<!-- {{limitedPrice === undefined}}-->
|
||||
<div v-if="limitedPrice !== undefined && userStore?.userInfo.trade_active !== 1"
|
||||
class="text-red text-xs flex gap-1 items-center justify-center mb-2">
|
||||
<Icon icon="vuesax-linear:info-circle" size="16"/>
|
||||
حداقل مبلغ اولیه برای ثبت سفارش {{ usePriceWithoutType(limitedPrice.value as number ?? 0) }} ریال می باشد.
|
||||
</div>
|
||||
<div class="bg-gray-50 w-full flex justify-evenly rounded-lg py-2">
|
||||
<div class="text-center w-full">
|
||||
<div>قیمت خرید از گلد دات آی آر</div>
|
||||
<div class="text-[10px] text-gray-500">(هر گرم طلای 18 عیار)</div>
|
||||
<div class="flex w-full mt-3 justify-evenly">
|
||||
<!-- <div class="text-[10px] gap-1 flex bg-green-100 rounded-xl px-1 text-green-600 items-center">
|
||||
<Icon icon="vuesax-linear:received" size="10"/>
|
||||
<div>2%</div>
|
||||
</div>-->
|
||||
<div v-if="price" class="flex text-gray-500 text-xs items-center gap-1">
|
||||
<div class="text-primary font-bold text-base">{{ usePriceWithoutType(price.buy ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-divider class="bg-gray-200 !h-auto !my-2" type="vertical"/>
|
||||
<div class="text-center w-full">
|
||||
<div>قیمت فروش به گلد دات آی آر</div>
|
||||
<div class="text-[10px] text-gray-500">(هر گرم طلای 18 عیار)</div>
|
||||
<div class="flex w-full mt-3 justify-evenly">
|
||||
<!-- <div class="text-[10px] gap-1 flex bg-red-100 rounded-xl px-1 text-red-600 items-center">
|
||||
<Icon icon="vuesax-linear:send" size="10"/>
|
||||
<div>3%</div>
|
||||
</div>-->
|
||||
<div v-if="price" class="flex text-gray-500 text-xs items-center gap-1">
|
||||
<div class="text-primary font-bold text-base">{{ usePriceWithoutType(price.sell ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-8">
|
||||
<div class="text-center w-full flex-flex-col items-center" style="text-align: -webkit-center"
|
||||
@click="router.push({name:'gold', query:{state: 'sell'}})">
|
||||
<div class="rounded-full w-[42px] h-[42px] bg-orange-100 flex items-center justify-center">
|
||||
<Icon class="text-orange-600" icon="vuesax-linear:money-send"/>
|
||||
</div>
|
||||
<div class="text-primary">فروش</div>
|
||||
</div>
|
||||
<div class="text-center w-full flex-flex-col items-center" style="text-align: -webkit-center"
|
||||
@click="router.push({name:'wallet', query:{state: 'deposit'}})">
|
||||
<div class="rounded-full w-[42px] h-[42px] bg-green-100 flex items-center justify-center">
|
||||
<Icon class="text-green-600" icon="vuesax-linear:card-add"/>
|
||||
</div>
|
||||
<div class="text-primary">واریز نقدی</div>
|
||||
</div>
|
||||
<div class="text-center w-full flex-flex-col items-center" style="text-align: -webkit-center"
|
||||
@click="router.push({name:'gold', query:{state: 'buy'}})">
|
||||
<div class="rounded-full w-[42px] h-[42px] bg-blue-100 flex items-center justify-center">
|
||||
<Icon class="text-blue-600" icon="vuesax-linear:money-receive"/>
|
||||
</div>
|
||||
<div class="text-primary">خرید</div>
|
||||
</div>
|
||||
<div class="text-center w-full flex-flex-col items-center" style="text-align: -webkit-center"
|
||||
@click="router.push({name: 'fund'})">
|
||||
<div class="rounded-full w-[42px] h-[42px] bg-yellow-100 flex items-center justify-center">
|
||||
<Icon class="text-yellow-600" icon="vuesax-linear:archive-1"/>
|
||||
</div>
|
||||
<div class="text-primary">صندوق</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-10 font-bold">نمودار نوسانات قیمت هر گرم طلای 18 عیار</div>
|
||||
<div class="w-full mt-2 relative bg-gray-100 rounded-lg h-[88px] flex flex-col justify-center">
|
||||
<img :src="img1" alt="" class="h-[88px] absolute">
|
||||
<div class="w-full items-center flex flex-col">
|
||||
<div class="text-gray-600">قیمت لحظه ای طلا</div>
|
||||
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
|
||||
<div class="font-bold text-2xl">{{ usePriceWithoutType(price.price_last ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-around mt-8">
|
||||
<div v-if="lastPrice" class="flex flex-col items-center">
|
||||
<div class="text-xs">بالاترین قیمت خرید امروز</div>
|
||||
<div class="text-green-600 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(lastPrice.buy ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="lastPrice" class="flex flex-col items-center">
|
||||
<div class="text-xs">بالاترین قیمت فروش امروز</div>
|
||||
<div class="text-red-600 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(lastPrice.sell ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<a-spin :spinning="chartLoading">
|
||||
<!-- <div id="chart" class="pb-20 mt-7 overflow-x-auto">
|
||||
<!– <apexchart :options="chartOptions" :series="series" :style="`width: ${chartWidth}`" height="350"
|
||||
type="candlestick"></apexchart>–>
|
||||
<div ref="main" class="w-full aspect-square"></div>
|
||||
</div>-->
|
||||
<div class="overflow-x-auto pb-10">
|
||||
<div ref="main" :style="`width: ${chartWidth}`" class="h-[20rem]"></div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
<div v-else class="bg-white w-screen h-[40vh] px-5 m-[-1px] flex justify-center">
|
||||
<a-spin :spinning="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="y>130? 'bg-white shadow opacity-95': ''"
|
||||
class=" px-4 py-2 top-0 fixed w-screen background-color-transition ">
|
||||
<div class="flex justify-between my-2">
|
||||
<div class="flex items-center gap-2" @click.stop="router.push({name: 'user'})">
|
||||
<!-- <img :src="testimg" alt="" class="w-[24px] h-[24px]">-->
|
||||
<div :class="y>130? 'text-primary': 'text-white'" class="color-transition font-bold">
|
||||
{{ userStore.userInfo?.mobile }}
|
||||
</div>
|
||||
</div>
|
||||
<Icon :color="y>130? 'primary': 'white'" class="color-transition" icon="vuesax-linear:logout"
|
||||
@click="showLogoutConfirm = true"/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogVant v-model:show="showLogoutConfirm" :closeOnClickOverlay="false" :timeOut="-1">
|
||||
<!-- <template v-slot:img>
|
||||
<img :src="registerDelayImage" alt="" class="opacity-80">
|
||||
</template>-->
|
||||
|
||||
<template v-slot:title>
|
||||
<div class="p-5 text-sm">
|
||||
آیا از خروج خود اطمینان دارید؟
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:button>
|
||||
<div class="text-center text-red" @click="logout">
|
||||
خروج
|
||||
</div>
|
||||
<div class="text-center" @click="showLogoutConfirm = false">
|
||||
انصراف
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</DialogVant>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import img from '@/assets/img/home_ly1.svg'
|
||||
import img1 from '@/assets/img/home_ly2.svg'
|
||||
import Icon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import {usePriceWithoutType} from "../../../utils/usePrice";
|
||||
import {computed, onMounted, ref, watch} from "vue";
|
||||
import router from "@/router";
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
import {useWindowScroll} from '@vueuse/core'
|
||||
import {loading, removeToken} from "@/utils";
|
||||
import {useUserStore} from "@/store/userStore";
|
||||
import {useWalletStore} from "@/store/walletStore";
|
||||
import DialogVant from "@/components/DialogVant.vue";
|
||||
import type {Price} from "@/models/home";
|
||||
import {getChart, getLastPrice, getPrice} from "@/api/home";
|
||||
|
||||
|
||||
const userStore = useUserStore()
|
||||
const walletStore = useWalletStore()
|
||||
const chartLoading = ref<boolean>(false)
|
||||
const {x, y} = useWindowScroll()
|
||||
const series = ref<Array<Array<number>>>([])
|
||||
const dates = ref<Array<string>>([])
|
||||
const price = ref<Price>()
|
||||
const lastPrice = ref<Price>()
|
||||
const main = ref(null)
|
||||
|
||||
const upColor = '#ec0000';
|
||||
const upBorderColor = '#8A0000';
|
||||
const downColor = '#00da3c';
|
||||
const downBorderColor = '#008F28';
|
||||
|
||||
// const limitedPrice: Const = walletStore?.limitedPrice
|
||||
watch(main, (n) => {
|
||||
if (main.value !== null) {
|
||||
// console.log('saaaa')
|
||||
const echart = echarts.init(main.value, null, {
|
||||
renderer: 'canvas'
|
||||
})
|
||||
echart.setOption({
|
||||
xAxis: {
|
||||
data: dates.value.values,
|
||||
show: true,
|
||||
},
|
||||
yAxis: {
|
||||
show: false,
|
||||
scale: true,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'candlestick',
|
||||
data: series.value
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
const limitedPrice = computed(() => {
|
||||
if (walletStore.limitedPrice)
|
||||
return walletStore?.limitedPrice[0]
|
||||
})
|
||||
|
||||
const limitedBuyGold = computed(() => {
|
||||
if (walletStore.limitedBuyGold)
|
||||
return walletStore?.limitedBuyGold[0]
|
||||
})
|
||||
|
||||
const chartWidth = computed(() => {
|
||||
if (series.value.length < 30)
|
||||
return '100vw'
|
||||
else if (series.value.length < 60)
|
||||
return '200vw'
|
||||
else if (series.value.length < 90)
|
||||
return '300vw'
|
||||
else if (series.value.length < 120)
|
||||
return '400vw'
|
||||
else if (series.value.length < 160)
|
||||
return '500vw'
|
||||
else if (series.value.length < 190)
|
||||
return '600vw'
|
||||
else if (series.value.length < 210)
|
||||
return '700vw'
|
||||
else if (series.value.length < 240)
|
||||
return '800vw'
|
||||
else if (series.value.length < 270)
|
||||
return '900vw'
|
||||
else if (series.value.length < 300)
|
||||
return '1000vw'
|
||||
else if (series.value.length < 330)
|
||||
return '1100vw'
|
||||
else if (series.value.length < 360)
|
||||
return '1200vw'
|
||||
else if (series.value.length < 390)
|
||||
return '1300vw'
|
||||
})
|
||||
|
||||
function splitData(rawData) {
|
||||
const categoryData = [];
|
||||
const values = [];
|
||||
for (var i = 0; i < rawData.length; i++) {
|
||||
categoryData.push(rawData[i].splice(0, 1)[0]);
|
||||
values.push(rawData[i]);
|
||||
}
|
||||
return {
|
||||
categoryData: categoryData,
|
||||
values: values
|
||||
};
|
||||
}
|
||||
|
||||
async function initChart() {
|
||||
try {
|
||||
chartLoading.value = true
|
||||
const data = await getChart()
|
||||
/* data.forEach(item => {
|
||||
series.value[0].data.push({
|
||||
x: toJalali(item[0]),
|
||||
y: item[1]
|
||||
})
|
||||
// console.log(x)
|
||||
})*/
|
||||
data.forEach(item => {
|
||||
series.value.push(item[1])
|
||||
dates.value.push(item[0])
|
||||
})
|
||||
// series.value = data
|
||||
// series.value = splitData(data)
|
||||
console.log(dates.value)
|
||||
console.log(series.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
chartLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
loading.value = true
|
||||
const data = await getPrice()
|
||||
const dataLast = await getLastPrice()
|
||||
price.value = data
|
||||
lastPrice.value = dataLast
|
||||
console.log(series.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initChart()
|
||||
initPrice()
|
||||
})
|
||||
|
||||
const chartOptions = ref(
|
||||
{
|
||||
chart: {
|
||||
type: 'candlestick',
|
||||
height: 600,
|
||||
toolbar: {
|
||||
autoSelected: 'pan',
|
||||
show: false
|
||||
},
|
||||
},
|
||||
title: {
|
||||
// text: 'CandleStick Chart',
|
||||
align: 'left'
|
||||
},
|
||||
xaxis: {
|
||||
type: 'datetime',
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
show: false,
|
||||
showAlways: false,
|
||||
showForNullSeries: false,
|
||||
tooltip: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
const showLogoutConfirm = ref<boolean>()
|
||||
|
||||
async function logout() {
|
||||
// baseConfirm('آیا از حساب کاربری خارج می شوید؟',async () => {
|
||||
removeToken()
|
||||
await router.push({name: 'login'})
|
||||
window.location.reload()
|
||||
// console.log('salam')
|
||||
// })
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,866 @@
|
||||
<template>
|
||||
<div class="h-35rem overflow-y-auto">
|
||||
<!-- <div class="bg-primary h-30 mt-[-3rem] z-100000000000"></div>-->
|
||||
<div class="h-[60vh] bg-[#0A1B37] wrap-fix">
|
||||
<div class="w-full justify-around mt-18">
|
||||
<div class="flex flex-col w-full justify-center items-center">
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs">مجموع دارایی طلایی</div>
|
||||
<transition mode="out-in" name="fade">
|
||||
<div
|
||||
v-if="!isHidden"
|
||||
class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs"
|
||||
@click="isHidden = true"
|
||||
>
|
||||
<div class="text-white text-base">{{ walletStore.walletInfo?.gold_sum ?? 0 }}</div>
|
||||
گرم
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="flex gap-2 items-center justify-center mt-3 mb-2"
|
||||
@click="isHidden = false"
|
||||
>
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<div class="text-white flex" @click="wholeBalanceVisible = true">
|
||||
<div class="ml-[-1.5rem]">موجودی ها</div>
|
||||
<DotLottieVue
|
||||
class="w-5rem h-5rem mt-[-1.6rem] ml-[-2rem]"
|
||||
autoplay
|
||||
loop
|
||||
src="https://lottie.host/3d46ebb3-a580-41eb-ade7-b8829c32b071/PJPuSKbpze.json"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">موجودی کیف طلا</div>
|
||||
<transition mode="out-in" name="fade">
|
||||
<div v-if="!isHidden" class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs"
|
||||
@click="isHidden = true">
|
||||
<div class="text-white text-base">{{ walletStore?.walletInfo?.gold ?? 0 }}</div>
|
||||
گرم
|
||||
</div>
|
||||
<div v-else class="flex gap-2 items-center justify-center mt-3" @click="isHidden = false">
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">مجموع دارایی طلایی</div>
|
||||
<transition mode="out-in" name="fade">
|
||||
<div v-if="!isHidden" class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs"
|
||||
@click="isHidden = true">
|
||||
<div class="text-white text-base">{{ walletStore.walletInfo?.gold_sum ?? 0 }}</div>
|
||||
گرم
|
||||
</div>
|
||||
<div v-else class="flex gap-2 items-center justify-center mt-3" @click="isHidden = false">
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="text-[#E5D7CE] text-xs ">موجودی کیف پول</div>
|
||||
<transition mode="out-in" name="fade">
|
||||
<div v-if="!isHidden"
|
||||
class="flex justify-center mt-1 text-[#B79379] gap-1 items-center text-xs"
|
||||
@click.stop="isHidden = true;console.log('sssssss')">
|
||||
<div class="text-white text-base">
|
||||
{{
|
||||
walletStore?.walletInfo?.cash === undefined ? 0 : usePriceWithoutType(walletStore.walletInfo?.cash)
|
||||
}}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
<div v-else class="flex gap-2 items-center justify-center mt-3" @click="isHidden = false">
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
<div class="bg-white rounded-full w-2 h-2" />
|
||||
</div>
|
||||
</transition>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-[9rem] relative pb-30">
|
||||
<img :src="img" alt="" class="w-screen h-[8rem]" />
|
||||
|
||||
<div
|
||||
v-if="userStore.userInfo && !loading"
|
||||
class="bg-white w-screen md:w-auto h-fit px-5 m-[-1px]"
|
||||
>
|
||||
<div
|
||||
v-if="limitedPrice !== undefined && userStore?.userInfo.trade_active !== 1"
|
||||
class="text-red text-xs flex gap-1 items-center justify-center mb-2"
|
||||
>
|
||||
<Icon icon="vuesax-linear:info-circle" size="16" />
|
||||
حداقل مبلغ اولیه برای ثبت سفارش
|
||||
{{ usePriceWithoutType(limitedPrice.value as number ?? 0) }} ریال می باشد.
|
||||
</div>
|
||||
|
||||
<!-- <div class="bg-white">
|
||||
<MySlider v-if="cardItems.length > 0" :items="cardItems" class=" pb-[20vh] "
|
||||
style="touch-action: none" />
|
||||
</div>-->
|
||||
<div
|
||||
class="w-full relative bg-gray-100 rounded-lg h-[88px] flex flex-col justify-center home_appear_fade_in"
|
||||
>
|
||||
<img :src="img1" alt="" class="h-[88px] absolute" />
|
||||
<div class="w-full items-center flex flex-col">
|
||||
<div class="text-gray-600">قیمت لحظه ای طلا</div>
|
||||
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
|
||||
<!-- <div id="odometer" class="font-bold text-2xl odometer animated fadeIn">
|
||||
<!– {{ usePriceWithoutType(useCounterAnim(price.price_last) ?? 0) }}–>
|
||||
</div>-->
|
||||
<!-- <div id="odometer" class="odometer animated fadeIn"></div>-->
|
||||
<Vue3Odometer
|
||||
:value="goldVal"
|
||||
class="o-text !text-2xl font-bold"
|
||||
style="font-family: iran-sans; direction: ltr"
|
||||
v-if="key % 2 === 0"
|
||||
/>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between mt-8">
|
||||
<div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_up"
|
||||
style="text-align: -webkit-center"
|
||||
@click="router.push({ name: 'gold', query: { state: 'sell' } })"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[42px] h-[42px] bg-orange-100 flex items-center justify-center"
|
||||
>
|
||||
<Icon class="text-orange-600" icon="vuesax-linear:money-send" />
|
||||
</div>
|
||||
<div class="text-primary">فروش</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_down"
|
||||
style="text-align: -webkit-center"
|
||||
@click="router.push({ name: 'wallet', query: { state: 'deposit' } })"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[42px] h-[42px] bg-green-100 flex items-center justify-center"
|
||||
>
|
||||
<Icon class="text-green-600" icon="vuesax-linear:card-add" />
|
||||
</div>
|
||||
<div class="text-primary">واریز نقدی</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_up"
|
||||
style="text-align: -webkit-center"
|
||||
@click="router.push({ name: 'gold', query: { state: 'buy' } })"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[42px] h-[42px] bg-blue-100 flex items-center justify-center"
|
||||
>
|
||||
<Icon class="text-blue-600" icon="vuesax-linear:money-receive" />
|
||||
</div>
|
||||
<div class="text-primary">خرید</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-center w-full flex-flex-col items-center home_appear_fade_in_down"
|
||||
style="text-align: -webkit-center"
|
||||
@click="router.push({ name: 'fund' })"
|
||||
>
|
||||
<div
|
||||
class="rounded-full w-[42px] h-[42px] bg-yellow-100 flex items-center justify-center"
|
||||
>
|
||||
<Icon class="text-yellow-600" icon="vuesax-linear:archive-1" />
|
||||
</div>
|
||||
<div class="text-primary">گنج</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="mt-10 font-bold home_appear_fade_in" @click="update">
|
||||
نوسانات قیمت هر گرم طلای 18 عیار
|
||||
</div>-->
|
||||
|
||||
<!-- <a-spin :spinning="chartLoading" class="relative">
|
||||
<div ref="target" class="absolute"></div>
|
||||
<div v-if="!chartLoading" id="chart" class="pb-20 mt-7 overflow-x-auto">
|
||||
<!– <apexchart v-if="targetIsVisible" :options="chartOptions" :series="test_series"
|
||||
:style="`width: ${chartWidth}`"
|
||||
height="350"
|
||||
type="candlestick"></apexchart>–>
|
||||
</div>
|
||||
</a-spin>-->
|
||||
<!-- <a-spin :spinning="chartLoading" >-->
|
||||
<!-- <div ref="target" class="absolute"></div>-->
|
||||
<!-- <div id="chart" class="mt-7">-->
|
||||
<div class="bg-gray-50 w-full flex justify-evenly rounded-lg py-4 mt-4 h-[15rem]">
|
||||
<div class="w-full text-center pt-2">
|
||||
<a-radio-group v-model:value="value" button-style="solid">
|
||||
<a-radio-button value="a" @click="updateData('DAILY')">24 ساعت اخیر</a-radio-button>
|
||||
<a-radio-button value="b" @click="updateData('WEEKLY')">هفته گذشته</a-radio-button>
|
||||
<a-radio-button value="c" @click="updateData('MONTHLY')">ماه گذشته</a-radio-button>
|
||||
</a-radio-group>
|
||||
<div id="chart-timeline">
|
||||
<apexchart
|
||||
type="area"
|
||||
height="200"
|
||||
ref="chart"
|
||||
:options="priceChartOptions"
|
||||
:series="priceChartSeries"
|
||||
></apexchart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" w-full flex justify-evenly rounded-lg py-2 home_appear_fade_in mt-6">
|
||||
<div class="text-center w-full">
|
||||
<div>بالاترین قیمت امروز</div>
|
||||
<div v-if="lastPrice" class="flex flex-col items-center mt-3">
|
||||
<div class="text-green-600 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(price.buy ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-divider class="bg-gray-200 !h-auto !my-2" type="vertical" />
|
||||
<div class="text-center w-full">
|
||||
<div>پایین ترین قیمت امروز</div>
|
||||
<div class="flex w-full mt-3 justify-evenly">
|
||||
<div v-if="lastPrice" class="flex flex-col items-center">
|
||||
<div class="text-red-600 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType(price.sell ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="text-center w-full">
|
||||
<div>قیمت خرید از گلد دات آی آر</div>
|
||||
<div class="text-[10px] text-gray-500">(هر گرم طلای 18 عیار)</div>
|
||||
<div class="flex w-full mt-3 justify-evenly">
|
||||
<!– <div class="text-[10px] gap-1 flex bg-green-100 rounded-xl px-1 text-green-600 items-center">
|
||||
<Icon icon="vuesax-linear:received" size="10"/>
|
||||
<div>2%</div>
|
||||
</div>–>
|
||||
<div v-if="price" class="flex text-gray-500 text-xs items-center gap-1">
|
||||
<div class="text-primary font-bold text-base">
|
||||
{{ usePriceWithoutType(lastPrice.buy ?? 0) }}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-divider class="bg-gray-200 !h-auto !my-2" type="vertical" />
|
||||
<div class="text-center w-full">
|
||||
<div>قیمت فروش به گلد دات آی آر</div>
|
||||
<div class="text-[10px] text-gray-500">(هر گرم طلای 18 عیار)</div>
|
||||
<div class="flex w-full mt-3 justify-evenly">
|
||||
<!– <div class="text-[10px] gap-1 flex bg-red-100 rounded-xl px-1 text-red-600 items-center">
|
||||
<Icon icon="vuesax-linear:send" size="10"/>
|
||||
<div>3%</div>
|
||||
</div>–>
|
||||
<div v-if="price" class="flex text-gray-500 text-xs items-center gap-1">
|
||||
<div class="text-primary font-bold text-base">
|
||||
{{ usePriceWithoutType(lastPrice.sell ?? 0) }}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
<!-- </a-spin>-->
|
||||
</div>
|
||||
<div v-else class="bg-white w-screen md:w-auto h-[80vh] px-5 m-[-1px] flex justify-center">
|
||||
<HomeSkeleton class="w-full" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
:class="y > 130 ? 'bg-white shadow opacity-95' : ''"
|
||||
class="px-4 py-2 top-0 wrap-fix background-color-transition"
|
||||
>
|
||||
<div class="flex justify-between my-2">
|
||||
<div class="flex items-center gap-2" @click.stop="router.push({ name: 'user' })">
|
||||
<!-- <img :src="testimg" alt="" class="w-[24px] h-[24px]">-->
|
||||
<div
|
||||
class="z-100000 rounded-full border-1"
|
||||
:class="y > 130 ? 'text-primary border-primary' : 'text-white border-white'"
|
||||
>
|
||||
<Icon icon="vuesax-linear:user" size="20" />
|
||||
</div>
|
||||
<div :class="y > 130 ? 'text-primary' : 'text-white'" class="color-transition font-bold">
|
||||
{{ userStore.userInfo?.name }}
|
||||
</div>
|
||||
</div>
|
||||
<Icon
|
||||
:color="y > 130 ? 'primary' : 'white'"
|
||||
class="color-transition"
|
||||
icon="vuesax-linear:logout"
|
||||
@click="showLogoutConfirm = true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogVant v-model:show="showLogoutConfirm" :closeOnClickOverlay="false" :timeOut="-1">
|
||||
<!-- <template v-slot:img>
|
||||
<img :src="registerDelayImage" alt="" class="opacity-80">
|
||||
</template>-->
|
||||
|
||||
<template v-slot:title>
|
||||
<div class="flex flex-col items-center">
|
||||
<DotLottieVue
|
||||
class="w-11rem h-11rem"
|
||||
autoplay
|
||||
src="https://lottie.host/129cf3a1-df84-4758-a856-58c133ae6013/R5RqclXA8G.json"
|
||||
/>
|
||||
<div class="p-5 text-sm">آیا از خروج خود اطمینان دارید؟</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:button>
|
||||
<div class="text-center text-red flex items-center justify-center" @click="logout">
|
||||
<a-spin :spinning="logoutLoading" size="small"> خروج </a-spin>
|
||||
</div>
|
||||
<div class="text-center" @click="showLogoutConfirm = false">انصراف</div>
|
||||
</template>
|
||||
</DialogVant>
|
||||
</div>
|
||||
<BasicActionSheet v-model:show="wholeBalanceVisible">
|
||||
<div class="pb-20">
|
||||
<div>
|
||||
<div class="w-full text-center font-bold">موجودی ها</div>
|
||||
<div class="h-30vh overflow-y-auto">
|
||||
<div class="mt-5">
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="مجموعه کل دارایی طلایی"
|
||||
is-line
|
||||
info="در این قسمت مجموع کل وزن طلایی که در گنج های خود و کیف اصلی طلایی دارید را مشاهده میفرمایید."
|
||||
infoHead="مجموع کل دارایی طلایی"
|
||||
:value="parseFloat((walletStore.walletInfo?.gold_sum ?? 0).toFixed(2)) + ' گرم'"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="دارایی کیف پول"
|
||||
is-line
|
||||
:value="usePrice(walletStore.walletInfo?.cash ?? 0)"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="دارایی کیف طلا"
|
||||
is-line
|
||||
:value="parseFloat((walletStore.walletInfo?.gold ?? 0)?.toFixed(2)) + ' گرم'"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="ارزش ریالی کیف طلا"
|
||||
is-line
|
||||
:value="
|
||||
usePrice(((walletStore.walletInfo?.gold ?? 0) * (goldVal ?? 0) ?? 0).toFixed(0))
|
||||
"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<!-- <BasicInfoItem class="flex justify-between" title="دارایی کیف پول(به گرم)" is-line
|
||||
:value="((walletStore.walletInfo?.cash?? 0) / (goldVal?? 0)).toFixed(2)+ ' گرم'" />
|
||||
<a-divider class="!my-1" />-->
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="مجموعه دارایی کلی (به ریال)"
|
||||
is-line
|
||||
:value="
|
||||
usePrice(
|
||||
(
|
||||
(walletStore.walletInfo?.gold_sum ?? 0) * (goldVal ?? 0) +
|
||||
(walletStore.walletInfo?.cash ?? 0)
|
||||
).toFixed(0)
|
||||
)
|
||||
"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<!-- <BasicInfoItem class="flex justify-between" title="مجموعه دارایی کلی (به گرم)" is-line
|
||||
:value="((((walletStore.walletInfo?.cash?? 0)/(goldVal?? 0) )+ (walletStore.walletInfo?.gold_sum?? 0))).toFixed(2)+ ' گرم'" />
|
||||
<a-divider class="!my-1" />-->
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="مجموعه دارایی قابل برداشت (به ریال)"
|
||||
is-line
|
||||
:value="
|
||||
usePrice(
|
||||
(
|
||||
(walletStore.walletInfo?.gold ?? 0) * (goldVal ?? 0) +
|
||||
(walletStore.walletInfo?.cash ?? 0)
|
||||
).toFixed(0)
|
||||
)
|
||||
"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="مجموعه دارایی قابل برداشت (به گرم)"
|
||||
is-line
|
||||
:value="
|
||||
parseFloat((
|
||||
(walletStore.walletInfo?.cash ?? 0) / (goldVal ?? 0) +
|
||||
(walletStore.walletInfo?.gold ?? 0)
|
||||
).toFixed(2)) + ' گرم'
|
||||
"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import img from '@/assets/img/home_ly1.svg'
|
||||
import img1 from '@/assets/img/home_ly2.svg'
|
||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import { usePrice, usePriceWithoutType } from '../../../utils/usePrice'
|
||||
import {computed, onMounted, onUnmounted, ref, watch, watchEffect} from 'vue'
|
||||
import router from '@/router'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
import { useIntersectionObserver, useWindowScroll } from '@vueuse/core'
|
||||
import { loading, removeToken } from '@/utils'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { useWalletStore } from '@/store/walletStore'
|
||||
import DialogVant from '@/components/DialogVant.vue'
|
||||
import type { Price } from '@/models/home'
|
||||
import { getAllPrices, getChart, getLastPrice, getPrice } from '@/api/home'
|
||||
// import odometer from 'odometer/odometer'
|
||||
import Vue3Odometer from 'vue3-odometer'
|
||||
import 'odometer/themes/odometer-theme-default.css'
|
||||
import HomeSkeleton from '@/views/base/home/components/HomeSkeleton.vue'
|
||||
import { toJalaliNotime } from '@/utils/useDateTime'
|
||||
import { getLastPrices, lastPrice, price, setIntervalGetAllPrice, stopPriceInterval } from '@/utils/price'
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import BasicInfoItem from '@/components/BasicPacks/BasicInfoItem.vue'
|
||||
import MySlider from '@/views/base/wallet/components/mySlider/MySlider.vue'
|
||||
import type { Card } from '@/models/wallet'
|
||||
import { getActivatedCards } from '@/api/wallet'
|
||||
import banner1 from '@/assets/img/banner/banner1.png'
|
||||
import banner2 from '@/assets/img/banner/banner2.png'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const walletStore = useWalletStore()
|
||||
const chartLoading = ref<boolean>(false)
|
||||
const wholeBalanceVisible = ref<boolean>(false)
|
||||
const { x, y } = useWindowScroll()
|
||||
const series = ref<Chart[]>([{ data: [] }])
|
||||
const key = ref<number>(0)
|
||||
const cardItems = [banner1, banner2]
|
||||
const main = ref(null)
|
||||
const logoutLoading = ref(false)
|
||||
const value = ref<string>('a')
|
||||
/*
|
||||
onMounted(() => {
|
||||
animateNum(2)
|
||||
})
|
||||
*/
|
||||
|
||||
const goldVal = ref<number | undefined>()
|
||||
|
||||
function update() {
|
||||
setInterval(() => {
|
||||
goldVal.value = lastPrice?.value.price_last
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const target = ref(null)
|
||||
const targetIsVisible = ref(false)
|
||||
|
||||
const isHidden = ref<boolean>(false)
|
||||
|
||||
const { stop } = useIntersectionObserver(target, ([{ isIntersecting }], observerElement) => {
|
||||
targetIsVisible.value = isIntersecting
|
||||
console.log('saaaaa', targetIsVisible.value)
|
||||
})
|
||||
|
||||
watch(main, (n) => {
|
||||
if (main.value !== null) {
|
||||
// console.log('saaaa')
|
||||
const echart = echarts.init(main.value, null, {
|
||||
renderer: 'canvas'
|
||||
})
|
||||
echart.setOption({
|
||||
xAxis: {
|
||||
data: dates.value.values,
|
||||
show: true
|
||||
},
|
||||
yAxis: {
|
||||
show: false,
|
||||
scale: true
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'candlestick',
|
||||
data: series.value
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
//whole prices
|
||||
const priceChartSeries = ref<{ data: [number, number][] }[]>([
|
||||
{
|
||||
name: 'قیمت',
|
||||
data: []
|
||||
}
|
||||
])
|
||||
const selection = ref('DAILY')
|
||||
const chartRef = ref<ApexCharts | null>(null)
|
||||
const priceChartOptions = ref({
|
||||
chart: {
|
||||
id: 'نوسانات قیمت',
|
||||
type: 'area',
|
||||
height: 200,
|
||||
toolbar: {
|
||||
show: false // Disable the toolbar to remove download and other options
|
||||
},
|
||||
zoom: {
|
||||
autoScaleYaxis: true
|
||||
},
|
||||
events: {
|
||||
mounted(chart) {
|
||||
chartRef.value = chart
|
||||
}
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
padding: {
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0
|
||||
},
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
width: 2
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
// formatter: (val) => toPersianNumber(val),
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
tickAmount: 8,
|
||||
show: false,
|
||||
title: {
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labels: {
|
||||
formatter: (val) => toPersianNumber(usePrice(val)),
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
},
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
show: false,
|
||||
type: 'datetime',
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
labels: {
|
||||
show: false,
|
||||
rotate: -45,
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
},
|
||||
// formatter: (val) => toPersianNumber(toJalaliNotime(new Date(val).toString()))
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
x: {
|
||||
// formatter: (val) => toPersianNumber(toJalaliNotime(new Date(val).toString()))
|
||||
formatter: (value) => {
|
||||
const date = new Date(value)
|
||||
return `${date.toLocaleDateString('fa-IR')} - ${date.toLocaleTimeString('fa-IR', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
})}`
|
||||
},
|
||||
},
|
||||
formatter: (val) => toPersianNumber(usePrice(val)),
|
||||
style: {
|
||||
fontFamily: "'IranSans', sans-serif",
|
||||
// fontWeight: 'bold'
|
||||
},
|
||||
markers:{
|
||||
show: false
|
||||
}
|
||||
},
|
||||
colors: ['#0A1B37'],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shadeIntensity: 1,
|
||||
opacityFrom: 0.7,
|
||||
opacityTo: 0.9,
|
||||
stops: [0, 100]
|
||||
},
|
||||
},
|
||||
|
||||
})
|
||||
const toPersianNumber = (num) => {
|
||||
return num.toString().replace(/\d/g, (d) => '۰۱۲۳۴۵۶۷۸۹'[d])
|
||||
}
|
||||
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 - 1])
|
||||
// console.log(priceChartSeries.value[0].data)
|
||||
chartRef.value?.updateOptions({
|
||||
series: priceChartSeries.value,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('خطا در دریافت دادهها', error)
|
||||
}
|
||||
}
|
||||
|
||||
const updateData = (timeline) => {
|
||||
selection.value = timeline
|
||||
fetchPrices()
|
||||
}
|
||||
|
||||
const limitedPrice = computed(() => {
|
||||
if (walletStore.limitedPrice) return walletStore?.limitedPrice[0]
|
||||
})
|
||||
|
||||
const limitedBuyGold = computed(() => {
|
||||
if (walletStore.limitedBuyGold) return walletStore?.limitedBuyGold[0]
|
||||
})
|
||||
|
||||
const chartWidth = computed(() => {
|
||||
if (series.value.length < 30) return '100vw'
|
||||
else if (series.value.length < 60) return '200vw'
|
||||
else if (series.value.length < 90) return '300vw'
|
||||
else if (series.value.length < 120) return '400vw'
|
||||
else if (series.value.length < 160) return '500vw'
|
||||
else if (series.value.length < 190) return '600vw'
|
||||
else if (series.value.length < 210) return '700vw'
|
||||
else if (series.value.length < 240) return '800vw'
|
||||
else if (series.value.length < 270) return '900vw'
|
||||
else if (series.value.length < 300) return '1000vw'
|
||||
else if (series.value.length < 330) return '1100vw'
|
||||
else if (series.value.length < 360) return '1200vw'
|
||||
else if (series.value.length < 390) return '1300vw'
|
||||
})
|
||||
const test_series = [
|
||||
{
|
||||
name: 'candle',
|
||||
data: []
|
||||
}
|
||||
]
|
||||
|
||||
async function initChart() {
|
||||
try {
|
||||
chartLoading.value = true
|
||||
const data = await getChart()
|
||||
/* data.forEach(item => {
|
||||
test_series[0].data.push({
|
||||
x: toJalali(item[0]),
|
||||
y: item[1]
|
||||
})
|
||||
// console.log(x)
|
||||
})*/
|
||||
data.forEach((item) => {
|
||||
test_series[0].data.push({
|
||||
x: item[0],
|
||||
y: item[1]
|
||||
})
|
||||
// console.log(x)
|
||||
})
|
||||
// console.log(test_series)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
chartLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
loading.value = true
|
||||
const val = price?.value?.price_last
|
||||
await getLastPrices()
|
||||
// await setIntervalGetPrice()
|
||||
if (val !== price?.value?.price_last) {
|
||||
update()
|
||||
/* key.value++
|
||||
key.value++*/
|
||||
}
|
||||
/* price.value = data
|
||||
lastPrice.value = dataLast*/
|
||||
goldVal.value = 0
|
||||
// console.log(price?.value.price_last)
|
||||
if (userStore.isFirst) {
|
||||
const timer = setInterval(function () {
|
||||
update()
|
||||
// if (current == end) {
|
||||
userStore.isFirst = false
|
||||
clearInterval(timer)
|
||||
// }
|
||||
}, 100)
|
||||
} else {
|
||||
goldVal.value = price.value?.price_last
|
||||
}
|
||||
// console.log(series.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await initChart()
|
||||
await initPrice()
|
||||
await fetchPrices()
|
||||
// console.log('okkkkkkhome')
|
||||
update()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
// stopPriceInterval()
|
||||
// console.log('okhome')
|
||||
})
|
||||
|
||||
const chartOptions = ref({
|
||||
chart: {
|
||||
type: 'candlestick',
|
||||
height: 600,
|
||||
toolbar: {
|
||||
autoSelected: 'pan',
|
||||
show: false
|
||||
}
|
||||
},
|
||||
title: {
|
||||
// text: 'CandleStick Chart',
|
||||
align: 'left'
|
||||
},
|
||||
xaxis: {
|
||||
type: 'datetime',
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
formatter: function (val, opts) {
|
||||
// console.log(val, toJalali(val))
|
||||
return toJalaliNotime(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
show: false,
|
||||
showAlways: false,
|
||||
showForNullSeries: false,
|
||||
tooltip: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
custom: function ({ seriesIndex, dataPointIndex, w }) {
|
||||
const o = w.globals.seriesCandleO[seriesIndex][dataPointIndex]
|
||||
const h = w.globals.seriesCandleH[seriesIndex][dataPointIndex]
|
||||
const l = w.globals.seriesCandleL[seriesIndex][dataPointIndex]
|
||||
const c = w.globals.seriesCandleC[seriesIndex][dataPointIndex]
|
||||
return (
|
||||
'<div class="apexcharts-tooltip-candlestick p-2">' +
|
||||
'<div>باز: <span class="value">' +
|
||||
o +
|
||||
'</span></div>' +
|
||||
'<div>بیشترین: <span class="value">' +
|
||||
h +
|
||||
'</span></div>' +
|
||||
'<div>کمترین: <span class="value">' +
|
||||
l +
|
||||
'</span></div>' +
|
||||
'<div>بسته: <span class="value">' +
|
||||
c +
|
||||
'</span></div>' +
|
||||
'</div>'
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const showLogoutConfirm = ref<boolean>()
|
||||
|
||||
async function logout() {
|
||||
logoutLoading.value = true
|
||||
// baseConfirm('آیا از حساب کاربری خارج می شوید؟',async () => {
|
||||
userStore.userInfo = undefined
|
||||
walletStore.walletInfo = undefined
|
||||
/* userStore.$reset()
|
||||
walletStore.$reset()*/
|
||||
removeToken()
|
||||
await router.push({ name: 'login' })
|
||||
logoutLoading.value = true
|
||||
window.location.reload()
|
||||
// console.log('salam')
|
||||
// })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
.odometer {
|
||||
font-size: 60px;
|
||||
//margin: 200px 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
animation-duration: 3s;
|
||||
}
|
||||
|
||||
label:focus-within {
|
||||
box-shadow: none !important
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
apexchart {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,384 @@
|
||||
<template>
|
||||
<div >
|
||||
<Transition>
|
||||
<div v-if="popVisible" class="top-0 bottom-0 bg-primary wrap-fix z-2000 opacity-60"
|
||||
@click="popVisible = false">
|
||||
</div>
|
||||
</Transition>
|
||||
<Transition name="slide-fade">
|
||||
<div v-if="popVisible" class="wrap-fix bottom-11vh z-2000">
|
||||
<div class="relative flex flex-col items-center ">
|
||||
<div class="flex items-center justify-center bg-white rounded-full w-[30px] h-[30px] mb-2"
|
||||
@click="popVisible = !popVisible">
|
||||
<BasicIcon
|
||||
icon="vuesax-linear:close-circle"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<BasicButton icon-size="16" class="!font-bold w-15rem"
|
||||
@click="$router.push({name: 'user'}); popVisible = false">
|
||||
<div class="flex gap-2 items-center">
|
||||
<BasicIcon icon="vuesax-linear:user" size="16" class="absolute right-2" />
|
||||
<div>حساب کاربری</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton icon-size="16" class="!font-bold w-15rem"
|
||||
@click="$router.push({name: 'notifyTrigger'}); popVisible = false">
|
||||
<div class="flex gap-2 items-center">
|
||||
<BasicIcon icon="vuesax-linear:bill" size="16" class="absolute right-2" />
|
||||
<div>هشدار قیمت</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton icon-size="16" class="!font-bold w-15rem"
|
||||
@click="$router.push({name: 'about'}); popVisible = false">
|
||||
<div class="flex gap-2 items-center">
|
||||
<BasicIcon icon="vuesax-linear:info-circle" size="16" class="absolute right-2" />
|
||||
<div>درباره ما</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<!-- <BasicButton icon-size="16" class="!font-bold w-15rem"-->
|
||||
<!-- @click="$router.push({name: 'physicalReceive'}); popVisible = false">-->
|
||||
<!-- <div class="flex gap-2 items-center">-->
|
||||
<!-- <BasicIcon icon="vuesax-linear:direct-inbox" size="16" class="absolute right-2" />-->
|
||||
<!-- <div>دریافت طلای فیزیکی</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </BasicButton>-->
|
||||
<BasicButton icon-size="16" class="!font-bold w-15rem"
|
||||
@click="$router.push({name: 'rules'}); popVisible = false">
|
||||
<div class="flex gap-2 items-center">
|
||||
<BasicIcon icon="vuesax-linear:task" size="16" class="absolute right-2" />
|
||||
<div>قوانین و مقررات</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<!-- <BasicButton icon-size="16" class="!font-bold w-50vw md:w-full"
|
||||
@click="$router.push({name: 'permissions'}); popVisible = false">
|
||||
<div class="flex gap-2 items-center">
|
||||
<BasicIcon icon="vuesax-linear:archive-book" size="16" class="absolute right-2" />
|
||||
<div>مجوز ها</div>
|
||||
</div>
|
||||
</BasicButton>-->
|
||||
<!-- <BasicButton icon-size="16" class="!font-bold w-50vw md:w-full"
|
||||
@click="$router.push({name: 'earnMoney'}); popVisible = false">
|
||||
<div class="flex gap-2 items-center">
|
||||
<BasicIcon icon="vuesax-linear:dollar-circle" size="16" class="absolute right-2" />
|
||||
<div>کسب درآمد</div>
|
||||
</div>
|
||||
</BasicButton>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
<div class=" !h-[calc(100vh-72px)] ">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<!-- Use any custom transition and to `fade` -->
|
||||
<transition :name="route.meta.transition || 'fade'">
|
||||
<component :is="Component" class="!h-[calc(100vh-72px)]" />
|
||||
</transition>
|
||||
</router-view>
|
||||
</div>
|
||||
<!-- <canvas ref="canvas" id="canvas1" width="400" height="80" class="w-full"></canvas>-->
|
||||
<div class="bottom-appbar w-auto mx-auto">
|
||||
<div class="tabs">
|
||||
<div :class="setNavColor('home')" class="tab" @click="setRoute('home')">
|
||||
<Icon icon="vuesax-linear:home" />
|
||||
<div class="text-xs mt-1 font-bold">صفحه اصلی</div>
|
||||
</div>
|
||||
<div :class="setNavColor('transactions')" class="tab" @click="setRoute('transactions')">
|
||||
<Icon icon="vuesax-linear:receipt-item" />
|
||||
<div class="text-xs mt-1 font-bold">گزارش</div>
|
||||
</div>
|
||||
<div class="main_in" @click="setRoute('buyProduct')">
|
||||
<div class="text-white circle_in">
|
||||
<div class="circle_into " @click="popVisible = !popVisible">
|
||||
<img
|
||||
class="p-2"
|
||||
:src="config.config.avatar"
|
||||
/>
|
||||
</div>
|
||||
<!-- <div class="flex justify-center">خرید </div>
|
||||
<div class="flex justify-center">محصول </div>-->
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<!-- <div :class="setNavColor('buyProduct')" class="tab" @click="setRoute('buyProduct')">
|
||||
<Icon icon="vuesax-linear:coin" />
|
||||
<div class="text-xs mt-1 font-bold">خرید محصول</div>
|
||||
</div>-->
|
||||
<div :class="setNavColor('wallet')" class="tab" @click="setRoute('wallet')">
|
||||
<Icon icon="vuesax-linear:wallet-1" />
|
||||
<div class="text-xs mt-1 font-bold">کیف پول</div>
|
||||
</div>
|
||||
<div :class="setNavColor('setting')" class="tab" @click="setRoute('user')">
|
||||
<Icon icon="vuesax-linear:setting-2" />
|
||||
<div class="text-xs mt-1 font-bold">تنظیمات</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="w-[80px] h-[80px] border-1">
|
||||
|
||||
</div>-->
|
||||
<div class="main">
|
||||
<div class="circle">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import router from '@/router'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import {useConfigStore} from "@/store/configStore";
|
||||
|
||||
/*onMounted(async () => {
|
||||
const c = await document.getElementById("canvas1");
|
||||
const ctx = c.getContext("2d");
|
||||
console.log(ctx)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0,20);
|
||||
ctx.lineTo(165,20)
|
||||
ctx.arc(200, 50, 45, 3.9, 5.5, false);
|
||||
ctx.lineTo(400,20)
|
||||
ctx.stroke();
|
||||
})*/
|
||||
const currentRoute = computed(() => router.currentRoute.value.name)
|
||||
const config=useConfigStore()
|
||||
|
||||
const popVisible = ref(false)
|
||||
|
||||
function setNavColor(val: string) {
|
||||
if (currentRoute.value === val) {
|
||||
return 'text-primary'
|
||||
} else {
|
||||
return 'text-gray-400'
|
||||
}
|
||||
}
|
||||
|
||||
function setRoute(val: string) {
|
||||
popVisible.value = false
|
||||
router.push({ name: val })
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less">
|
||||
|
||||
.bottom-appbar {
|
||||
z-index: 5000;
|
||||
height: 80px;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left:0;
|
||||
@media screen and (min-width: 426px) {
|
||||
width: 426px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
height: 90%;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background: white;
|
||||
//background-color: red;
|
||||
justify-content: space-between;
|
||||
position: absolute;
|
||||
z-index: 400;
|
||||
//border: 1px dashed primary;
|
||||
box-shadow: 0px -2px 4px -2px #0000001A;
|
||||
|
||||
.tab {
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
flex-flow: column;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.main_in {
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
|
||||
.circle_in {
|
||||
margin-top: -10px;
|
||||
border-radius: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
//border: 1px dashed primary;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
flex-wrap: wrap;
|
||||
background-color: #0A1B37;
|
||||
|
||||
|
||||
|
||||
.circle_into {
|
||||
overflow:hidden;
|
||||
@apply bg-primary;
|
||||
border-radius: 100%;
|
||||
width: 90%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
flex-wrap: wrap;
|
||||
height: 90%;
|
||||
border: white 1px solid;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
position: relative;
|
||||
|
||||
.circle {
|
||||
border-radius: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 20;
|
||||
//border: 1px dashed primary;
|
||||
box-shadow: 0px -5px 4px -2px #0000001A;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*.wrapper{
|
||||
max-width: 400px;
|
||||
margin: 0px auto;
|
||||
}
|
||||
.page{
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
img{
|
||||
max-width: 60%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.bottom-appbar {
|
||||
height: 70px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 20;
|
||||
.tabs {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
.tab {
|
||||
&--left {
|
||||
width: 100%;
|
||||
border-top-right-radius: 30px;
|
||||
border-top: 1px solid rgba(167, 161, 161, 0.69);
|
||||
box-shadow: 0px 6px 7px 0px rgba(23, 23, 23, 0.28);
|
||||
}
|
||||
&--right {
|
||||
width: 100%;
|
||||
border-top-left-radius: 30px;
|
||||
border-top: 1px solid rgba(167, 161, 161, 0.69);
|
||||
box-shadow: 15px 4px 15px 0px rgba(23, 23, 23, 0.28);
|
||||
}
|
||||
&--fab {
|
||||
width: 180px;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
border: none;
|
||||
display: flex;
|
||||
|
||||
.top {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
border-bottom-left-radius: 100px;
|
||||
border-bottom-right-radius: 100px;
|
||||
background-color: transparent;
|
||||
box-shadow: 0px 30px 0px 25px #fff;
|
||||
border-bottom: 1px solid rgba(167, 161, 161, 0.69);
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
background-color: #fff;
|
||||
width: 33.4%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid #eee;
|
||||
box-shadow: 1x 1x 3px #ccc, -1px -1px 3px #ccc;
|
||||
font-size: 24px;
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
i {
|
||||
font-size: 24px;
|
||||
}
|
||||
&.is-active {
|
||||
color: #fd9d97;
|
||||
}
|
||||
}
|
||||
.fab {
|
||||
border-radius: 50%;
|
||||
background-color: #fe989c;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
font-weight: bold;
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
transform: translate(2px,-60%);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
.v-enter-active,
|
||||
.v-leave-active {
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
|
||||
.v-enter-from,
|
||||
.v-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-fade-enter-active {
|
||||
transition: all 0.3s ease-out;
|
||||
}
|
||||
|
||||
.slide-fade-leave-active {
|
||||
transition: all 0.4s cubic-bezier(1, 0.5, 0.8, 1);
|
||||
}
|
||||
|
||||
.slide-fade-enter-from,
|
||||
.slide-fade-leave-to {
|
||||
transform: translateX(20px);
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<div ref="el" class="px-3 pt-15"
|
||||
>
|
||||
<div class="flex gap-2">
|
||||
<BasicSelect v-model:value="selectedProduct" :items="items"
|
||||
class="w-full"
|
||||
key-name="id"
|
||||
:show-search="false"
|
||||
value-name="title"
|
||||
size="large"
|
||||
placeholder="لطفا محصول را انتخاب کنید"
|
||||
:has-tooltip="false"/>
|
||||
<BasicButton :disabled-b="selectedProduct==null" type="primary" @click="handleAdd">افزودن</BasicButton>
|
||||
</div>
|
||||
<div class="h-70vh rounded-lg bg-white mt-2 border-gray-200 border-1 overflow-y-auto p-2">
|
||||
<div v-for="(val,index) in selectedProducts" class="rounded-lg p-2 bg-gray-100 mb-2">
|
||||
<div class="flex">
|
||||
<div class="bg-gray-100 m-2 rounded-lg w-28 h-28 flex justify-center p-2">
|
||||
<img v-if="val.product.group_type=='گوی'" :src="goyImg">
|
||||
<img v-if="val.product.group_type=='مکعب'" :src="mokaabImg">
|
||||
<img v-if="val.product.group_type=='سکه'" :src="sekkeImg">
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="flex justify-between">
|
||||
<div class="font-bold text-lg">
|
||||
{{ val.product.title }}
|
||||
</div>
|
||||
<BasicButton icon="vuesax-linear:trash" icon-class="text-red" @click="handleRemove(val.product.id)"/>
|
||||
</div>
|
||||
<div class="flex mt-3 justify-between items-center">
|
||||
<div>تعداد موجودی:</div>
|
||||
<div class="flex gap-1 items-center">
|
||||
<div class="font-bold">{{ val.product.wallet.gold }}</div>
|
||||
<div>{{ val.product.unit }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-center mt-2">
|
||||
<div>تعداد درخواستی:</div>
|
||||
<div class="flex gap-1 items-center w-40%">
|
||||
<BasicInput v-model:value="val.count" addon-before="عدد"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BasicButton :disabled-b="selectedProducts.length==0" class="w-full absolute bottom-10 mt-2"
|
||||
@click="handelFirstSubmit()">ثبت
|
||||
</BasicButton>
|
||||
</div>
|
||||
<!-- <ActionSheet v-model:show="editPassVisible">salam</ActionSheet>-->
|
||||
</div>
|
||||
<BasicActionSheet v-model:show="showAddress">
|
||||
<div class="h-120 flex flex-col ">
|
||||
<div class="text-center">
|
||||
انتخاب آدرس
|
||||
</div>
|
||||
<div class="overflow-y-scroll h-85">
|
||||
<ARadioGroup v-model:value="selectedAddressID">
|
||||
<div class="flex flex-col ">
|
||||
<div class="text-base rounded-lg p-4 m-2 shadow-md font-medium" v-for="item in address">
|
||||
<ARadio :value="item.id">{{ item.province }} / {{ item.city }} / {{ item.address }}</ARadio>
|
||||
</div>
|
||||
</div>
|
||||
</ARadioGroup>
|
||||
</div>
|
||||
<div class="flex gap-2 pt-2">
|
||||
|
||||
<BasicButton class=" " @click="showAddress=false;addAddressVisible=true">افزودن آدرس +</BasicButton>
|
||||
<BasicButton class="w-2/3 " type="primary" @click="handelsubmit">ثبت نهایی</BasicButton>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</BasicActionSheet>
|
||||
<BasicActionSheet v-model:show="addAddressVisible" >
|
||||
<div class=" ">
|
||||
<New_EditAddress @onOk="handleAddress"></New_EditAddress>
|
||||
</div>
|
||||
|
||||
</BasicActionSheet>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import router from '@/router'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BasicSelect from '@/components/BasicPacks/BasicSelect.vue'
|
||||
import {onMounted, ref} from 'vue'
|
||||
import {loading} from '@/utils'
|
||||
import {getProductInventory} from '@/api/products'
|
||||
import type {CountPInventory, PInventory} from '@/models/products'
|
||||
import goyImg from '@/assets/img/goyImg.svg'
|
||||
import mokaabImg from '@/assets/img/mokaabImg.svg'
|
||||
import sekkeImg from '@/assets/img/sekkeImg.svg'
|
||||
import defaultImg from '@/assets/img/defaultAbshodeh.svg'
|
||||
import {usePrice} from '@/utils/usePrice'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import {cloneDeep} from 'lodash'
|
||||
import BasicActionSheet from "@/components/BasicPacks/BasicActionSheet.vue"
|
||||
import {getCity, tableAddress} from "@/api/address"
|
||||
import type {Address} from "@/models/address"
|
||||
import Item from "@/views/base/address/components/Item.vue"
|
||||
import {physicalReceiveApi} from "@/api/physicalreceive"
|
||||
import {message} from "ant-design-vue"
|
||||
import {required} from "@/utils/inputRules"
|
||||
import BasicTextArea from "@/components/BasicPacks/BasicTextArea.vue"
|
||||
import New_EditAddress from "@/views/base/address/components/New_EditAddress.vue"
|
||||
|
||||
const items = ref<PInventory[]>()
|
||||
const baseItems = ref<PInventory[]>()
|
||||
const selectedAddressID = ref<number>()
|
||||
const selectedProduct = ref<number>()
|
||||
const productsByWalletId = ref<Array>([])
|
||||
const address = ref<Address>()
|
||||
const selectedProducts = ref<CountPInventory[]>([])
|
||||
const showAddress = ref<boolean>(false)
|
||||
const addAddressVisible = ref<boolean>(false)
|
||||
|
||||
function handleAdd() {
|
||||
console.log(selectedProducts.value)
|
||||
selectedProducts.value?.push({
|
||||
count: 0,
|
||||
product: items.value?.find(x => x.id === selectedProduct.value)
|
||||
})
|
||||
items.value?.splice(items.value?.findIndex(x => x.id === selectedProduct.value), 1)
|
||||
selectedProduct.value = undefined
|
||||
}
|
||||
function handleAddress() {
|
||||
getAddress()
|
||||
addAddressVisible.value = false
|
||||
showAddress.value = true
|
||||
}
|
||||
|
||||
function handleRemove(id: number) {
|
||||
const findItem = baseItems.value?.find(x => x.id === id)
|
||||
console.log(baseItems.value, id)
|
||||
if (findItem) {
|
||||
items.value?.push(findItem)
|
||||
}
|
||||
selectedProducts.value?.splice(selectedProducts.value?.findIndex(x => x.product.id === id), 1)
|
||||
}
|
||||
|
||||
async function initProductWallet() {
|
||||
try {
|
||||
loading.value = true
|
||||
items.value = (await getProductInventory()).rows.filter(x => (x.title !== 'آبشده نقدی' && x.wallet?.gold && x.wallet?.gold > 0))
|
||||
baseItems.value = cloneDeep(items.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handelFirstSubmit() {
|
||||
try {
|
||||
const zeroAmount = selectedProducts.value.map(item => item.count <= 0)
|
||||
if (zeroAmount.includes(true)) {
|
||||
message.error(`لطفاً تعداد درخواستی محصول را وارد کنید.`)
|
||||
}
|
||||
else {
|
||||
showAddress.value = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
async function handelsubmit() {
|
||||
try {
|
||||
loading.value = true
|
||||
productsByWalletId.value = selectedProducts.value.map((val) => {
|
||||
return {
|
||||
wallet_id: val.product.wallet.id,
|
||||
value: val.count
|
||||
}
|
||||
})
|
||||
await physicalReceiveApi({
|
||||
address_id: selectedAddressID.value,
|
||||
wallets: productsByWalletId.value
|
||||
}
|
||||
)
|
||||
await initProductWallet()
|
||||
message.success("درخواست شما با موفقیت ارسال شد")
|
||||
selectedProducts.value = []
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
showAddress.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await initProductWallet()
|
||||
await getAddress()
|
||||
})
|
||||
async function getAddress(){
|
||||
let {rows} = await tableAddress({page: 0, limit: 150})
|
||||
address.value = rows
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.trans{
|
||||
transition: height 1s;
|
||||
}*/
|
||||
</style>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="rounded-lg shadow-md mx-2 bg-gradient-to-l from-primary rounded-lg p-[2px] to-transparent ">
|
||||
<div class="rounded-lg flex flex-col gap-2 bg-white p-2 ">
|
||||
<div class="flex justify-between ">
|
||||
<div class="font-bold">شماره سند: {{ props.item.id }}</div>
|
||||
<div class="font-bold">{{ toJalali(props.item.created_at) }}</div>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
|
||||
<div class="flex flex-col w-full gap-1 ">
|
||||
<div class="w-full flex justify-between" v-for="item in props.item.transaction">
|
||||
<div class="flex items-center gap-1 ">
|
||||
<div class="w-7 h-7 flex justify-center rounded-lg bg-gray-100 ">
|
||||
<img width="30" class="p-1" :src="item.product.group_type=='گوی'?goyImg:mokaabImg">
|
||||
</div>
|
||||
<div>{{ item.title }}</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div>{{ item.gold * -1 }} عدد</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<div class="font-bold">وضعیت:</div>
|
||||
<ATag color="blue" class="!py-1 !px-2 !ml-0">
|
||||
{{ props.item.sts_str }}
|
||||
</ATag>
|
||||
|
||||
</div>
|
||||
<ADivider class="!m-1"></ADivider>
|
||||
<div class="flex flex-col justify-between">
|
||||
<div class="font-bold">آدرس:</div>
|
||||
<div>{{ props.item.address.province }}/{{ props.item.address.city }}/{{ props.item.address.address }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {Physicalreceive} from "@/models/physicalreceive";
|
||||
import {toJalali} from "../../../../utils/useDateTime";
|
||||
import goyImg from "@/assets/img/goyImg.svg"
|
||||
import mokaabImg from "@/assets/img/mokaabImg.svg"
|
||||
|
||||
interface Prop {
|
||||
item: Physicalreceive
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex flex-col gap-4 pt-13 pb-35 px-2">
|
||||
<RequestItem v-for="item in requestItems" :item="item"></RequestItem>
|
||||
</div>
|
||||
<Transition mode="out-in" name="fade">
|
||||
<div
|
||||
class="wrap-fix bottom-0 h-[19vh] bg-[#FBFBFC] shadow-lg rounded-3xl flex justify-center pt-3 z-200"
|
||||
style="box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 26px 11px"
|
||||
@click="openAdd()">
|
||||
<BasicIcon icon="vuesax-linear:add" />
|
||||
<div class="cursor-pointer">افزودن درخواست جدید</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {onMounted, ref} from "vue";
|
||||
import {getPhysicalReceiveList} from "@/api/physicalreceive";
|
||||
import type {Physicalreceive} from "@/models/physicalreceive";
|
||||
import RequestItem from "@/views/base/physicalReceive/components/RequestItem.vue";
|
||||
import BasicIcon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import router from "@/router";
|
||||
|
||||
const requestItems = ref<Physicalreceive[]>([])
|
||||
const openAdd = () => {
|
||||
router.push('physicalReceive/new')
|
||||
}
|
||||
onMounted(async () => {
|
||||
let {rows} = await getPhysicalReceiveList()
|
||||
requestItems.value = rows
|
||||
console.log(rows)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<div style="max-height: calc(100vh - 50px)">
|
||||
<div class="bg-white py-3 px-3 z-100000 text-primary font-bold drop-shadow flex flex-col wrap-fix">
|
||||
<div class="flex">
|
||||
<div @click="router.back()">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1"/>
|
||||
</div>
|
||||
<div v-if="route.name=='list'" class="mr-2">دریافت طلای فیزیکی</div>
|
||||
<div v-else class="mr-2">دریافت طلای فیزیکی-درخواست جدید</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {ref} from "vue";
|
||||
import RequestList from "@/views/base/physicalReceive/components/RequestList.vue";
|
||||
import NewRequest from "@/views/base/physicalReceive/components/NewRequest.vue";
|
||||
import router from "@/router";
|
||||
import BasicIcon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
const activekey=ref(1)
|
||||
const route=useRoute()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.trans{
|
||||
transition: height 1s;
|
||||
}*/
|
||||
</style>
|
||||
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div @click="infoVisible = true" class="shadow mb-2 p-2 rounded-lg">
|
||||
|
||||
<div class="flex justify-between">
|
||||
<div>
|
||||
<div class="font-bold text-base mb-2">{{usePrice(item.target_price) }}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 ">
|
||||
<BasicIcon color="red" icon="vuesax-linear:trash" @click.stop="deleteConfirmVisible = true" class="p-1"/>
|
||||
<BasicIcon color="green" icon="vuesax-linear:edit" @click.stop="emits('edit',item)" class="p-1"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 mt-2">
|
||||
<BasicInfoItem is-line title="جهت قیمت" :value="returnPriceCondition(item.price_condition)"/>
|
||||
|
||||
<BasicInfoItem is-line title="نوع هشدار" :value="returnAction(item.action)"/>
|
||||
</div>
|
||||
<a-divider class="!my-3" />
|
||||
|
||||
<div class="flex justify-between mt-1">
|
||||
<div class="mb-2">{{toJalali(item.created_at)}}</div>
|
||||
<a-switch v-model:checked="isActive" checked-children="فعال" un-checked-children="غیر فعال" @change="changeActive"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- <teleport to="app">-->
|
||||
<DialogVant v-model:show="deleteConfirmVisible" teleport="body" :closeOnClickOverlay="false" :timeOut="-1">
|
||||
<!-- <template v-slot:img>
|
||||
<img :src="registerDelayImage" alt="" class="opacity-80">
|
||||
</template>-->
|
||||
|
||||
<template v-slot:title>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="p-5 text-sm">
|
||||
آیا از حذف هشدار اطمینان دارید؟
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:button>
|
||||
<div class="text-center text-red flex items-center justify-center" @click="deleteItem">
|
||||
<a-spin :spinning="deleteLoading" size="small">
|
||||
تایید
|
||||
</a-spin>
|
||||
</div>
|
||||
<div class="text-center" @click="deleteConfirmVisible = false">
|
||||
انصراف
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</DialogVant>
|
||||
<!-- </teleport>-->
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { usePrice, usePriceWithoutType } from '../../../../utils/usePrice'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import { toJalali, toJalaliNotime, toJalaliOutOfUTC, toTime } from '../../../../utils/useDateTime'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import type { PriceTrigger } from '@/models/PriceTrigger'
|
||||
import BasicInfoItem from '@/components/BasicPacks/BasicInfoItem.vue'
|
||||
import DialogVant from '@/components/DialogVant.vue'
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
import { deletePriceTrigger, updatePriceTrigger } from '@/api/triggerPrice'
|
||||
import { loading } from '@/utils'
|
||||
|
||||
const infoVisible = ref<boolean>(false)
|
||||
|
||||
const isActive = ref<boolean>(false)
|
||||
|
||||
const deleteLoading = ref(false)
|
||||
const deleteConfirmVisible = ref(false)
|
||||
|
||||
interface Prop {
|
||||
item: PriceTrigger
|
||||
}
|
||||
onMounted(()=> isActive.value = props.item.is_active)
|
||||
function changeActive(val: boolean) {
|
||||
console.log(val)
|
||||
try {
|
||||
loading.value = true
|
||||
updatePriceTrigger(props?.item.id, {is_active: val})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
isActive.value = !isActive.value
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function returnPriceCondition(val: string) {
|
||||
switch (val) {
|
||||
case '==': return 'مساوی'
|
||||
case '<': return 'کوچکتر'
|
||||
// case '==': return 'مساوی'
|
||||
}
|
||||
/* if (val === '=='){
|
||||
return 'مساوی'
|
||||
} else if (val === '<'){
|
||||
return 'کوچکتر'
|
||||
}*/
|
||||
}
|
||||
|
||||
async function deleteItem() {
|
||||
try {
|
||||
deleteLoading.value = true
|
||||
await deletePriceTrigger(props.item.id)
|
||||
deleteConfirmVisible.value = false
|
||||
emits('refresh')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
deleteLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function returnAction(val: string) {
|
||||
switch (val) {
|
||||
case 'sms': return 'پیامک'
|
||||
case 'email': return 'ایمیل'
|
||||
case 'notify': return 'نوتیفیکیشن'
|
||||
// case '==': return 'مساوی'
|
||||
}
|
||||
/* if (val === '=='){
|
||||
return 'مساوی'
|
||||
} else if (val === '<'){
|
||||
return 'کوچکتر'
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const emits = defineEmits(['edit','refresh'])
|
||||
|
||||
const isUp = computed(() => props.item.type === 3 || props.item.type === 1 || props.item.type === 8)
|
||||
const isGold = computed(() => props.item.type === 1 || props.item.type === 2 || props.item.type === 10)
|
||||
/*const title = computed(() => {
|
||||
if (isUp.value) {
|
||||
if (isGold.value) {
|
||||
return 'واریز ریالی'
|
||||
} else {
|
||||
return 'خرید طلا'
|
||||
}
|
||||
} else {
|
||||
if (isGold.value) {
|
||||
return 'برداشت ریالی'
|
||||
} else {
|
||||
return 'فروش طلا'
|
||||
}
|
||||
}
|
||||
})*/
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-white py-3 px-3 text-primary font-bold drop-shadow wrap-fix flex z-10">
|
||||
<div @click="router.back()">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1" />
|
||||
</div>
|
||||
<div class="mr-2">هشدارهای فعلی</div>
|
||||
</div>
|
||||
<!-- <a-spin :spinning="loading">-->
|
||||
<div ref="el" :class="loading? 'h-screen': ''" class="px-3 pt-16 pb-2 overflow-y-scroll"
|
||||
style="max-height: calc(100vh - 50px)">
|
||||
|
||||
<list-anim v-if="!loading" class="pb-12vh">
|
||||
<Item v-for="item in items" :key="item.id" :item="item" @edit="openEdit" @refresh="initItems" />
|
||||
<!-- <TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />-->
|
||||
</list-anim>
|
||||
<div v-if="loading">
|
||||
<TransactionSkeleton v-for="i in 13" :key="i" class="mt-1" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- </a-spin>-->
|
||||
<BasicActionSheet v-model:show="addTriggerVisible" teleport="body">
|
||||
<a-form ref="formRef" :model="form" class="!mt-5" name="basic"
|
||||
@finish="ok()">
|
||||
<div class="flex flex-col gap-4 pb-12 w-full">
|
||||
<div class="font-bold text-lg">هشدار قیمت</div>
|
||||
<a-form-item :rules="[required()]" class="home_appear_fade_in_down" label="جهت قیمت" name="price_condition">
|
||||
<BasicSelect :items="typeItems" v-model:value="form.price_condition" :show-search="false" value-name="value"
|
||||
key-name="key"
|
||||
placeholder="انتخاب نوع جهت قیمت"
|
||||
size="large"></BasicSelect>
|
||||
</a-form-item>
|
||||
<a-form-item :rules="[required()]" class="home_appear_fade_in_down" label="قیمت" name="target_price">
|
||||
<BasicInput v-model:value="form.target_price" place-holder="وارد کردن قیمت" type="price" size="large"
|
||||
addon-before="ریال" />
|
||||
</a-form-item>
|
||||
<a-form-item :rules="[required()]" class="home_appear_fade_in_down" name="action"
|
||||
label="نوع هشدار را انتخاب کنید">
|
||||
<a-radio-group v-model:value="form.action">
|
||||
<a-radio :style="radioStyle" value="sms">ارسال پیامک</a-radio>
|
||||
<a-radio :style="radioStyle" value="email">ارسال ایمیل</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-spin :spinning="loading">
|
||||
<BasicButton class="w-full" type="primary" html-type="submit">
|
||||
{{ editId ? 'ویرایش هشدار' : 'ثبت هشدار' }}
|
||||
</BasicButton>
|
||||
</a-spin>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form>
|
||||
</BasicActionSheet>
|
||||
<!-- <div class="bg-primary w-3rem h-3rem flex items-center justify-center rounded-lg fixed bottom-12vh left-8vw"
|
||||
@click="openAdd()">
|
||||
<BasicIcon icon="vuesax-linear:add" color="white" />
|
||||
</div>-->
|
||||
<Transition mode="out-in" name="fade">
|
||||
<div
|
||||
class="wrap-fix bottom-0 h-[16vh] bg-[#FBFBFC] shadow-lg rounded-3xl flex justify-center pt-3 z-200"
|
||||
style="box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 26px 11px"
|
||||
@click="openAdd()">
|
||||
<BasicIcon icon="vuesax-linear:add" />
|
||||
<div>افزودن هشدار جدید</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { createPriceTrigger, getPriceTriggers, updatePriceTrigger } from '@/api/triggerPrice'
|
||||
|
||||
const radioStyle = reactive({
|
||||
display: '',
|
||||
height: '30px',
|
||||
lineHeight: '30px'
|
||||
})
|
||||
import type { SelectItem } from '@/models/SelectItem'
|
||||
|
||||
// import Item from "./components/Item.vue";
|
||||
/*import {lengthValidation, required} from "@/utils/inputRules";
|
||||
import {loading} from "@/utils";
|
||||
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
|
||||
import BasicActionSheet from "@/components/BasicPacks/BasicActionSheet.vue";
|
||||
import BasicInput from "@/components/BasicPacks/BasicInput.vue";*/
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import type { TableEngineInput, TableOutput } from '@/models/table'
|
||||
import { loading, loadingMore } from '@/utils'
|
||||
// import {getOrders} from "@/api/order";
|
||||
import { getTransactionTable } from '@/api/transaction'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue'
|
||||
import { useInfiniteScroll, useScroll } from '@vueuse/core'
|
||||
import ListAnim from '@/components/ListAnim.vue'
|
||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
import { mobileValidation, required } from '@/utils/inputRules'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { User } from '@/models/login'
|
||||
import { type FormInstance, message } from 'ant-design-vue'
|
||||
import type { PriceTrigger } from '@/models/PriceTrigger'
|
||||
import BasicSelect from '@/components/BasicPacks/BasicSelect.vue'
|
||||
import Item from './components/Item.vue'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import router from '@/router'
|
||||
|
||||
const items = ref<PriceTrigger[]>([])
|
||||
const addTriggerVisible = ref<boolean>(false)
|
||||
const editId = ref<number | undefined>(undefined)
|
||||
const el = ref()
|
||||
|
||||
const form = ref<PriceTrigger>({
|
||||
price_condition: '',
|
||||
is_active: true,
|
||||
action: '',
|
||||
target_price: ''
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
onMounted(() => {
|
||||
initItems()
|
||||
})
|
||||
|
||||
function resetFields() {
|
||||
form.value = {
|
||||
price_condition: '',
|
||||
is_active: true,
|
||||
action: '',
|
||||
target_price: ''
|
||||
}
|
||||
}
|
||||
|
||||
function openAdd() {
|
||||
resetFields()
|
||||
editId.value = undefined
|
||||
addTriggerVisible.value = true
|
||||
}
|
||||
|
||||
async function initItems() {
|
||||
try {
|
||||
items.value = []
|
||||
items.value = await getPriceTriggers()
|
||||
// console.log(items.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function openEdit(val: PriceTrigger) {
|
||||
form.value = cloneDeep(val)
|
||||
editId.value = form.value.id
|
||||
addTriggerVisible.value = true
|
||||
}
|
||||
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
editId.value ? await updatePriceTrigger(editId.value, form.value) : await createPriceTrigger(form.value)
|
||||
message.success('هشدار با موفقیت ایجاد شد')
|
||||
await initItems()
|
||||
addTriggerVisible.value = false
|
||||
//
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const typeItems: SelectItem[] = [
|
||||
{
|
||||
value: 'بزرگتر',
|
||||
key: '>'
|
||||
},
|
||||
{
|
||||
value: 'کوچکتر',
|
||||
key: '<'
|
||||
},
|
||||
{
|
||||
value: 'مساوی',
|
||||
key: '=='
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,721 @@
|
||||
<template>
|
||||
<div class="h-35rem overflow-y-auto">
|
||||
<div class=" !overflow-y-scroll bg-white py-3 text-primary font-bold flex justify-evenly">
|
||||
<!-- <div @click="isBuy = false" class="w-full text-center" :class="!isBuy?'text-primary':'text-gray-400'">خرید طلا</div>
|
||||
<div @click="isBuy = true" class="w-full text-center" :class="isBuy?'text-primary':'text-gray-400'">فروش طلا</div>-->
|
||||
<div class="flex justify-evenly w-full px-2 h-11 items-center bg-gray-50 relative rounded ">
|
||||
<div :class="isBuy?'text-secondary':'text-gray-400'" class="w-full text-center z-2"
|
||||
@click.stop="setIsBuy(true) "
|
||||
:style="!props?.ProductItem?.open_buy ? 'pointer-events: none; opacity: 0.5;' : ''">
|
||||
خرید {{ props?.ProductItem?.title }}
|
||||
</div>
|
||||
<div :class="!isBuy?'text-secondary':'text-gray-400'" class="w-full text-center z-2"
|
||||
@click.stop="setIsBuy(false) "
|
||||
:style="!props?.ProductItem?.open_sell ? 'pointer-events: none; opacity: 0.5;' : ''"
|
||||
>
|
||||
فروش {{ props?.ProductItem?.title }}
|
||||
</div>
|
||||
<!-- <div ref="bganim" class="absolute bg-white h-8 w-1/2 rounded-lg " :style="`transform: translateX(${isbuy? '0':'-100%'}); left: ${isbuy? '0':'100%'}`"></div>-->
|
||||
<div ref="bganim" :style="useStyle()"
|
||||
class="absolute bg-white h-8 w-1/2 rounded-lg animate right"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="userStore" class=" mt-5 pb-2 mb-19vh">
|
||||
<!-- <a-spin :spinning="loading">-->
|
||||
<div v-if="!loading" :class="!isBuy? ' bg-red-100' : ' bg-green-100'"
|
||||
class="w-full relative rounded-lg h-[88px] flex flex-col justify-center background-color-transition">
|
||||
<img :src="img1" alt="" class="h-[88px] absolute">
|
||||
<div class="w-full items-center flex flex-col">
|
||||
<div class="text-gray-700 font-bold">{{ !isBuy ? 'قیمت فروش' : 'قیمت خرید' }}</div>
|
||||
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
|
||||
<div :class="!isBuy? 'text-red-700' : 'text-green-700'" class="font-bold text-2xl color-transition">
|
||||
{{ usePriceWithoutType(isBuy ? ((props?.ProductItem?.price ?? 0) + (props?.ProductItem?.cash_fee_buy ?? 0)) : ((props?.ProductItem?.price ?? 0) - (props?.ProductItem?.cash_fee_sell ?? 0))) }}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="w-full h-[88px]">
|
||||
<GoldSkeleton class="w-full" />
|
||||
</div>
|
||||
<div v-if="limitedPrice !== undefined && userStore?.userInfo.trade_active !== 1"
|
||||
class="text-red text-xs flex gap-1 items-center justify-center my-2">
|
||||
<Icon icon="vuesax-linear:info-circle" size="16" />
|
||||
حداقل مبلغ اولیه برای ثبت سفارش {{ usePriceWithoutType(limitedPrice.value as number ?? 0) }} ریال می باشد.
|
||||
</div>
|
||||
<!-- </a-spin>-->
|
||||
<a-form ref="refInput" :model="form" class="!mt-5" name="basic" @finish="okConfirm()">
|
||||
<div class="border-gray-200 border-1 rounded-xl p-5 relative">
|
||||
<bg_main />
|
||||
<div class="z-100 relative">
|
||||
<a-form-item name="method" :rules="[required()]">
|
||||
<BasicSelect v-model:value="form.method" :items="typeDeal"
|
||||
key-name="key"
|
||||
:show-search="false"
|
||||
value-name="value"
|
||||
:allow-clear="false"
|
||||
:placeholder="isBuy?'نحوه خرید را انتخاب کنید':' نحوه فروش را انتخاب کنید'"
|
||||
size="large"
|
||||
:has-tooltip="false" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="isBuy" name="goldValue"
|
||||
:rules="[justNumber2(props?.ProductItem?.price , form.method , props?.ProductItem?.amount, true)]">
|
||||
<BasicInput v-model:value="form.goldValue" addon-before="تعداد" addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="تعداد"
|
||||
size="large" type="number" inputmode="number" @onchange="calculateCash" />
|
||||
</a-form-item>
|
||||
<a-form-item v-else name="goldValue"
|
||||
:rules="[justNumber3(props?.ProductItem?.sellPrice, productNum ,false)]">
|
||||
<BasicInput v-model:value="form.goldValue" addon-before="تعداد" addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="تعداد"
|
||||
size="large" type="number" inputmode="number" @onchange="calculateCash" />
|
||||
</a-form-item>
|
||||
|
||||
<div class="flex justify-between">
|
||||
<div> قیمت کل</div>
|
||||
<div>{{ usePrice(form.goldCash ?? 0) }}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="props?.ProductItem?.group_type !== 'سکه'" class="flex justify-between">
|
||||
<div> وزن کل</div>
|
||||
<div>{{ form.goldVazn ?? 0 }} گرم</div>
|
||||
</div>
|
||||
|
||||
<!-- {{walletStore?.walletInfo?.gold}}-->
|
||||
<Transition mode="out-in" name="fade" class="mt-2">
|
||||
<div v-if="isBuy&&form.method=='gold'" class="font-bold text-xs">
|
||||
<div> {{ `موجودی کیف طلا: ${walletStore?.walletInfo?.gold ?? 0} گرم` }}</div>
|
||||
</div>
|
||||
<div v-else-if="isBuy" class="font-bold text-xs">
|
||||
{{ `موجودی کیف پول: ${usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)} ریال` }}
|
||||
</div>
|
||||
<div class="font-bold text-xs" v-else>{{ `موجودی محصول: ${getInventoryById(props?.ProductItem?.id)}` }}
|
||||
</div>
|
||||
</Transition>
|
||||
<Transition mode="out-in" name="fade">
|
||||
<div v-if="priceErrorVisible" class="flex gap-1 items-center text-xs mt-[-15px] text-orange-600">
|
||||
<BasicIcon icon="vuesax-linear:danger" />
|
||||
ارزش کل وارد شده بر حسب گرم طلا محاسبه خواهد شد و قیمت وارد شده معادل {{ usePrice(finalPrice) }} می
|
||||
باشد!
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
<GoldLoading v-model:show="infoVisible" title="" />
|
||||
<a-form-item>
|
||||
<BasicButton
|
||||
v-if="walletStore"
|
||||
:disabled="disableTransaction"
|
||||
class=" w-full py-2 mt-5"
|
||||
html-type="submit"
|
||||
type="primary"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>{{ !isBuy ? 'فروش' : 'خرید' }}</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<!-- <div class=" w-full !z-100 px-6 rounded-xl py-1 border-1 bg-white mt-2">
|
||||
<!– <BasicInfoItem is-line title="کارمزد" :value="parseFloat(((form.goldValue?? 0)*0.005).toFixed(3))" />–>
|
||||
<!– <BasicInfoItem is-line title="کارمزد" :value="parseFloat(((form.goldValue?? 0)*0.005).toFixed(3))" />–>
|
||||
<div class="flex justify-between items-center">
|
||||
<div>کارمزد:</div>
|
||||
<div class="flex gap-2 items-center">
|
||||
<!– <div class="line-through">{{ parseFloat(((form.goldValue ?? 0) * 0.005).toFixed(3)) }}</div>–>
|
||||
<!– <div>{{props.ProductItem.price}}</div>–>
|
||||
<div v-if="isBuy && form.method=='cash' " class="">{{
|
||||
usePriceWithoutType(buyFee ?? 0)
|
||||
}}
|
||||
</div>
|
||||
<div v-if="isBuy && form.method!='cash'" class="">{{
|
||||
buyFeeGeram ?? 0
|
||||
}}
|
||||
</div>
|
||||
<div v-if="!isBuy && form.method=='cash' " class="">{{
|
||||
usePriceWithoutType(sellFee ?? 0)
|
||||
}}
|
||||
</div>
|
||||
<div v-if="!isBuy && form.method!='cash'" class="">{{
|
||||
sellFeeGeram ?? 0
|
||||
}}
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
{{ form.method == "cash" ? "ریال" : "گرم" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- <div v-if="!isBuy && form.goldValue > walletStore?.walletInfo?.gold"
|
||||
class="text-red-700 text-xs font-bold mt-2">
|
||||
مقدار گرم طلای وارد شده جهت فروش ({{ form.goldValue }}گرم) بیشتر از مقدار موجودی شما
|
||||
({{ walletStore?.walletInfo?.gold }}گرم) می باشد.
|
||||
</div>
|
||||
<!– <div>{{form?.goldValue? true: false}}</div>–>
|
||||
<div v-if="isBuy? ((form?.goldValue || form.goldValue === 0)? form?.goldCash < 500000: false) : false"
|
||||
class="text-red-700 text-xs font-bold mt-2">
|
||||
حداقل مقدار طلا جهت خرید 500,000 ریال می باشد.
|
||||
</div>-->
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
<van-dialog v-model:show="noCompleteVisible" class="completeButtonStyle" confirm-button-text="تکمیل اطلاعات"
|
||||
show-confirm-button @confirm="router.push('user')">
|
||||
<div class="flex flex-col items-center p-2">
|
||||
<BasicIcon class="home_appear_fade_in_up text-center" color="orange"
|
||||
icon="vuesax-linear:info-circle"
|
||||
size="50" />
|
||||
<!-- <div class="home_appear_fade_in_up delay-100">به روز رسانی</div>-->
|
||||
<div class="home_appear_fade_in_up mt-2 text-justify text-center">برای ثبت سفارش، لطفا اطلاعات خود را تکمیل کنید
|
||||
یا در صورت تکمیل اطلاعات، منتظر تایید اطلاعات خود بمانید.
|
||||
</div>
|
||||
</div>
|
||||
</van-dialog>
|
||||
</div>
|
||||
<BasicActionSheet v-model:show="confirmAction">
|
||||
<div class="font-bold text-lg"></div>
|
||||
<div class="w-full rounded-lg bg-gray-50 p-3">
|
||||
<div class="flex justify-between ">
|
||||
<div>تعداد:</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">{{ form.goldValue }}</div>
|
||||
<div class="text-xs mr-1"> عدد</div>
|
||||
<div class="text-base font-bold mr-1"> عدد {{ props?.ProductItem?.title }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>قیمت:</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">
|
||||
{{ usePriceWithoutType(isBuy ? props?.ProductItem.price ?? 0 : props?.ProductItem?.sellPrice ?? 0) }}
|
||||
</div>
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>کارمزد:</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div v-if="isBuy" class="">{{
|
||||
buyFee
|
||||
}}
|
||||
</div>
|
||||
<!-- <div class="font-bold line-through">{{ 0 }}</div>-->
|
||||
<div v-else class="">{{
|
||||
sellFee
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>{{ isBuy ? 'قیمت قابل پرداخت:' : 'مبلغ دریافتی:' }}</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">{{ usePriceWithoutType(payablePrice.toFixed(0)) }}</div>
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<BasicButton class="mb-20 mt-5 w-full" type="primary" @click="ok(); confirmAction= false">ثبت نهایی</BasicButton>
|
||||
</BasicActionSheet>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import img1 from '@/assets/img/home_ly2.svg'
|
||||
import {useFormat, usePrice, usePriceWithoutType, useTowDecimal} from '@/utils/usePrice'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { Gold } from '@/models/gold'
|
||||
import { loading, loadingMore, toFixedDownThreeChar } from '@/utils'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import router from '@/router'
|
||||
import { useWalletStore } from '@/store/walletStore'
|
||||
import { createOrder } from '@/api/order'
|
||||
import { FormInstance, message } from 'ant-design-vue'
|
||||
import type { Price } from '@/models/home'
|
||||
// import {getLastPrice} from '@/api/home'
|
||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import { justNumber, justNumber2, justNumber3, required, ruleNumber } from '@/utils/inputRules'
|
||||
import GoldSkeleton from '@/views/base/gold/components/GoldSkeleton.vue'
|
||||
import GoldLoading from '@/components/GoldLoading.vue'
|
||||
// import {update} from 'lodash'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import type { TableEngineInput, TableOutput } from '@/models/table'
|
||||
import { useInfiniteScroll } from '@vueuse/core'
|
||||
import { getTransactionTable } from '@/api/transaction'
|
||||
import { getLastPrices, lastPrice, setIntervalGetAllPrice, stopPriceInterval } from '@/utils/price'
|
||||
import { Product } from '@/models/products'
|
||||
import BasicSelect from '@/components/BasicPacks/BasicSelect.vue'
|
||||
import { SelectItem } from '@/models/SelectItem'
|
||||
import Bg_main from '@/components/bg_main.vue'
|
||||
import { useFundUserStore } from '@/store/fundStore'
|
||||
// import Bg_main from "@/components/bg_main.vue";
|
||||
const typeDeal: SelectItem[] = [
|
||||
{
|
||||
value: 'نقدی',
|
||||
key: 'cash'
|
||||
},
|
||||
{
|
||||
value: ' طلایی',
|
||||
key: 'gold'
|
||||
}
|
||||
|
||||
]
|
||||
const infoVisible = ref(false)
|
||||
const walletStore = useWalletStore()
|
||||
const userStore = useUserStore()
|
||||
const confirmAction = ref<boolean>(false)
|
||||
const noCompleteVisible = ref<boolean>(false)
|
||||
const buyItems = ref<Transaction[]>([])
|
||||
const sellItems = ref<Transaction[]>([])
|
||||
const priceErrorVisible = ref<boolean>(false)
|
||||
const buyTableOutput = ref<TableOutput<Transaction> | null>(null)
|
||||
const sellTableOutput = ref<TableOutput<Transaction> | null>(null)
|
||||
const fundStore = useFundUserStore()
|
||||
const refInput = ref<FormInstance>()
|
||||
const el = ref()
|
||||
|
||||
interface Prop {
|
||||
ProductItem?: Product
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const isBuy = ref<boolean>(true)
|
||||
const buyFee = computed(() => ((props?.ProductItem?.amount * (props?.ProductItem?.percent_fee_buy ?? 0) * (props?.ProductItem?.price ?? 0)).toFixed(0)))
|
||||
const sellFee = computed(() => ((props?.ProductItem?.amount * (props?.ProductItem?.percent_fee_sell ?? 0) * (props?.ProductItem?.sellPrice ?? 0)).toFixed(0)))
|
||||
const sellFeeGeram = computed(() => {
|
||||
if (form.value.goldVazn)
|
||||
return (form.value.goldVazn * props.ProductItem?.percent_fee_sell).toFixed(3)
|
||||
|
||||
})
|
||||
const buyFeeGeram = computed(() => {
|
||||
if (form.value.goldVazn)
|
||||
return (form.value.goldVazn * props.ProductItem?.percent_fee_buy).toFixed(3)
|
||||
})
|
||||
const buyPagination = ref<TableEngineInput>({
|
||||
filters: [{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 1
|
||||
}], limit: 6, page: 0
|
||||
})
|
||||
const sellPagination = ref<TableEngineInput>({
|
||||
filters: [{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 2
|
||||
}], limit: 6, page: 0
|
||||
})
|
||||
|
||||
const finalPrice = computed(() => (form.value?.goldValue * (isBuy.value ? props.ProductItem?.price ?? 0 : props.ProductItem?.sellPrice ?? 0)))
|
||||
// const payablePrice = computed(() => finalPrice.value + finalPrice.value * 0.007)
|
||||
const payablePrice = computed(() => finalPrice.value)
|
||||
|
||||
const disableTransaction = computed(() =>
|
||||
loading.value ||
|
||||
form.value?.goldValue === undefined ||
|
||||
form.value?.goldValue === '' ||
|
||||
form.value?.goldCash === '' ||
|
||||
form.value?.goldCash === undefined ||
|
||||
(isBuy.value ? (form.value?.goldCash ?? 0) < 500000 : (form.value?.goldValue ?? 0) < 0.001) ||
|
||||
// (!isBuy.value && form.value.goldValue > walletStore?.walletInfo?.gold) ||
|
||||
price.value?.buy === undefined)
|
||||
|
||||
function refreshTable() {
|
||||
sellItems.value = []
|
||||
buyItems.value = []
|
||||
sellPagination.value = {
|
||||
filters: [{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 2
|
||||
}], limit: 6, page: 0
|
||||
}
|
||||
buyPagination.value = {
|
||||
filters: [{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 1
|
||||
}], limit: 6, page: 0
|
||||
}
|
||||
/* initSellTable()
|
||||
initBuyTable()*/
|
||||
}
|
||||
|
||||
|
||||
async function initBuyTable() {
|
||||
try {
|
||||
buyPagination.value.page === 0 ? loading.value = true : loadingMore.value = true
|
||||
buyTableOutput.value = await getTransactionTable(buyPagination.value)
|
||||
buyItems.value.push(...buyTableOutput.value.rows)
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initSellTable() {
|
||||
try {
|
||||
sellPagination.value.page === 0 ? loading.value = true : loadingMore.value = true
|
||||
sellTableOutput.value = await getTransactionTable(sellPagination.value)
|
||||
sellItems.value.push(...sellTableOutput.value.rows)
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// if (!userStore.isSingle) {
|
||||
/*useInfiniteScroll(
|
||||
el,
|
||||
async () => {
|
||||
// load more
|
||||
// console.log('salamss')
|
||||
if (!userStore.isSingle) {
|
||||
if (isbuy.value) {
|
||||
// console.log((buyeTableOutput.value.query.page))
|
||||
// console.log(buyeTableOutput.value.query.total)
|
||||
// console.log((buyeTableOutput.value.query.page + 1) * buyPagination.value.limit < buyeTableOutput.value.query.total)
|
||||
if (
|
||||
buyeTableOutput.value &&
|
||||
(buyPagination.value.page + 1) * buyPagination.value.limit < buyeTableOutput.value.query.total
|
||||
) {
|
||||
// console.log('gfgf')
|
||||
buyPagination.value.page++
|
||||
await initbuyTable()
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
sellTableOutput.value &&
|
||||
(sellPagination.value.page + 1) * sellPagination.value.limit < sellTableOutput.value.query.total
|
||||
) {
|
||||
// console.log('gfgf')
|
||||
sellPagination.value.page++
|
||||
await initsellTable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{distance: 12}
|
||||
)*/
|
||||
// }
|
||||
|
||||
onMounted(async () => {
|
||||
switch (router.currentRoute.value.query.state) {
|
||||
case 'sell':
|
||||
isBuy.value = false
|
||||
break
|
||||
case 'buy':
|
||||
isBuy.value = true
|
||||
break
|
||||
}
|
||||
/* await initSellTable()
|
||||
await initBuyTable()*/
|
||||
})
|
||||
|
||||
const form = ref<Gold>({
|
||||
goldCash: undefined,
|
||||
goldValue: undefined,
|
||||
percentWallet: undefined,
|
||||
method: 'cash',
|
||||
goldVazn:undefined
|
||||
})
|
||||
const allowedAsciiCodeFloat = [46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
|
||||
// const allowedAsciiCodeInt = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57]
|
||||
watch(form.value, () => {
|
||||
if (form.value.goldValue) {
|
||||
form.value.goldValue = parseFloat(form.value.goldValue)
|
||||
const lastCharGoldStr: string = form.value.goldValue.toString()
|
||||
if (!allowedAsciiCodeFloat.includes(lastCharGoldStr.slice(-1).charCodeAt(0))) {
|
||||
calculateCash(form.value.goldValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
console.log(userStore.userInfo?.is_legal === 2)
|
||||
if (userStore.userInfo?.is_legal === 0) {
|
||||
noCompleteVisible.value = true
|
||||
}
|
||||
})
|
||||
const productNum = ref<number>(0)
|
||||
const getInventoryById = (id: number) => {
|
||||
|
||||
userStore?.productWallet?.forEach((val) => {
|
||||
if (val.product_id == id)
|
||||
productNum.value = val.gold
|
||||
})
|
||||
return productNum.value ?? 0
|
||||
}
|
||||
|
||||
/*function percentChange(val: number) {
|
||||
if (val !== 0)
|
||||
if (isBuy.value) {
|
||||
form.value.goldCash = unitCashCalculator.value * val
|
||||
calculateGold(form.value.goldCash)
|
||||
calculateCash(form.value.goldValue)
|
||||
} else {
|
||||
// console.log((unitGoldCalculator.value * val).toFixed(2))
|
||||
// form.value.goldValue = parseFloat((unitGoldCalculator.value * val).toFixed(2))
|
||||
form.value.goldValue = toFixedDownThreeChar(parseFloat(unitGoldCalculator.value * val))
|
||||
calculateCash(form.value.goldValue)
|
||||
}
|
||||
else {
|
||||
form.value.goldValue = undefined
|
||||
form.value.goldCash = undefined
|
||||
}
|
||||
}*/
|
||||
|
||||
const unitGoldCalculator = computed(() => {
|
||||
// console.log(walletStore?.walletInfo?.gold / 100)
|
||||
return (walletStore?.walletInfo?.gold ?? 0) / 100
|
||||
})
|
||||
|
||||
const unitCashCalculator = computed(() => {
|
||||
return (walletStore?.walletInfo?.cash ?? 0) / 100
|
||||
})
|
||||
|
||||
const limitedPrice = computed(() => {
|
||||
if (walletStore.limitedPrice)
|
||||
return walletStore?.limitedPrice[0]
|
||||
})
|
||||
|
||||
function calculateCash(val: number) {
|
||||
priceErrorVisible.value = false
|
||||
|
||||
// console.log(val)
|
||||
if (price.value) {
|
||||
form.value.goldVazn = parseFloat((val * (( props?.ProductItem?.price) + (props?.ProductItem?.cash_fee_buy)))/lastPrice.value?.buy).toFixed(1)
|
||||
console.log(val,props?.ProductItem?.price,props?.ProductItem?.cash_fee_buy,lastPrice.value?.buy)
|
||||
if (isBuy.value) {
|
||||
if (val){
|
||||
form.value.goldCash = parseFloat(val * (( props?.ProductItem?.price) + (props?.ProductItem?.cash_fee_buy))).toFixed(0)
|
||||
}
|
||||
else {
|
||||
form.value.goldCash = 0
|
||||
form.value.goldVazn = 0
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (val)
|
||||
form.value.goldCash = parseFloat((val * props?.ProductItem?.price) + (props?.ProductItem?.cash_fee_sell)).toFixed(0)
|
||||
else{
|
||||
form.value.goldCash = 0
|
||||
form.value.goldVazn = 0
|
||||
}
|
||||
}
|
||||
console.log(form.value.goldVazn)
|
||||
}
|
||||
}
|
||||
|
||||
/*function calculateGold(val: number) {
|
||||
// console.log(val)
|
||||
// form.value.goldCash = usePriceWithoutType(form.value.goldCash)
|
||||
if (price.value) {
|
||||
if (isBuy.value) {
|
||||
if (val) {
|
||||
form.value.goldValue = toFixedDownThreeChar(parseFloat(val / price?.value?.buy))
|
||||
if (parseInt(finalPrice.value) > 0) priceErrorVisible.value = true
|
||||
if (parseInt(finalPrice.value) === 0) priceErrorVisible.value = false
|
||||
} else if (val.toString() === '') {
|
||||
form.value.goldValue = undefined
|
||||
priceErrorVisible.value = false
|
||||
} else {
|
||||
form.value.goldValue = 0
|
||||
priceErrorVisible.value = false
|
||||
}
|
||||
} else {
|
||||
if (val) {
|
||||
form.value.goldValue = toFixedDownThreeChar(parseFloat((val / price?.value?.sell)))
|
||||
if (parseInt(finalPrice.value) > 0) priceErrorVisible.value = true
|
||||
if (parseInt(finalPrice.value) === 0) priceErrorVisible.value = false
|
||||
} else if (val.toString() === '') {
|
||||
// console.log('sasasasasasa')
|
||||
form.value.goldValue = undefined
|
||||
priceErrorVisible.value = false
|
||||
} else {
|
||||
form.value.goldValue = 0
|
||||
priceErrorVisible.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/*watch(form.value?.goldValue, (n)=>{
|
||||
console.log('salammmm', n)
|
||||
})*/
|
||||
|
||||
const bganim = ref(null)
|
||||
|
||||
function useStyle() {
|
||||
if (isBuy.value) return 'right: 2%;'
|
||||
// if (isbuy.value) return 'animation-direction: normal'
|
||||
// else return 'animation-direction: reverse'
|
||||
else return ' right: 98%; transform: translate(100%, 0);'
|
||||
}
|
||||
|
||||
|
||||
function setIsBuy(val: boolean) {
|
||||
isBuy.value = val
|
||||
form.value.goldValue = undefined
|
||||
form.value.goldCash = undefined
|
||||
form.value.percentWallet = 0
|
||||
priceErrorVisible.value = false
|
||||
|
||||
// console.log(bganim.value.classList)
|
||||
// bganim?.value?.classList.add(val?'right':'left')
|
||||
// bganim?.value?.style.transform = `translateX(${val ? '0' : '-100'});`
|
||||
// bganim?.value?.style.animationDirection = val? 'normal':'reverse'
|
||||
// val? bganim?.value?.classList?.add("move") : bganim?.value?.classList?.remove("move")
|
||||
// const el = bganim.value?.
|
||||
// el.
|
||||
}
|
||||
|
||||
const formatter = (value: number) => {
|
||||
return `${value}%`
|
||||
}
|
||||
|
||||
|
||||
const price = computed((): Price => <Price>lastPrice.value ?? 0)
|
||||
onMounted(async () => {
|
||||
// await initPrice()
|
||||
// await setIntervalGetPrice()
|
||||
// console.log('okkkkkkkkgold')
|
||||
})
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
// chartLoading.value = true
|
||||
await getLastPrices()
|
||||
// await setIntervalGetPrice()
|
||||
loading.value = true
|
||||
price.value = lastPrice.value
|
||||
props.ProductItem.price = lastPrice.value?.buy * props.ProductItem?.amount
|
||||
props.ProductItem.sellPrice = lastPrice.value?.sell * props.ProductItem?.amount
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
// chartLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// onMounted(() => {
|
||||
// initPrice()
|
||||
// })
|
||||
|
||||
function okConfirm() {
|
||||
confirmAction.value = true
|
||||
refInput.value?.validateFields()
|
||||
}
|
||||
|
||||
async function ok() {
|
||||
try {
|
||||
loading.value = true
|
||||
infoVisible.value = true
|
||||
await createOrder({
|
||||
direction: isBuy.value ? 1 : 2,
|
||||
product_id: props.ProductItem.id,
|
||||
method: form.value.method,
|
||||
number: form.value.goldValue ?? 0
|
||||
})
|
||||
await walletStore.getMyWallet()
|
||||
await router.push({ name: 'transactions' })
|
||||
form.value = {
|
||||
goldValue: undefined,
|
||||
goldCash: undefined,
|
||||
percentWallet: undefined,
|
||||
method: 'cash'
|
||||
}
|
||||
// refreshTable()
|
||||
await fundStore.getMyFund()
|
||||
message.success('سفارش شما با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
// console.log(e)
|
||||
// await initPrice()
|
||||
} finally {
|
||||
loading.value = false
|
||||
infoVisible.value = false
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.completeButtonStyle{
|
||||
background: blue;
|
||||
}*/
|
||||
.completeButtonStyle .van-dialog__confirm .van-button__content {
|
||||
background: #0A1B37;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.left {
|
||||
transform: translateX(0);
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.toggle-transe-parent {
|
||||
animation: ease-in-out infinite alternate swingParent;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
.text-secondary{
|
||||
color: #d3a233 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div class="flex bg-white border-1 border-gray-200 rounded-lg"
|
||||
:class="props.ProductItem.show ? 'bg-white opacity-100' : 'bg-gray-200 opacity-50'">
|
||||
<div class="bg-gray-100 m-2 rounded-lg w-28 h-28 flex justify-center p-2">
|
||||
<img v-if="props.ProductItem.group_type=='گوی'" :src="goyImg">
|
||||
<img v-if="props.ProductItem.group_type=='مکعب'" :src="mokaabImg">
|
||||
<img v-if="props.ProductItem.group_type=='سکه'" :src="sekkeImg">
|
||||
<img v-if="props.ProductItem.group_type=='سکه پارسیان'" :src="parsianImg">
|
||||
<img v-if="props.ProductItem.group_type=='آبشده'|| props.ProductItem.group_type== null" :src="defaultImg">
|
||||
</div>
|
||||
<div class="m-1 flex flex-col gap-1 justify-center">
|
||||
<div class="text-base font-500">{{ props.ProductItem.title }}</div>
|
||||
<br>
|
||||
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class=" font-500">{{ amountProduct}}</div>-->
|
||||
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class="text-secondary font-500">{{ props.ProductItem.amount }}گرم</div>-->
|
||||
<!-- <div v-else class="text-secondary font-500">حداقل خرید یک گرم</div>-->
|
||||
<div>{{usePrice((props.ProductItem.price ?? 0) + (props.ProductItem.cash_fee_buy ?? 0))}}</div>
|
||||
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class="text-xs text-gray-400">شامل 33 هزار تومان اجرت</div>-->
|
||||
<!-- <div v-else class="text-xs text-gray-400">محاسبه بر اساس قیمت روز</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import defaultImg from "@/assets/img/defaultAbshodeh.svg"
|
||||
import goyImg from "@/assets/img/goyImg.svg"
|
||||
import mokaabImg from "@/assets/img/mokaabImg.svg"
|
||||
import sekkeImg from "@/assets/img/sekkeImg.svg"
|
||||
import parsianImg from "@/assets/img/parsianImg.svg"
|
||||
|
||||
import type {Product} from "@/models/products";
|
||||
import {usePrice} from "../../../../utils/usePrice";
|
||||
import {computed, ref} from "vue";
|
||||
|
||||
interface Prop {
|
||||
ProductItem: Product
|
||||
}
|
||||
const amountProduct=computed(()=>{
|
||||
if (0<props.ProductItem.amount && props.ProductItem.amount<1){
|
||||
return `${props.ProductItem.amount*1000}سوت`
|
||||
}else return `${props.ProductItem.amount}گرم`
|
||||
})
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
// const typeOfProduct=(val:string)=>{
|
||||
// if (val.includes('گوی'))
|
||||
// return 'گوی'
|
||||
// if (val.includes('شمش'))
|
||||
// return 'شمش'
|
||||
// if (val.includes('مکعب'))
|
||||
// return 'مکعب'
|
||||
// if (val.includes('24 عیار'))
|
||||
// return '24 عیار'
|
||||
//
|
||||
// return 'آب شده'
|
||||
// }
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<div class="bottom-0 fixed top-0">
|
||||
<img :src="img" alt="" class=" w-inherit "
|
||||
:style="{ backgroundRepeat: 'repeat', }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<a-spin :spinning="loading">
|
||||
<div class=" !h-full overflow-y-scroll">
|
||||
|
||||
<div class="w-full flex justify-center top-0 py-5">
|
||||
<ARadioGroup size="large" @change="changeTab" v-model:value="activekey" button-style="solid">
|
||||
<ARadioButton class="cats" value="همه">همه</ARadioButton>
|
||||
<ARadioButton class="cats" v-for="item in typeItems" :value="item">{{ item }}</ARadioButton>
|
||||
</ARadioGroup>
|
||||
</div>
|
||||
|
||||
<div class="mx-5 pb-30 pt-2" style="color: #1b2b07">
|
||||
<div class="mt-3" v-for="item in items">
|
||||
<ProductItem :ProductItem="item" @click="clickProduct(item)"></ProductItem>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
|
||||
<!-- <BasicActionSheet v-model:show="showFilter">-->
|
||||
<!-- <indexGold ></indexGold>-->
|
||||
<!-- </BasicActionSheet>-->
|
||||
|
||||
<BasicActionSheet placement="bottom" v-model:show="showFilter">
|
||||
<div class="">
|
||||
<indexGold v-if="selectedProduct?.group_type=='آبشده'" :ProductItem="selectedProduct"></indexGold>
|
||||
<DealProduct v-else :ProductItem="selectedProduct"></DealProduct>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
|
||||
<BasicModal
|
||||
v-model:visible="isAfterCloseTime"
|
||||
custom-footer
|
||||
:closable="false"
|
||||
>
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-red-600">مشتریان گرامی</div>
|
||||
<div class="mt-2 leading-relaxed">
|
||||
<p>فروشگاه در حال حاضر بسته است.</p>
|
||||
<p>ساعت کاری فروشگاه از {{ openTime }} تا {{ closeTime }} میباشد.</p>
|
||||
<p>از همراهی و اعتماد شما سپاسگزاریم.🤍</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<a-button type="primary" class="w-full" @click="isAfterCloseTime = false">
|
||||
متوجه شدم
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import router from '@/router'
|
||||
import ProductItem from '@/views/base/products/components/ProductItem.vue'
|
||||
import { getProducts } from '@/api/products'
|
||||
import {
|
||||
getLastPrices,
|
||||
lastPrice,
|
||||
stopPriceInterval
|
||||
} from '@/utils/price'
|
||||
import { loading } from '@/utils'
|
||||
import { Price } from '@/models/home'
|
||||
import type { Product } from '@/models/products'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import indexGold from '@/views/base/gold/index.vue'
|
||||
import DealProduct from '@/views/base/products/components/DealProduct.vue'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import img from "@/assets/img/user_ly1.svg";
|
||||
import BasicModal from "@/components/BasicPacks/BasicModal.vue";
|
||||
const activekey = ref('آبشده')
|
||||
const showFilter = ref()
|
||||
const selectedProduct = ref<Product>()
|
||||
const closeTime = ref<string>('')
|
||||
const openTime = ref<string>('')
|
||||
const isAfterCloseTime = ref<boolean>(false)
|
||||
|
||||
watch([openTime, closeTime], ([open, close]) => {
|
||||
if (!open || !close) return
|
||||
const now = new Date()
|
||||
const currentSeconds = now.getHours() * 3600 + now.getMinutes() * 60 + now.getSeconds()
|
||||
const [oh, om, os] = open.split(':').map(Number)
|
||||
const [ch, cm, cs] = close.split(':').map(Number)
|
||||
const openSeconds = oh * 3600 + om * 60 + os
|
||||
const closeSeconds = ch * 3600 + cm * 60 + cs
|
||||
isAfterCloseTime.value = currentSeconds < openSeconds || currentSeconds > closeSeconds
|
||||
})
|
||||
|
||||
function clickProduct(item: Product) {
|
||||
if(item?.show){
|
||||
showFilter.value = true
|
||||
selectedProduct.value = cloneDeep(item)
|
||||
}
|
||||
}
|
||||
|
||||
function changeTab() {
|
||||
if (activekey.value != 'همه') {
|
||||
items.value = firstItems.value?.filter((val) =>
|
||||
val.group_type == activekey.value
|
||||
)
|
||||
} else items.value = firstItems.value
|
||||
}
|
||||
|
||||
const firstItems = ref<Product[]>()
|
||||
const price = ref<Price>()
|
||||
const items = ref<Product[]>()
|
||||
const typeItems = ref([])
|
||||
onMounted(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
items.value = await getProducts()
|
||||
|
||||
if (items.value?.length) {
|
||||
closeTime.value = items.value[0].auto_close_at
|
||||
openTime.value = items.value[0].auto_open_at
|
||||
}
|
||||
|
||||
items.value?.forEach((val, index) => {
|
||||
if (!typeItems.value.includes(val.group_type)){
|
||||
typeItems.value.push(val.group_type)
|
||||
}
|
||||
// typeItems.value[index] = val.group_type
|
||||
})
|
||||
firstItems.value = items.value
|
||||
await initPrice()
|
||||
// await setIntervalGetLastPrice()
|
||||
// console.log('run product')
|
||||
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
if (router.currentRoute.value.query.cat=="coin"){
|
||||
activekey.value="سکه"
|
||||
changeTab()
|
||||
}
|
||||
|
||||
if (router.currentRoute.value.query.state) {
|
||||
if (router.currentRoute.value.query.product) {
|
||||
clickProduct(items.value?.find(x => x.title === 'سکه'))
|
||||
} else {
|
||||
clickProduct(items.value?.find(x => x.title === 'آبشده نقدی'))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
onUnmounted(() => {
|
||||
stopPriceInterval()
|
||||
// console.log('stop product')
|
||||
|
||||
// console.log('okgold')
|
||||
})
|
||||
// watch(lastPrice, async () => {
|
||||
// // console.log(items);
|
||||
// items.value?.forEach((val) => {
|
||||
// // console.log(lastPrice.value)
|
||||
// if (val.group_type == 'آبشده') {
|
||||
// val.price = lastPrice.value?.price_last
|
||||
// val.sellPrice = lastPrice.value?.sell
|
||||
// } else {
|
||||
// val.price = val.amount * lastPrice.value?.price_last
|
||||
// val.sellPrice = val.amount * lastPrice.value?.sell
|
||||
//
|
||||
// // console.log(lastPrice.value?.price_last + "*" + val.amount + ' ' + val.price)
|
||||
// }
|
||||
//
|
||||
// })
|
||||
// })
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
// chartLoading.value = true
|
||||
await getLastPrices()
|
||||
// await setIntervalGetPrice()
|
||||
loading.value = true
|
||||
price.value = lastPrice.value
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
// chartLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.cats:hover span {
|
||||
--un-text-opacity: 1;
|
||||
color: rgba(206, 163, 76, var(--un-text-opacity))!important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="wrap-fix z-1 bg-white py-3 px-3 text-primary font-bold drop-shadow flex">
|
||||
<div @click="router.back()" class="cursor-pointer">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1" />
|
||||
</div>
|
||||
<div class="mr-2">قوانین و مقررات</div>
|
||||
</div>
|
||||
<div class="pt-20">
|
||||
<div>
|
||||
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0" />
|
||||
</div>
|
||||
<div class="text-justify text-base z-200000 relative">
|
||||
<div class="px-10">
|
||||
<!-- <div class="h-20vh flex justify-center">
|
||||
<img :src="logoFull" class="mb-20 h-15vh mt-5" />
|
||||
</div>-->
|
||||
<div class="overflow-y-auto h-60vh pb-20 border-primary">
|
||||
<div
|
||||
class="mt-5 text-5 border-solid border-2 border-primary text-primary rounded-[12px] p-4"
|
||||
>
|
||||
<div class="font-bold text-sm text-primary">
|
||||
قوانین و مقررات معاملات طلا در بستر گلد دات آی آر
|
||||
</div>
|
||||
<div class="w-full h-1px my-3 bg-secondary"></div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• کاربران موظفند قبل از ثبت نام، تمامی مفاد این تعهدنامه را مطالعه نموده و صرفاً در
|
||||
صورت پذیرش آن اقدام به ثبتنام نمایند.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• کاربران گلد دات آی آر میپذیرند که کلیهی فعالیتهای آنها در گلد دات آی آر، در چارچوب قوانین
|
||||
جمهوری اسلامی ایران بوده و هیچ گونه فعالیتی خارج از این چارچوب انجام نخواهد شد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• احراز هویت برای استفاده از خدمات گلد دات آی آر ضروری بوده و کاربران موظفند اطلاعات صحیح
|
||||
خود را بارگذاری نمایند؛ بدیهی است در صورت وجود هرگونه تخلف در احراز هویت، مسئولیت به
|
||||
عهدهی فرد متخلف بوده و گلد دات آی آر حق توقف ارائه خدمات به کاربر مذکور و ارجاع موارد
|
||||
تخلف به مراجع ذیصلاح را خواهد داشت.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• گلد دات آی آر خود را ملزم به حفظ اطلاعات شخصی کاربران در چارچوب قوانین قضایی کشور
|
||||
میداند.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• کاربران گلد دات آی آر تعهد میدهند که از قرار دادن حساب خود در اختیار دیگران خودداری
|
||||
نمایند. از خدمات سایت، تنها برای حساب شخصی خود استفاده نموده و مسئولیت استفاده از
|
||||
خدمات گلد دات آی آر برای فردی دیگر، به عهده کاربر خواهد بود. شماره حساب اعلام شده به سایت
|
||||
باید متعلق به کاربر بوده و کاربران مجاز به دادن شماره حساب متعلق به اشخاص دیگر
|
||||
نیستند.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• کاربران میپذیرند در صورت تشخیص کارشناسان پشتیبانی، جهت حفظ امنیت دارایی حساب
|
||||
کاربریشان با اطلاع قبلی نسبت به برقراری تماس تصویری با تیم پشتیبان همکاری نمایند.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• هرگونه سهلانگاری کاربران در حفظ اطلاعات شخصی و امنیتی از جمله: رمز عبور کاربر،
|
||||
سرقت گوشی کاربر، سرقت کارت ملی و مدارک شناسایی کاربر، سپردن مدارک شخصی و موبایل به
|
||||
فرد ثالث و ... به عهدهی شخص کاربر بوده و گلد دات آی آر هیچ گونه مسئولیتی در این موارد
|
||||
نخواهد داشت.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• اکیداً توصیه میشود از رمز عبوری پیچیده، امن و همچنین کد شناسایی دو عاملی استفاده
|
||||
شود.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• گلد دات آی آر این اطمینان را میدهد که داراییهای کاربران را نزد خود به امانت و به
|
||||
بهترین شکل و با بالاترین استانداردهای امنیتی ممکن حفظ نماید؛ در صورت بروز هرگونه
|
||||
مشکل امنیتی، گلد دات آی آر متعهد به جبران خسارت خواهد بود.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• به عنوان پلتفرم معاملات برخط فلزات گرانبها، هیچگونه مسئولیتی در قبال تصمیمات
|
||||
اقتصادی فی مابین کاربران و سود و زیان حاصل از آن بر عهده گلد دات آی آر نمیباشد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• گلد دات آی آر حق اصلاح و تغییر قوانین و مقررات ذکر شده در این صفحه را چه به صورت کلی و
|
||||
چه به صورت جزئی دارد و نسخه نهایی را در این صفحه در معرض دید قرار میدهد. استفاده از
|
||||
خدمات گلد دات آی آر پس از اعمال تغییرات، به معنای پذیرش همه تغییرات میباشد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• از لحظه خرید کاربران تا زمان تحویل طلای خریداری شده، مسئولیت حفظ و نگهداری اصل طلا
|
||||
بر عهده گلد دات آی آر میباشد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• کاربران گلد دات آی آر اذعان میدارند که از ریسکهای اقتصادی مربوط به سرمایهگذاری در
|
||||
حوزه طلا مطلع بوده و با علم بر این موضوع اقدام به تبادل و سرمایهگذاری میکنند.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• گلد دات آی آر متعهد میشود در حد توان از حریم شخصی شما محافظت کند و در این راستا،
|
||||
تکنولوژی مورد نیاز در سایت و پلتفرم را برای هر چه مطمئنتر و امنتر شدن استفاده شما،
|
||||
توسعه دهد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• در صورت بروز نوسان شدید در قیمت طلا و هرگونه رویداد برهمزننده نظم حاکم بر بازار
|
||||
طلا، گلد دات آی آر میتواند برای خرید و فروش طلا توسط کاربر سقف تعیین کند تا دو طرف متضرر
|
||||
نشوند.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• گلد دات آی آر مجاز است بدون اطلاع قبلی و به صلاحدید شخصی نسبت به توقف سفارشگیری جدید،
|
||||
معاملات (از جمله سفارشهای باز) را متوقف کند؛ بدیهی است که کلیه سفارشهای تکمیلشده
|
||||
قبل از توقف سفارشگیری، پردازش و تحویل داده خواهد شد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• در صورت بروز هرگونه اختلال در اینترنت و خدمات زیرساخت به دلایل حاکمیتی، هیچگونه
|
||||
مسئولیتی به عهده گلد دات آی آر نمیباشد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• درخواست برداشت ریال از حساب کاربری در سریعترین زمان ممکن پس از ثبت، بررسی خواهد
|
||||
شد. زمان واریز پول به حساب کاربران بر اساس محدودیتهای انتقال وجه بین بانکی، متفاوت
|
||||
خواهد بود. برای اطلاعات بیشتر، به قوانین انتقال وجه بین بانکی (پایا، ساتنا) مراجعه
|
||||
فرمایید.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• کاربر میپذیرد که به جز در موارد مورد تعهد، حق هیچگونه داعیه، طلب و شکایت از
|
||||
سایت، مدیران، کارمندان و افراد مرتبط با این سایت را نخواهد داشت.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• اگر کاربر تحت هر عنوان اشتباهاً یا من غیر حق، وجوهی را به حساب کاربر منظور یا در
|
||||
محاسبات خود هر نوع اشتباهی نماید، گلد دات آی آر هر زمان مجاز و مختار است راساً و مستقلاً و
|
||||
بدون انجام هیچگونه تشریفات اداری و قضایی و دریافت اجازه کتبی از متعهد (صاحب حساب)
|
||||
در رفع اشتباه و برداشت از حسابهای وی اقدام نماید و تشخیص نسبت به وقوع اشتباه یا
|
||||
پرداخت بدون حق و لزوم برداشت از حساب معتبر خواهد بود و کاربر حق هرگونه اعتراض و
|
||||
ادعایی را در خصوص نحوه عملکرد گلد دات آی آر از هر جهت از خود ساقط مینماید.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• در صورت بروز هرگونه مشکل یا ابهام در هر یک از معاملات (مانند دستکاری قیمت، اختلال
|
||||
در وبسرویسها، انجام معامله خارج از دامنه نوسان و ...)، گلد دات آی آر حق دارد مستقلاً آن
|
||||
معامله را ابطال کرده و داراییهای هر یک از طرفین را به حساب خودشان عودت دهد. بدیهی
|
||||
است در صورتی که اشکال از سمت گلد دات آی آر باشد، شرکت موظف خواهد بود که جبران خسارت نماید
|
||||
و در غیر این صورت، کاربر حق هرگونه اعتراض و ادعایی در خصوص نحوه عملکرد از هر جهت را
|
||||
از خود ساقط مینماید.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• در صورت فوت یا حجر کاربر، گلد دات آی آر پیرو قوانین جمهوری اسلامی ایران میباشد. کاربر
|
||||
با علم و اطلاع از مقررات این بند نسبت به افتتاح حساب کاربری در گلد دات آی آر اقدام نموده و
|
||||
کاربر، اشخاص ثالث، ورثه یا قائممقام قانونی ایشان حق اعتراض و یا ادعایی در آینده در
|
||||
این خصوص نخواهند داشت.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• هزینه خدمات و کارمزد تراکنشهای مالی انجام شده در مطابق با توضیحات ارائه شده در
|
||||
صفحه راهنمای استفاده از گلد دات آی آر گلد میباشد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• تمامی علائم تجاری، طرحهای گرافیکی، رابط کاربری، رابط بصری، عکس، لوگو، کدهای
|
||||
نرمافزار، ساختار، نحوه بیان، تنظیم مطالب و محتوای موجود در گلد دات آی آر و شبکههای متعلق
|
||||
به گلد دات آی آر و بهطور کلی، سایر حقوق و امتیازات مربوطه منحصراً در مالکیت گلد دات آی آر
|
||||
میباشد و هیچ شخصی حق استفاده از آن را بدون رضایت گلد دات آی آر ندارد.
|
||||
</div>
|
||||
<div class="mt-5 text-xs leading-5">
|
||||
• اگر هر یک از مفاد این موافقتنامه بر اساس هر قانون لازمالاجرا، نامعتبر یا غیرقابل
|
||||
اجرا تشخیص داده شود، این امر بر اعتبار هیچ ماده دیگری تأثیری نخواهد داشت و بقیه
|
||||
مقررات اجرا میشود.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap-fix bottom-0 px-10 py-6 flex gap-2 bg-white">
|
||||
<a class="w-full" href="tel:09190909884">
|
||||
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
|
||||
</a>
|
||||
<!-- <BasicButton type="primary" @click="$router.push({name: 'permissions'})">
|
||||
<div>مجوز ها</div>
|
||||
</BasicButton>-->
|
||||
<a href="https://t.me/saminn_gold">
|
||||
<img src="@/assets/img/telegram.png" alt="" class="h-10 w-10"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <ActionSheet v-model:show="editPassVisible">salam</ActionSheet>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import img from '@/assets/img/user_ly1.svg'
|
||||
// import gr_bottom from './assets/img/gr_bottom_white.svg'
|
||||
import { loading } from '@/utils'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import { lengthValidation, required } from '@/utils/inputRules'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { User } from '@/models/login'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import router from '@/router'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { updateMe } from '@/api/me'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker'
|
||||
|
||||
const userFormState = ref<User>({
|
||||
fname: '',
|
||||
lname: '',
|
||||
mobile: undefined,
|
||||
birth_date: '',
|
||||
phone_number: '',
|
||||
province: '',
|
||||
city: '',
|
||||
n_code: undefined
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// const editPassVisible = ref<boolean>(false)
|
||||
const editPassVisible = ref<boolean>(false)
|
||||
|
||||
function setForm() {
|
||||
userFormState.value = userStore.userInfo
|
||||
}
|
||||
|
||||
function copyCode() {
|
||||
// nextTick(() => {
|
||||
const val = userStore.userInfo?.referral_id
|
||||
navigator.clipboard.writeText(val)
|
||||
message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
function shareCode() {
|
||||
// nextTick(() => {
|
||||
const val = `⭐️الان طلا بخر؛ آخر ماه سودشو ببر!
|
||||
با خرید طلای آبشده در مقدارهای کم ولی مستمر، سود بیشتری ببر!
|
||||
|
||||
این دعوت نامه از طرف "${userStore.userInfo?.name}" عزیز برای شما ارسال شده تا شما هم از بازار طلای گلد داتت آی آر جا نمونید.
|
||||
روی لینک زیر کلیک کنید و ثبت نام خود را تکمیل کنید.
|
||||
|
||||
gold.ir/login?id=${userStore.userInfo?.referral_id}`
|
||||
navigator.share({
|
||||
title: ' گلد',
|
||||
text: val
|
||||
})
|
||||
// message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
userFormState.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
mobile: undefined,
|
||||
birth_date: '',
|
||||
phone_number: '',
|
||||
province: '',
|
||||
city: '',
|
||||
n_code: undefined
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setForm()
|
||||
})
|
||||
|
||||
function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await updateMe(userFormState.value)
|
||||
await userStore.getMyInfo()
|
||||
editPassVisible.value = false
|
||||
message.success('اطلاعات شما با موفقیت به روز رسانی شد')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.trans{
|
||||
transition: height 1s;
|
||||
}*/
|
||||
</style>
|
||||
@@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div class="bg-white wra-fix z-1 py-3 px-3 text-primary font-bold drop-shadow flex">
|
||||
<div @click="router.back()" class="cursor-pointer">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1" />
|
||||
</div>
|
||||
<div class="mr-2">مجوز ها</div>
|
||||
</div>
|
||||
<div class="pt-20">
|
||||
<div class="">
|
||||
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0">
|
||||
</div>
|
||||
<div class="px-1 text-justify text-base z-200000 relative">
|
||||
<div>
|
||||
<!-- <img :src="logoFull" class="mb-20 mt-5 px-10" />-->
|
||||
<div class="overflow-y-auto h-65vh pb-20 border-primary">
|
||||
<div class=" font-bold text-sm text-primary text-center">جواز کسب و کار</div>
|
||||
<!-- <img :src="permission1" alt="" class="w-full">-->
|
||||
<div class="mt-5 text-xs"></div>
|
||||
<div class="wrap-fix bottom-0 px-2 py-6 flex gap-2 bg-white">
|
||||
<a class="w-full" href="tel:09190909884">
|
||||
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
|
||||
</a>
|
||||
<a href="https://t.me/saminn_gold">
|
||||
<img src="@/assets/img/telegram.png" alt="" class="h-10 w-10"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<!-- <ActionSheet v-model:show="editPassVisible">salam</ActionSheet>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import img from '@/assets/img/user_ly1.svg'
|
||||
// import gr_bottom from './assets/img/gr_bottom_white.svg'
|
||||
import { loading } from '@/utils'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import { lengthValidation, required } from '@/utils/inputRules'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { User } from '@/models/login'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import router from '@/router'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { updateMe } from '@/api/me'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker'
|
||||
|
||||
const userFormState = ref<User>({
|
||||
fname: '',
|
||||
lname: '',
|
||||
mobile: undefined,
|
||||
birth_date: '',
|
||||
phone_number: '',
|
||||
province: '',
|
||||
city: '',
|
||||
n_code: undefined
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// const editPassVisible = ref<boolean>(false)
|
||||
const editPassVisible = ref<boolean>(false)
|
||||
|
||||
function setForm() {
|
||||
userFormState.value = userStore.userInfo
|
||||
}
|
||||
|
||||
function copyCode() {
|
||||
// nextTick(() => {
|
||||
const val = userStore.userInfo?.referral_id
|
||||
navigator.clipboard.writeText(val)
|
||||
message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
function shareCode() {
|
||||
// nextTick(() => {
|
||||
const val = `⭐️الان طلا بخر؛ آخر ماه سودشو ببر!
|
||||
با خرید طلای آبشده در مقدارهای کم ولی مستمر، سود بیشتری ببر!
|
||||
|
||||
این دعوت نامه از طرف "${userStore.userInfo?.name}" عزیز برای شما ارسال شده تا شما هم از بازار طلای گلد جا نمونید.
|
||||
روی لینک زیر کلیک کنید و ثبت نام خود را تکمیل کنید.
|
||||
|
||||
gold.ir/login?id=${userStore.userInfo?.referral_id}`
|
||||
navigator.share({
|
||||
title: ' گلد',
|
||||
text: val
|
||||
})
|
||||
// message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
userFormState.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
mobile: undefined,
|
||||
birth_date: '',
|
||||
phone_number: '',
|
||||
province: '',
|
||||
city: '',
|
||||
n_code: undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
setForm()
|
||||
})
|
||||
|
||||
function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await updateMe(userFormState.value)
|
||||
await userStore.getMyInfo()
|
||||
editPassVisible.value = false
|
||||
message.success('اطلاعات شما با موفقیت به روز رسانی شد')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.trans{
|
||||
transition: height 1s;
|
||||
}*/
|
||||
</style>
|
||||
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<div @click="infoVisible = true">
|
||||
<!-- {{ item}}-->
|
||||
<div class="flex">
|
||||
<div :class="isUp? 'bg-green-50':'bg-red-50'" class="rounded-lg p-3 h-fit w-fit flex justify-center items-center">
|
||||
<Icon :class="isUp? 'text-green-600':'text-red-600'"
|
||||
:icon="`vuesax-linear:${isUp? 'arrow-up-2':'arrow-down-2'}`" />
|
||||
</div>
|
||||
<div class="w-full mr-3">
|
||||
<div class="flex justify-between w-full">
|
||||
<div>{{ item.title }}</div>
|
||||
<div>{{ toJalaliOutOfUTC(item.expire_at) }}</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-2">
|
||||
<div :class="item.gold >= 0? 'text-green-600':'text-red-600'"
|
||||
class="text-gray-500 text-xs number-ltr">{{ item.gold }}
|
||||
<div>{{item.unit}}</div>
|
||||
</div>
|
||||
<div class="text-gray-500 flex gap-1 text-xs items-center number-ltr">
|
||||
<div :class="item.cash > 0 ? 'text-green-600':'text-red-600'" class="text-base">
|
||||
{{ usePriceWithoutType(item.cash?? 0) }}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isGold" class="flex w-full justify-between mt-2">
|
||||
<div class="text-gray-500">قیمت معامله:</div>
|
||||
<div class="text-gray-500 flex gap-1 text-xs items-center">
|
||||
<!-- <div class="text-base">{{ typeof parseInt((Math.abs(item.cash) / Math.abs(item.gold)).toFixed(0)) }}</div>-->
|
||||
<div class="text-base">{{ usePriceWithoutType(parseInt((Math.abs(item.cash) / Math.abs(item.gold)).toFixed(0))) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-full justify-between mt-2">
|
||||
<div class="text-gray-500">وضعیت :</div>
|
||||
<div class="text-gray-500 flex gap-1 text-xs items-center">
|
||||
<ATag class="!py-1 !px-6 !ml-0" color="blue">
|
||||
{{ item.order?.sts_str ?? item.withdraw?.sts_str }}
|
||||
</ATag>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div v-else class="h-8"></div>-->
|
||||
<a-divider class="!my-3" />
|
||||
<BasicActionSheet v-model:show="infoVisible">
|
||||
<div class="font-bold text-lg">{{ props.item.title }}</div>
|
||||
<div class="pb-20 mt-5">
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">مبلغ:</div>
|
||||
<div :class="item.cash > 0? 'text-green-600' : 'text-red-600'" class="flex text-xs items-center number-ltr">
|
||||
<div class="text-base ml-1">{{ usePriceWithoutType(item.cash?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="item.order" class="flex justify-between mb-3">
|
||||
<div class="text-primary">قیمت هر گرم طلا حین معامله:</div>
|
||||
<div class="flex text-xs items-center number-ltr">
|
||||
<div class="text-base ml-1">{{ usePriceWithoutType(item.order?.price?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">مقدار {{item.wallet?.product? item.wallet.product.title: 'آبشده' }} مبادله شده:</div>
|
||||
<div :class="item.gold >= 0? 'text-green-600' : 'text-red-600'" class="flex text-xs items-center number-ltr">
|
||||
<div class="text-base ml-1">{{ item.gold }}</div>
|
||||
{{item.unit}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">موجودی کیف پول:</div>
|
||||
<div :class="item.cash > 0? 'text-green-600' : 'text-red-600'" class="flex text-xs items-center number-ltr">
|
||||
<div class="text-base">{{ usePriceWithoutType(item.balance_cash ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3" v-if="item.wallet?.product">
|
||||
<div class="text-primary">موجودی {{item.wallet.product.title}}:</div>
|
||||
<div class="flex text-xs text-yellow-700 items-center">
|
||||
<div class="text-base ml-1">{{ item.balance_gold }}</div>
|
||||
{{item.wallet.product.unit}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3" v-else>
|
||||
<div class="text-primary">موجودی کیف آبشده:</div>
|
||||
<div class="flex text-xs text-yellow-700 items-center">
|
||||
<div class="text-base ml-1">{{ item.balance_gold }}</div>
|
||||
گرم
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex justify-between mb-3">
|
||||
<div class="text-primary">موجودی کیف پول:</div>
|
||||
<div class="flex text-xs items-center" :class="isUp? 'text-green-600' : 'text-red-600'"><div class="text-base">{{usePriceWithoutType(12000000)}}</div>ریال</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">موجودی کیف طلا:</div>
|
||||
<div class="flex items-center" :class="isUp? 'text-red-600' : 'text-green-600'">60 گرم</div>
|
||||
</div>-->
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">وضعیت:</div>
|
||||
<div class="flex text-xs items-center">
|
||||
<ATag :color="item.active? 'blue': 'blue'" class="!py-1 !px-6 !ml-0">
|
||||
{{ item.order?.sts_str ?? item.withdraw?.sts_str }}
|
||||
</ATag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">تاریخ:</div>
|
||||
<div>{{ toJalaliNotime(item.expire_at) }}</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-primary">زمان:</div>
|
||||
<div>{{ toTime(item.expire_at) }}</div>
|
||||
</div>
|
||||
<!-- <div class="flex justify-between mb-3">
|
||||
<div class="text-primary">وضعیت معامله:</div>
|
||||
<div class="flex text-xs items-center">
|
||||
<ATag class="!py-1 !px-6 !ml-0" color="orange">
|
||||
معاملات باز
|
||||
</ATag>
|
||||
</div>
|
||||
</div>-->
|
||||
<div v-if="item.eaj" class="flex justify-between mb-3">
|
||||
<div class="text-primary">مهلت ارسال فیش:</div>
|
||||
<div>{{ item.eaj }}</div>
|
||||
</div>
|
||||
<BasicButton class="w-full mt-5" @click="infoVisible = false">بازگشت</BasicButton>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Icon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import { usePriceWithoutType } from '../../../../utils/usePrice'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import { toJalaliNotime, toJalaliOutOfUTC, toTime } from '../../../../utils/useDateTime'
|
||||
|
||||
const infoVisible = ref<boolean>(false)
|
||||
|
||||
interface Prop {
|
||||
item: Transaction
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const isUp = computed(() => props.item.type === 3 || props.item.type === 1 || props.item.type === 8 || props.item.type === 9)
|
||||
const isGold = computed(() => props.item.type === 1 || props.item.type === 2 || props.item.type === 10)
|
||||
/*const title = computed(() => {
|
||||
if (isUp.value) {
|
||||
if (isGold.value) {
|
||||
return 'واریز ریالی'
|
||||
} else {
|
||||
return 'خرید طلا'
|
||||
}
|
||||
} else {
|
||||
if (isGold.value) {
|
||||
return 'برداشت ریالی'
|
||||
} else {
|
||||
return 'فروش طلا'
|
||||
}
|
||||
}
|
||||
})*/
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<div >
|
||||
<!-- <teleport to="body">-->
|
||||
<!-- <div class="fixed top-0 right-0 left-0 bottom-0"></div>-->
|
||||
<!-- </teleport>-->
|
||||
<div class="absolute inset-0 bg-cover bg-center opacity-60"></div>
|
||||
<div
|
||||
class="bg-white w-full transaction-list py-3 px-3 font-bold drop-shadow flex justify-between z-10"
|
||||
>
|
||||
<div>لیست تراکنش ها</div>
|
||||
<BasicIcon icon="vuesax-linear:filter" @click="showFilter = true" />
|
||||
</div>
|
||||
<!-- <a-spin :spinning="loading">-->
|
||||
<div
|
||||
ref="el"
|
||||
:class="loading ? 'h-screen' : ''"
|
||||
class="px-3 pt-16 pb-10 "
|
||||
|
||||
>
|
||||
<!-- <div v-for="item in items">ss</div>-->
|
||||
<list-anim v-if="!loading">
|
||||
<Item v-for="item in items" :key="item.id" :item="item" />
|
||||
<div ref="observer" v-show="!loading" class="w-full opacity-0 relative">
|
||||
در حال بارگذاری
|
||||
</div>
|
||||
<TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />
|
||||
</list-anim>
|
||||
<TransactionSkeleton v-for="i in 13" v-else :key="i" class="mt-1" />
|
||||
<div v-if="items.length <= 0" class="flex flex-col items-center justify-center h-80vh">
|
||||
<DotLottieVue
|
||||
class="w-11rem h-11rem"
|
||||
autoplay
|
||||
src="https://lottie.host/51d3315a-cf88-4c18-bb4d-a31511fd4325/KjSBzcMbi6.json"
|
||||
/>
|
||||
<div class="font-bold">تراکنشی موجود نیست</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </a-spin>-->
|
||||
<BasicActionSheet v-model:show="showFilter">
|
||||
<div class="font-bold text-lg">فیلتر</div>
|
||||
<div class="pb-20 mt-5">
|
||||
<a-form-item class="w-full gap-2 !flex-col" label="تاریخ" name="password">
|
||||
<BaseDatePicker v-model:value="dateFilter" class="w-full" size="large" />
|
||||
</a-form-item>
|
||||
<BasicButton class="w-full mt-5" type="primary" @click="applyFilter"
|
||||
>اعمال فیلتر</BasicButton
|
||||
>
|
||||
<BasicButton class="w-full mt-2" @click="showFilter = false">بازگشت</BasicButton>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Item from './components/Item.vue'
|
||||
/*import {lengthValidation, required} from "@/utils/inputRules";
|
||||
import {loading} from "@/utils";
|
||||
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
|
||||
import BasicActionSheet from "@/components/BasicPacks/BasicActionSheet.vue";
|
||||
import BasicInput from "@/components/BasicPacks/BasicInput.vue";*/
|
||||
import { onMounted, ref } from 'vue'
|
||||
import type { TableEngineInput, TableOutput } from '@/models/table'
|
||||
import { loading, loadingMore } from '@/utils'
|
||||
// import {getOrders} from "@/api/order";
|
||||
import { getTransactionTable } from '@/api/transaction'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue'
|
||||
import {useInfiniteScroll, useIntersectionObserver, useScroll} from '@vueuse/core'
|
||||
import ListAnim from '@/components/ListAnim.vue'
|
||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
import img from "@/assets/img/user_ly1.svg";
|
||||
|
||||
const pagination = ref<TableEngineInput>({ filters: [], limit: 7, page: 0 })
|
||||
const items = ref<Transaction[]>([])
|
||||
const tableOutput = ref<TableOutput<Transaction> | null>(null)
|
||||
const showFilter = ref<boolean>(false)
|
||||
const dateFilter = ref<string>()
|
||||
const observer = ref()
|
||||
// const { y } = useScroll(el)
|
||||
|
||||
async function initTable() {
|
||||
try {
|
||||
if (dateFilter.value) {
|
||||
pagination.value.filters = []
|
||||
pagination.value.filters.push({
|
||||
field: 'created_at',
|
||||
cr: 'and',
|
||||
type: 'date',
|
||||
op: 'eq',
|
||||
value: dateFilter.value
|
||||
})
|
||||
} else {
|
||||
pagination.value.filters = []
|
||||
}
|
||||
pagination.value.page === 0 ? (loading.value = true) : (loadingMore.value = true)
|
||||
tableOutput.value = await getTransactionTable(pagination.value)
|
||||
items.value.push(...tableOutput.value.rows)
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function applyFilter() {
|
||||
pagination.value.page = 0
|
||||
items.value = []
|
||||
await initTable()
|
||||
showFilter.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initTable()
|
||||
})
|
||||
|
||||
/*useInfiniteScroll(
|
||||
el,
|
||||
async () => {
|
||||
// load more
|
||||
// console.log('salamss')
|
||||
if (
|
||||
tableOutput.value &&
|
||||
(pagination.value.page + 1) * pagination.value.limit < tableOutput.value.query.total
|
||||
) {
|
||||
// console.log('gfgf')
|
||||
pagination.value.page++
|
||||
await initTable()
|
||||
}
|
||||
},
|
||||
{ distance: 12 }
|
||||
)*/
|
||||
|
||||
useIntersectionObserver(
|
||||
observer,
|
||||
async ([{isIntersecting}]) => {
|
||||
if ( isIntersecting &&
|
||||
tableOutput.value &&
|
||||
(pagination.value.page + 1) * pagination.value.limit < tableOutput.value.query.total
|
||||
) {
|
||||
// console.log('gfgf')
|
||||
pagination.value.page++
|
||||
await initTable()
|
||||
}
|
||||
},
|
||||
{
|
||||
root: null,
|
||||
rootMargin: '300px',
|
||||
threshold: 0.01
|
||||
}
|
||||
)
|
||||
|
||||
/*const items = [
|
||||
{
|
||||
isUp: true,
|
||||
hasTransition: true
|
||||
},
|
||||
{
|
||||
isUp: false,
|
||||
hasTransition: false
|
||||
},
|
||||
{
|
||||
isUp: true,
|
||||
hasTransition: false
|
||||
},
|
||||
{
|
||||
isUp: true,
|
||||
hasTransition: true
|
||||
},
|
||||
{
|
||||
isUp: false,
|
||||
hasTransition: false
|
||||
},
|
||||
{
|
||||
isUp: true,
|
||||
hasTransition: false
|
||||
},
|
||||
{
|
||||
isUp: true,
|
||||
hasTransition: true
|
||||
},
|
||||
{
|
||||
isUp: true,
|
||||
hasTransition: true
|
||||
},
|
||||
{
|
||||
isUp: false,
|
||||
hasTransition: false
|
||||
},
|
||||
{
|
||||
isUp: true,
|
||||
hasTransition: true
|
||||
},
|
||||
]*/
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.transaction-list {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
left: 0;
|
||||
@media screen and (min-width: 426px) {
|
||||
width: 426px;
|
||||
left: auto;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,9 @@
|
||||
<svg width="428" height="331" viewBox="0 0 428 331" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="428" height="331" transform="matrix(1 0 0 -1 0 331)" fill="url(#paint0_linear_455_10939)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_455_10939" x1="214" y1="0" x2="214" y2="331" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 438 B |
@@ -0,0 +1,466 @@
|
||||
<template>
|
||||
<div class="relative">
|
||||
<div>
|
||||
<!-- <img :src="gr_bottom" alt="" class="absolute bottom-20">-->
|
||||
<img :src="img" alt="" class="mt-2 w-full absolute bottom-0" />
|
||||
</div>
|
||||
<div class="bg-white w-full py-3 px-3 text-primary font-bold drop-shadow flex">
|
||||
<div @click="router.back()" class="cursor-pointer">
|
||||
<BasicIcon icon="vuesax-linear:arrow-right-1" />
|
||||
</div>
|
||||
<div class="mr-2 mt-2">اطلاعات حساب کاربری</div>
|
||||
</div>
|
||||
<div class="pt-16 pb-8 z-30 relative">
|
||||
<div
|
||||
class="border-gray-200 border-1 rounded-xl p-5 trans flex flex-col items-center mx-5 z-1000 relative bg-white shadow-lg"
|
||||
>
|
||||
<div class="text-primary font-bold w-full text-center flex justify-between">
|
||||
نام و نام خانوادگی:
|
||||
<div class="mr-2">{{ userStore.userInfo?.name }}</div>
|
||||
</div>
|
||||
<div class="text-primary font-bold w-full text-center flex justify-between">
|
||||
شماره تلفن همراه:
|
||||
<div class="mr-2">{{ userStore.userInfo?.mobile }}</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="userStore.userInfo?.referral_id"
|
||||
class="text-primary font-bold w-full text-center flex justify-between gap-2 items-center"
|
||||
>
|
||||
کد معرف:
|
||||
<div class="flex gap-2">
|
||||
<div class="mr-2">{{ userStore.userInfo?.referral_id }}</div>
|
||||
<!-- <BasicIcon icon="vuesax-linear:copy" color="#2563EB" class="cursor-pointer" size="18"
|
||||
@click.stop="copyCode()" />
|
||||
<!– vuesax-linear:hierarchy-3–>
|
||||
<BasicIcon icon="vuesax-linear:share" color="#2563EB" class="cursor-pointer" size="18"
|
||||
@click.stop="shareCode()" />-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full flex gap-2 mt-1">
|
||||
<BasicButton
|
||||
icon="vuesax-linear:share"
|
||||
size="small"
|
||||
class="flex-1"
|
||||
icon-size="18"
|
||||
@click.stop="shareCode()"
|
||||
>
|
||||
اشتراک گذاری
|
||||
</BasicButton>
|
||||
<BasicButton
|
||||
icon="vuesax-linear:copy"
|
||||
size="small"
|
||||
class="flex-1"
|
||||
icon-size="18"
|
||||
@click.stop="copyCode()"
|
||||
>
|
||||
رونوشت
|
||||
</BasicButton>
|
||||
</div>
|
||||
<BasicButton
|
||||
class="mt-5 w-full"
|
||||
icon=""
|
||||
iconSize="18"
|
||||
size="large"
|
||||
type="primary"
|
||||
@click="editPassVisible = true"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:eye" class="absolute right-8" />
|
||||
<div>ویرایش اطلاعات کاربری</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<div class="h-40vh overflow-y-auto mt-4">
|
||||
<BasicButton
|
||||
class="mt-2 w-full"
|
||||
icon=""
|
||||
iconSize="18"
|
||||
size="large"
|
||||
@click="editPasswordVisible = true"
|
||||
:key="10"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:lock" class="absolute right-8" />
|
||||
<div>تغییر رمز عبور</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton
|
||||
class="w-full mt-2"
|
||||
size="large"
|
||||
@click="$router.push({ name: 'address' })"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:map" class="absolute right-8" />
|
||||
<div>آدرس ها</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton
|
||||
class="w-full mt-2"
|
||||
size="large"
|
||||
@click="$router.push({ name: 'notifyTrigger' })"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:bill" class="absolute right-8" />
|
||||
<div>هشدار قیمت</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton
|
||||
class="mt-2 w-full"
|
||||
icon=""
|
||||
iconSize="18"
|
||||
size="large"
|
||||
@click="$router.push({ name: 'about' })"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:info-circle" class="absolute right-8" />
|
||||
<div>درباره ما</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton
|
||||
class="mt-2 w-full"
|
||||
icon=""
|
||||
iconSize="18"
|
||||
size="large"
|
||||
@click="$router.push({ name: 'physicalReceive' })"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:direct-inbox" class="absolute right-8" />
|
||||
<div>دریافت طلای فیزیکی</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton
|
||||
class="mt-2 w-full"
|
||||
icon=""
|
||||
iconSize="18"
|
||||
size="large"
|
||||
@click="$router.push({ name: 'rules' })"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:task" class="absolute right-8" />
|
||||
<div>قوانین و مقررات</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<!-- <BasicButton
|
||||
class="mt-2 w-full"
|
||||
icon=""
|
||||
iconSize="18"
|
||||
size="large"
|
||||
@click="$router.push({ name: 'permissions' })"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:archive-book" class="absolute right-8" />
|
||||
<div>مجوز ها</div>
|
||||
</div>
|
||||
</BasicButton>-->
|
||||
<!-- <BasicButton
|
||||
class="mt-2 w-full"
|
||||
icon=""
|
||||
iconSize="18"
|
||||
size="large"
|
||||
@click="$router.push({ name: 'earnMoney' })"
|
||||
>
|
||||
<div class="flex">
|
||||
<BasicIcon icon="vuesax-linear:dollar-circle" class="absolute right-8" />
|
||||
<div>کسب درآمد</div>
|
||||
</div>
|
||||
</BasicButton>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BasicActionSheet v-model:show="editPassVisible">
|
||||
<div class="flex justify-center justify-between">
|
||||
<div class="font-bold text-lg">ویرایش اطلاعات</div>
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
<BasicIcon :icon="isLegal.icon" size="30" :class="isLegal.color" />
|
||||
<p class="text-[10px] mt-1" :class="isLegal.color">{{ isLegal.title }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h60vh overflow-y-auto pb20">
|
||||
<a-form ref="formRef" :model="userFormState" class="!mt-5" name="basic" @finish="ok">
|
||||
<a-form-item :rules="[isValidPersian()]" label="نام" name="fname">
|
||||
<BasicInput v-model:value="userFormState.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item :rules="[isValidPersian()]" label="نام خانوادگی" name="lname">
|
||||
<BasicInput v-model:value="userFormState.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ تولد" name="birth_date">
|
||||
<BaseDatePicker v-model:value="userFormState.birth_date" class="w-full" inputReadOnly />
|
||||
</a-form-item>
|
||||
<a-form-item :rules="[requireNationalCode()]" label="شماره ملی" name="n_code">
|
||||
<BasicInput v-model:value="userFormState.n_code" type="number" :disabled="userFormState.is_legal == 1 || userFormState.is_legal == 2" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام شهر" name="city">
|
||||
<BasicInput v-model:value="userFormState.city" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<div class="wrap-fix md:w-[395px] bottom-5 px-3">
|
||||
<BasicButton
|
||||
:disabled="loading"
|
||||
class="w-full py-2 mb-20"
|
||||
html-type="submit"
|
||||
type="primary"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>ثبت</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
<BasicActionSheet v-model:show="editPasswordVisible">
|
||||
<div class="font-bold text-lg">ویرایش رمزعبور</div>
|
||||
<div class="h30vh overflow-y-auto pb20">
|
||||
<a-form
|
||||
ref="formPassRef"
|
||||
:model="userPassForm"
|
||||
class="!mt-5"
|
||||
name="basic"
|
||||
@finish="submitPassForm"
|
||||
>
|
||||
<a-form-item label="کلمه عبور جدید" :rules="passwordRules()" name="password">
|
||||
<BasicInput v-model:value="userPassForm.password" isPassword place-holder="کلمه عبور " />
|
||||
<div
|
||||
:class="[
|
||||
guideTypePassword.color,
|
||||
userPassForm.password.length >= 6 ? 'block' : 'hidden'
|
||||
]"
|
||||
class="text-[12px] mt-1"
|
||||
>
|
||||
{{ guideTypePassword.text }}
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<div class="wrap-fix md:w-[395px] bottom-5 px-3">
|
||||
<BasicButton
|
||||
:disabled="loading"
|
||||
class="w-full py-2 mb-20"
|
||||
html-type="submit"
|
||||
type="primary"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>ثبت</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref, computed } from 'vue'
|
||||
import img from '@/assets/img/user_ly1.svg'
|
||||
import gr_bottom from './assets/img/gr_bottom_white.svg'
|
||||
import { loading } from '@/utils'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import {
|
||||
lengthValidation,
|
||||
required,
|
||||
requireNationalCode,
|
||||
passwordRules,
|
||||
guideTypePassword,
|
||||
isValidPersian,
|
||||
} from '@/utils/inputRules'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { User, Password } from '@/models/login'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import router from '@/router'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { updateMe, updatePass } from '@/api/me'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker'
|
||||
const userFormState = ref<User>({
|
||||
fname: '',
|
||||
lname: '',
|
||||
mobile: undefined,
|
||||
birth_date: '',
|
||||
city: '',
|
||||
n_code: undefined
|
||||
})
|
||||
const userPassForm = ref<Password>({
|
||||
password: ''
|
||||
})
|
||||
const formRef = ref<FormInstance>()
|
||||
const formPassRef = ref<FormInstance>()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// const editPassVisible = ref<boolean>(false)
|
||||
const editPassVisible = ref<boolean>(false)
|
||||
const editPasswordVisible = ref<boolean>(false)
|
||||
|
||||
function setForm() {
|
||||
userFormState.value = userStore.userInfo
|
||||
}
|
||||
|
||||
function copyCode() {
|
||||
// nextTick(() => {
|
||||
const val = userStore.userInfo?.referral_id
|
||||
navigator.clipboard.writeText(val)
|
||||
message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
const isLegal = computed(() => {
|
||||
const result = {
|
||||
title: '',
|
||||
color: '',
|
||||
icon: ''
|
||||
}
|
||||
switch (userFormState.value.is_legal) {
|
||||
case 0:
|
||||
result.title = 'احراز هویت نشده'
|
||||
result.color = 'reject'
|
||||
result.icon = 'vuesax-linear:close-circle'
|
||||
break
|
||||
case 1:
|
||||
result.title = 'احراز هویت شده'
|
||||
result.color = 'success'
|
||||
result.icon = 'vuesax-linear:verify'
|
||||
|
||||
break
|
||||
case 2:
|
||||
result.title = 'احراز هویت شده'
|
||||
result.color = 'success'
|
||||
result.icon = 'vuesax-linear:verify'
|
||||
|
||||
break
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
function shareCode() {
|
||||
// nextTick(() => {
|
||||
const val = `⭐️الان طلا بخر؛ آخر ماه سودشو ببر!
|
||||
با خرید طلای آبشده در مقدارهای کم ولی مستمر، سود بیشتری ببر!
|
||||
|
||||
این دعوت نامه از طرف "${userStore.userInfo?.name}" عزیز برای شما ارسال شده تا شما هم از بازار طلای گلد دات آی آر جا نمونید.
|
||||
روی لینک زیر کلیک کنید و ثبت نام خود را تکمیل کنید.
|
||||
|
||||
gold.ir/login?id=${userStore.userInfo?.referral_id}`
|
||||
navigator.share({
|
||||
title: ' گلد دات آی آر',
|
||||
text: val
|
||||
})
|
||||
// message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
userFormState.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
mobile: undefined,
|
||||
birth_date: '',
|
||||
city: '',
|
||||
n_code: undefined
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setForm()
|
||||
})
|
||||
|
||||
function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await updateMe(userFormState.value)
|
||||
await userStore.getMyInfo()
|
||||
editPassVisible.value = false
|
||||
message.success('اطلاعات شما با موفقیت به روز رسانی شد')
|
||||
location.reload()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
function submitPassForm() {
|
||||
formPassRef.value?.validateFields().then(async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
await updatePass(userPassForm.value)
|
||||
await userStore.getMyInfo()
|
||||
editPassVisible.value = false
|
||||
message.success('پسورد شما با موفقیت به روز رسانی شد')
|
||||
editPasswordVisible.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log(userStore.userInfo?.is_legal === 2)
|
||||
if (userStore.userInfo?.is_legal === 0) {
|
||||
editPassVisible.value = true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.trans{
|
||||
transition: height 1s;
|
||||
}*/
|
||||
.midLevel {
|
||||
color: orange;
|
||||
}
|
||||
.week,
|
||||
.reject {
|
||||
color: red;
|
||||
}
|
||||
.success {
|
||||
color: green;
|
||||
}
|
||||
.background-image-container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.background-image-container img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
z-index: 40;
|
||||
}
|
||||
|
||||
.relative {
|
||||
overflow-y: auto;
|
||||
max-height: 100vh;
|
||||
//scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 50; /* بالاتر از همه */
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div
|
||||
:style="findPositionStyle(props.selfIndex)"
|
||||
class="card relative"
|
||||
@click="localValue = props.selfIndex"
|
||||
>
|
||||
<!-- <img :src="ly1" class="absolute h-full w-full object-cover rounded-2xl" alt="">-->
|
||||
<!-- <img :src="ly2 " class="absolute h-full w-full object-cover rounded-2xl" alt="">-->
|
||||
<div class="flex flex-col items-center">
|
||||
<img :src="img" alt="" class="w-full h-full" />
|
||||
<div class="mt-[1.5vh] text-white w-full text-center text-xl font-bold" dir="ltr">
|
||||
{{ useCardNumber(props.cardNumber) }}
|
||||
</div>
|
||||
<div class="mt-3 text-white text-lg">{{ useShabaNumber(props.shaba) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { useCardNumber, useShabaNumber } from '@/utils/useCardNumber'
|
||||
|
||||
interface Prop {
|
||||
sliderIndex: number
|
||||
selfIndex: number
|
||||
img: string
|
||||
color?: string
|
||||
}
|
||||
|
||||
const localValue = computed({
|
||||
get() {
|
||||
return props.sliderIndex
|
||||
},
|
||||
|
||||
set(value) {
|
||||
emits('update:sliderIndex', value)
|
||||
}
|
||||
})
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
const emits = defineEmits(['update:sliderIndex'])
|
||||
|
||||
function findPositionStyle(pos: number) {
|
||||
// console.log(localValue.value)
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === props.sliderIndex) {
|
||||
debug = `width: 100%; z-index: 100; opacity: 1;/* margin-top: -160px;*/ top: 20%; position: absolute; background-color: ${props.color};`
|
||||
} /*if (pos > index.value)*/ else {
|
||||
// debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
debug = `width: ${100 - Math.abs(props.sliderIndex - pos) * 3}%;
|
||||
z-index: ${100 - Math.abs(props.sliderIndex - pos)};
|
||||
opacity: ${1 - Math.abs((props.sliderIndex - pos) * 15) / 100};
|
||||
/*
|
||||
margin-top: ${-160 - Math.abs((props.sliderIndex - pos) * 15)}px;
|
||||
*/
|
||||
position: absolute;
|
||||
top : ${
|
||||
pos > props.sliderIndex
|
||||
? checkTopLimit(topDetail(true, pos) as number)
|
||||
? 100
|
||||
: 35 +
|
||||
Math.abs((props.sliderIndex - pos) * (35 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
: checkTopLimit(topDetail(false, pos) as number)
|
||||
? 0
|
||||
: 35 - Math.abs((props.sliderIndex - pos) * (35 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
}%;
|
||||
background-color: ${props.color};`
|
||||
}
|
||||
// console.log(debug)
|
||||
return debug
|
||||
}
|
||||
|
||||
/**
|
||||
* /!*checkTopLimit(topDetail(true, pos) as number) ? 100 :*!/ topDetail(true, pos) :
|
||||
* /!*checkTopLimit(topDetail(false, pos) as number) ? 0 :*!/ topDetail(false, pos)
|
||||
*/
|
||||
|
||||
function topDetail(isAfterIndex: boolean, pos: number) {
|
||||
if (isAfterIndex)
|
||||
return 35 + Math.abs((props.sliderIndex - pos) * (35 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
else
|
||||
return (
|
||||
35 - Math.abs((props.sliderIndex - pos) * (35 - Math.abs((props.sliderIndex - pos) * 4))) < 0
|
||||
)
|
||||
}
|
||||
|
||||
function checkTopLimit(val: number) {
|
||||
return val > 100 || val < 0
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
|
||||
.card
|
||||
height: fit-content
|
||||
width: 100%
|
||||
align-self: center
|
||||
border-radius: 24px
|
||||
transition: .5s
|
||||
|
||||
.card:first-child
|
||||
margin-top: 0 !important
|
||||
</style>
|
||||
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div >
|
||||
<div class="flex">
|
||||
<div :class="isUp? 'bg-green-50':'bg-red-50'" class="rounded-lg p-4 h-fit w-fit flex justify-center items-center">
|
||||
<Icon :class="isUp? 'text-green-600':'text-red-600'"
|
||||
:icon="`vuesax-linear:${isUp? 'tick-circle':'close-circle'}`"/>
|
||||
</div>
|
||||
<div class=" w-full mr-2 ">
|
||||
<div class="flex w-full text-xs ">{{item.note ?? '-'}}</div>
|
||||
<div class="flex mt-1 text-xs">
|
||||
<div>وضعیت:</div>
|
||||
<div :class="'text-green-600'" class="mr-1" v-if="item.transaction[0]">موفق</div>
|
||||
<div :class="'text-red-600'" class="mr-1" v-else>ناموفق</div>
|
||||
</div>
|
||||
<div class="flex mt-1 text-xs ">
|
||||
<div class="w-4rem">کد پیگیری: </div>
|
||||
<div class=" mr-1">{{item.tracked_number ?? '-'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full mr-3">
|
||||
<div class="flex justify-between w-full">
|
||||
<div>{{ item.type_str }}</div>
|
||||
<div>{{ toJalaliNotime(item.created_at) }}</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-2">
|
||||
<div :class="item.gold >= 0? 'text-green-600':'text-red-600'" class="text-gray-500 text-xs number-ltr">
|
||||
<!-- {{ item.gold }}
|
||||
<div>گرم</div>-->
|
||||
</div>
|
||||
<div class="text-gray-500 flex gap-1 text-xs items-center">
|
||||
<div :class="item.cash > 0 ? 'text-green-600':'text-red-600'" class="text-base number-ltr">
|
||||
{{ usePriceWithoutType(item.cash ?? 0) }}
|
||||
</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isGold" class="flex w-full justify-between mt-2">
|
||||
<div class="text-gray-500">قیمت معامله:</div>
|
||||
<div class="text-gray-500 flex gap-1 text-xs items-center">
|
||||
<div class="text-base">{{ usePriceWithoutType((Math.abs(item.cash) / Math.abs(item.gold)).toFixed(0)) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex w-full justify-between mt-2">
|
||||
<div class="text-gray-500">وضعیت :</div>
|
||||
<div class="text-gray-500 flex gap-1 text-xs items-center">
|
||||
<ATag class="!py-1 !px-6 !ml-0" color="blue">
|
||||
{{ item.order?.sts_str ?? '' }}
|
||||
</ATag>
|
||||
</div>
|
||||
</div>-->
|
||||
<!-- <div v-else class="h-8"></div>-->
|
||||
<a-divider class="!my-3"/>
|
||||
<BasicActionSheet v-model:show="infoVisible">
|
||||
<div class="font-bold text-lg">{{ props.item.type_str }}</div>
|
||||
<div class="pb-20 mt-5">
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-black">مبلغ:</div>
|
||||
<div :class="item.cash > 0? 'text-green-600' : 'text-red-600'" class="flex text-xs items-center">
|
||||
<div class="text-base ml-1 number-ltr">{{ usePriceWithoutType(item.cash) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-black">مقدار طلا مبادله شده:</div>
|
||||
<div :class="item.gold >= 0? 'text-green-600' : 'text-red-600'" class="flex text-xs items-center">
|
||||
<div class="text-base ml-1 number-ltr">{{ item.gold }}</div>
|
||||
گرم
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="item.order" class="flex justify-between mb-3">
|
||||
<div class="text-black">قیمت هر گرم طلا حین معامله:</div>
|
||||
<div class="flex text-xs items-center number-ltr">
|
||||
<div class="text-base ml-1">{{ usePriceWithoutType(item.order?.price?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-black">موجودی کیف پول:</div>
|
||||
<div :class="item.cash > 0? 'text-green-600' : 'text-red-600'" class="flex text-xs items-center">
|
||||
<div class="text-base number-ltr">{{ usePriceWithoutType(item.balance_cash ?? 0) }}</div>
|
||||
ریال
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-black">موجودی کیف طلا:</div>
|
||||
<div class="flex text-xs text-yellow-700 items-center">
|
||||
<div class="text-base ml-1">{{ item.balance_gold }}</div>
|
||||
گرم
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex justify-between mb-3">
|
||||
<div class="text-black">موجودی کیف پول:</div>
|
||||
<div class="flex text-xs items-center" :class="isUp? 'text-green-600' : 'text-red-600'"><div class="text-base">{{usePriceWithoutType(12000000)}}</div>ریال</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-black">موجودی کیف طلا:</div>
|
||||
<div class="flex items-center" :class="isUp? 'text-red-600' : 'text-green-600'">60 گرم</div>
|
||||
</div>-->
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-black">وضعیت:</div>
|
||||
<div class="flex text-xs items-center">
|
||||
<ATag :color="item.active? 'blue': 'red'" class="!py-1 !px-6 !ml-0">{{
|
||||
item.order?.sts_str
|
||||
}}
|
||||
</ATag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-black">تاریخ:</div>
|
||||
<div>{{ toJalaliNotime(item.expire_at) }}</div>
|
||||
</div>
|
||||
<div class="flex justify-between mb-3">
|
||||
<div class="text-black">زمان:</div>
|
||||
<div>{{ toTime(item.expire_at) }}</div>
|
||||
</div>
|
||||
<!-- <div class="flex justify-between mb-3">
|
||||
<div class="text-black">وضعیت معامله:</div>
|
||||
<div class="flex text-xs items-center">
|
||||
<ATag class="!py-1 !px-6 !ml-0" color="orange">
|
||||
معاملات باز
|
||||
</ATag>
|
||||
</div>
|
||||
</div>-->
|
||||
<div v-if="item.eaj" class="flex justify-between mb-3">
|
||||
<div class="text-black">مهلت ارسال فیش:</div>
|
||||
<div>{{ item.eaj }}</div>
|
||||
</div>
|
||||
<BasicButton class="w-full mt-5" @click="infoVisible = false">بازگشت</BasicButton>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Icon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import {usePriceWithoutType} from "../../../../utils/usePrice";
|
||||
import BasicActionSheet from "@/components/BasicPacks/BasicActionSheet.vue";
|
||||
import {computed, ref} from "vue";
|
||||
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
|
||||
import type {Transaction} from "@/models/transaction";
|
||||
import {toJalaliNotime, toJalaliOutOfUTC, toTime} from "../../../../utils/useDateTime";
|
||||
|
||||
const infoVisible = ref<boolean>(false)
|
||||
|
||||
interface Prop {
|
||||
item: Transaction
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
// const isUp = computed(() => props.item.type === 3 || props.item.type === 1)
|
||||
const isUp = computed(() => props.item.transaction[0])
|
||||
const isGold = computed(() => props.item.type === 1 || props.item.type === 2 || props.item.type === 10)
|
||||
/*const title = computed(() => {
|
||||
if (isUp.value) {
|
||||
if (isGold.value) {
|
||||
return 'واریز ریالی'
|
||||
} else {
|
||||
return 'خرید طلا'
|
||||
}
|
||||
} else {
|
||||
if (isGold.value) {
|
||||
return 'برداشت ریالی'
|
||||
} else {
|
||||
return 'فروش طلا'
|
||||
}
|
||||
}
|
||||
})*/
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
<template>
|
||||
<van-dialog
|
||||
class="updateButton"
|
||||
confirm-button-text="متوجه شدم"
|
||||
:show-confirm-button="false"
|
||||
@confirm="update()"
|
||||
>
|
||||
<div class="flex flex-col items-center p-2 mt-7 mb-3">
|
||||
<div class="typewriter">
|
||||
<div class="slide"><i></i></div>
|
||||
<div class="paper"></div>
|
||||
<div class="keyboard"></div>
|
||||
</div>
|
||||
<div class="font-bold mt-5">در حال انجام تراکنش</div>
|
||||
<div class="home_appear_fade_in_up mt-2 text-sm mb-5">
|
||||
سفارش شما در حال پیگیری است، لطفا صبور باشید!
|
||||
</div>
|
||||
</div>
|
||||
</van-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import { update } from 'lodash'
|
||||
import { ref } from 'vue'
|
||||
interface Prop {
|
||||
title: string
|
||||
info?: string
|
||||
infoHead?: string
|
||||
isLine?: boolean
|
||||
value?: string | number
|
||||
}
|
||||
const props = withDefaults(defineProps<Prop>(), {
|
||||
isLine: false
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
/* From Uiverse.io by Nawsome */
|
||||
.typewriter {
|
||||
--blue: #5c86ff;
|
||||
--blue-dark: #275efe;
|
||||
--key: #fff;
|
||||
--paper: #eef0fd;
|
||||
--text: #d3d4ec;
|
||||
--tool: #fbc56c;
|
||||
--duration: 3s;
|
||||
position: relative;
|
||||
-webkit-animation: bounce05 var(--duration) linear infinite;
|
||||
animation: bounce05 var(--duration) linear infinite;
|
||||
}
|
||||
|
||||
.typewriter .slide {
|
||||
width: 92px;
|
||||
height: 20px;
|
||||
border-radius: 3px;
|
||||
margin-left: 14px;
|
||||
transform: translateX(14px);
|
||||
background: linear-gradient(var(--blue), var(--blue-dark));
|
||||
-webkit-animation: slide05 var(--duration) ease infinite;
|
||||
animation: slide05 var(--duration) ease infinite;
|
||||
}
|
||||
|
||||
.typewriter .slide:before,
|
||||
.typewriter .slide:after,
|
||||
.typewriter .slide i:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background: var(--tool);
|
||||
}
|
||||
|
||||
.typewriter .slide:before {
|
||||
width: 2px;
|
||||
height: 8px;
|
||||
top: 6px;
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.typewriter .slide:after {
|
||||
left: 94px;
|
||||
top: 3px;
|
||||
height: 14px;
|
||||
width: 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.typewriter .slide i {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 100%;
|
||||
width: 6px;
|
||||
height: 4px;
|
||||
top: 4px;
|
||||
background: var(--tool);
|
||||
}
|
||||
|
||||
.typewriter .slide i:before {
|
||||
right: 100%;
|
||||
top: -2px;
|
||||
width: 4px;
|
||||
border-radius: 2px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.typewriter .paper {
|
||||
position: absolute;
|
||||
left: 24px;
|
||||
top: -26px;
|
||||
width: 40px;
|
||||
height: 46px;
|
||||
border-radius: 5px;
|
||||
background: var(--paper);
|
||||
transform: translateY(46px);
|
||||
-webkit-animation: paper05 var(--duration) linear infinite;
|
||||
animation: paper05 var(--duration) linear infinite;
|
||||
}
|
||||
|
||||
.typewriter .paper:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
right: 6px;
|
||||
top: 7px;
|
||||
border-radius: 2px;
|
||||
height: 4px;
|
||||
transform: scaleY(0.8);
|
||||
background: var(--text);
|
||||
box-shadow:
|
||||
0 12px 0 var(--text),
|
||||
0 24px 0 var(--text),
|
||||
0 36px 0 var(--text);
|
||||
}
|
||||
|
||||
.typewriter .keyboard {
|
||||
width: 120px;
|
||||
height: 56px;
|
||||
margin-top: -10px;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.typewriter .keyboard:before,
|
||||
.typewriter .keyboard:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.typewriter .keyboard:before {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 7px;
|
||||
background: linear-gradient(135deg, var(--blue), var(--blue-dark));
|
||||
transform: perspective(10px) rotateX(2deg);
|
||||
transform-origin: 50% 100%;
|
||||
}
|
||||
|
||||
.typewriter .keyboard:after {
|
||||
left: 2px;
|
||||
top: 25px;
|
||||
width: 11px;
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
-webkit-animation: keyboard05 var(--duration) linear infinite;
|
||||
animation: keyboard05 var(--duration) linear infinite;
|
||||
}
|
||||
|
||||
@keyframes bounce05 {
|
||||
85%,
|
||||
92%,
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
89% {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
95% {
|
||||
transform: translateY(2px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide05 {
|
||||
5% {
|
||||
transform: translateX(14px);
|
||||
}
|
||||
|
||||
15%,
|
||||
30% {
|
||||
transform: translateX(6px);
|
||||
}
|
||||
|
||||
40%,
|
||||
55% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
65%,
|
||||
70% {
|
||||
transform: translateX(-4px);
|
||||
}
|
||||
|
||||
80%,
|
||||
89% {
|
||||
transform: translateX(-12px);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(14px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes paper05 {
|
||||
5% {
|
||||
transform: translateY(46px);
|
||||
}
|
||||
|
||||
20%,
|
||||
30% {
|
||||
transform: translateY(34px);
|
||||
}
|
||||
|
||||
40%,
|
||||
55% {
|
||||
transform: translateY(22px);
|
||||
}
|
||||
|
||||
65%,
|
||||
70% {
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
80%,
|
||||
85% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
92%,
|
||||
100% {
|
||||
transform: translateY(46px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes keyboard05 {
|
||||
5%,
|
||||
12%,
|
||||
21%,
|
||||
30%,
|
||||
39%,
|
||||
48%,
|
||||
57%,
|
||||
66%,
|
||||
75%,
|
||||
84% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
|
||||
9% {
|
||||
box-shadow:
|
||||
15px 2px 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
|
||||
18% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 2px 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
|
||||
27% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 12px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
|
||||
36% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 12px 0 var(--key),
|
||||
60px 12px 0 var(--key),
|
||||
68px 12px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
|
||||
45% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 2px 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
|
||||
54% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 2px 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
|
||||
63% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 12px 0 var(--key);
|
||||
}
|
||||
|
||||
72% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 2px 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 10px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
|
||||
81% {
|
||||
box-shadow:
|
||||
15px 0 0 var(--key),
|
||||
30px 0 0 var(--key),
|
||||
45px 0 0 var(--key),
|
||||
60px 0 0 var(--key),
|
||||
75px 0 0 var(--key),
|
||||
90px 0 0 var(--key),
|
||||
22px 10px 0 var(--key),
|
||||
37px 12px 0 var(--key),
|
||||
52px 10px 0 var(--key),
|
||||
60px 10px 0 var(--key),
|
||||
68px 10px 0 var(--key),
|
||||
83px 10px 0 var(--key);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<div
|
||||
:style="findPositionStyle(props.selfIndex)"
|
||||
class="card relative"
|
||||
@click="localValue = props.selfIndex"
|
||||
>
|
||||
<div class="p-3 flex flex-col items-center">
|
||||
<div class="flex justify-between w-full">
|
||||
<div class="text-white font-bold text-lg w-full">{{ props.title }}</div>
|
||||
<div
|
||||
class="text-white px-2 flex justify-center items-center rounded-lg w-5rem"
|
||||
:class="active ? 'bg-green-600' : 'bg-red-600'"
|
||||
>
|
||||
{{ active ? 'فعال' : 'غیر فعال' }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="props.cardNumber"
|
||||
class="mt-[1.5vh] text-white w-full text-center text-xl font-bold"
|
||||
dir="ltr"
|
||||
>
|
||||
{{ useCardNumber(props.cardNumber) }}
|
||||
</div>
|
||||
<div v-if="props.shaba" class="mt-3 text-white text-lg">
|
||||
{{ useShabaNumber(props.shaba) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { useCardNumber, useShabaNumber } from '@/utils/useCardNumber'
|
||||
|
||||
interface Prop {
|
||||
sliderIndex: number
|
||||
selfIndex: number
|
||||
title?: string
|
||||
cardNumber?: string
|
||||
shaba?: string
|
||||
color?: string
|
||||
active?: boolean
|
||||
}
|
||||
|
||||
const localValue = computed({
|
||||
get() {
|
||||
return props.sliderIndex
|
||||
},
|
||||
|
||||
set(value) {
|
||||
emits('update:sliderIndex', value)
|
||||
}
|
||||
})
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
const emits = defineEmits(['update:sliderIndex'])
|
||||
|
||||
function findPositionStyle(pos: number) {
|
||||
// console.log(localValue.value)
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === props.sliderIndex) {
|
||||
debug = `width: 100%; z-index: 100; opacity: 1;/* margin-top: -160px;*/ top: 20%; position: absolute; background-color: ${props.color};`
|
||||
} /*if (pos > index.value)*/ else {
|
||||
// debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
debug = `width: ${100 - Math.abs(props.sliderIndex - pos) * 10}%;
|
||||
z-index: ${100 - Math.abs(props.sliderIndex - pos)};
|
||||
position: absolute;
|
||||
top : ${
|
||||
pos > props.sliderIndex
|
||||
? checkTopLimit(topDetail(true, pos) as number)
|
||||
? 100
|
||||
: 20 +
|
||||
Math.abs((props.sliderIndex - pos) * (18 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
: checkTopLimit(topDetail(false, pos) as number)
|
||||
? 0
|
||||
: 20 - Math.abs((props.sliderIndex - pos) * (18 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
}%;
|
||||
background-color: ${props.color};`
|
||||
}
|
||||
console.log(debug, topDetail(true, pos))
|
||||
return debug
|
||||
}
|
||||
|
||||
/*
|
||||
function findPositionStyle(pos: number) {
|
||||
// console.log(localValue.value)
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === props.sliderIndex) {
|
||||
debug = `width: 100%; z-index: 100; opacity: 1;/!* margin-top: -160px;*!/ top: 20%; position: absolute; background-color: ${props.color};`
|
||||
} else /!*if (pos > index.value)*!/{
|
||||
// debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
debug = `width: ${100 - Math.abs(props.sliderIndex - pos) * 10}%;
|
||||
z-index: ${100 - Math.abs(props.sliderIndex - pos)};
|
||||
/!*
|
||||
opacity: ${1 - Math.abs((props.sliderIndex - pos) * 15) / 100};
|
||||
*!/
|
||||
/!*
|
||||
margin-top: ${-160 - Math.abs((props.sliderIndex - pos) * 15)}px;
|
||||
*!/
|
||||
position: absolute;
|
||||
top : ${pos > props.sliderIndex ?
|
||||
checkTopLimit(topDetail(true, pos) as number) ? 100 :
|
||||
(20 + Math.abs((props.sliderIndex - pos) * (18 - (Math.abs((props.sliderIndex - pos) * 4))))) :
|
||||
checkTopLimit(topDetail(false, pos) as number) ? 0 :
|
||||
(20 - Math.abs((props.sliderIndex - pos) * (18 - (Math.abs((props.sliderIndex - pos) * 4)))))}%;
|
||||
background-color: ${props.color};`
|
||||
}
|
||||
console.log(debug)
|
||||
return debug
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* /!*checkTopLimit(topDetail(true, pos) as number) ? 100 :*!/ topDetail(true, pos) :
|
||||
* /!*checkTopLimit(topDetail(false, pos) as number) ? 0 :*!/ topDetail(false, pos)
|
||||
*/
|
||||
|
||||
function topDetail(isAfterIndex: boolean, pos: number) {
|
||||
/* console.log((20 - Math.abs((props.sliderIndex - pos) * (24 - (Math.abs((props.sliderIndex - pos) * 4))))), pos)
|
||||
console.log(Math.abs((props.sliderIndex - pos)) * (24 - (Math.abs((props.sliderIndex - pos) * 4))))*/
|
||||
console.log(
|
||||
20 - Math.abs((props.sliderIndex - pos) * (24 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
)
|
||||
/* if (isAfterIndex) console.log(20 + Math.abs(props.sliderIndex - pos))
|
||||
else console.log(20 - Math.abs(props.sliderIndex - pos))*/
|
||||
if (isAfterIndex)
|
||||
return 20 + Math.abs((props.sliderIndex - pos) * (18 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
else
|
||||
return 20 - Math.abs((props.sliderIndex - pos) * (18 - Math.abs((props.sliderIndex - pos) * 4)))
|
||||
}
|
||||
|
||||
/*
|
||||
function topDetail(isAfterIndex: boolean, pos: number) {
|
||||
console.log(pos, isAfterIndex, (20 + Math.abs((props.sliderIndex - pos) * (24 - (Math.abs((props.sliderIndex - pos) * 4))))))
|
||||
if (isAfterIndex) return (20 + Math.abs((props.sliderIndex - pos) * (24 - (Math.abs((props.sliderIndex - pos) * 4)))))
|
||||
else return (20 - Math.abs((props.sliderIndex - pos) * (24 - (Math.abs((props.sliderIndex - pos) * 4))))) < 0 //12*64
|
||||
}
|
||||
*/
|
||||
|
||||
function checkTopLimit(val: number) {
|
||||
return val > 100 || val < 0
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
|
||||
.card
|
||||
height: 22vh
|
||||
width: 100%
|
||||
align-self: center
|
||||
border-radius: 24px
|
||||
transition: .5s
|
||||
|
||||
.card:first-child
|
||||
margin-top: 0 !important
|
||||
</style>
|
||||
@@ -0,0 +1,162 @@
|
||||
<template lang="pug">
|
||||
.container
|
||||
.slider
|
||||
.slide(data-slide='1' style="background-color: green")
|
||||
.slide(data-slide='2' style="background-color: red")
|
||||
.slide(data-slide='3' style="background-color: orange")
|
||||
.slide.slide--active(data-slide='4' style="background-color: blue")
|
||||
.slide(data-slide='5' style="background-color: violet")
|
||||
.slide(data-slide='5' style="background-color: primary")
|
||||
.slide(data-slide='5' style="background-color: pink")
|
||||
.slide(data-slide='5' style="background-color: teal")
|
||||
.controls
|
||||
#back Back
|
||||
#forvard Forvard
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
renderSlider('.slider');
|
||||
});
|
||||
|
||||
const nextSlide = () => {
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
if (nextSlide) {
|
||||
activeSlide.classList.remove('slide--active');
|
||||
nextSlide.classList.remove('next');
|
||||
nextSlide.classList.add('slide--active');
|
||||
renderSlides();
|
||||
renderBtns();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const renderBtns = () => {
|
||||
let nextBtn = document.querySelector('#forvard');
|
||||
let prevBtn = document.querySelector('#back');
|
||||
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
!prevSlide ? prevBtn.classList.add('disabled')
|
||||
: prevBtn.classList.remove('disabled');
|
||||
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
!nextSlide ? nextBtn.classList.add('disabled')
|
||||
: nextBtn.classList.remove('disabled');
|
||||
}
|
||||
|
||||
const prevSlide = () => {
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
if (prevSlide) {
|
||||
activeSlide.classList.remove('slide--active');
|
||||
prevSlide.classList.remove('prev');
|
||||
prevSlide.classList.add('slide--active');
|
||||
renderSlides();
|
||||
renderBtns();
|
||||
}
|
||||
}
|
||||
|
||||
const renderSlides = () => {
|
||||
let slides = document.querySelectorAll('.slide');
|
||||
if (!slides) {
|
||||
return;
|
||||
}
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
if (!activeSlide) {
|
||||
activeSlide = slides.item(0);
|
||||
activeSlide.classList.add('slide--active');
|
||||
}
|
||||
[].forEach.call(slides, function (slide) {
|
||||
slide.classList.remove('prev', 'next')
|
||||
});
|
||||
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
prevSlide && prevSlide.classList.add('prev');
|
||||
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
nextSlide && nextSlide.classList.add('next');
|
||||
|
||||
}
|
||||
|
||||
const renderSlider = (element) => {
|
||||
const slider = document.querySelector(element);
|
||||
if (slider) {
|
||||
let nextButton = document.querySelector("#forvard");
|
||||
nextButton.addEventListener('click', function () {
|
||||
nextSlide();
|
||||
})
|
||||
|
||||
let prevButton = document.querySelector("#back");
|
||||
prevButton.addEventListener('click', function () {
|
||||
prevSlide();
|
||||
})
|
||||
renderSlides();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
.container
|
||||
display: flex
|
||||
flex-flow: column
|
||||
justify-content: center
|
||||
margin: 50px auto 0
|
||||
width: 500px
|
||||
height: 300px
|
||||
|
||||
.controls
|
||||
display: flex
|
||||
justify-content: center
|
||||
|
||||
div
|
||||
padding: 12px 14px
|
||||
cursor: pointer
|
||||
border: 1px solid #fff
|
||||
color: #fff
|
||||
font-size: 16px
|
||||
font-weight: bold
|
||||
margin: 0 5px
|
||||
border-radius: 10px
|
||||
|
||||
&.disabled
|
||||
opacity: 0
|
||||
cursor: default
|
||||
|
||||
|
||||
.slider
|
||||
position: relative
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
.slide
|
||||
position: absolute
|
||||
top: 25%
|
||||
left: 10%
|
||||
width: 80%
|
||||
height: 50%
|
||||
background-color: red
|
||||
border: 1px solid #fff
|
||||
border-radius: 15px
|
||||
opacity: 0
|
||||
transition: all 0.7s ease-out
|
||||
|
||||
&--active
|
||||
opacity: 1
|
||||
z-index: 9
|
||||
|
||||
.prev,
|
||||
.next
|
||||
opacity: .3
|
||||
|
||||
|
||||
.prev
|
||||
transform: translate(0, -30%) scale(0.8)
|
||||
|
||||
.next
|
||||
transform: translate(0, 30%) scale(0.8)
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,259 @@
|
||||
<template>
|
||||
|
||||
<div ref="container" class=" h-[38vh] flex items-center">
|
||||
<div ref="el" class="w-full flex flex-col relative h-full test">
|
||||
<CardItem v-for="(item,i) in props?.items" :key="i" v-model:sliderIndex="index" :card-number="item?.cart_number"
|
||||
:color="colors[i%3]"
|
||||
:self-index="i" :shaba="item?.shaba_number" :title="item?.bank_name" :active="item.sts === 2"/>
|
||||
<div class="absolute bottom-15vh right-0 left-0 z-100 flex justify-center items-center opacity-70">
|
||||
<div class="flex gap-1 bg-gray-500 px-2 py-1 rounded-lg">
|
||||
<Transition name="slide-up" mode="out-in" v-for="i in items.length" :key="i">
|
||||
<div v-if="i - 1 === index" class="w-2 h-2 rounded-full bg-primary"/>
|
||||
<div v-else class="w-2 h-2 rounded-full bg-white"/>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
// import {usePointerSwipe} from '@vueuse/core'
|
||||
// import type {UseSwipeDirection} from '@vueuse/core'
|
||||
// import type { UseSwipeDirection } from '@vueuse/core'
|
||||
import { useSwipe } from '@vueuse/core'
|
||||
import CardItem from './CardItem.vue'
|
||||
import type { Card } from '@/models/wallet'
|
||||
|
||||
const el = ref(null)
|
||||
const container = ref<HTMLElement | null>(null)
|
||||
|
||||
interface Prop {
|
||||
items: Array<Card>
|
||||
id: number | string
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
const emits = defineEmits(['update:id'])
|
||||
|
||||
const localValue = computed({
|
||||
get() {
|
||||
return props.id
|
||||
},
|
||||
|
||||
set(value) {
|
||||
emits('update:id', value)
|
||||
}
|
||||
})
|
||||
// const decideSwip = ref<boolean>(false)
|
||||
|
||||
const { direction, isSwiping, lengthX, lengthY } = useSwipe(el/*, {
|
||||
onSwipeStart(){
|
||||
console.log('salam')
|
||||
},
|
||||
onSwipe(e: PointerEvent, direction: UseSwipeDirection) {
|
||||
console.log('container',direction)
|
||||
if (!decideSwip.value){
|
||||
if (direction === 'up') {
|
||||
index.value++
|
||||
} else if (direction === 'down') {
|
||||
index.value--
|
||||
}
|
||||
decideSwip.value = true
|
||||
}
|
||||
},
|
||||
onSwipeEnd(e: PointerEvent){
|
||||
console.log('container1')
|
||||
|
||||
decideSwip.value = false
|
||||
}
|
||||
}*/)
|
||||
|
||||
function getRandomColor() {
|
||||
var letters = '0123456789ABCDEF'
|
||||
var color = '#'
|
||||
for (var i = 0; i < 6; i++) {
|
||||
color += letters[Math.floor(Math.random() * 16)]
|
||||
}
|
||||
return color
|
||||
}
|
||||
|
||||
const colors = ['#4B84EB', '#889BCD', '#C9A68D']
|
||||
|
||||
watch(isSwiping, () => {
|
||||
// console.log(direction.value)
|
||||
if (isSwiping.value) {
|
||||
// console.log('salam')
|
||||
if (direction.value === 'up' && props.items.length - 1 > index.value) {
|
||||
index.value++
|
||||
} else if (direction.value === 'down' && index.value > 0) {
|
||||
index.value--
|
||||
}
|
||||
// console.log(index.value)
|
||||
}
|
||||
})
|
||||
|
||||
const index = ref<number>(props.items.length - 1)
|
||||
onMounted(()=> localValue.value = props.items[index.value]?.id)
|
||||
watch(index, (n: number)=> {
|
||||
console.log(n)
|
||||
localValue.value = props.items[n]?.id
|
||||
})
|
||||
|
||||
/*
|
||||
const items = [
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملت',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک سامان',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک پاسارگاد',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک صادرات',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملت',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک سامان',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک پاسارگاد',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
]
|
||||
*/
|
||||
|
||||
// const indexCss = computed(()=> index.value)
|
||||
|
||||
// watch(index,()=>{
|
||||
// key++
|
||||
// console.log(key)
|
||||
// })
|
||||
|
||||
// let key = 0
|
||||
/*function findPosition(pos: number) {
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === index.value){
|
||||
debug = 'w-full z-100'
|
||||
}
|
||||
else /!*if (pos > index.value)*!/{
|
||||
debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
}
|
||||
console.log(debug)
|
||||
return debug
|
||||
}*/
|
||||
/*
|
||||
function mouseUp() {
|
||||
index.value--
|
||||
}
|
||||
|
||||
function mouseDown() {
|
||||
console.log('salam')
|
||||
index.value++
|
||||
}
|
||||
*/
|
||||
|
||||
/*function findPositionStyle(pos: number) {
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === index.value) {
|
||||
debug = 'width: 100; z-index: 100; opacity: 1; margin-top: -200px;'
|
||||
} else /!*if (pos > index.value)*!/{
|
||||
// debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
debug = `width: ${100 - Math.abs(index.value - pos) * 3}%;
|
||||
z-index: ${100 - Math.abs(index.value - pos)};
|
||||
opacity: ${1 - Math.abs((index.value - pos) * 15) / 100};
|
||||
margin-top: ${-200 - Math.abs((index.value - pos) * 4)}px;`
|
||||
}
|
||||
// console.log(debug)
|
||||
return debug
|
||||
}*/
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.slide-up-enter-active,
|
||||
.slide-up-leave-active {
|
||||
transition: all 0.25s ease-out;
|
||||
}
|
||||
|
||||
.slide-up-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateY(3px);
|
||||
}
|
||||
|
||||
.slide-up-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
//.test .card:first-child
|
||||
// margin-top: 0 !important
|
||||
|
||||
//.card
|
||||
// height: 215px
|
||||
// width: 100%
|
||||
// align-self: center
|
||||
// border-radius: 24px
|
||||
// transition: .5s
|
||||
//
|
||||
//.card:first-child
|
||||
// margin-top: 0 !important
|
||||
|
||||
//$total-items: 30
|
||||
|
||||
//@for $i from 1 through $total-items
|
||||
// .card:nth-child(#{$i})
|
||||
// @if($i > v-bind(indexCss))
|
||||
// width: calc(percentage(100 - ($i * 4)) / 100)
|
||||
// @if($i == v-bind(indexCss))
|
||||
// width: 100%
|
||||
// @if($i < v-bind(indexCss))
|
||||
// width: calc(percentage(100 - ($i * 4)) / 100)
|
||||
|
||||
//.animate > div:nth-child(#{$i})
|
||||
// animation-delay: .08s * $i
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,262 @@
|
||||
<template>
|
||||
|
||||
<div ref="container" class=" h-[25vh] flex items-center">
|
||||
<div ref="el" class="w-full flex flex-col relative h-full test">
|
||||
<!-- <div class="card bg-primary" :style="findPositionStyle(1)" @click="index = 1"></div>
|
||||
<div class="card bg-red" :style="findPositionStyle(2)" @click="index = 2"></div>
|
||||
<div class="card bg-yellow" :style="findPositionStyle(3)" @click="index = 3"></div>
|
||||
<div class="card bg-pink relative" :style="findPositionStyle(4)" @click="index = 4">
|
||||
<img :src="ly1" class="absolute h-full" alt="">
|
||||
<img :src="ly2" class="absolute h-full" alt="">
|
||||
</div>-->
|
||||
<!-- <CardItem v-model:sliderIndex="index" color="primary" :self-index="1"/>
|
||||
<CardItem v-model:sliderIndex="index" color="yellow" :self-index="2"/>
|
||||
<CardItem v-model:sliderIndex="index" color="pink" :self-index="3"/>-->
|
||||
<!-- <div class="card bg-pink" :style="findPositionStyle(5)" @click="index = 5"></div>
|
||||
<div class="card bg-pink" :style="findPositionStyle(6)" @click="index = 6"></div>
|
||||
<div class="card bg-pink" :style="findPositionStyle(7)" @click="index = 7"></div>
|
||||
<div class="card bg-pink" :style="findPositionStyle(8)" @click="index = 8"></div>
|
||||
<div class="card bg-pink" :style="findPositionStyle(9)" @click="index = 9"></div>-->
|
||||
<CardItem v-for="(item,i) in props?.items" :key="i" v-model:sliderIndex="index"
|
||||
:color="colors[i%3]"
|
||||
:self-index="i" :img="item"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
// import {usePointerSwipe} from '@vueuse/core'
|
||||
// import type {UseSwipeDirection} from '@vueuse/core'
|
||||
// import type { UseSwipeDirection } from '@vueuse/core'
|
||||
import { useSwipe } from '@vueuse/core'
|
||||
import CardItem from '@/views/base/wallet/components/CardItem.vue'
|
||||
import type { Card } from '@/models/wallet'
|
||||
|
||||
const el = ref(null)
|
||||
const container = ref<HTMLElement | null>(null)
|
||||
|
||||
interface Prop {
|
||||
items: string[]
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
// const decideSwip = ref<boolean>(false)
|
||||
|
||||
const { direction, isSwiping, lengthX, lengthY } = useSwipe(el/*, {
|
||||
onSwipeStart(){
|
||||
console.log('salam')
|
||||
},
|
||||
onSwipe(e: PointerEvent, direction: UseSwipeDirection) {
|
||||
console.log('container',direction)
|
||||
if (!decideSwip.value){
|
||||
if (direction === 'up') {
|
||||
index.value++
|
||||
} else if (direction === 'down') {
|
||||
index.value--
|
||||
}
|
||||
decideSwip.value = true
|
||||
}
|
||||
},
|
||||
onSwipeEnd(e: PointerEvent){
|
||||
console.log('container1')
|
||||
|
||||
decideSwip.value = false
|
||||
}
|
||||
}*/)
|
||||
|
||||
function getRandomColor() {
|
||||
var letters = '0123456789ABCDEF'
|
||||
var color = '#'
|
||||
for (var i = 0; i < 6; i++) {
|
||||
color += letters[Math.floor(Math.random() * 16)]
|
||||
}
|
||||
return color
|
||||
}
|
||||
|
||||
const colors = ['#4B84EB', '#889BCD', '#C9A68D']
|
||||
|
||||
// Automatic slider logic
|
||||
let interval: ReturnType<typeof setInterval>
|
||||
const intervalTime = 10000 // Time interval for sliding (in milliseconds)
|
||||
|
||||
const startAutoSlide = () => {
|
||||
interval = setInterval(() => {
|
||||
if (index.value < props.items.length - 1) {
|
||||
index.value++
|
||||
} else {
|
||||
index.value = 0 // Reset to first card when reaching the end
|
||||
}
|
||||
}, intervalTime)
|
||||
}
|
||||
|
||||
const stopAutoSlide = () => {
|
||||
clearInterval(interval)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
startAutoSlide() // Start sliding when component mounts
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
stopAutoSlide() // Clear interval when component is destroyed
|
||||
})
|
||||
|
||||
watch(isSwiping, () => {
|
||||
// console.log(direction.value)
|
||||
if (isSwiping.value) {
|
||||
// console.log('salam')
|
||||
if (direction.value === 'up' && props.items.length - 1 > index.value) {
|
||||
index.value++
|
||||
} else if (direction.value === 'down' && index.value > 0) {
|
||||
index.value--
|
||||
}
|
||||
// console.log(index.value)
|
||||
}
|
||||
})
|
||||
|
||||
const index = ref<number>(0)
|
||||
|
||||
|
||||
/*
|
||||
const items = [
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملت',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک سامان',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک پاسارگاد',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک صادرات',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملی',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک ملت',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک سامان',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
{
|
||||
title: 'بانک پاسارگاد',
|
||||
cardNumber: 6219861918606103,
|
||||
shaba: 'IR590560611828005106225701',
|
||||
color: getRandomColor()
|
||||
},
|
||||
]
|
||||
*/
|
||||
|
||||
// const indexCss = computed(()=> index.value)
|
||||
|
||||
// watch(index,()=>{
|
||||
// key++
|
||||
// console.log(key)
|
||||
// })
|
||||
|
||||
// let key = 0
|
||||
/*function findPosition(pos: number) {
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === index.value){
|
||||
debug = 'w-full z-100'
|
||||
}
|
||||
else /!*if (pos > index.value)*!/{
|
||||
debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
}
|
||||
console.log(debug)
|
||||
return debug
|
||||
}*/
|
||||
/*
|
||||
function mouseUp() {
|
||||
index.value--
|
||||
}
|
||||
|
||||
function mouseDown() {
|
||||
console.log('salam')
|
||||
index.value++
|
||||
}
|
||||
*/
|
||||
|
||||
/*function findPositionStyle(pos: number) {
|
||||
// console.log(pos,index)
|
||||
let debug
|
||||
if (pos === index.value) {
|
||||
debug = 'width: 100; z-index: 100; opacity: 1; margin-top: -200px;'
|
||||
} else /!*if (pos > index.value)*!/{
|
||||
// debug = `w-[${100 - Math.abs(index.value-pos) * 2}%] z-${100 - Math.abs(index.value-pos)}`
|
||||
debug = `width: ${100 - Math.abs(index.value - pos) * 3}%;
|
||||
z-index: ${100 - Math.abs(index.value - pos)};
|
||||
opacity: ${1 - Math.abs((index.value - pos) * 15) / 100};
|
||||
margin-top: ${-200 - Math.abs((index.value - pos) * 4)}px;`
|
||||
}
|
||||
// console.log(debug)
|
||||
return debug
|
||||
}*/
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
//.test .card:first-child
|
||||
// margin-top: 0 !important
|
||||
|
||||
//.card
|
||||
// height: 215px
|
||||
// width: 100%
|
||||
// align-self: center
|
||||
// border-radius: 24px
|
||||
// transition: .5s
|
||||
//
|
||||
//.card:first-child
|
||||
// margin-top: 0 !important
|
||||
|
||||
//$total-items: 30
|
||||
|
||||
//@for $i from 1 through $total-items
|
||||
// .card:nth-child(#{$i})
|
||||
// @if($i > v-bind(indexCss))
|
||||
// width: calc(percentage(100 - ($i * 4)) / 100)
|
||||
// @if($i == v-bind(indexCss))
|
||||
// width: 100%
|
||||
// @if($i < v-bind(indexCss))
|
||||
// width: calc(percentage(100 - ($i * 4)) / 100)
|
||||
|
||||
//.animate > div:nth-child(#{$i})
|
||||
// animation-delay: .08s * $i
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,162 @@
|
||||
<template lang="pug">
|
||||
.container
|
||||
.slider
|
||||
.slide(data-slide='1' style="background-color: green")
|
||||
.slide(data-slide='2' style="background-color: red")
|
||||
.slide(data-slide='3' style="background-color: orange")
|
||||
.slide.slide--active(data-slide='4' style="background-color: blue")
|
||||
.slide(data-slide='5' style="background-color: violet")
|
||||
.slide(data-slide='5' style="background-color: primary")
|
||||
.slide(data-slide='5' style="background-color: pink")
|
||||
.slide(data-slide='5' style="background-color: teal")
|
||||
.controls
|
||||
#back Back
|
||||
#forvard Forvard
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
renderSlider('.slider');
|
||||
});
|
||||
|
||||
const nextSlide = () => {
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
if (nextSlide) {
|
||||
activeSlide.classList.remove('slide--active');
|
||||
nextSlide.classList.remove('next');
|
||||
nextSlide.classList.add('slide--active');
|
||||
renderSlides();
|
||||
renderBtns();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const renderBtns = () => {
|
||||
let nextBtn = document.querySelector('#forvard');
|
||||
let prevBtn = document.querySelector('#back');
|
||||
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
!prevSlide ? prevBtn.classList.add('disabled')
|
||||
: prevBtn.classList.remove('disabled');
|
||||
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
!nextSlide ? nextBtn.classList.add('disabled')
|
||||
: nextBtn.classList.remove('disabled');
|
||||
}
|
||||
|
||||
const prevSlide = () => {
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
if (prevSlide) {
|
||||
activeSlide.classList.remove('slide--active');
|
||||
prevSlide.classList.remove('prev');
|
||||
prevSlide.classList.add('slide--active');
|
||||
renderSlides();
|
||||
renderBtns();
|
||||
}
|
||||
}
|
||||
|
||||
const renderSlides = () => {
|
||||
let slides = document.querySelectorAll('.slide');
|
||||
if (!slides) {
|
||||
return;
|
||||
}
|
||||
let activeSlide = document.querySelector('.slide--active');
|
||||
if (!activeSlide) {
|
||||
activeSlide = slides.item(0);
|
||||
activeSlide.classList.add('slide--active');
|
||||
}
|
||||
[].forEach.call(slides, function (slide) {
|
||||
slide.classList.remove('prev', 'next')
|
||||
});
|
||||
|
||||
let prevSlide = activeSlide.previousElementSibling;
|
||||
prevSlide && prevSlide.classList.add('prev');
|
||||
|
||||
let nextSlide = activeSlide.nextElementSibling;
|
||||
nextSlide && nextSlide.classList.add('next');
|
||||
|
||||
}
|
||||
|
||||
const renderSlider = (element) => {
|
||||
const slider = document.querySelector(element);
|
||||
if (slider) {
|
||||
let nextButton = document.querySelector("#forvard");
|
||||
nextButton.addEventListener('click', function () {
|
||||
nextSlide();
|
||||
})
|
||||
|
||||
let prevButton = document.querySelector("#back");
|
||||
prevButton.addEventListener('click', function () {
|
||||
prevSlide();
|
||||
})
|
||||
renderSlides();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
.container
|
||||
display: flex
|
||||
flex-flow: column
|
||||
justify-content: center
|
||||
margin: 50px auto 0
|
||||
width: 500px
|
||||
height: 300px
|
||||
|
||||
.controls
|
||||
display: flex
|
||||
justify-content: center
|
||||
|
||||
div
|
||||
padding: 12px 14px
|
||||
cursor: pointer
|
||||
border: 1px solid #fff
|
||||
color: #fff
|
||||
font-size: 16px
|
||||
font-weight: bold
|
||||
margin: 0 5px
|
||||
border-radius: 10px
|
||||
|
||||
&.disabled
|
||||
opacity: 0
|
||||
cursor: default
|
||||
|
||||
|
||||
.slider
|
||||
position: relative
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
.slide
|
||||
position: absolute
|
||||
top: 25%
|
||||
left: 10%
|
||||
width: 80%
|
||||
height: 50%
|
||||
background-color: red
|
||||
border: 1px solid #fff
|
||||
border-radius: 15px
|
||||
opacity: 0
|
||||
transition: all 0.7s ease-out
|
||||
|
||||
&--active
|
||||
opacity: 1
|
||||
z-index: 9
|
||||
|
||||
.prev,
|
||||
.next
|
||||
opacity: .3
|
||||
|
||||
|
||||
.prev
|
||||
transform: translate(0, -30%) scale(0.8)
|
||||
|
||||
.next
|
||||
transform: translate(0, 30%) scale(0.8)
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,687 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="absolute inset-0 bg-cover bg-center opacity-60" :style="{ backgroundImage: `url(${img})` }"></div>
|
||||
<div class="bg-white py-3 px-3 text-primary font-bold drop-shadow z-[1999] wrap-fix">کیف پول</div>
|
||||
<div
|
||||
class="bg-white wrap-fix py-3 top-11 px-3 text-primary font-bold flex justify-evenly z-[1999]"
|
||||
>
|
||||
<div class="flex justify-evenly w-full px-2 h-11 items-center bg-gray-50 relative rounded">
|
||||
<div
|
||||
:class="isDeposit ? 'text-primary' : 'text-gray-400'"
|
||||
class="w-full text-center z-2"
|
||||
@click="setIsDeposit(true)"
|
||||
>
|
||||
واریز
|
||||
</div>
|
||||
<div
|
||||
:class="!isDeposit ? 'text-primary' : 'text-gray-400'"
|
||||
class="w-full text-center z-2"
|
||||
@click="setIsDeposit(false)"
|
||||
>
|
||||
برداشت
|
||||
</div>
|
||||
<!-- <div ref="bganim" class="absolute bg-white h-8 w-1/2 rounded-lg " :style="`transform: translateX(${isDeposit? '0':'-100%'}); left: ${isDeposit? '0':'100%'}`"></div>-->
|
||||
<div
|
||||
ref="bganim"
|
||||
:style="useStyle()"
|
||||
class="absolute bg-white h-8 w-1/2 rounded-lg animate right"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-5 pt-26 pb-2">
|
||||
<a-form :model="form" class="!mt-5" name="basic" @finish="ok()">
|
||||
<div class="border-gray-200 border-1 rounded-xl p-5 trans h-40 relative">
|
||||
<bg_main />
|
||||
<div class="z-100 relative">
|
||||
<a-form-item :rules="[required()]">
|
||||
<BasicInput
|
||||
v-model:value="form.value"
|
||||
addon-before="ریال"
|
||||
addon-bg-color="#0A1B37"
|
||||
addon-text-color="white"
|
||||
place-holder="مبلغ"
|
||||
size="large"
|
||||
type="price"
|
||||
/>
|
||||
</a-form-item>
|
||||
<Transition mode="out-in" name="fade">
|
||||
<div v-if="!isDeposit">
|
||||
<div class="font-bold text-xs">
|
||||
{{
|
||||
`موجودی کیف پول: ${usePriceWithoutType(
|
||||
walletStore?.walletInfo?.cash ?? 0
|
||||
)} ریال`
|
||||
}}
|
||||
</div>
|
||||
<a-form-item v-if="walletStore?.walletInfo" class="!mt-3">
|
||||
<a-slider
|
||||
v-model:value="form.percentWallet"
|
||||
:disabled="walletStore?.walletInfo?.cash <= 0"
|
||||
:max="100"
|
||||
:min="0"
|
||||
:step="10"
|
||||
:tip-formatter="formatter"
|
||||
@change="percentChange"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-else class="flex gap-2 mt-3">
|
||||
<BasicButton class="w-full font-bold !px-1" @click="form.value = 10000000">
|
||||
{{ usePriceWithoutType(10000000) }}
|
||||
</BasicButton>
|
||||
<BasicButton class="w-full font-bold !px-1" @click="form.value = 50000000">
|
||||
{{ usePriceWithoutType(50000000) }}
|
||||
</BasicButton>
|
||||
<BasicButton class="w-full font-bold !px-1" @click="form.value = 100000000">
|
||||
{{ usePriceWithoutType(100000000) }}
|
||||
</BasicButton>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
<a-form-item>
|
||||
<BasicButton
|
||||
:disabled="disableButton"
|
||||
class="w-full py-2 mt-5"
|
||||
html-type="submit"
|
||||
type="primary"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>{{ isDeposit ? 'واریز' : 'برداشت' }}</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<div
|
||||
v-if="isDeposit"
|
||||
ref="el"
|
||||
:class="loading ? 'h-screen' : ''"
|
||||
class="px-3 overflow-y-scroll w-full h-[49vh] pb-16"
|
||||
style="max-height: calc(100vh - 50px)"
|
||||
>
|
||||
<list-anim v-if="!loading" :numberItemsAnim="4">
|
||||
<Item
|
||||
v-for="item in isDeposit ? depositItems : withdrawItems"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
/>
|
||||
<TransactionSkeleton v-if="loadingMore" class="mt-1 mb-8" />
|
||||
</list-anim>
|
||||
<TransactionSkeleton v-for="i in 13" v-else :key="i" class="mt-1" />
|
||||
</div>
|
||||
<!-- <Slider/>-->
|
||||
<Transition mode="out-in" name="fade">
|
||||
<template v-if="!isDeposit">
|
||||
<!-- <MySlider v-if="cardItems.length > 0" :items="cardItems" class="mt-[5vh] pb-[25vh] mb-[16vh]"
|
||||
style="touch-action: none"/>-->
|
||||
<CardSlider
|
||||
v-if="cardItems.length > 0"
|
||||
:items="cardItems"
|
||||
v-model:id="form.card_id"
|
||||
class="card-slider-wrap mt-[2vh] px-3 fixed bottom-10 right-0 left-0"
|
||||
style="touch-action: none"
|
||||
/>
|
||||
<div
|
||||
v-else-if="!loading && cardItems.length === 0"
|
||||
class="h-30 flex items-center justify-center"
|
||||
>
|
||||
هیچ کارتی یافت نشد
|
||||
</div>
|
||||
</template>
|
||||
</Transition>
|
||||
</div>
|
||||
<Transition mode="out-in" name="fade">
|
||||
<div
|
||||
v-if="!isDeposit"
|
||||
class="add-card fixed bottom-0 h-[18vh] bg-[#FBFBFC] w-full shadow-lg rounded-3xl flex justify-center pt-3 z-200"
|
||||
style="box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 26px 11px"
|
||||
@click="showAddCard = true"
|
||||
>
|
||||
<div>افزودن کارت جدید</div>
|
||||
<BasicIcon icon="vuesax-linear:add" />
|
||||
<BasicActionSheet v-model:show="showAddCard" class="!max-h-[95vh]">
|
||||
<div class="font-bold text-lg">افزودن کارت</div>
|
||||
<div class="mt-4 text-red-600 font-bold">توجه : حتما شماره کارت صاحب حساب نرم افزار وارد شود.</div>
|
||||
<div class="pb-20 mt-5">
|
||||
<a-form :model="cardForm">
|
||||
<a-form-item
|
||||
:rules="required()"
|
||||
class="w-full gap-2 !flex-col"
|
||||
label="نام بانک"
|
||||
name="bank_name"
|
||||
>
|
||||
<BasicInput v-model:value="cardForm.bank_name" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item
|
||||
:rules="cardNumberValidation()"
|
||||
class="w-full gap-2 !flex-col"
|
||||
label="شماره کارت"
|
||||
name="cart_number"
|
||||
>
|
||||
<BasicInput v-model:value="cardForm.cart_number" type="number" />
|
||||
</a-form-item>-->
|
||||
<!-- <a-form-item
|
||||
v-if="walletStore.walletInfo"
|
||||
class="w-full gap-2 !flex-col"
|
||||
label="تاریخ تولد"
|
||||
name="cart_number"
|
||||
>
|
||||
<BaseDatePicker v-model:value="cardForm.birth_date" class="w-full" inputReadOnly/>
|
||||
</a-form-item>-->
|
||||
<!-- <a-form-item
|
||||
:rules="required()"
|
||||
class="w-full gap-2 !flex-col"
|
||||
label="شماره حساب"
|
||||
name="account_number"
|
||||
>
|
||||
<BasicInput v-model:value="cardForm.account_number" type="number" />
|
||||
</a-form-item>-->
|
||||
<a-form-item
|
||||
:rules="required()"
|
||||
class="w-full gap-2 !flex-col"
|
||||
label="شماره شبا"
|
||||
name="shaba_number"
|
||||
>
|
||||
<BasicInput v-model:value="cardForm.shaba_number" />
|
||||
</a-form-item>
|
||||
<BasicButton
|
||||
:disabled="loading"
|
||||
class="w-full mt-5 md:mt-10"
|
||||
type="primary"
|
||||
@click="addCard"
|
||||
>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<div v-else>ثبت</div>
|
||||
</BasicButton>
|
||||
<BasicButton class="w-full mt-2" @click="showAddCard = false">بازگشت</BasicButton>
|
||||
</a-form>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
</div>
|
||||
</Transition>
|
||||
<DialogVant v-model:show="showConfirmCode" :closeOnClickOverlay="true" :timeOut="-1">
|
||||
<template v-slot:title>
|
||||
<div>
|
||||
<div class="flex justify-end">
|
||||
<BasicIcon
|
||||
@click="showConfirmCode = false"
|
||||
icon="vuesax-linear:close-circle"
|
||||
size="30"
|
||||
class="text-red"
|
||||
/>
|
||||
</div>
|
||||
<div class="p-5 text-sm">لطفا کد ارسالی را وارد کنید.</div>
|
||||
<div>
|
||||
<OtpInput
|
||||
ref="refOtpInput"
|
||||
:is-input-num="true"
|
||||
:num-inputs="4"
|
||||
:should-auto-focus="true"
|
||||
autocomplete="one-time-code"
|
||||
class="mt-5 justify-center"
|
||||
input-classes="otp-input"
|
||||
separator=""
|
||||
style="direction: ltr"
|
||||
value=""
|
||||
@on-complete="handleOnComplete"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:button>
|
||||
<div></div>
|
||||
<div class="flex justify-end">
|
||||
<BasicButton @click="showConfirmCode = false" class="py-2" type="primary">
|
||||
بستن
|
||||
</BasicButton>
|
||||
</div>
|
||||
</template>
|
||||
</DialogVant>
|
||||
<SkeletonLoading v-model:show="infoVisible" />
|
||||
|
||||
<!--
|
||||
<transaction mode="out-in" name="fade">
|
||||
<div v-if="isDeposit"
|
||||
class="bg-white fixed right-0 left-0 bottom-0 top-20 z-100 op-90 flex justify-center items-center">
|
||||
<div class="flex flex-col justify-center mt-[-20vh] items-center px-5">
|
||||
<DotLottieVue class="w-80vw " autoplay loop
|
||||
src="https://lottie.host/203d9dc9-a102-43a6-864a-2d3eef2daf4d/xNBrLOheY7.json" />
|
||||
<div class="flex justify-center items-center text-justify text-primary font-bold">
|
||||
با توجه به اختلال پیش آمده در سامانه پیپینگ
|
||||
برای شارژ کیف پول خود از طریق لینک زیر اقدام نمایید:
|
||||
</div>
|
||||
<a class="mt-2 w-full " href="https://www.payping.ir/d/Hzy0">
|
||||
<BasicButton class="w-full">https://www.payping.ir/d/Hzy0</BasicButton>
|
||||
</a>
|
||||
<div class="w-full">
|
||||
<div class="text-justify mt-2 text-primary font-bold">
|
||||
و یا مبلغ مورد نظر خود را به شماره حساب:
|
||||
</div>
|
||||
</div>
|
||||
<BasicButton icon="vuesax-linear:copy" class="flex-1 w-full mt-1" icon-size="18" @click.stop="copyCode('838-40-89997745-1')">
|
||||
838-40-89997745-1
|
||||
</BasicButton>
|
||||
<div class="w-full">
|
||||
<div class="text-justify mt-2 text-primary font-bold">
|
||||
با شماره شبا:
|
||||
</div>
|
||||
<BasicButton icon="vuesax-linear:copy" class="flex-1 w-full mt-1" icon-size="18" @click.stop="copyCode('IR550560083804089997745001')">
|
||||
IR550560083804089997745001
|
||||
</BasicButton>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="text-justify mt-2 text-primary font-bold flex">
|
||||
به نام
|
||||
<div class="mx-1 font-extrabold text-blue-600">پديده طلاي شقايق</div>
|
||||
بانک سامان واریز نمایید.
|
||||
</div>
|
||||
<div class="text-justify mt-2 text-primary font-bold">
|
||||
توجه داشته باشید بعد از پرداخت موفق، رسید خود را به شماره 09190909884 در واتس اپ ارسال نمایید.
|
||||
</div>
|
||||
</div>
|
||||
<a class="mt-1 w-full " href="https://wa.me/09190909884">
|
||||
<BasicButton class="w-full !text-green-600" icon="vuesax-linear:whatsapp">شماره واتساپ</BasicButton>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</transaction>
|
||||
-->
|
||||
<BasicModal
|
||||
v-model:visible="chargeAccountModal"
|
||||
custom-footer
|
||||
:closable="false"
|
||||
>
|
||||
<div class="text-center">
|
||||
<div class=" font-bold text-red-600">مشتریان گرامی</div>
|
||||
<div class="mt-2">
|
||||
<span>جهت شارژ حساب کاربری خود، کلمه "شماره حساب" را برای پشتیبانی ارسال نمایید.</span>
|
||||
</div>
|
||||
<BasicButton class="mt-4">
|
||||
<a class="w-full" href="https://wa.me/989123113112">
|
||||
پیام به پشتیبانی
|
||||
</a>
|
||||
</BasicButton>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<a-button type="primary" class="w-full" @click="chargeAccountModal = false">
|
||||
متوجه شدم
|
||||
</a-button>
|
||||
</template>
|
||||
</BasicModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { usePriceWithoutType } from '@/utils/usePrice'
|
||||
import { loading, loadingMore } from '@/utils'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import router from '@/router'
|
||||
import { useWalletStore } from '@/store/walletStore'
|
||||
import Bg_main from '@/components/bg_main.vue'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
import { createCard, deposit, getActivatedCards, withdraw, confirmCode } from '@/api/wallet'
|
||||
import { useInfiniteScroll } from '@vueuse/core'
|
||||
import { message } from 'ant-design-vue'
|
||||
import ListAnim from '@/components/ListAnim.vue'
|
||||
import TransactionSkeleton from '@/components/TransactionSkeleton.vue'
|
||||
import Item from './components/Item.vue'
|
||||
import type { TableEngineInput, TableOutput } from '@/models/table'
|
||||
import {getTransactionTable, getTransactionTable2} from '@/api/transaction'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import CardSlider from './components/UISlider/index.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import type { Card } from '@/models/wallet'
|
||||
import { cardNumberValidation , required } from '@/utils/inputRules'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
import OtpInput from 'vue3-otp-input'
|
||||
import DialogVant from '@/components/DialogVant.vue'
|
||||
import SkeletonLoading from './components/SkeletonLoading.vue'
|
||||
import BaseDatePicker from "@/components/BasicPacks/BaseDatePicker";
|
||||
import img from "@/assets/img/user_ly1.svg";
|
||||
import BasicModal from "@/components/BasicPacks/BasicModal.vue";
|
||||
const isDeposit = ref<boolean>(true)
|
||||
const walletStore = useWalletStore()
|
||||
const userStore = useUserStore()
|
||||
const showAddCard = ref<boolean>(false)
|
||||
const chargeAccountModal = ref<boolean>(false)
|
||||
const showConfirmCode = ref<boolean>(false)
|
||||
const refOtpInput = ref<InstanceType<typeof VOtpInput> | null>(null)
|
||||
|
||||
onMounted(() => {
|
||||
if (router.currentRoute.value.query.state === 'deposit') {
|
||||
isDeposit.value = true
|
||||
}
|
||||
walletStore.getMyWallet()
|
||||
isDeposit.value = true
|
||||
})
|
||||
|
||||
const form = ref<Transaction>({
|
||||
value: undefined,
|
||||
percentWallet: 0,
|
||||
card_id: undefined
|
||||
})
|
||||
|
||||
const infoVisible = ref<boolean>(false)
|
||||
const cardForm = ref<Card>({
|
||||
birth_date: 0,
|
||||
account_number: '',
|
||||
bank_name: '',
|
||||
cart_number: '',
|
||||
shaba_number: ''
|
||||
})
|
||||
|
||||
const disableButton = computed(() => {
|
||||
if (!loading.value) {
|
||||
if (walletStore?.walletInfo?.cash && !isDeposit.value) {
|
||||
if (cardItems.value.length > 0) {
|
||||
return (
|
||||
walletStore?.walletInfo?.cash <= 0 ||
|
||||
walletStore?.walletInfo?.cash < parseInt(form.value?.value) ||
|
||||
isNaN(parseInt(form.value?.value)) ||
|
||||
parseInt(form.value?.value) < 1000000
|
||||
)
|
||||
} else return true
|
||||
} else if (isDeposit.value) {
|
||||
return isNaN(parseInt(form.value?.value)) || parseInt(form.value?.value) < 1000000
|
||||
} else return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
const bganim = ref(null)
|
||||
|
||||
const unitCalculator = computed(() => {
|
||||
return (walletStore?.walletInfo?.cash ?? 0) / 100
|
||||
})
|
||||
|
||||
function copyCode(val: string) {
|
||||
// nextTick(() => {
|
||||
navigator.clipboard.writeText(val)
|
||||
message.info('کد رونوشت شد')
|
||||
// })
|
||||
}
|
||||
|
||||
const cardItems = ref<Card[]>([])
|
||||
|
||||
const cardTableOutput = ref<TableOutput<Card> | null>(null)
|
||||
|
||||
const resetData = () => {
|
||||
form.value.value = undefined
|
||||
form.value.percentWallet = 0
|
||||
}
|
||||
|
||||
async function addCard() {
|
||||
try {
|
||||
loading.value = true
|
||||
await createCard(cardForm.value)
|
||||
await getCards()
|
||||
showAddCard.value = false
|
||||
cardForm.value = {
|
||||
birth_date: 0,
|
||||
account_number: '',
|
||||
bank_name: '',
|
||||
cart_number: '',
|
||||
shaba_number: ''
|
||||
}
|
||||
message.success('کارت وارد شده با موفقیت افزوده شد و پس از تایید نمایش داده خواهد شد.')
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function getCards() {
|
||||
try {
|
||||
/* cardTableOutput.value = await getCardsTable()
|
||||
cardItems.value.push(...cardTableOutput.value.rows)*/
|
||||
cardItems.value = (await getActivatedCards()) ?? []
|
||||
form.value.card_id = (await cardItems.value.length) ? cardItems.value[0].id : undefined
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
function setIsDeposit(val: boolean) {
|
||||
isDeposit.value = val
|
||||
form.value.value = undefined
|
||||
form.value.percentWallet = 0
|
||||
// console.log(bganim.value.classList)
|
||||
// bganim?.value?.classList.add(val?'right':'left')
|
||||
// bganim?.value?.style.transform = `translateX(${val ? '0' : '-100'});`
|
||||
// bganim?.value?.style.animationDirection = val? 'normal':'reverse'
|
||||
// val? bganim?.value?.classList?.add("move") : bganim?.value?.classList?.remove("move")
|
||||
// const el = bganim.value?.
|
||||
// el.
|
||||
}
|
||||
|
||||
function useStyle() {
|
||||
if (isDeposit.value) return 'right: 2%;'
|
||||
// if (isDeposit.value) return 'animation-direction: normal'
|
||||
// else return 'animation-direction: reverse'
|
||||
else return ' right: 98%; transform: translate(100%, 0);'
|
||||
}
|
||||
|
||||
const formatter = (value: number) => {
|
||||
return `${value}%`
|
||||
}
|
||||
|
||||
function percentChange(val: number) {
|
||||
if (val !== 0) form.value.value = parseInt((unitCalculator.value * val).toFixed())
|
||||
else form.value.value = undefined
|
||||
}
|
||||
|
||||
async function ok() {
|
||||
try {
|
||||
if (form.value.value !== undefined) {
|
||||
loading.value = true
|
||||
if (!isDeposit.value) {
|
||||
await confirmCode({ value: form.value.value })
|
||||
showConfirmCode.value = await true
|
||||
}
|
||||
if (isDeposit.value) {
|
||||
chargeAccountModal.value = true
|
||||
/*const data = await deposit(form.value)
|
||||
window.location.href = data
|
||||
await walletStore.getMyWallet()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')*/
|
||||
}
|
||||
} else {
|
||||
message.error('ابتدا مبلغ را وارد کنید')
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
//table
|
||||
const items = ref<Transaction[]>([])
|
||||
const depositItems = ref<Transaction[]>([])
|
||||
const withdrawItems = ref<Transaction[]>([])
|
||||
const depositTableOutput = ref<TableOutput<Transaction> | null>(null)
|
||||
const withdrawTableOutput = ref<TableOutput<Transaction> | null>(null)
|
||||
const depositPagination = ref<TableEngineInput>({
|
||||
filters: [
|
||||
/*{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 3
|
||||
}*/
|
||||
],
|
||||
limit: 6,
|
||||
page: 0
|
||||
})
|
||||
const withdrawPagination = ref<TableEngineInput>({
|
||||
filters: [
|
||||
{
|
||||
field: 'type',
|
||||
cr: 'and',
|
||||
type: 'number',
|
||||
op: 'eq',
|
||||
value: 4
|
||||
}
|
||||
],
|
||||
limit: 6,
|
||||
page: 0
|
||||
})
|
||||
const el = ref()
|
||||
// const {y} = useScroll(el)
|
||||
|
||||
onMounted(async () => {
|
||||
cardForm.value.birth_date = userStore.userInfo?.birth_date
|
||||
await initWithdrawTable()
|
||||
await initDepositTable()
|
||||
await getCards()
|
||||
})
|
||||
if (!userStore.isSingle) {
|
||||
useInfiniteScroll(
|
||||
el,
|
||||
async () => {
|
||||
// load more
|
||||
// if (!userStore.isSingle) {
|
||||
if (isDeposit.value) {
|
||||
if (
|
||||
depositTableOutput.value &&
|
||||
(depositPagination.value.page + 1) * depositPagination.value.limit <
|
||||
depositTableOutput.value.query.total
|
||||
) {
|
||||
depositPagination.value.page++
|
||||
console.log('Updated Page:', depositPagination.value.page)
|
||||
await initDepositTable()
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
withdrawTableOutput.value &&
|
||||
(withdrawPagination.value.page + 1) * withdrawPagination.value.limit <
|
||||
withdrawTableOutput.value.query.total
|
||||
) {
|
||||
// console.log('gfgf')
|
||||
withdrawPagination.value.page++
|
||||
await initWithdrawTable()
|
||||
}
|
||||
}
|
||||
// }
|
||||
},
|
||||
{ distance: 12 }
|
||||
)
|
||||
}
|
||||
|
||||
async function initDepositTable() {
|
||||
try {
|
||||
depositPagination.value.page === 0 ? (loading.value = true) : (loadingMore.value = true)
|
||||
depositTableOutput.value = await getTransactionTable2(depositPagination.value)
|
||||
depositItems.value.push(...depositTableOutput.value.rows)
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function initWithdrawTable() {
|
||||
try {
|
||||
withdrawPagination.value.page === 0 ? (loading.value = true) : (loadingMore.value = true)
|
||||
withdrawTableOutput.value = await getTransactionTable(withdrawPagination.value)
|
||||
withdrawItems.value.push(...withdrawTableOutput.value.rows)
|
||||
// console.log(tableOutput.value)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleOnComplete(value: string) {
|
||||
try {
|
||||
infoVisible.value = true
|
||||
showConfirmCode.value = false
|
||||
await withdraw({ ...form.value, otp: value })
|
||||
await walletStore.getMyWallet()
|
||||
await message.success('عملیات با موفقیت انجام شد')
|
||||
resetData()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
infoVisible.value = false
|
||||
refOtpInput.value?.clearInput()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*.right {
|
||||
left: 100%;
|
||||
transform: translateX(-100%);
|
||||
}*/
|
||||
|
||||
.left {
|
||||
transform: translateX(0);
|
||||
left: 0;
|
||||
}
|
||||
|
||||
/*.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}*/
|
||||
/*.trans{
|
||||
transition: height 1s;
|
||||
}*/
|
||||
.toggle-transe-parent {
|
||||
animation: ease-in-out infinite alternate swingParent;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 426px) {
|
||||
:deep(.ant-form-item .ant-form-item-label) {
|
||||
margin-top: 30px !important;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 426px) {
|
||||
.card-slider-wrap {
|
||||
width: 426px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 426px) {
|
||||
.add-card {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user