gateway
This commit is contained in:
+8
-5
@@ -62,6 +62,9 @@ export function setEnableAuthenticate() {
|
||||
|
||||
|
||||
function goToLogin(to: RouteLocationNormalized, next: NavigationGuardNext) {
|
||||
if (to.name === 'buyProduct') {
|
||||
return next() // Allow access to buyProduct without login
|
||||
}
|
||||
if (to.name !== 'login') {
|
||||
return next({ name: 'login' }) // Redirect to login
|
||||
} else {
|
||||
@@ -135,9 +138,9 @@ router.beforeEach(async (to, from, next) => {
|
||||
return next()
|
||||
}
|
||||
} else {
|
||||
// If no token, handle redirect to login or allow access to login or 404
|
||||
if (['login', '404'].includes(to.name as string)) {
|
||||
return next() // Allow access to login or 404
|
||||
// If no token, handle redirect to login or allow access to login, 404, or buyProduct
|
||||
if (['login', '404', 'buyProduct'].includes(to.name as string)) {
|
||||
return next() // Allow access to login, 404, or buyProduct
|
||||
}
|
||||
goToLogin(to, next) // Redirect to login if no token
|
||||
}
|
||||
@@ -153,8 +156,8 @@ router.beforeEach(async (to, from, next) => {
|
||||
return next() // Proceed to the intended route
|
||||
} else {
|
||||
// If no token, ensure proper redirection to login or 404
|
||||
if (['login', '404'].includes(to.name as string)) {
|
||||
return next() // Allow access to login or 404
|
||||
if (['login', '404', 'buyProduct'].includes(to.name as string)) {
|
||||
return next() // Allow access to login, 404, or buyProduct
|
||||
}
|
||||
return next({ name: 'login' })
|
||||
}
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ export interface Gold {
|
||||
goldValue?: number | null,
|
||||
percentWallet?: number,
|
||||
method?:string,
|
||||
goldVazn?: number | null
|
||||
goldVazn?: number | null,
|
||||
gateway?: boolean
|
||||
|
||||
}
|
||||
@@ -20,4 +20,5 @@ export interface Order {
|
||||
"product_id"?:number
|
||||
"method"?:string
|
||||
"number"?:number
|
||||
"gateway"?:boolean
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@ const router = createRouter({
|
||||
{
|
||||
path: `/`,
|
||||
name: 'main',
|
||||
redirect: {name: 'login'},
|
||||
redirect: {name: 'buyProduct'},
|
||||
component: () => import('../views/base/index.vue'),
|
||||
children: [
|
||||
{
|
||||
|
||||
+16
-12
@@ -135,6 +135,7 @@ let methodP = 'cash'
|
||||
let amountP = 0
|
||||
let isBuyP = true
|
||||
let NumP = 0
|
||||
let gatewayP = false
|
||||
const checkNumber = async (_rule: Rule, value: number) => {
|
||||
|
||||
|
||||
@@ -145,18 +146,20 @@ const checkNumber = async (_rule: Rule, value: number) => {
|
||||
return Promise.reject('استفاده از اعداد اعشاری مجاز نمی باشد')
|
||||
}
|
||||
if (isBuyP) {
|
||||
if (!walletCash?.walletInfo?.cash && methodP == 'cash') {
|
||||
return Promise.reject('موجودی کیف پول ناکافی است')
|
||||
// Skip wallet balance check if gateway is enabled
|
||||
if (!gatewayP) {
|
||||
if (!walletCash?.walletInfo?.cash && methodP == 'cash') {
|
||||
return Promise.reject('موجودی کیف پول ناکافی است')
|
||||
}
|
||||
if (!walletCash?.walletInfo?.gold && methodP == 'gold') {
|
||||
return Promise.reject('موجودی کیف طلا ناکافی است')
|
||||
}
|
||||
if (priceP * value > walletCash?.walletInfo?.cash && methodP == 'cash')
|
||||
return Promise.reject('موجودی کیف پول ناکافی است')
|
||||
if (amountP * value > walletCash?.walletInfo?.gold && methodP == 'gold')
|
||||
return Promise.reject('موجودی کیف طلا ناکافی است')
|
||||
}
|
||||
if (!walletCash?.walletInfo?.gold && methodP == 'gold') {
|
||||
return Promise.reject('موجودی کیف طلا ناکافی است')
|
||||
}
|
||||
if (priceP * value > walletCash?.walletInfo?.cash && methodP == 'cash')
|
||||
return Promise.reject('موجودی کیف پول ناکافی است')
|
||||
if (amountP * value > walletCash?.walletInfo?.gold && methodP == 'gold')
|
||||
return Promise.reject('موجودی کیف طلا ناکافی است')
|
||||
else
|
||||
return Promise.resolve()
|
||||
return Promise.resolve()
|
||||
} else {
|
||||
if (value > NumP)
|
||||
return Promise.reject('موجودی محصول ناکافی است')
|
||||
@@ -165,11 +168,12 @@ const checkNumber = async (_rule: Rule, value: number) => {
|
||||
}
|
||||
|
||||
}
|
||||
export const justNumber2 = (price: number, method?: string, amount?: number, isBuy?: boolean) => {
|
||||
export const justNumber2 = (price: number, method?: string, amount?: number, isBuy?: boolean, gateway?: boolean) => {
|
||||
priceP = price
|
||||
methodP = method
|
||||
amountP = amount
|
||||
isBuyP = isBuy
|
||||
gatewayP = gateway ?? false
|
||||
return {
|
||||
required: true,
|
||||
validator: checkNumber,
|
||||
|
||||
@@ -65,8 +65,10 @@ _axios.interceptors.response.use(
|
||||
///removeToken()
|
||||
console.log('error')
|
||||
removeToken()
|
||||
// router.push({ name: 'login' })
|
||||
await router.push({name: 'login'})
|
||||
// Don't redirect to login if user is on buyProduct page
|
||||
if (router.currentRoute.value.name !== 'buyProduct') {
|
||||
await router.push({name: 'login'})
|
||||
}
|
||||
} else if (error.response && error.response.status == 403) {
|
||||
message.error('شما دسترسی لازم برای انجام این عملیات را ندارید')
|
||||
} else if (error.response && error.response.status == 422) {
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
<div>دریافت طلای فیزیکی</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton icon-size="16" class="!font-bold w-15rem"
|
||||
@click="$router.push({name: 'buyProduct'}); popVisible = false">
|
||||
<div class="flex gap-2 items-center">
|
||||
<BasicIcon icon="vuesax-linear:products" size="16" class="absolute right-2" />
|
||||
<div>محصولات</div>
|
||||
</div>
|
||||
</BasicButton>
|
||||
<BasicButton icon-size="16" class="!font-bold w-15rem"
|
||||
@click="openReceivesList(); popVisible = false">
|
||||
<div class="flex gap-2 items-center">
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
حداقل مبلغ اولیه برای ثبت سفارش {{ usePriceWithoutType(limitedPrice.value as number ?? 0) }} ریال می باشد.
|
||||
</div>
|
||||
<!-- </a-spin>-->
|
||||
<a-form ref="refInput" :model="form" class="!mt-5" name="basic" @finish="okConfirm()">
|
||||
<a-form ref="refInput" :model="form" class="!mt-5" name="basic" @finish="okConfirm()" @finishFailed="(errorInfo) => { console.log('Form submit failed:', errorInfo); console.log('Error fields details:', JSON.stringify(errorInfo.errorFields, null, 2)); if (errorInfo.errorFields && errorInfo.errorFields.length > 0) { const firstError = errorInfo.errorFields[0]; console.log('First error field:', firstError.name, 'errors:', firstError.errors); message.error(firstError.errors?.[0] || 'لطفا تمام فیلدها را به درستی پر کنید') } }">
|
||||
<div class="border-gray-200 border-1 rounded-xl p-5 relative">
|
||||
<bg_main />
|
||||
<div class="z-100 relative">
|
||||
@@ -60,7 +60,7 @@
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="isBuy" name="goldValue"
|
||||
:rules="[justNumber2(props?.ProductItem?.price , form.method , props?.ProductItem?.amount, true)]">
|
||||
:rules="[justNumber2(props?.ProductItem?.price , form.method , props?.ProductItem?.amount, true, form.gateway)]">
|
||||
<BasicInput v-model:value="form.goldValue" addon-before="تعداد" addon-bg-color="#521620"
|
||||
addon-text-color="white"
|
||||
place-holder="تعداد"
|
||||
@@ -104,6 +104,16 @@
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
<a-form-item-rest v-if="isBuy && form.method === 'cash'">
|
||||
<div class="mt-4 w-full px-6 rounded-xl py-1 border-1 bg-white">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>استفاده از درگاه:</div>
|
||||
<div class="flex gap-2 items-center">
|
||||
<a-switch v-model:checked="form.gateway" size="small" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-form-item-rest>
|
||||
<GoldLoading v-model:show="infoVisible" title="" />
|
||||
<a-form-item>
|
||||
<BasicButton
|
||||
@@ -112,6 +122,7 @@
|
||||
class=" w-full py-2 mt-5"
|
||||
html-type="submit"
|
||||
type="primary"
|
||||
@click="() => console.log('Button clicked, disabled:', disableTransaction, 'walletStore:', !!walletStore)"
|
||||
>
|
||||
<div>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
@@ -221,25 +232,24 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<BasicButton class="mb-20 mt-5 w-full" type="primary" @click="ok(); confirmAction= false">ثبت نهایی</BasicButton>
|
||||
<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 { computed, onMounted, ref, watch } from 'vue'
|
||||
import img1 from '@/assets/img/home_ly2.svg'
|
||||
import {useFormat, usePrice, usePriceWithoutType, useTowDecimal} from '@/utils/usePrice'
|
||||
import {useFormat, usePrice, usePriceWithoutType} from '@/utils/usePrice'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import type { Gold } from '@/models/gold'
|
||||
import { loading, loadingMore, toFixedDownThreeChar } from '@/utils'
|
||||
import { loading, loadingMore } 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'
|
||||
@@ -250,15 +260,14 @@ import GoldLoading from '@/components/GoldLoading.vue'
|
||||
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 { getLastPrices, lastPrice } 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: 'نقدی',
|
||||
@@ -324,15 +333,30 @@ const finalPrice = computed(() => (form.value?.goldValue * (isBuy.value ? props.
|
||||
// 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)
|
||||
const disableTransaction = computed(() => {
|
||||
// If gateway is enabled, skip wallet balance checks
|
||||
if (isBuy.value && form.value?.gateway) {
|
||||
return (
|
||||
loading.value ||
|
||||
form.value?.goldValue === undefined ||
|
||||
form.value?.goldValue === '' ||
|
||||
form.value?.goldCash === '' ||
|
||||
form.value?.goldCash === undefined ||
|
||||
price.value?.buy === undefined
|
||||
)
|
||||
}
|
||||
// Normal validation when gateway is disabled
|
||||
return (
|
||||
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 = []
|
||||
@@ -442,8 +466,10 @@ const form = ref<Gold>({
|
||||
goldValue: undefined,
|
||||
percentWallet: undefined,
|
||||
method: 'cash',
|
||||
goldVazn:undefined
|
||||
goldVazn:undefined,
|
||||
gateway: false
|
||||
})
|
||||
|
||||
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, () => {
|
||||
@@ -454,8 +480,26 @@ watch(form.value, () => {
|
||||
calculateCash(form.value.goldValue)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Re-validate when gateway changes
|
||||
watch(() => form.value.gateway, () => {
|
||||
if (isBuy.value && form.value.goldValue) {
|
||||
// Clear validation errors and re-validate
|
||||
refInput.value?.clearValidate('goldValue')
|
||||
setTimeout(() => {
|
||||
refInput.value?.validateFields(['goldValue']).catch(() => {
|
||||
// Ignore validation errors, just trigger re-validation
|
||||
})
|
||||
}, 100)
|
||||
}
|
||||
})
|
||||
|
||||
// Reset gateway when method changes to non-cash
|
||||
watch(() => form.value.method, (newMethod) => {
|
||||
if (newMethod !== 'cash' && form.value.gateway) {
|
||||
form.value.gateway = false
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
@@ -508,7 +552,6 @@ const limitedPrice = computed(() => {
|
||||
|
||||
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)
|
||||
@@ -520,7 +563,6 @@ console.log(val,props?.ProductItem?.price,props?.ProductItem?.cash_fee_buy,lastP
|
||||
else {
|
||||
form.value.goldCash = 0
|
||||
form.value.goldVazn = 0
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -581,7 +623,6 @@ function useStyle() {
|
||||
else return ' right: 98%; transform: translate(100%, 0);'
|
||||
}
|
||||
|
||||
|
||||
function setIsBuy(val: boolean) {
|
||||
isBuy.value = val
|
||||
form.value.goldValue = undefined
|
||||
@@ -602,13 +643,7 @@ 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 {
|
||||
@@ -627,36 +662,68 @@ async function initPrice() {
|
||||
}
|
||||
}
|
||||
|
||||
// onMounted(() => {
|
||||
// initPrice()
|
||||
// })
|
||||
|
||||
function okConfirm() {
|
||||
confirmAction.value = true
|
||||
refInput.value?.validateFields()
|
||||
async function okConfirm() {
|
||||
try {
|
||||
console.log('okConfirm called, form values:', form.value)
|
||||
console.log('disableTransaction:', disableTransaction.value)
|
||||
await refInput.value?.validateFields()
|
||||
console.log('Validation passed, showing confirmation action sheet')
|
||||
// If validation passes, show confirmation action sheet
|
||||
confirmAction.value = true
|
||||
console.log('confirmAction set to:', confirmAction.value)
|
||||
} catch (error) {
|
||||
// Validation failed, don't show action sheet
|
||||
console.error('Validation failed:', error)
|
||||
message.error('لطفا تمام فیلدها را به درستی پر کنید')
|
||||
}
|
||||
}
|
||||
|
||||
async function ok() {
|
||||
console.log('ok() function called')
|
||||
try {
|
||||
loading.value = true
|
||||
infoVisible.value = true
|
||||
await createOrder({
|
||||
const data = await createOrder({
|
||||
direction: isBuy.value ? 1 : 2,
|
||||
price: isBuy.value ? price.value?.buy : price.value?.sell,
|
||||
amount: form.value.goldValue ?? 0,
|
||||
gateway: form.value.gateway,
|
||||
product_id: props.ProductItem.id,
|
||||
method: form.value.method,
|
||||
number: form.value.goldValue ?? 0
|
||||
})
|
||||
|
||||
// console.log('Order response:', data) // Debug log
|
||||
// Check if response has returnUrl (for gateway payment)
|
||||
|
||||
let returnUrl = null
|
||||
if (Array.isArray(data)) {
|
||||
const itemWithReturnUrl = data.find(item => item?.returnUrl)
|
||||
returnUrl = itemWithReturnUrl?.returnUrl
|
||||
} else if (data?.returnUrl) {
|
||||
returnUrl = data.returnUrl
|
||||
}
|
||||
|
||||
console.log('Return URL:', returnUrl) // Debug log
|
||||
|
||||
// If returnUrl exists, redirect to gateway and stop execution
|
||||
if (returnUrl) {
|
||||
window.location.href = returnUrl
|
||||
return // Stop execution here
|
||||
}
|
||||
// If no gateway, continue with normal flow
|
||||
await walletStore.getMyWallet()
|
||||
await router.push({ name: 'transactions' })
|
||||
form.value = {
|
||||
goldValue: undefined,
|
||||
goldCash: undefined,
|
||||
percentWallet: undefined,
|
||||
method: 'cash'
|
||||
method: 'cash',
|
||||
gateway: false
|
||||
}
|
||||
// refreshTable()
|
||||
await fundStore.getMyFund()
|
||||
message.success('سفارش شما با موفقیت انجام شد')
|
||||
await fundStore.getMyFund()
|
||||
} catch (e) {
|
||||
// console.log(e)
|
||||
// await initPrice()
|
||||
@@ -706,7 +773,6 @@ async function ok() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.animate.right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
/>
|
||||
</div>
|
||||
<a-spin :spinning="loading">
|
||||
|
||||
<div class=" !h-full overflow-y-scroll">
|
||||
|
||||
<div class="w-full flex justify-center top-0 py-5" style="align-self: center">
|
||||
<ARadioGroup @change="changeTab" v-model:value="activekey" button-style="solid">
|
||||
<ARadioButton class="cats" value="همه">همه</ARadioButton>
|
||||
@@ -44,15 +42,11 @@ import { getProducts } from '@/api/products'
|
||||
import {
|
||||
getLastPrices,
|
||||
lastPrice,
|
||||
setIntervalGetAllPrice,
|
||||
// setIntervalGetLastPrice,
|
||||
stopPriceInterval
|
||||
} from '@/utils/price'
|
||||
import { loading } from '@/utils'
|
||||
import { Price } from '@/models/home'
|
||||
import type { Product } from '@/models/products'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import indexGold from '@/views/base/gold/index.vue'
|
||||
import DealProduct from '@/views/base/products/components/DealProduct.vue'
|
||||
@@ -98,8 +92,14 @@ onMounted(async () => {
|
||||
// await setIntervalGetLastPrice()
|
||||
// console.log('run product')
|
||||
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
// If 401 error, set empty items to show page without products
|
||||
if (e?.response?.status === 401) {
|
||||
items.value = []
|
||||
firstItems.value = []
|
||||
typeItems.value = []
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
if (router.currentRoute.value.query.cat=="coin"){
|
||||
@@ -146,8 +146,13 @@ async function initPrice() {
|
||||
// await setIntervalGetPrice()
|
||||
loading.value = true
|
||||
price.value = lastPrice.value
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
// If 401 error, just skip price initialization
|
||||
if (e?.response?.status === 401) {
|
||||
// Price will not be available, but page can still be shown
|
||||
price.value = undefined
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
// chartLoading.value = false
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
متوجه شدم
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</DialogVantOneButton>
|
||||
|
||||
<!-- <van-dialog/>-->
|
||||
|
||||
Reference in New Issue
Block a user