修复bug
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 11m14s

This commit is contained in:
sexygoat
2026-04-08 10:19:25 +08:00
parent ff087abd44
commit b510b4539f
55 changed files with 2274 additions and 2612 deletions

View File

@@ -53,13 +53,11 @@
:pageSize="pagination.pageSize"
:total="pagination.total"
:marginTop="10"
:row-class-name="getRowClassName"
:actions="getActions"
:actionsWidth="180"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@selection-change="handleSelectionChange"
@row-contextmenu="handleRowContextMenu"
@cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave"
>
<template #default>
<ElTableColumn type="selection" width="55" />
@@ -67,9 +65,6 @@
</template>
</ArtTable>
<!-- 鼠标悬浮提示 -->
<TableContextMenuHint :visible="showContextMenuHint" :position="hintPosition" />
<!-- 批量分配对话框 -->
<ElDialog v-model="allocateDialogVisible" title="批量分配设备" width="600px">
<ElForm
@@ -284,7 +279,7 @@
<!-- 设备详情弹窗 -->
<ElDialog v-model="deviceDetailDialogVisible" title="设备详情" width="1000px">
<div v-if="deviceDetailLoading" style=" padding: 40px 0;text-align: center">
<div v-if="deviceDetailLoading" style="padding: 40px 0; text-align: center">
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
</div>
<div v-else-if="currentDeviceDetail">
@@ -296,17 +291,17 @@
}}</ElDescriptionsItem>
<ElDescriptionsItem label="设备名称">{{
currentDeviceDetail.device_name || '--'
currentDeviceDetail.device_name || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="设备型号">{{
currentDeviceDetail.device_model || '--'
currentDeviceDetail.device_model || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="设备类型">{{
currentDeviceDetail.device_type || '--'
currentDeviceDetail.device_type || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="制造商">{{
currentDeviceDetail.manufacturer || '--'
currentDeviceDetail.manufacturer || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="最大插槽数">{{
currentDeviceDetail.max_sim_slots
@@ -321,11 +316,11 @@
</ElTag>
</ElDescriptionsItem>
<ElDescriptionsItem label="批次号" :span="2">{{
currentDeviceDetail.batch_no || '--'
currentDeviceDetail.batch_no || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="创建时间" :span="3">{{
formatDateTime(currentDeviceDetail.created_at) || '--'
formatDateTime(currentDeviceDetail.created_at) || '-'
}}</ElDescriptionsItem>
</ElDescriptions>
</div>
@@ -398,7 +393,7 @@
</ElCard>
<!-- 已绑定卡片列表 -->
<div v-if="deviceCardsLoading" style=" padding: 40px 0;text-align: center">
<div v-if="deviceCardsLoading" style="padding: 40px 0; text-align: center">
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
</div>
<div v-else>
@@ -406,15 +401,15 @@
<ElTableColumn prop="slot_position" label="插槽位置" width="120" align="center">
<template #default="{ row }">
<div
style="display: flex; gap: 4px; align-items: center; justify-content: center"
style="display: flex; gap: 10px; align-items: center; justify-content: center"
>
<span>{{ row.slot_position }}</span>
<span>SIM-{{ row.slot_position }}</span>
<ElTag v-if="row.is_current" type="success" size="small">当前</ElTag>
</div>
</template>
</ElTableColumn>
<ElTableColumn prop="iccid" label="ICCID" min-width="180" />
<ElTableColumn prop="msisdn" label="接入号" width="140" />
<ElTableColumn prop="iccid" label="ICCID" min-width="120" />
<ElTableColumn prop="msisdn" label="接入号" width="160" />
<ElTableColumn prop="network_status" label="网络状态" width="100" align="center">
<template #default="{ row }">
<ElTag :type="getNetworkStatusTagType(row.network_status)">
@@ -424,7 +419,7 @@
</ElTableColumn>
<ElTableColumn prop="bind_time" label="绑定时间" width="180">
<template #default="{ row }">
{{ formatDateTime(row.bind_time) || '--' }}
{{ formatDateTime(row.bind_time) || '-' }}
</template>
</ElTableColumn>
<ElTableColumn label="操作" width="100" fixed="right" align="center">
@@ -437,21 +432,13 @@
</ElTable>
<div
v-if="deviceCards.length === 0"
style=" padding: 20px; color: #909399;text-align: center"
style="padding: 20px; color: #909399; text-align: center"
>
暂无设备绑定的卡
</div>
</div>
</ElDialog>
<!-- 设备操作右键菜单 -->
<ArtMenuRight
ref="deviceOperationMenuRef"
:menu-items="deviceOperationMenuItems"
:menu-width="140"
@select="handleDeviceOperationMenuSelect"
/>
<!-- 设置限速对话框 -->
<ElDialog v-model="speedLimitDialogVisible" title="设置限速" width="50%">
<ElForm
@@ -471,7 +458,7 @@
controls-position="right"
style="width: 100%"
/>
<div style=" margin-top: 4px; font-size: 12px;color: #909399">单位: KB/s</div>
<div style="margin-top: 4px; font-size: 12px; color: #909399">单位: KB/s</div>
</ElFormItem>
<ElFormItem label="上行速率" prop="upload_speed">
<ElInputNumber
@@ -481,7 +468,7 @@
controls-position="right"
style="width: 100%"
/>
<div style=" margin-top: 4px; font-size: 12px;color: #909399">单位: KB/s</div>
<div style="margin-top: 4px; font-size: 12px; color: #909399">单位: KB/s</div>
</ElFormItem>
</ElForm>
<template #footer>
@@ -494,7 +481,7 @@
<!-- 切换SIM卡对话框 -->
<ElDialog v-model="switchCardDialogVisible" title="切换SIM卡" width="600px">
<div v-if="loadingDeviceCards" style=" padding: 40px;text-align: center">
<div v-if="loadingDeviceCards" style="padding: 40px; text-align: center">
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
<div style="margin-top: 16px">加载设备绑定的卡列表中...</div>
</div>
@@ -647,11 +634,7 @@
import type { SearchFormItem } from '@/types'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { useAuth } from '@/composables/useAuth'
import { useTableContextMenu } from '@/composables/useTableContextMenu'
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
import TableContextMenuHint from '@/components/core/others/TableContextMenuHint.vue'
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
import { formatDateTime } from '@/utils/business/format'
import { CommonStatus, getStatusText } from '@/config/constants'
import type { PackageSeriesResponse } from '@/types/api'
@@ -661,15 +644,6 @@
const { hasAuth } = useAuth()
const router = useRouter()
// 使用表格右键菜单功能
const {
showContextMenuHint,
hintPosition,
getRowClassName,
handleCellMouseEnter,
handleCellMouseLeave
} = useTableContextMenu()
const loading = ref(false)
const allocateLoading = ref(false)
const recallLoading = ref(false)
@@ -738,11 +712,8 @@
]
})
// 设备操作右键菜单
const deviceOperationMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
const currentOperatingDeviceNo = ref<string>('')
const currentOperatingDevice = ref<Device | null>(null)
const currentOperatingImei = ref<string>('') // 用于存储当前操作设备的IMEI
const currentOperatingDevice = ref<Device | null>(null)
const switchCardDialogVisible = ref(false)
const switchCardLoading = ref(false)
@@ -901,7 +872,7 @@
const goToDeviceSearchDetail = (deviceNo: string) => {
if (hasAuth('device:view_detail')) {
router.push({
path: '/asset-management/single-card',
path: '/asset-management/asset-information',
query: {
virtual_no: deviceNo
}
@@ -920,14 +891,14 @@
bindCardForm.iot_card_id = undefined
bindCardForm.slot_position = 1
// 加载设备卡列表和默认IoT卡列表
await Promise.all([loadDeviceCards(device.id), loadDefaultIotCards()])
await Promise.all([loadDeviceCards(device.virtual_no), loadDefaultIotCards()])
}
// 加载设备绑定的卡列表
const loadDeviceCards = async (deviceId: number) => {
const loadDeviceCards = async (virtualNo: string) => {
deviceCardsLoading.value = true
try {
const res = await DeviceService.getDeviceCards(deviceId)
const res = await DeviceService.getDeviceCards(virtualNo)
if (res.code === 0 && res.data) {
deviceCards.value = res.data.bindings || []
console.log('设备绑定的卡列表:', deviceCards.value)
@@ -995,7 +966,7 @@
if (valid) {
bindCardLoading.value = true
try {
const res = await DeviceService.bindCard(currentDeviceDetail.value.id, {
const res = await DeviceService.bindCard(currentDeviceDetail.value.virtual_no, {
iot_card_id: bindCardForm.iot_card_id!,
slot_position: bindCardForm.slot_position
})
@@ -1006,7 +977,7 @@
bindCardForm.slot_position = 1
bindCardFormRef.value.resetFields()
// 重新加载卡列表
await loadDeviceCards(currentDeviceDetail.value.id)
await loadDeviceCards(currentDeviceDetail.value.virtual_no)
// 刷新设备详情以更新绑定卡数量
const detailRes = await AssetService.resolveAsset(currentDeviceDetail.value.virtual_no)
if (detailRes.code === 0 && detailRes.data) {
@@ -1031,11 +1002,14 @@
})
.then(async () => {
try {
const res = await DeviceService.unbindCard(currentDeviceDetail.value.id, row.iot_card_id)
const res = await DeviceService.unbindCard(
currentDeviceDetail.value.virtual_no,
row.iccid
)
if (res.code === 0) {
ElMessage.success('解绑成功')
// 重新加载卡列表
await loadDeviceCards(currentDeviceDetail.value.id)
await loadDeviceCards(currentDeviceDetail.value.virtual_no)
// 刷新设备详情以更新绑定卡数量
const detailRes = await AssetService.resolveAsset(currentDeviceDetail.value.virtual_no)
if (detailRes.code === 0 && detailRes.data) {
@@ -1367,7 +1341,7 @@
)
.then(async () => {
try {
await DeviceService.deleteDevice(row.id)
await DeviceService.deleteDevice(row.virtual_no)
ElMessage.success('删除成功')
await getTableData()
} catch (error) {
@@ -1581,13 +1555,16 @@
}
// 设备操作路由
const handleDeviceOperation = async (command: string, deviceNo: string) => {
const handleDeviceOperation = async (command: string, deviceNo: string, device?: Device) => {
// 设置当前操作的设备
currentOperatingDevice.value = device || null
switch (command) {
case 'view-cards':
handleViewCardsByDeviceNo(deviceNo)
break
case 'reboot': {
const imei = await getDeviceImei(deviceNo)
const imei = device?.imei || (await getDeviceImei(deviceNo))
if (!imei) {
ElMessage.error('无法获取设备IMEI,无法执行重启操作')
return
@@ -1596,7 +1573,7 @@
break
}
case 'reset': {
const imei = await getDeviceImei(deviceNo)
const imei = device?.imei || (await getDeviceImei(deviceNo))
if (!imei) {
ElMessage.error('无法获取设备IMEI,无法执行重置操作')
return
@@ -1605,7 +1582,7 @@
break
}
case 'speed-limit': {
const imei = await getDeviceImei(deviceNo)
const imei = device?.imei || (await getDeviceImei(deviceNo))
if (!imei) {
ElMessage.error('无法获取设备IMEI,无法执行限速操作')
return
@@ -1614,7 +1591,7 @@
break
}
case 'switch-card': {
const imei = await getDeviceImei(deviceNo)
const imei = device?.imei || (await getDeviceImei(deviceNo))
if (!imei) {
ElMessage.error('无法获取设备IMEI,无法执行切卡操作')
return
@@ -1623,7 +1600,7 @@
break
}
case 'set-wifi': {
const imei = await getDeviceImei(deviceNo)
const imei = device?.imei || (await getDeviceImei(deviceNo))
if (!imei) {
ElMessage.error('无法获取设备IMEI,无法执行WiFi设置操作')
return
@@ -1669,7 +1646,7 @@
)
.then(async () => {
try {
const res = await DeviceService.deactivateDevice(device.id)
const res = await AssetService.deactivateAsset(device.virtual_no)
if (res.code === 0) {
ElMessage.success('手动停用成功')
loadDeviceList()
@@ -1798,7 +1775,7 @@
// 加载设备绑定的卡列表
loadingDeviceCards.value = true
try {
const res = await DeviceService.getDeviceCards(device.id)
const res = await DeviceService.getDeviceCards(device.virtual_no)
if (res.code === 0 && res.data) {
deviceBindingCards.value = res.data.bindings || []
@@ -1884,89 +1861,76 @@
}
// 设备操作菜单项配置
const deviceOperationMenuItems = computed((): MenuItemType[] => {
const items: MenuItemType[] = []
// 表格操作列配置
const getActions = (row: Device) => {
const actions: any[] = []
// 第一个按钮切换SIM卡
if (hasAuth('device:switch_sim')) {
actions.push({
label: '切换SIM卡',
handler: () => handleDeviceOperation('switch-card', row.virtual_no, row),
type: 'primary'
})
}
// 其他操作放到"更多"下拉菜单中
const moreActions: any[] = []
// 添加设备绑定的卡到菜单最前面
if (hasAuth('device:view_cards')) {
items.push({
key: 'view-cards',
label: '设备绑定的卡'
moreActions.push({
label: '设备绑定的卡',
handler: () => handleDeviceOperation('view-cards', row.virtual_no, row),
type: 'primary'
})
}
if (hasAuth('device:reboot')) {
items.push({
key: 'reboot',
label: '重启设备'
moreActions.push({
label: '重启设备',
handler: () => handleDeviceOperation('reboot', row.virtual_no, row),
type: 'primary'
})
}
if (hasAuth('device:factory_reset')) {
items.push({
key: 'reset',
label: '恢复出厂'
})
}
// if (hasAuth('device:set_speed_limit')) {
// items.push({
// key: 'speed-limit',
// label: '设置限速'
// })
// }
if (hasAuth('device:switch_sim')) {
items.push({
key: 'switch-card',
label: '切换SIM卡'
moreActions.push({
label: '恢复出厂',
handler: () => handleDeviceOperation('reset', row.virtual_no, row),
type: 'primary'
})
}
if (hasAuth('device:set_wifi')) {
items.push({
key: 'set-wifi',
label: '设置WiFi'
moreActions.push({
label: '设置WiFi',
handler: () => handleDeviceOperation('set-wifi', row.virtual_no, row),
type: 'primary'
})
}
if (hasAuth('device:manual_deactivate')) {
items.push({
key: 'manual-deactivate',
label: '手动停用'
moreActions.push({
label: '手动停用',
handler: () => handleDeviceOperation('manual-deactivate', row.virtual_no, row),
type: 'primary'
})
}
if (hasAuth('device:delete')) {
items.push({
key: 'delete',
label: '删除设备'
moreActions.push({
label: '删除设备',
handler: () => handleDeviceOperation('delete', row.virtual_no, row),
type: 'primary'
})
}
return items
})
// 如果有更多操作,添加到 actions 中
if (moreActions.length > 0) {
actions.push(...moreActions)
}
// 显示设备操作菜单
const showDeviceOperationMenu = (e: MouseEvent, deviceNo: string, device?: Device) => {
e.preventDefault()
e.stopPropagation()
currentOperatingDeviceNo.value = deviceNo
currentOperatingDevice.value = device || null
deviceOperationMenuRef.value?.show(e)
}
// 处理设备操作菜单选择
const handleDeviceOperationMenuSelect = (item: MenuItemType) => {
const deviceNo = currentOperatingDeviceNo.value
if (!deviceNo) return
handleDeviceOperation(item.key, deviceNo)
}
// 处理表格行右键菜单
const handleRowContextMenu = (row: Device, column: any, event: MouseEvent) => {
showDeviceOperationMenu(event, row.virtual_no, row)
return actions
}
</script>