This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user