1404/11/19-add inventory for product

This commit is contained in:
2026-02-09 13:43:02 +03:30
parent 71312d809d
commit 8919374055
10 changed files with 55 additions and 43 deletions
+1
View File
@@ -26,6 +26,7 @@ export interface Product {
description: string
wallet: Wallet
similar?:Product[]
inventory:number
}
export interface PInventory {
+2 -2
View File
@@ -67,10 +67,10 @@
</div>
</div>
<div class="wrap-fix bottom-0 px-10 py-6 flex gap-2 bg-white items-center">
<a class="w-full" href="https://rubika.ir/nore8tom">
<a class="w-full" href="https://web.rubika.ir/#c=u0I8F1U0a939b0df5ba9f73618d33d7c">
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
</a>
<a href="https://rubika.ir/nore8tom">
<a href="https://web.rubika.ir/#c=u0I8F1U0a939b0df5ba9f73618d33d7c">
<img src="@/assets/img/rubika.webp" alt="" class=" w-12"/>
</a>
</div>
+1 -1
View File
@@ -308,7 +308,7 @@ async function handleCheckout() {
return {
direction: 1, // 1 for buy (cart items are always buy orders)
price: productPrice,
amount: item.quantity,
amount: product.amount,
gateway: item.gateway,
product_id: product.id,
method: item.method,
@@ -95,7 +95,7 @@
</div>
<span
v-if="!props.ProductItem.show"
v-if="!props.ProductItem?.inventory || props.ProductItem?.inventory==0"
class="text-xs bg-gray-300 text-gray-600 px-2 py-0.5 rounded-md"
>
ناموجود
@@ -30,7 +30,7 @@
</div>
<span
v-if="!props.ProductItem.show"
v-if="!props.ProductItem?.inventory || props.ProductItem?.inventory==0"
class="text-xs bg-gray-300 text-gray-600 px-2 py-0.5 rounded-md"
>
ناموجود
+3 -4
View File
@@ -18,11 +18,10 @@
</div>
<div class="mx-5 pb-30 pt-2 grid grid-cols-2 gap-2" style="color: #1b2b07">
<div class="mt-3 gap-2 " :class="!viewVertical?'col-span-2':''" v-for="item in items">
<ProductItemVertical v-if="viewVertical" :ProductItem="item" @click="clickProduct(item)"></ProductItemVertical>
<ProductItem v-else class="col-span-2" :ProductItem="item" @click="clickProduct(item)"></ProductItem>
<div class="mt-3 gap-2 " :class="!viewVertical?'col-span-2':''" v-for="item in items?.filter(i => i.show)">
<ProductItemVertical v-if="viewVertical" :ProductItem="item" @click="clickProduct(item)"></ProductItemVertical>
<ProductItem v-else class="col-span-2" :ProductItem="item" @click="clickProduct(item)"></ProductItem>
</div>
</div>
</div>
+42 -30
View File
@@ -1,13 +1,13 @@
<template>
<div class="bottom-0 fixed top-0">
<img :src="img" alt="" class="w-inherit" :style="{ backgroundRepeat: 'repeat' }" />
<img :src="img" alt="" class="w-inherit" :style="{ backgroundRepeat: 'repeat' }"/>
</div>
<a-spin :spinning="loading">
<div class="!h-full overflow-y-scroll">
<div class="mx-5 pb-30 pt-5" style="color: #1b2b07">
<!-- Product Image -->
<div class="bg-gray-100 rounded-lg w-full flex justify-center mb-4">
<img :src="getProductImage(product)" class="max-w-full h-auto" />
<img :src="getProductImage(product)" class="max-w-full h-auto"/>
</div>
<!-- Product Title -->
@@ -20,7 +20,7 @@
<div class="flex-1">
<!-- Buy Button -->
<BasicButton
v-if="product?.show && product?.open_buy"
v-if="product?.show && product?.open_buy &&(product?.inventory || product?.inventory >0)"
class="w-full py-3 "
type="primary"
size="large"
@@ -34,6 +34,9 @@
<div v-else-if="!product?.open_buy" class="text-center text-gray-500 py-4">
خرید این محصول در حال حاضر امکان پذیر نیست
</div>
<div v-else-if="!product?.inventory || product?.inventory==0" class="text-center text-gray-500 py-4">
ناموجود
</div>
</div>
@@ -44,30 +47,30 @@
<div v-if="product?.description" class="mb-6">
<div class="text-lg font-semibold mb-2">توضیحات محصول:</div>
<div class="text-base text-gray-700 whitespace-pre-line">{{ product?.description }}</div>
<!-- <div class="text-base text-gray-700 whitespace-pre-line">شمش طلای نقش برجسته ونوس ۱ گرمی انتخابی ظریف و ارزشمند برای سرمایه‌گذاری و هدیه است. این شمش از طلای خالص با عیار بالا ساخته شده و نقش برجسته‌ی الهه ونوس، نمادی از زیبایی و ظرافت، جلوه‌ای هنری و خاص به آن بخشیده است. وزن دقیق ۱ گرم، ابعاد مناسب و بسته‌بندی شکیل، این محصول را به گزینه‌ای ایده‌آل برای نگهداری ارزش، هدیه‌های خاص و کلکسیون‌های طلا تبدیل می‌کند. </div>-->
<!-- <div class="text-base text-gray-700 whitespace-pre-line">شمش طلای نقش برجسته ونوس ۱ گرمی انتخابی ظریف و ارزشمند برای سرمایه‌گذاری و هدیه است. این شمش از طلای خالص با عیار بالا ساخته شده و نقش برجسته‌ی الهه ونوس، نمادی از زیبایی و ظرافت، جلوه‌ای هنری و خاص به آن بخشیده است. وزن دقیق ۱ گرم، ابعاد مناسب و بسته‌بندی شکیل، این محصول را به گزینه‌ای ایده‌آل برای نگهداری ارزش، هدیه‌های خاص و کلکسیون‌های طلا تبدیل می‌کند. </div>-->
</div>
<!-- Similar Products -->
<div v-if="product?.similar?.length" class="mt-8">
<div class="text-lg font-semibold mb-4">محصولات مشابه</div>
<swiper
:slides-per-view="2.25"
:space-between="16"
class="similar-products-swiper"
:slides-per-view="2.25"
:space-between="16"
class="similar-products-swiper"
>
<swiper-slide
v-for="item in product.similar"
:key="item.id"
v-for="item in product.similar"
:key="item.id"
>
<div
class="bg-white rounded-lg shadow p-4 cursor-pointer h-full"
@click="goToProduct(item.id)"
class="bg-white rounded-lg shadow p-4 cursor-pointer h-full"
@click="goToProduct(item.id)"
>
<!-- Image -->
<div class="bg-gray-100 rounded-md flex justify-center p-4 mb-2">
<img
:src="getProductImage(item)"
class="h-20 object-contain"
:src="getProductImage(item)"
class="h-20 object-contain"
/>
</div>
@@ -75,11 +78,17 @@
<div class="text-sm font-semibold mb-1 line-clamp-2">
{{ item.title }}
</div>
<!-- Price -->
<div class="text-sm text-primary font-bold">
<div class="text-sm text-primary font-bold mb-3">
{{ usePrice((item.price ?? 0) + (item.cash_fee_buy ?? 0)) }}
</div>
<span
v-if="item.inventory || item.inventory==0"
class="text-xs bg-gray-300 text-gray-600 px-1 py-0.5 rounded-md "
>
ناموجود
</span>
</div>
</swiper-slide>
</swiper>
@@ -101,24 +110,24 @@
<script setup lang="ts">
import {onMounted, onUnmounted, ref, computed, watch} from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {useRoute, useRouter} from 'vue-router'
import {getProductById, getProducts} from '@/api/products'
import { loading, getToken } from '@/utils'
import type { Product } from '@/models/products'
import {loading, getToken} from '@/utils'
import type {Product} from '@/models/products'
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
import indexGold from '@/views/base/gold/index.vue'
import DealProduct from '@/views/base/products/components/DealProduct.vue'
import { cloneDeep } from 'lodash'
import {cloneDeep} from 'lodash'
import img from '@/assets/img/user_ly1.svg'
import { message } from 'ant-design-vue'
import {message} from 'ant-design-vue'
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
import { usePrice } from '@/utils/usePrice'
import {usePrice} from '@/utils/usePrice'
import {
getLastPrices,
lastPrice,
stopPriceInterval
} from '@/utils/price'
import { Swiper, SwiperSlide } from 'swiper/vue'
import {Swiper, SwiperSlide} from 'swiper/vue'
import 'swiper/swiper-bundle.css'
// Image imports
@@ -143,10 +152,11 @@ watch(
(newId, oldId) => {
if (newId && newId !== oldId) {
loadProduct()
window.scrollTo({ top: 0, behavior: 'smooth' })
window.scrollTo({top: 0, behavior: 'smooth'})
}
}
)
async function loadProduct() {
try {
loading.value = true
@@ -155,7 +165,7 @@ async function loadProduct() {
const foundProduct = products
if (!foundProduct) {
message.error('محصول یافت نشد')
router.push({ name: 'buyProduct' })
router.push({name: 'buyProduct'})
return
}
product.value = foundProduct
@@ -164,7 +174,7 @@ async function loadProduct() {
console.log(e)
if (e?.response?.status === 401) {
message.warning('برای مشاهده محصولات، لطفا ابتدا وارد حساب کاربری خود شوید')
router.push({ name: 'login' })
router.push({name: 'login'})
} else {
message.error('خطا در بارگذاری محصول')
}
@@ -172,9 +182,10 @@ async function loadProduct() {
loading.value = false
}
}
watch(lastPrice, async () => {
// console.log(items);
if (lastPrice.value && product.value.similar) {
if (lastPrice.value && product.value.similar) {
product.value.similar.forEach((val) => {
// console.log(lastPrice.value)
if (val.group_type == 'آبشده') {
@@ -189,7 +200,7 @@ watch(lastPrice, async () => {
})
}
}, { deep: true })
}, {deep: true})
async function initPrice() {
try {
@@ -215,7 +226,7 @@ function handleBuyClick() {
if (!product.value?.show) {
return
}
// // Check if user is logged in
// if (!getToken()) {
// message.warning('برای خرید یا فروش محصولات، لطفا ابتدا وارد حساب کاربری خود شوید')
@@ -234,8 +245,9 @@ onMounted(() => {
onUnmounted(() => {
stopPriceInterval()
})
function goToProduct(id: number) {
router.push({ name: 'productDetail', params: { id } })
router.push({name: 'productDetail', params: {id}})
}
function getProductImage(product: any) {
@@ -243,7 +255,7 @@ function getProductImage(product: any) {
if (product?.file?.src) {
return product.file.src
}
// Fallback to local images based on group_type if file is empty or doesn't exist
const type = product?.group_type
switch (type) {
+2 -2
View File
@@ -155,13 +155,13 @@
</div>
</div>
<div class="wrap-fix bottom-0 px-10 py-6 flex gap-2 bg-white items-center">
<a class="w-full" href="https://rubika.ir/nore8tom">
<a class="w-full" href="https://web.rubika.ir/#c=u0I8F1U0a939b0df5ba9f73618d33d7c">
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
</a>
<!-- <BasicButton type="primary" @click="$router.push({name: 'permissions'})">
<div>مجوز ها</div>
</BasicButton>-->
<a href="https://rubika.ir/nore8tom">
<a href="https://web.rubika.ir/#c=u0I8F1U0a939b0df5ba9f73618d33d7c">
<img src="@/assets/img/rubika.webp" alt="" class="w-12"/>
</a>
</div>
+1 -1
View File
@@ -302,7 +302,7 @@
<span>جهت شارژ حساب کاربری خود، کلمه "شماره حساب" را برای پشتیبانی ارسال نمایید.</span>
</div>
<BasicButton class="mt-4">
<a class="w-full" href="https://rubika.ir/nore8tom">
<a class="w-full" href="https://web.rubika.ir/#c=u0I8F1U0a939b0df5ba9f73618d33d7c">
پیام به پشتیبانی
</a>
</BasicButton>