diff --git a/src/api/wallet.js b/src/api/wallet.js index a63e5e7..4148ce4 100644 --- a/src/api/wallet.js +++ b/src/api/wallet.js @@ -120,6 +120,15 @@ export function searchFreightUser(account) { return get(`/wallet/freight/search-user?account=${account}`) } +/** + * 经销商搜索已有 coin seller + * @param {string} account - 用户账号 + * @returns {Promise} 返回 coin seller 用户信息 + */ +export function searchDealerFreightUser(account) { + return get(`/wallet/freight/dealer/search-user?account=${account}`) +} + /** * 金币充值 * @param {Object} data - 充值数据 @@ -131,6 +140,35 @@ export function freightRecharge(data) { return post('/wallet/freight/ship', data) } +/** + * 获取当前超级经销商的子 coin seller 列表 + * @returns {Promise} 返回子 coin seller 列表 + */ +export function getFreightSubSellers() { + return get('/wallet/freight/super/sub-sellers') +} + +/** + * 绑定已有 coin seller 为当前超级经销商的子 coin seller + * @param {Object} data + * @param {number|string} data.userId - 子 coin seller 用户ID + * @returns {Promise} + */ +export function addFreightSubSeller(data) { + return post('/wallet/freight/super/sub-sellers', data) +} + +/** + * 从当前超级经销商币商钱包转账给子 coin seller 币商钱包 + * @param {Object} data + * @param {number|string} data.acceptUserId - 子 coin seller 用户ID + * @param {number|string} data.quantity - 转账金币数量 + * @returns {Promise} 返回当前超级经销商剩余余额 + */ +export function transferFreightSubSeller(data) { + return post('/wallet/freight/super/sub-sellers/transfer', data) +} + /** * 获取金币交易流水 * @param {string} data diff --git a/src/locales/ar.json b/src/locales/ar.json index 4dd1b61..edc2215 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -92,7 +92,20 @@ "join_team_steps": "انا>مركز>طلب الانضمام إلى الفريق", "enter_team_id": "أدخل id الفريق وانقر على إرسال للانضمام", "recharge_agency": "وكيل الشحن", + "invite_sub_coin_seller": "Invite sub coin seller", "my_coins": "عملاتي الذهبية", + "current_balance": "الرصيد الحالي", + "balance": "الرصيد", + "refresh": "تحديث", + "sub_coin_sellers": "بائعو العملات الفرعيون", + "sub_coin_seller_list": "قائمة بائعي العملات الفرعيين", + "enter_coin_seller_id": "أدخل معرف بائع العملات", + "bind_sub_coin_seller": "ربط", + "sub_coin_seller_bound": "تمت إضافة بائع العملات الفرعي", + "no_sub_coin_sellers": "لا يوجد بائعو عملات فرعيون", + "transfer_to_sub_coin_seller": "تحويل إلى بائع العملات الفرعي", + "enter_transfer_amount": "أدخل مبلغ التحويل", + "sub_coin_seller_transfer_success": "تم التحويل بنجاح", "user": "مستخدم", "search_user": "البحث عن المستخدم", "enter_user_id": "يرجى إدخال id المستخدم", @@ -290,6 +303,7 @@ "prowide_income": "الدخل المقدم", "copied_successfully": "تم النسخ بنجاح", "please_enter_valid_invitation_code": "يرجى إدخال رمز دعوة صالح.", + "please_enter_valid_amount": "يرجى إدخال مبلغ صالح.", "invitation_code_bound_successfully": "تم ربط رمز الدعوة بنجاح!", "invitation_code_binding_failed": "فشل ربط رمز الدعوة.", "user_id_prefix": "المعرف:", diff --git a/src/locales/bn.json b/src/locales/bn.json index bcab449..734dbfb 100644 --- a/src/locales/bn.json +++ b/src/locales/bn.json @@ -92,7 +92,20 @@ "join_team_steps": "আমি > হোস্ট সেন্টার > দলে যোগদানের জন্য আবেদন করুন।", "enter_team_id": "দল আইডি লিখুন, যোগদান করতে পাঠান এ ক্লিক করুন।", "recharge_agency": "রিচার্জ এজেন্সি", + "invite_sub_coin_seller": "Invite sub coin seller", "my_coins": "আমার মুদ্রা:", + "current_balance": "বর্তমান ব্যালেন্স", + "balance": "ব্যালেন্স", + "refresh": "রিফ্রেশ", + "sub_coin_sellers": "সাব coin seller", + "sub_coin_seller_list": "সাব coin seller তালিকা", + "enter_coin_seller_id": "coin seller ID লিখুন", + "bind_sub_coin_seller": "বাইন্ড", + "sub_coin_seller_bound": "সাব coin seller যোগ করা হয়েছে", + "no_sub_coin_sellers": "কোনো সাব coin seller নেই", + "transfer_to_sub_coin_seller": "সাব coin seller-এ ট্রান্সফার", + "enter_transfer_amount": "ট্রান্সফার পরিমাণ লিখুন", + "sub_coin_seller_transfer_success": "ট্রান্সফার সফল", "user": "ব্যবহারকারী:", "search_user": "ব্যবহারকারী অনুসন্ধান", "enter_user_id": "দয়া করে ব্যবহারকারী আইডি লিখুন", @@ -290,6 +303,7 @@ "prowide_income": "প্রোওয়াইড আয়", "copied_successfully": "সফলভাবে কপি করা হয়েছে", "please_enter_valid_invitation_code": "দয়া করে একটি বৈধ আমন্ত্রণ কোড লিখুন।", + "please_enter_valid_amount": "একটি বৈধ পরিমাণ লিখুন।", "invitation_code_bound_successfully": "আমন্ত্রণ কোড সফলভাবে বাউন্ড হয়েছে!", "invitation_code_binding_failed": "আমন্ত্রণ কোড বাউন্ডিং ব্যর্থ।", "user_id_prefix": "আইডি:", diff --git a/src/locales/en.json b/src/locales/en.json index c508615..08a728f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -92,7 +92,20 @@ "join_team_steps": "Me > Host Center >Apply to join the team.", "enter_team_id": "Enter the team ID,click send to join.", "recharge_agency": "Recharge agency", + "invite_sub_coin_seller": "Invite sub coin seller", "my_coins": "My coins:", + "current_balance": "Current balance", + "balance": "Balance", + "refresh": "Refresh", + "sub_coin_sellers": "Sub coin sellers", + "sub_coin_seller_list": "Sub coin seller list", + "enter_coin_seller_id": "Enter coin seller ID", + "bind_sub_coin_seller": "Bind", + "sub_coin_seller_bound": "Sub coin seller added", + "no_sub_coin_sellers": "No sub coin sellers", + "transfer_to_sub_coin_seller": "Transfer to sub coin seller", + "enter_transfer_amount": "Enter transfer amount", + "sub_coin_seller_transfer_success": "Transfer successful", "user": "User :", "search_user": "Search user", "enter_user_id": "Please enter the user ID", @@ -290,6 +303,7 @@ "prowide_income": "Prowide income", "copied_successfully": "Copied successfully", "please_enter_valid_invitation_code": "Please enter a valid invitation code.", + "please_enter_valid_amount": "Please enter a valid amount.", "invitation_code_bound_successfully": "Invitation code bound successfully!", "invitation_code_binding_failed": "Invitation code binding failed.", "user_id_prefix": "ID:", diff --git a/src/locales/tr.json b/src/locales/tr.json index d91dbcf..27498ba 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -92,7 +92,20 @@ "join_team_steps": "Ben > Host Merkezi > Takıma katılmak için başvur.", "enter_team_id": "Takım ID'sini girin, katılmak için gönder'e tıklayın.", "recharge_agency": "Yükleme acentesi", + "invite_sub_coin_seller": "Invite sub coin seller", "my_coins": "Coinlerim:", + "current_balance": "Mevcut bakiye", + "balance": "Bakiye", + "refresh": "Yenile", + "sub_coin_sellers": "Alt coin seller", + "sub_coin_seller_list": "Alt coin seller listesi", + "enter_coin_seller_id": "Coin seller ID girin", + "bind_sub_coin_seller": "Bağla", + "sub_coin_seller_bound": "Alt coin seller eklendi", + "no_sub_coin_sellers": "Alt coin seller yok", + "transfer_to_sub_coin_seller": "Alt coin seller'a transfer", + "enter_transfer_amount": "Transfer tutarını girin", + "sub_coin_seller_transfer_success": "Transfer başarılı", "user": "Kullanıcı:", "search_user": "Kullanıcı ara", "enter_user_id": "Lütfen kullanıcı ID'sini girin", @@ -290,6 +303,7 @@ "prowide_income": "Prowide geliri", "copied_successfully": "Başarıyla kopyalandı", "please_enter_valid_invitation_code": "Lütfen geçerli bir davet kodu girin.", + "please_enter_valid_amount": "Lütfen geçerli bir miktar girin.", "invitation_code_bound_successfully": "Davet kodu başarıyla bağlandı!", "invitation_code_binding_failed": "Davet kodu bağlama başarısız.", "user_id_prefix": "ID:", diff --git a/src/locales/zh.json b/src/locales/zh.json index 6544eae..10325b4 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -92,7 +92,20 @@ "join_team_steps": "我>主播中心>申请加入团队", "enter_team_id": "输入团队ID,点击发送加入。", "recharge_agency": "充值代理", + "invite_sub_coin_seller": "Invite sub coin seller", "my_coins": "我的金币", + "current_balance": "当前余额", + "balance": "余额", + "refresh": "刷新", + "sub_coin_sellers": "子 coin seller", + "sub_coin_seller_list": "子 coin seller 列表", + "enter_coin_seller_id": "请输入 coin seller ID", + "bind_sub_coin_seller": "绑定", + "sub_coin_seller_bound": "子 coin seller 已添加", + "no_sub_coin_sellers": "暂无子 coin seller", + "transfer_to_sub_coin_seller": "转账给子 coin seller", + "enter_transfer_amount": "请输入转账金额", + "sub_coin_seller_transfer_success": "转账成功", "user": "用户", "search_user": "搜索用户", "enter_user_id": "请输入用户id", @@ -290,6 +303,7 @@ "prowide_income": "提供收入", "copied_successfully": "复制成功", "please_enter_valid_invitation_code": "请输入有效的邀请码。", + "please_enter_valid_amount": "请输入有效金额。", "invitation_code_bound_successfully": "邀请码绑定成功!", "invitation_code_binding_failed": "邀请码绑定失败。", "user_id_prefix": "ID:", diff --git a/src/router/index.js b/src/router/index.js index 43f034c..c19f5a6 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -143,6 +143,12 @@ const router = createRouter({ component: () => import('../views/RechargeAgency/SellerRecordsView.vue'), meta: { requiresAuth: true }, }, + { + path: '/coin-seller/sub-sellers', + name: 'coin-seller-sub-sellers', + component: () => import('../views/RechargeAgency/SubSellers.vue'), + meta: { requiresAuth: true, requiresSuperDealer: true }, + }, { path: '/recharge-agency-recruit', name: 'recharge-agency-recruit', diff --git a/src/utils/permissionManager.js b/src/utils/permissionManager.js index a48f43d..809140e 100644 --- a/src/utils/permissionManager.js +++ b/src/utils/permissionManager.js @@ -17,6 +17,7 @@ export const USER_ROLES = { // 页面路径常量 export const PAGES = { COIN_SELLER: '/coin-seller', + COIN_SELLER_SUB_SELLERS: '/coin-seller/sub-sellers', AGENCY_CENTER: '/agency-center', BD_LEADER_CENTER: '/bd-leader-center', BD_CENTER: '/bd-center', @@ -146,6 +147,7 @@ export const ROLE_PERMISSIONS = { // Freight Agent (充值代理Rechange Agency/货运代理Freight Agent/金币代理Coin Seller) [USER_ROLES.FREIGHT_AGENT]: [ PAGES.COIN_SELLER, // 主页面 + PAGES.COIN_SELLER_SUB_SELLERS, // 超级经销商子coin seller '/seller-records', '/coin-seller-search', ], diff --git a/src/utils/routeGuard.js b/src/utils/routeGuard.js index eaf16e3..108376e 100644 --- a/src/utils/routeGuard.js +++ b/src/utils/routeGuard.js @@ -5,7 +5,7 @@ * 3. redirecting users to pages they can access */ -import { getUserIdentity, getMemberProfile } from '../api/wallet.js' +import { apiGetFreightThreshold, getUserIdentity, getMemberProfile } from '../api/wallet.js' import { isPublicPath } from '@/config/security.js' import { isDebugMode } from './env.js' import { permissionManager, PAGES, USER_ROLES } from './permissionManager.js' @@ -156,6 +156,15 @@ class IdentityChecker { } } +class SuperDealerRouteChecker { + async check(userId) { + if (!userId) return false + + const response = await apiGetFreightThreshold(userId) + return Boolean(response?.status && response.body?.superDealer) + } +} + class PageRedirector { async redirectToCorrectPage(router, targetPath, currentPath) { const hasPermission = permissionManager.hasPagePermission(targetPath) @@ -183,6 +192,7 @@ class RouteGuard { constructor() { this.appConnectionChecker = new AppConnectionChecker() this.identityChecker = new IdentityChecker() + this.superDealerRouteChecker = new SuperDealerRouteChecker() this.pageRedirector = new PageRedirector() this.isGuardActive = false } @@ -233,6 +243,16 @@ class RouteGuard { } if (permissionManager.hasPagePermission(to.path)) { + if (to.meta?.requiresSuperDealer) { + // Super dealer pages need a second check because the base role only tells us the user is a coin seller. + const isSuperDealer = await this.superDealerRouteChecker.check(getUserId()) + if (!isSuperDealer) { + console.groupEnd() + next(PAGES.COIN_SELLER) + return + } + } + console.groupEnd() next() return diff --git a/src/views/RechargeAgency/SubSellers.vue b/src/views/RechargeAgency/SubSellers.vue new file mode 100644 index 0000000..49c54cb --- /dev/null +++ b/src/views/RechargeAgency/SubSellers.vue @@ -0,0 +1,566 @@ + + + + + diff --git a/src/views/RechargeAgency/index.vue b/src/views/RechargeAgency/index.vue index f033d79..afade28 100644 --- a/src/views/RechargeAgency/index.vue +++ b/src/views/RechargeAgency/index.vue @@ -92,6 +92,12 @@ + + +