1404/10/28-base
This commit is contained in:
@@ -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