fix(operator): fix operator edit issue
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m35s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m35s
This commit is contained in:
@@ -0,0 +1,352 @@
|
||||
/**
|
||||
* 资产信息数据管理 Composable
|
||||
* 负责资产详情数据的加载和状态管理
|
||||
*/
|
||||
|
||||
import { ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { AssetService } from '@/api/modules'
|
||||
import type { AssetWalletResponse } from '@/types/api'
|
||||
|
||||
/**
|
||||
* 格式化数据大小(MB -> GB/MB)
|
||||
*/
|
||||
const formatDataSize = (mb: number) => {
|
||||
if (mb >= 1024) {
|
||||
return `${(mb / 1024).toFixed(2)}GB`
|
||||
}
|
||||
return `${mb.toFixed(2)}MB`
|
||||
}
|
||||
|
||||
export function useAssetInfo() {
|
||||
// 状态管理
|
||||
const loading = ref(false)
|
||||
const cardInfo = ref<any>(null) // 使用 any 以保持与原始实现一致
|
||||
const deviceRealtime = ref<DeviceRealtimeInfo | null>(null)
|
||||
const currentPackage = ref<PackageInfo | null>(null)
|
||||
const currentPackageLoading = ref(false)
|
||||
const currentPackageErrorMsg = ref('')
|
||||
const packageList = ref<PackageInfo[]>([])
|
||||
const walletInfo = ref<AssetWalletResponse | null>(null)
|
||||
const walletLoading = ref(false)
|
||||
|
||||
/**
|
||||
* 获取资产详情
|
||||
* @param identifier - 资产标识符(ICCID、IMEI、SN、虚拟号或MSISDN)
|
||||
*/
|
||||
const fetchAssetDetail = async (identifier: string) => {
|
||||
try {
|
||||
loading.value = true
|
||||
const response = await AssetService.resolveAsset(identifier)
|
||||
|
||||
if (response.code === 0 && response.data) {
|
||||
const data = response.data
|
||||
|
||||
// 映射API数据到页面显示格式
|
||||
cardInfo.value = {
|
||||
// 基本信息
|
||||
asset_type: data.asset_type, // card 或 device
|
||||
asset_id: data.asset_id,
|
||||
virtual_no: data.virtual_no,
|
||||
status: data.status,
|
||||
batch_no: data.batch_no,
|
||||
shop_id: data.shop_id,
|
||||
shop_name: data.shop_name,
|
||||
series_id: data.series_id,
|
||||
series_name: data.series_name,
|
||||
real_name_status: data.real_name_status,
|
||||
activated_at: data.activated_at,
|
||||
created_at: data.created_at,
|
||||
updated_at: data.updated_at,
|
||||
accumulated_recharge: data.accumulated_recharge,
|
||||
first_commission_paid: data.first_commission_paid,
|
||||
|
||||
// 卡专属字段 (asset_type === 'card')
|
||||
iccid: data.iccid || '',
|
||||
msisdn: data.msisdn || '',
|
||||
imsi: data.imsi || '',
|
||||
carrier_id: data.carrier_id,
|
||||
carrier_type: data.carrier_type || '',
|
||||
carrier_name: data.carrier_name || '',
|
||||
supplier: data.supplier || '',
|
||||
network_status: data.network_status,
|
||||
bound_device_id: data.bound_device_id,
|
||||
bound_device_no: data.bound_device_no || '',
|
||||
bound_device_name: data.bound_device_name || '',
|
||||
card_category: data.card_category || '',
|
||||
activation_status: data.activation_status,
|
||||
enable_polling: data.enable_polling,
|
||||
|
||||
// 设备专属字段 (asset_type === 'device')
|
||||
device_name: data.device_name || '',
|
||||
device_model: data.device_model || '',
|
||||
device_type: data.device_type || '',
|
||||
manufacturer: data.manufacturer || '',
|
||||
imei: data.imei || '',
|
||||
sn: data.sn || '',
|
||||
max_sim_slots: data.max_sim_slots || 0,
|
||||
bound_card_count: data.bound_card_count || 0,
|
||||
cards: data.cards || [],
|
||||
device_protect_status: data.device_protect_status,
|
||||
online_status: data.online_status,
|
||||
last_online_time: data.last_online_time,
|
||||
software_version: data.software_version,
|
||||
switch_mode: data.switch_mode,
|
||||
last_gateway_sync_at: data.last_gateway_sync_at,
|
||||
|
||||
// 流量/套餐信息
|
||||
current_package: data.current_package || '',
|
||||
packageSeries: data.series_name || '-',
|
||||
packageTotalFlow: formatDataSize(data.package_total_mb || 0),
|
||||
usedFlow: formatDataSize(data.package_used_mb || 0),
|
||||
remainFlow: formatDataSize(data.package_remain_mb || 0),
|
||||
usedFlowPercentage:
|
||||
data.package_total_mb > 0
|
||||
? `${((data.package_used_mb / data.package_total_mb) * 100).toFixed(2)}%`
|
||||
: '0.00%',
|
||||
packageList: [] // 套餐列表需要单独调用API获取
|
||||
}
|
||||
|
||||
// 获取资产标识符并加载其他数据
|
||||
const assetIdentifier = data.asset_type === 'card' ? data.iccid : data.virtual_no
|
||||
if (assetIdentifier) {
|
||||
// 并行调用多个接口: 当前生效套餐、套餐列表、实时状态、钱包概况
|
||||
Promise.all([
|
||||
loadCurrentPackage(assetIdentifier),
|
||||
loadPackageList(assetIdentifier),
|
||||
loadRealtimeStatus(assetIdentifier, data.asset_type),
|
||||
loadAssetWallet(assetIdentifier)
|
||||
])
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(response.msg || '查询失败')
|
||||
cardInfo.value = null
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('获取卡片信息失败:', error)
|
||||
if (error?.response?.status === 404) {
|
||||
ElMessage.error('未找到该资产')
|
||||
} else if (error?.response?.status === 403) {
|
||||
ElMessage.error('无权限访问该资产')
|
||||
} else {
|
||||
ElMessage.error(error?.message || '获取卡片信息失败')
|
||||
}
|
||||
cardInfo.value = null
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载套餐列表
|
||||
* @param identifier - 资产标识符
|
||||
*/
|
||||
const loadPackageList = async (identifier: string) => {
|
||||
try {
|
||||
const response = await AssetService.getAssetPackages(identifier, {
|
||||
page: 1,
|
||||
page_size: 50
|
||||
})
|
||||
if (response.code === 0 && response.data) {
|
||||
// 使用分页响应中的 items 数组
|
||||
cardInfo.value.packageList = response.data.items || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取套餐列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载当前生效套餐
|
||||
* @param identifier - 资产标识符
|
||||
*/
|
||||
const loadCurrentPackage = async (identifier: string) => {
|
||||
try {
|
||||
currentPackageLoading.value = true
|
||||
// 清空之前的错误信息
|
||||
currentPackageErrorMsg.value = ''
|
||||
|
||||
const response = await AssetService.getCurrentPackage(identifier)
|
||||
if (response.code === 0) {
|
||||
if (response.data) {
|
||||
const pkg = response.data
|
||||
// 保存完整的当前套餐数据
|
||||
cardInfo.value.currentPackageDetail = {
|
||||
package_usage_id: pkg.package_usage_id,
|
||||
package_id: pkg.package_id,
|
||||
package_name: pkg.package_name,
|
||||
package_type: pkg.package_type,
|
||||
status: pkg.status,
|
||||
status_name: pkg.status_name,
|
||||
data_limit_mb: pkg.data_limit_mb,
|
||||
data_usage_mb: pkg.data_usage_mb,
|
||||
virtual_limit_mb: pkg.virtual_limit_mb,
|
||||
virtual_used_mb: pkg.virtual_used_mb,
|
||||
virtual_remain_mb: pkg.virtual_remain_mb,
|
||||
virtual_ratio: pkg.virtual_ratio,
|
||||
activated_at: pkg.activated_at,
|
||||
expires_at: pkg.expires_at,
|
||||
created_at: pkg.created_at,
|
||||
master_usage_id: pkg.master_usage_id,
|
||||
priority: pkg.priority,
|
||||
usage_type: pkg.usage_type
|
||||
}
|
||||
// 同时更新流量显示信息
|
||||
cardInfo.value.current_package = pkg.package_name
|
||||
cardInfo.value.packageTotalFlow = formatDataSize(pkg.virtual_limit_mb || 0)
|
||||
cardInfo.value.usedFlow = formatDataSize(pkg.virtual_used_mb || 0)
|
||||
cardInfo.value.remainFlow = formatDataSize(pkg.virtual_remain_mb || 0)
|
||||
cardInfo.value.usedFlowPercentage =
|
||||
(pkg.virtual_limit_mb || 0) > 0
|
||||
? `${(((pkg.virtual_used_mb || 0) / (pkg.virtual_limit_mb || 1)) * 100).toFixed(2)}%`
|
||||
: '0.00%'
|
||||
} else {
|
||||
// code 为 0 但 data 为空,表示暂无当前生效套餐(正常情况)
|
||||
currentPackageErrorMsg.value = '暂无当前生效套餐'
|
||||
}
|
||||
} else {
|
||||
// 接口返回 code 不为 0,保存错误信息
|
||||
currentPackageErrorMsg.value = response.msg || '获取当前套餐失败'
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 404表示无当前生效套餐,这是正常情况
|
||||
if (error?.response?.status === 404) {
|
||||
currentPackageErrorMsg.value = '暂无当前生效套餐'
|
||||
} else {
|
||||
console.error('获取当前套餐失败:', error)
|
||||
currentPackageErrorMsg.value = error?.message || '获取当前套餐失败'
|
||||
}
|
||||
} finally {
|
||||
currentPackageLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载实时状态
|
||||
* @param identifier - 资产标识符
|
||||
* @param assetType - 资产类型(card/device)
|
||||
*/
|
||||
const loadRealtimeStatus = async (identifier: string, assetType: string) => {
|
||||
try {
|
||||
const response = await AssetService.getRealtimeStatus(identifier)
|
||||
if (response.code === 0 && response.data) {
|
||||
const data = response.data
|
||||
// 更新实时状态数据
|
||||
if (assetType === 'card') {
|
||||
// 卡的实时状态
|
||||
if (data.network_status !== undefined) {
|
||||
cardInfo.value.network_status = data.network_status
|
||||
}
|
||||
if (data.real_name_status !== undefined) {
|
||||
cardInfo.value.real_name_status = data.real_name_status
|
||||
}
|
||||
if (data.last_sync_time !== undefined) {
|
||||
cardInfo.value.last_sync_time = data.last_sync_time
|
||||
}
|
||||
if (data.current_month_usage_mb !== undefined) {
|
||||
cardInfo.value.current_month_usage_mb = data.current_month_usage_mb
|
||||
}
|
||||
} else if (assetType === 'device') {
|
||||
// 设备的实时状态
|
||||
if (data.device_protect_status !== undefined) {
|
||||
cardInfo.value.device_protect_status = data.device_protect_status
|
||||
}
|
||||
if (data.cards && data.cards.length > 0) {
|
||||
cardInfo.value.cards = data.cards
|
||||
}
|
||||
if (data.online_status !== undefined) {
|
||||
cardInfo.value.online_status = data.online_status
|
||||
}
|
||||
if (data.last_online_time !== undefined) {
|
||||
cardInfo.value.last_online_time = data.last_online_time
|
||||
}
|
||||
if (data.software_version !== undefined) {
|
||||
cardInfo.value.software_version = data.software_version
|
||||
}
|
||||
if (data.switch_mode !== undefined) {
|
||||
cardInfo.value.switch_mode = data.switch_mode
|
||||
}
|
||||
if (data.last_gateway_sync_at !== undefined) {
|
||||
cardInfo.value.last_gateway_sync_at = data.last_gateway_sync_at
|
||||
}
|
||||
// 设备实时信息(Gateway 数据)
|
||||
if (data.device_realtime !== undefined) {
|
||||
deviceRealtime.value = data.device_realtime
|
||||
console.log('设备实时信息:', deviceRealtime.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取实时状态失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载钱包概况
|
||||
* @param identifier - 资产标识符
|
||||
*/
|
||||
const loadAssetWallet = async (identifier: string) => {
|
||||
try {
|
||||
walletLoading.value = true
|
||||
const response = await AssetService.getAssetWallet(identifier)
|
||||
if (response.code === 0 && response.data) {
|
||||
walletInfo.value = response.data
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error?.response?.status === 403) {
|
||||
// 企业账号禁止查看钱包信息,不显示错误
|
||||
walletInfo.value = null
|
||||
} else {
|
||||
console.error('获取钱包概况失败:', error)
|
||||
}
|
||||
} finally {
|
||||
walletLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新资产数据(调用refresh接口后重新加载)
|
||||
* @param identifier - 资产标识符
|
||||
* @param assetType - 资产类型(card/device)
|
||||
*/
|
||||
const refreshAsset = async (identifier: string, assetType: string) => {
|
||||
try {
|
||||
await AssetService.refreshAsset(identifier)
|
||||
ElMessage.success('刷新成功')
|
||||
|
||||
// 刷新成功后重新加载实时状态数据
|
||||
if (identifier) {
|
||||
await loadRealtimeStatus(identifier, assetType)
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 检查429错误(冷却期)
|
||||
if (error?.response?.status === 429) {
|
||||
ElMessage.warning('刷新过于频繁,请稍后再试')
|
||||
} else {
|
||||
ElMessage.error(error?.message || '刷新失败')
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
loading,
|
||||
cardInfo,
|
||||
deviceRealtime,
|
||||
currentPackage,
|
||||
currentPackageLoading,
|
||||
currentPackageErrorMsg,
|
||||
packageList,
|
||||
walletInfo,
|
||||
walletLoading,
|
||||
|
||||
// Methods
|
||||
fetchAssetDetail,
|
||||
loadPackageList,
|
||||
loadCurrentPackage,
|
||||
loadRealtimeStatus,
|
||||
loadAssetWallet,
|
||||
refreshAsset
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user