diff --git a/src/components/core/layouts/art-notification/index.vue b/src/components/core/layouts/art-notification/index.vue
index dace245..0848193 100644
--- a/src/components/core/layouts/art-notification/index.vue
+++ b/src/components/core/layouts/art-notification/index.vue
@@ -3,9 +3,7 @@
@@ -119,7 +117,7 @@
ElMessage.info(item.body || '该通知暂无可跳转目标')
return
}
- if (!navigateNotificationTarget(router, targetResponse.data)) {
+ if (!navigateNotificationTarget(router, item.ref_type, targetResponse.data)) {
ElMessage.info(item.body || '该通知暂无可跳转目标')
} else {
close()
diff --git a/src/router/routes/asyncRoutes.ts b/src/router/routes/asyncRoutes.ts
index 4234a07..cf38408 100644
--- a/src/router/routes/asyncRoutes.ts
+++ b/src/router/routes/asyncRoutes.ts
@@ -739,7 +739,7 @@ export const asyncRoutes: AppRouteRecord[] = [
{
path: 'agent-fund-overview',
name: 'AgentFundOverview',
- component: RoutesAlias.AgentFundOverview,
+ component: RoutesAlias.AgentFundOverviewComponent,
meta: {
title: 'menus.commission.agentCommission',
keepAlive: true,
diff --git a/src/router/routesAlias.ts b/src/router/routesAlias.ts
index c0bc861..6e06647 100644
--- a/src/router/routesAlias.ts
+++ b/src/router/routesAlias.ts
@@ -89,7 +89,8 @@ export enum RoutesAlias {
// 佣金管理
WithdrawalApproval = '/commission-management/withdrawal-approval', // 提现审批
MyCommission = '/commission-management/my-commission', // 我的佣金
- AgentFundOverview = '/commission-management/agent-fund-overview', // 代理商资金概况
+ AgentFundOverview = '/commission/agent-fund-overview', // 代理商资金概况
+ AgentFundOverviewComponent = '/commission-management/agent-fund-overview', // 代理商资金概况组件路径
// 设置管理
WithdrawalSettings = '/settings/withdrawal-settings', // 提现配置
diff --git a/src/types/api/notification.ts b/src/types/api/notification.ts
index 609fba3..bbb2db5 100644
--- a/src/types/api/notification.ts
+++ b/src/types/api/notification.ts
@@ -1,6 +1,22 @@
export type NotificationCategory = 'approval' | 'expiry' | 'sync' | 'system' | string
export type NotificationSeverity = 'info' | 'warning' | 'error' | 'critical' | string
+/** 后台通知引用的受控资源类型。 */
+export type NotificationRefType =
+ | 'system_config'
+ | 'integration_log'
+ | 'package'
+ | 'asset'
+ | 'refund'
+ | 'agent_recharge'
+ | 'wecom_approval'
+ | 'iot_card'
+ | 'device'
+ | 'expiring_asset'
+ | 'shop_fund'
+ | 'card_sync'
+ | (string & {})
+
export interface NotificationItem {
id: number
title: string
@@ -11,7 +27,7 @@ export interface NotificationItem {
is_read: boolean
created_at: string
read_at: string | null
- ref_type: string | null
+ ref_type: NotificationRefType | null
ref_id: string | null
ref_key: string | null
}
@@ -63,7 +79,7 @@ export interface NotificationReadAllResponse {
export interface NotificationTarget {
available: boolean
- target_id: number | null
+ target_id: number | string | null
target_key: string
target_type: string
}
diff --git a/src/utils/business/notificationNavigation.ts b/src/utils/business/notificationNavigation.ts
index e7a77ea..6cc2457 100644
--- a/src/utils/business/notificationNavigation.ts
+++ b/src/utils/business/notificationNavigation.ts
@@ -1,70 +1,56 @@
-import type { Router } from 'vue-router'
-import type { NotificationTarget } from '@/types/api'
+import type { RouteLocationRaw, Router } from 'vue-router'
+import type { NotificationRefType, NotificationTarget } from '@/types/api'
import { RoutesAlias } from '@/router/routesAlias'
-type TargetRoute = {
- path: string
- query?: Record
+type TargetRoute = RouteLocationRaw
+
+const resolveTargetRoute = (
+ refType: NotificationRefType | null,
+ target: NotificationTarget
+): TargetRoute | null => {
+ const targetId = target.target_id === null ? '' : String(target.target_id)
+
+ switch (refType) {
+ case 'system_config':
+ return { path: RoutesAlias.SystemConfigs }
+ case 'refund':
+ return { path: RoutesAlias.RefundManagement }
+ case 'agent_recharge':
+ return { path: RoutesAlias.AgentRecharge }
+ case 'iot_card':
+ return targetId ? { path: RoutesAlias.AssetInformation, query: { iccid: targetId } } : null
+ case 'device':
+ return targetId
+ ? { path: RoutesAlias.AssetInformation, query: { virtual_no: targetId } }
+ : null
+ case 'expiring_asset':
+ return { path: RoutesAlias.ExpiringAssets }
+ case 'shop_fund':
+ return { path: RoutesAlias.AgentFundOverview }
+ case 'integration_log':
+ case 'package':
+ case 'asset':
+ case 'wecom_approval':
+ case 'card_sync':
+ default:
+ return null
+ }
}
-const resolveTargetRoute = (target: NotificationTarget): TargetRoute | null => {
- const targetId = target.target_id === null ? undefined : String(target.target_id)
- const targetKey = target.target_key || ''
-
- if (target.target_type === 'refund_detail' && targetId) {
- return { path: `${RoutesAlias.RefundDetail}/${targetId}` }
+export const navigateNotificationTarget = (
+ router: Router,
+ refType: NotificationRefType | null,
+ target?: NotificationTarget | null
+) => {
+ if (!target) return false
+ if (!target.available) {
+ void router.push(RoutesAlias.Exception403)
+ return true
}
- if (target.target_type === 'agent_recharge_detail' && targetId) {
- return { path: `${RoutesAlias.AgentRechargeDetail}/${targetId}` }
- }
-
- if (target.target_type === 'iot_card_detail' && (targetKey || targetId)) {
- return {
- path: RoutesAlias.AssetInformation,
- query: { iccid: targetKey || targetId || '' }
- }
- }
-
- if (target.target_type === 'device_detail' && (targetKey || targetId)) {
- return {
- path: RoutesAlias.AssetInformation,
- query: { virtual_no: targetKey || targetId || '' }
- }
- }
-
- if (
- target.target_type === 'expiring_asset_list' ||
- target.target_key === 'expiring_assets' ||
- target.target_key === 'expiring_asset_list'
- ) {
- return { path: RoutesAlias.ExpiringAssets }
- }
-
- if (target.target_type === 'shop_fund_summary') {
- return {
- path: RoutesAlias.AgentFundOverview,
- query: targetId ? { shop_id: targetId } : undefined
- }
- }
-
- if (target.target_type === 'system_config') {
- return {
- path: RoutesAlias.SystemConfigs,
- query: targetKey ? { config_key: targetKey } : undefined
- }
- }
-
- return null
-}
-
-export const navigateNotificationTarget = (router: Router, target?: NotificationTarget | null) => {
- if (!target?.available) return false
- const route = resolveTargetRoute(target)
+ const route = resolveTargetRoute(refType, target)
if (!route) return false
- const resolved = router.resolve({ path: route.path, query: route.query })
- if (!resolved.matched.length || resolved.name === 'Exception404') return false
- void router.push(resolved)
+ void router.push(route)
return true
}
diff --git a/src/views/asset-management/asset-information/index.vue b/src/views/asset-management/asset-information/index.vue
index 50158d2..2627843 100644
--- a/src/views/asset-management/asset-information/index.vue
+++ b/src/views/asset-management/asset-information/index.vue
@@ -831,15 +831,20 @@
try {
const response = await CardService.setSpeedTier(iccid, data.code)
if (response.code !== 0) {
+ speedLimitDialogVisible.value = false
+ await nextTick()
ElMessage.error(response.msg || '限速设置失败')
return
}
- ElMessage.success(`限速设置成功:${response.data.speed_tier_name}`)
speedLimitDialogVisible.value = false
+ await nextTick()
+ ElMessage.success(`限速设置成功:${response.data.speed_tier_name}`)
await handleRefresh()
} catch (error) {
console.error('设置限速失败:', error)
+ speedLimitDialogVisible.value = false
+ await nextTick()
ElMessage.error(normalizeApiError(error).message)
} finally {
speedTierSubmitting.value = false
diff --git a/src/views/asset-management/device-list/index.vue b/src/views/asset-management/device-list/index.vue
index d687e5b..e345795 100644
--- a/src/views/asset-management/device-list/index.vue
+++ b/src/views/asset-management/device-list/index.vue
@@ -17,6 +17,21 @@
@refresh="handleRefresh"
>
+
+ 批量分配
+
+
+ 批量回收
+
{
+ if (selectedDevices.value.length === 0) {
+ ElMessage.warning('请先选择要分配的设备')
+ return
+ }
+ allocateForm.target_shop_id = undefined
+ allocateForm.remark = ''
+ allocateResult.value = null
+ shopCascadeOptions.value = []
+ allocateDialogVisible.value = true
+ }
+
// 确认批量分配
const handleConfirmAllocate = async () => {
if (!allocateFormRef.value) return
@@ -2400,6 +2428,17 @@
}
}
+ // 批量回收(设备列表原有操作,和设备批量任务页面并行保留)
+ const handleBatchRecall = () => {
+ if (selectedDevices.value.length === 0) {
+ ElMessage.warning('请先选择要回收的设备')
+ return
+ }
+ recallForm.remark = ''
+ recallResult.value = null
+ recallDialogVisible.value = true
+ }
+
// 确认批量回收
const handleConfirmRecall = async () => {
recallLoading.value = true