This commit is contained in:
@@ -122,7 +122,7 @@
|
||||
:key="item.device_id"
|
||||
style="margin-bottom: 8px; font-size: 12px; color: #f56c6c"
|
||||
>
|
||||
设备号: {{ item.device_no }} - {{ item.reason }}
|
||||
设备号: {{ item.virtual_no }} - {{ item.reason }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -178,7 +178,7 @@
|
||||
:key="item.device_id"
|
||||
style="margin-bottom: 8px; font-size: 12px; color: #f56c6c"
|
||||
>
|
||||
设备号: {{ item.device_no }} - {{ item.reason }}
|
||||
设备号: {{ item.virtual_no }} - {{ item.reason }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -260,7 +260,7 @@
|
||||
:key="item.device_id"
|
||||
style="margin-bottom: 8px; font-size: 12px; color: #f56c6c"
|
||||
>
|
||||
设备号: {{ item.device_no }} - {{ item.reason }}
|
||||
设备号: {{ item.virtual_no }} - {{ item.reason }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -292,7 +292,7 @@
|
||||
<ElDescriptions :column="3" border style="margin-bottom: 20px">
|
||||
<ElDescriptionsItem label="设备ID">{{ currentDeviceDetail.id }}</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="设备号" :span="2">{{
|
||||
currentDeviceDetail.device_no
|
||||
currentDeviceDetail.virtual_no
|
||||
}}</ElDescriptionsItem>
|
||||
|
||||
<ElDescriptionsItem label="设备名称">{{
|
||||
@@ -332,10 +332,72 @@
|
||||
</ElDialog>
|
||||
|
||||
<!-- 绑定卡片列表弹窗 -->
|
||||
<ElDialog v-model="deviceCardsDialogVisible" title="绑定的卡片" width="900px">
|
||||
<div style="margin-bottom: 10px; text-align: right">
|
||||
<ElButton type="primary" @click="handleBindCard">绑定新卡</ElButton>
|
||||
</div>
|
||||
<ElDialog v-model="deviceCardsDialogVisible" title="设备绑定的卡" width="60%">
|
||||
<!-- 绑定新卡表单 -->
|
||||
<ElCard shadow="never" class="bind-card-section" style="margin-bottom: 20px">
|
||||
<template #header>
|
||||
<div style="font-weight: bold">绑定新卡</div>
|
||||
</template>
|
||||
<ElForm
|
||||
ref="bindCardFormRef"
|
||||
:model="bindCardForm"
|
||||
:rules="bindCardRules"
|
||||
label-width="100px"
|
||||
>
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :span="10">
|
||||
<ElFormItem label="IoT卡" prop="iot_card_id">
|
||||
<ElSelect
|
||||
v-model="bindCardForm.iot_card_id"
|
||||
placeholder="请选择或搜索IoT卡(支持ICCID搜索)"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="searchIotCards"
|
||||
:loading="iotCardSearchLoading"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="card in iotCardList"
|
||||
:key="card.id"
|
||||
:label="`${card.iccid} ${card.msisdn ? '(' + card.msisdn + ')' : ''}`"
|
||||
:value="card.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
</ElCol>
|
||||
<ElCol :span="10">
|
||||
<ElFormItem label="插槽位置" prop="slot_position">
|
||||
<ElSelect
|
||||
v-model="bindCardForm.slot_position"
|
||||
placeholder="请选择插槽位置"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="i in currentDeviceDetail?.max_sim_slots || 4"
|
||||
:key="i"
|
||||
:label="`插槽 ${i}`"
|
||||
:value="i"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
</ElCol>
|
||||
<ElCol :span="4">
|
||||
<ElButton
|
||||
type="primary"
|
||||
@click="handleConfirmBindCard"
|
||||
:loading="bindCardLoading"
|
||||
style="width: 100%"
|
||||
>
|
||||
确认绑定
|
||||
</ElButton>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</ElForm>
|
||||
</ElCard>
|
||||
|
||||
<!-- 已绑定卡片列表 -->
|
||||
<div v-if="deviceCardsLoading" style="text-align: center; padding: 40px 0">
|
||||
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
||||
</div>
|
||||
@@ -368,7 +430,7 @@
|
||||
v-if="deviceCards.length === 0"
|
||||
style="text-align: center; padding: 20px; color: #909399"
|
||||
>
|
||||
暂无绑定的卡片
|
||||
暂无设备绑定的卡
|
||||
</div>
|
||||
</div>
|
||||
</ElDialog>
|
||||
@@ -381,57 +443,6 @@
|
||||
@select="handleDeviceOperationMenuSelect"
|
||||
/>
|
||||
|
||||
<!-- 绑定卡弹窗 -->
|
||||
<ElDialog v-model="bindCardDialogVisible" title="绑定卡到设备" width="500px">
|
||||
<ElForm
|
||||
ref="bindCardFormRef"
|
||||
:model="bindCardForm"
|
||||
:rules="bindCardRules"
|
||||
label-width="100px"
|
||||
>
|
||||
<ElFormItem label="IoT卡" prop="iot_card_id">
|
||||
<ElSelect
|
||||
v-model="bindCardForm.iot_card_id"
|
||||
placeholder="请选择或搜索IoT卡(支持ICCID搜索)"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="searchIotCards"
|
||||
:loading="iotCardSearchLoading"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="card in iotCardList"
|
||||
:key="card.id"
|
||||
:label="`${card.iccid} ${card.msisdn ? '(' + card.msisdn + ')' : ''}`"
|
||||
:value="card.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="插槽位置" prop="slot_position">
|
||||
<ElSelect
|
||||
v-model="bindCardForm.slot_position"
|
||||
placeholder="请选择插槽位置"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="i in currentDeviceDetail?.max_sim_slots || 4"
|
||||
:key="i"
|
||||
:label="`插槽 ${i}`"
|
||||
:value="i"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
<ElButton @click="bindCardDialogVisible = false">取消</ElButton>
|
||||
<ElButton type="primary" @click="handleConfirmBindCard" :loading="bindCardLoading">
|
||||
确认绑定
|
||||
</ElButton>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 设置限速对话框 -->
|
||||
<ElDialog v-model="speedLimitDialogVisible" title="设置限速" width="500px">
|
||||
<ElForm
|
||||
@@ -552,7 +563,13 @@
|
||||
<script setup lang="ts">
|
||||
import { h } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { DeviceService, ShopService, CardService, PackageSeriesService } from '@/api/modules'
|
||||
import {
|
||||
DeviceService,
|
||||
ShopService,
|
||||
CardService,
|
||||
PackageSeriesService,
|
||||
AssetService
|
||||
} from '@/api/modules'
|
||||
import {
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
@@ -635,7 +652,6 @@
|
||||
const deviceCardsDialogVisible = ref(false)
|
||||
|
||||
// 绑定卡相关
|
||||
const bindCardDialogVisible = ref(false)
|
||||
const bindCardLoading = ref(false)
|
||||
const bindCardFormRef = ref<FormInstance>()
|
||||
const iotCardList = ref<any[]>([])
|
||||
@@ -704,7 +720,7 @@
|
||||
|
||||
// 搜索表单初始值
|
||||
const initialSearchState = {
|
||||
device_no: '',
|
||||
virtual_no: '',
|
||||
device_name: '',
|
||||
status: undefined as DeviceStatus | undefined,
|
||||
batch_no: '',
|
||||
@@ -719,7 +735,7 @@
|
||||
const searchFormItems: SearchFormItem[] = [
|
||||
{
|
||||
label: '设备号',
|
||||
prop: 'device_no',
|
||||
prop: 'virtual_no',
|
||||
type: 'input',
|
||||
config: {
|
||||
clearable: true,
|
||||
@@ -788,7 +804,7 @@
|
||||
|
||||
// 列配置
|
||||
const columnOptions = [
|
||||
{ label: '设备号', prop: 'device_no' },
|
||||
{ label: '设备号', prop: 'virtual_no' },
|
||||
{ label: '设备名称', prop: 'device_name' },
|
||||
{ label: '设备型号', prop: 'device_model' },
|
||||
{ label: '设备类型', prop: 'device_type' },
|
||||
@@ -825,7 +841,7 @@
|
||||
router.push({
|
||||
path: '/asset-management/single-card',
|
||||
query: {
|
||||
device_no: deviceNo
|
||||
virtual_no: deviceNo
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@@ -833,12 +849,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 查看设备绑定的卡片
|
||||
// 查看设备设备绑定的卡
|
||||
const handleViewCards = async (device: Device) => {
|
||||
currentDeviceDetail.value = device
|
||||
deviceCards.value = []
|
||||
deviceCardsDialogVisible.value = true
|
||||
await loadDeviceCards(device.id)
|
||||
// 重置绑定卡表单
|
||||
bindCardForm.iot_card_id = undefined
|
||||
bindCardForm.slot_position = 1
|
||||
// 加载设备卡列表和默认IoT卡列表
|
||||
await Promise.all([loadDeviceCards(device.id), loadDefaultIotCards()])
|
||||
}
|
||||
|
||||
// 加载设备绑定的卡列表
|
||||
@@ -856,15 +876,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 打开绑定卡弹窗
|
||||
const handleBindCard = async () => {
|
||||
bindCardForm.iot_card_id = undefined
|
||||
bindCardForm.slot_position = 1
|
||||
bindCardDialogVisible.value = true
|
||||
// 加载默认的IoT卡列表
|
||||
await loadDefaultIotCards()
|
||||
}
|
||||
|
||||
// 加载默认的IoT卡列表
|
||||
const loadDefaultIotCards = async () => {
|
||||
iotCardSearchLoading.value = true
|
||||
@@ -920,22 +931,20 @@
|
||||
})
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('绑定成功')
|
||||
bindCardDialogVisible.value = false
|
||||
// 重置表单
|
||||
bindCardForm.iot_card_id = undefined
|
||||
bindCardForm.slot_position = 1
|
||||
bindCardFormRef.value.resetFields()
|
||||
// 重新加载卡列表
|
||||
await loadDeviceCards(currentDeviceDetail.value.id)
|
||||
// 刷新设备详情以更新绑定卡数量
|
||||
const detailRes = await DeviceService.getDeviceByImei(
|
||||
currentDeviceDetail.value.device_no
|
||||
)
|
||||
const detailRes = await AssetService.resolveAsset(currentDeviceDetail.value.virtual_no)
|
||||
if (detailRes.code === 0 && detailRes.data) {
|
||||
currentDeviceDetail.value = detailRes.data
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(res.message || '绑定失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('绑定卡失败:', error)
|
||||
ElMessage.error(error?.message || '绑定失败')
|
||||
} finally {
|
||||
bindCardLoading.value = false
|
||||
}
|
||||
@@ -958,9 +967,7 @@
|
||||
// 重新加载卡列表
|
||||
await loadDeviceCards(currentDeviceDetail.value.id)
|
||||
// 刷新设备详情以更新绑定卡数量
|
||||
const detailRes = await DeviceService.getDeviceByImei(
|
||||
currentDeviceDetail.value.device_no
|
||||
)
|
||||
const detailRes = await AssetService.resolveAsset(currentDeviceDetail.value.virtual_no)
|
||||
if (detailRes.code === 0 && detailRes.data) {
|
||||
currentDeviceDetail.value = detailRes.data
|
||||
}
|
||||
@@ -1013,7 +1020,7 @@
|
||||
// 动态列配置
|
||||
const { columnChecks, columns } = useCheckedColumns(() => [
|
||||
{
|
||||
prop: 'device_no',
|
||||
prop: 'virtual_no',
|
||||
label: '设备号',
|
||||
minWidth: 150,
|
||||
showOverflowTooltip: true,
|
||||
@@ -1024,10 +1031,10 @@
|
||||
style: 'color: var(--el-color-primary); cursor: pointer; text-decoration: underline;',
|
||||
onClick: (e: MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
goToDeviceSearchDetail(row.device_no)
|
||||
goToDeviceSearchDetail(row.virtual_no)
|
||||
}
|
||||
},
|
||||
row.device_no
|
||||
row.virtual_no
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -1156,7 +1163,7 @@
|
||||
const params = {
|
||||
page: pagination.page,
|
||||
page_size: pagination.pageSize,
|
||||
device_no: searchForm.device_no || undefined,
|
||||
virtual_no: searchForm.virtual_no || undefined,
|
||||
device_name: searchForm.device_name || undefined,
|
||||
status: searchForm.status,
|
||||
batch_no: searchForm.batch_no || undefined,
|
||||
@@ -1212,11 +1219,15 @@
|
||||
|
||||
// 删除设备
|
||||
const deleteDevice = (row: Device) => {
|
||||
ElMessageBox.confirm(`确定删除设备 ${row.device_no} 吗?删除后将自动解绑所有卡。`, '删除确认', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'error'
|
||||
})
|
||||
ElMessageBox.confirm(
|
||||
`确定删除设备 ${row.virtual_no} 吗?删除后将自动解绑所有卡。`,
|
||||
'删除确认',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'error'
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
try {
|
||||
await DeviceService.deleteDevice(row.id)
|
||||
@@ -1449,9 +1460,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 通过设备号查看卡片
|
||||
// 通过设备号设备绑定的卡
|
||||
const handleViewCardsByDeviceNo = (deviceNo: string) => {
|
||||
const device = deviceList.value.find((d) => d.device_no === deviceNo)
|
||||
const device = deviceList.value.find((d) => d.virtual_no === deviceNo)
|
||||
if (device) {
|
||||
handleViewCards(device)
|
||||
} else {
|
||||
@@ -1462,7 +1473,7 @@
|
||||
// 通过设备号删除设备
|
||||
const handleDeleteDeviceByNo = async (deviceNo: string) => {
|
||||
// 先根据设备号找到设备对象
|
||||
const device = deviceList.value.find((d) => d.device_no === deviceNo)
|
||||
const device = deviceList.value.find((d) => d.virtual_no === deviceNo)
|
||||
if (device) {
|
||||
deleteDevice(device)
|
||||
} else {
|
||||
@@ -1636,11 +1647,11 @@
|
||||
const deviceOperationMenuItems = computed((): MenuItemType[] => {
|
||||
const items: MenuItemType[] = []
|
||||
|
||||
// 添加查看卡片到菜单最前面
|
||||
// 添加设备绑定的卡到菜单最前面
|
||||
if (hasAuth('device:view_cards')) {
|
||||
items.push({
|
||||
key: 'view-cards',
|
||||
label: '查看卡片'
|
||||
label: '设备绑定的卡'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1707,7 +1718,7 @@
|
||||
|
||||
// 处理表格行右键菜单
|
||||
const handleRowContextMenu = (row: Device, column: any, event: MouseEvent) => {
|
||||
showDeviceOperationMenu(event, row.device_no)
|
||||
showDeviceOperationMenu(event, row.virtual_no)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user