# Khanegi — اپ مشتری (User Panel) پنل وب/PWA برای **مشتریان خانگی** پلتفرم معاملات طلا و آبشده. این اپ بخش front-end مشتری در monorepo پروژه Khanegi است. | مورد | مقدار | |------|--------| | نام پکیج | `customer` | | نسخه | `1.0.8` | | فریم‌ورک | Vue 3 + TypeScript | | بیلد | Vite 4 | | State | Pinia | | UI | Ant Design Vue 3 + Vant 4 (موبایل) | | پورت dev | `3100` | --- ## نقش در معماری Khanegi ``` Khanegi/ ├── userModular/ ← این پروژه (پنل مشتری) ├── admin/ ← پنل مدیریت └── server/ ← API اصلی (Laravel) ``` | اتصال | پروتکل | آدرس | |--------|--------|------| | API اصلی | HTTPS + JWT | `{node_server}/customer/*`, `/auth/*` | | قیمت لحظه‌ای | SSE | `{node_server}/api/price/stream` | | تنظیمات tenant | HTTPS | `/get_user` (قبل از لود اپ) | --- ## پیش‌نیازها - Node.js 18+ - npm، yarn یا pnpm --- ## نصب و اجرا ```bash cd userModular npm install npm run dev # http://localhost:3100 npm run build # vite build npm run preview # پیش‌نمایش production npm run type-check # بررسی TypeScript npm run lint # ESLint npm run format # Prettier ``` --- ## ساختار پروژه ``` userModular/ ├── src/ │ ├── views/ # صفحات اصلی │ │ ├── login/ # ورود / ثبت‌نام │ │ └── base/ # صفحات اپ (mobile/ + desktop/) │ ├── api/ # لایه REST (18 ماژول) │ ├── router/ # مسیرها + guard │ ├── store/ # Pinia (user, wallet, fund, settings, config) │ ├── config/ # بارگذاری tenant config │ ├── app/ # bootstrap.ts, createApp.ts, setupRouter │ ├── utils/ # priceSocket (SSE), authToken, useAxios │ ├── modules/ # PWA manifest │ ├── models/ # TypeScript types │ ├── layouts/ # Layout موبایل/دسکتاپ │ └── sw.ts # Service Worker (PWA) ├── public/ ├── index.html ├── vite.config.ts ├── uno.config.ts ├── themeConfig.ts └── src/mainConfig.ts ``` --- ## قابلیت‌های اصلی ### احراز هویت - ورود با رمز عبور یا SMS - تأیید OTP (`POST /auth/verify`) - ثبت‌نام (`POST /auth/register`) — کد معرف، احراز Jibit (اختیاری) - Provider: `customer` ### صفحه اصلی و معاملات - نمودار قیمت و صفحه home - خرید/فروش طلا (`/gold`) - خرید محصول (`/buyProduct`) - قیمت لحظه‌ای از SSE با fallback polling ### کیف پول و تراکنش‌ها - مانده ریال و طلا (`/wallet`) - تاریخچه تراکنش‌ها (`/transactions`) - برداشت نقدی و فیزیکی - شارژ از درگاه PayPing ### صندوق (Fund) - لیست صندوق‌ها (`/fund`) - جزئیات صندوق (`/fund/:id`) - واریز/برداشت صندوق ### سایر - پروفایل کاربر (`/user`) - آدرس (`/address`) - دریافت فیزیکی طلا (`/physicalReceive`) - هشدار قیمت (`/notifyTrigger`) - کسب درآمد / معرف (`/earnMoney`) - کارت هدیه (`/giftCard`) - قوانین و مجوزها (`/rules`, `/permissions`) - آموزش (`/educate`) - درباره ما (`/aboutUs`) ### حالت فروشگاهی (`is_store`) - سبد خرید (`/api/cart/*`) - حواله (`/customer/havale`) - checkout (`/customer/cart/checkout`) --- ## مسیرها (Routes) | مسیر | نام | توضیح | |------|-----|--------| | `/login` | login | ورود | | `/home` | home | صفحه اصلی / نمودار | | `/gold` | gold | معامله طلا | | `/buyProduct` | buyProduct | خرید محصول | | `/wallet` | wallet | کیف پول | | `/transactions` | transactions | تراکنش‌ها | | `/user` | user | پروفایل | | `/notifyTrigger` | notifyTrigger | هشدار قیمت | | `/address` | address | آدرس | | `/physicalReceive` | physicalReceive | دریافت فیزیکی | | `/physicalReceive/new` | new | درخواست جدید | | `/earnMoney` | earnMoney | کسب درآمد / معرف | | `/giftCard` | giftCard | کارت هدیه | | `/fund` | fund | صندوق‌ها | | `/fund/:id` | fund_info | جزئیات صندوق | | `/fund/add` | fund_add | صندوق جدید | | `/rules` | rules | قوانین | | `/permissions` | permissions | مجوزها | | `/educate` | educate | آموزش | | `/aboutUs` | aboutUs | درباره ما | **ساختار UI:** هر صفحه معمولاً `mobile/` و `desktop/` دارد. **Guard:** بدون token به `/login` هدایت می‌شود. --- ## اتصال به Backend ### Bootstrap 1. `index.html` — loader 2. `bootstrap.ts` → `loadAppConfig()` — fetch config tenant 3. `setAppConfig()` + `applyAppConfig()` — نگاشت `node_server` 4. `startPwaManifest()` — PWA 5. mount Vue؛ اگر token باشد: `getUserInfo()` + `initPriceRealtimeChannel()` ### REST API - **Base URL:** `getConfigApp('node_server')` ← فیلد `node_server` در JSON tenant - **Token:** `customer_session_token` (ثابت) یا `{name}_app_token` (legacy) - **Header:** `Authorization: Bearer ` - **Axios:** `src/utils/useAxios.ts` — 401 → logout؛ verify با `/customer/me` | پیشوند | کاربرد | |--------|--------| | `/auth/*` | login, verify, register | | `/customer/*` | me, order, wallet, fund, address | | `/api/*` | candle, price/last, city, get_settings | ### قیمت لحظه‌ای (SSE) - **فایل:** `src/utils/priceSocket.ts` - **Endpoint:** `GET /api/price/stream` (EventSource) - **Fallback:** polling هر 10 ثانیه اگر SSE قطع شود - **Reconnection:** exponential backoff (3s → 30s) - در حالت non-store نیاز به JWT customer دارد ### Multi-tenant Config URLهای failover برای `/get_user`: - `https://nerkh.gold/get_user` - `https://tablo.talasevin.ir/get_user` - `https://abshode-service.montgit.ir/server/get_user` - `http://212.23.201.173:8381/get_user` - `http://91.212.174.137:4040/server/get_user` | فیلد JSON | معادل اپ | |-----------|----------| | `node_server` | API base | | `name`, `name_fa`, `avatar` | برند | | `color`, `background_color` | تم | Cache: `localStorage.CONFIG_Success_URL` + cookie `APP_CONFIG_CACHE` --- ## Pinia Stores | Store | نقش | |-------|-----| | `userStore` | اطلاعات کاربر، auth | | `walletStore` | مانده کیف پول | | `fundStore` | صندوق‌ها | | `settingsStore` | تنظیمات اپ | | `configStore` | config tenant | | `useAuthStore` | وضعیت احراز هویت | --- ## API Modules | فایل | Endpoints | |------|-----------| | `login.ts` | `/auth/login`, `/auth/verify`, `/auth/register` | | `me.ts` | `/customer/me`, `/customer/me/update` | | `home.ts` | نمودار، قیمت | | `order.ts` | `/customer/order` | | `wallet.ts` | `/customer/wallet/*` | | `fund.ts` | `/customer/fund/*` | | `products.ts` | محصولات | | `address.ts` | `/customer/address` | | `giftCard.ts` | `/customer/giftcard/use` | | `earnMoney.ts` | معرف | | `triggerPrice.ts` | هشدار قیمت | | `physicalreceive.ts` | دریافت فیزیکی | | `configuration.ts` | `/api/get_settings` | --- ## PWA - `vite-plugin-pwa` با `injectManifest` - Service Worker: `src/sw.ts` - Manifest: نام و آیکون از config tenant - `display: standalone`, `orientation: portrait-primary` --- ## فایل‌های Config مهم | فایل | نقش | |------|-----| | `vite.config.ts` | Vite، PWA، UnoCSS، port 3100 | | `src/config/load-config.ts` | fetch config ریموت | | `src/config/app-config.ts` | نگاشت tenant | | `src/themeConfig.ts` | token keys، رنگ‌ها | | `src/utils/useAxios.ts` | Axios + auth | | `src/router/index.ts` | routes | | `src/app/bootstrap.ts` | راه‌اندازی اپ | | `src/sw.ts` | Service Worker | --- ## نکات توسعه 1. **دو لایه realtime:** REST روی Laravel؛ قیمت از SSE با fallback polling. 2. **Multi-tenant:** یک build برای چند برند؛ رفتار با `settings` و `is_store` تغییر می‌کند. 3. **Responsive:** هر view دو نسخه `mobile/` و `desktop/` دارد. 4. **Token persistence:** `customer_session_token` برای جلوگیری از گم شدن token هنگام به‌روزرسانی config. 5. **انیمیشن:** Lottie (`@lottiefiles/dotlottie-vue`)، Odometer برای اعداد. --- ## مستندات مرتبط - [README سرور Laravel](../server/README.md) - [README پنل ادمین](../admin/README.md) - [README نمای کلی](../README.md)