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 @@
+
+
+ {{ currentBalance }}
+
+
+
+
+