This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<ArtSearchBar
|
||||
v-model:filter="searchForm"
|
||||
:items="searchFormItems"
|
||||
label-width="100"
|
||||
@reset="handleReset"
|
||||
@search="handleSearch"
|
||||
></ArtSearchBar>
|
||||
@@ -340,7 +341,11 @@
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :span="6">
|
||||
<ElFormItem label="搜索类型" prop="search_type">
|
||||
<ElSelect v-model="bindCardForm.search_type" placeholder="请选择搜索类型" style="width: 100%">
|
||||
<ElSelect
|
||||
v-model="bindCardForm.search_type"
|
||||
placeholder="请选择搜索类型"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption label="ICCID" value="iccid" />
|
||||
<ElOption label="运营商名称" value="carrier_name" />
|
||||
</ElSelect>
|
||||
@@ -655,6 +660,10 @@
|
||||
})
|
||||
const seriesBindingResult = ref<BatchSetDeviceSeriesBindingResponse | null>(null)
|
||||
|
||||
// 搜索表单店铺/系列选项
|
||||
const shopOptions = ref<any[]>([])
|
||||
const searchSeriesOptions = ref<any[]>([])
|
||||
|
||||
// 设备详情弹窗相关
|
||||
const deviceDetailDialogVisible = ref(false)
|
||||
const deviceDetailLoading = ref(false)
|
||||
@@ -734,7 +743,12 @@
|
||||
status: undefined as DeviceStatus | undefined,
|
||||
batch_no: '',
|
||||
device_type: '',
|
||||
manufacturer: ''
|
||||
manufacturer: '',
|
||||
shop_id: undefined as number | undefined,
|
||||
series_id: undefined as number | undefined,
|
||||
dateRange: [] as string[],
|
||||
created_at_start: '',
|
||||
created_at_end: ''
|
||||
}
|
||||
|
||||
// 搜索表单
|
||||
@@ -801,6 +815,54 @@
|
||||
clearable: true,
|
||||
placeholder: '请输入制造商'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '店铺名称',
|
||||
prop: 'shop_id',
|
||||
type: 'select',
|
||||
config: {
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
remote: true,
|
||||
remoteMethod: (query: string) => searchShops(query),
|
||||
loading: false,
|
||||
placeholder: '请选择或搜索店铺名称'
|
||||
},
|
||||
options: () =>
|
||||
shopOptions.value.map((shop) => ({
|
||||
label: shop.shop_name,
|
||||
value: shop.id
|
||||
}))
|
||||
},
|
||||
{
|
||||
label: '套餐系列',
|
||||
prop: 'series_id',
|
||||
type: 'select',
|
||||
config: {
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
remote: true,
|
||||
remoteMethod: (query: string) => searchSeries(query),
|
||||
loading: seriesLoading.value,
|
||||
placeholder: '请选择或搜索套餐系列'
|
||||
},
|
||||
options: () =>
|
||||
searchSeriesOptions.value.map((s) => ({
|
||||
label: s.series_name,
|
||||
value: s.id
|
||||
}))
|
||||
},
|
||||
{
|
||||
label: '起始至结束',
|
||||
prop: 'dateRange',
|
||||
type: 'date',
|
||||
config: {
|
||||
type: 'datetimerange',
|
||||
rangeSeparator: '至',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
valueFormat: 'YYYY-MM-DDTHH:mm:ssZZ'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -814,21 +876,26 @@
|
||||
// 列配置
|
||||
const columnOptions = [
|
||||
{ label: '设备号', prop: 'virtual_no' },
|
||||
{ label: 'IMEI', prop: 'imei' },
|
||||
{ label: '设备名称', prop: 'device_name' },
|
||||
{ label: '设备型号', prop: 'device_model' },
|
||||
{ label: '设备类型', prop: 'device_type' },
|
||||
{ label: '店铺名称', prop: 'shop_name' },
|
||||
{ label: '套餐系列', prop: 'series_name' },
|
||||
{ label: '设备型号', prop: 'device_model' },
|
||||
{ label: '设备类型', prop: 'device_type' },
|
||||
{ label: '状态', prop: 'status' },
|
||||
{ label: '状态名称', prop: 'status_name' },
|
||||
{ label: '在线状态', prop: 'online_status' },
|
||||
{ label: '实名策略', prop: 'realname_policy' },
|
||||
{ label: '切卡模式', prop: 'switch_mode' },
|
||||
{ label: '激活时间', prop: 'activated_at' },
|
||||
{ label: '制造商', prop: 'manufacturer' },
|
||||
{ label: '软件版本', prop: 'software_version' },
|
||||
{ label: '最大插槽数', prop: 'max_sim_slots' },
|
||||
{ label: '已绑定卡数', prop: 'bound_card_count' },
|
||||
{ label: '状态', prop: 'status' },
|
||||
{ label: '在线状态', prop: 'online_status' },
|
||||
|
||||
{ label: '切卡模式', prop: 'switch_mode' },
|
||||
{ label: '序列号', prop: 'sn' },
|
||||
{ label: '批次号', prop: 'batch_no' },
|
||||
{ label: '最后在线时间', prop: 'last_online_time' },
|
||||
{ label: '最后同步时间', prop: 'last_gateway_sync_at' },
|
||||
{ label: '批次号', prop: 'batch_no' },
|
||||
{ label: '创建时间', prop: 'created_at' },
|
||||
{ label: '操作', prop: 'operation' }
|
||||
]
|
||||
@@ -875,10 +942,7 @@
|
||||
bindCardForm.iot_card_id = undefined
|
||||
bindCardForm.slot_position = 1
|
||||
// 加载未绑定设备的卡列表
|
||||
await Promise.all([
|
||||
loadDeviceCards(device.virtual_no),
|
||||
loadDefaultIotCards()
|
||||
])
|
||||
await Promise.all([loadDeviceCards(device.virtual_no), loadDefaultIotCards()])
|
||||
}
|
||||
|
||||
// 加载设备绑定的卡列表
|
||||
@@ -1055,7 +1119,7 @@
|
||||
{
|
||||
prop: 'virtual_no',
|
||||
label: '设备号',
|
||||
minWidth: 150,
|
||||
minWidth: 170,
|
||||
showOverflowTooltip: true,
|
||||
formatter: (row: Device) => {
|
||||
return h(
|
||||
@@ -1071,21 +1135,18 @@
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'imei',
|
||||
label: 'IMEI',
|
||||
minWidth: 150,
|
||||
showOverflowTooltip: true,
|
||||
formatter: (row: Device) => row.imei || '-'
|
||||
},
|
||||
{
|
||||
prop: 'device_name',
|
||||
label: '设备名称',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'device_model',
|
||||
label: '设备型号',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'device_type',
|
||||
label: '设备类型',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
prop: 'shop_name',
|
||||
label: '店铺名称',
|
||||
@@ -1097,23 +1158,14 @@
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'manufacturer',
|
||||
label: '制造商',
|
||||
prop: 'device_model',
|
||||
label: '设备型号',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'max_sim_slots',
|
||||
label: '最大插槽数',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
prop: 'bound_card_count',
|
||||
label: '已绑定卡数',
|
||||
width: 110,
|
||||
formatter: (row: Device) => {
|
||||
const color = row.bound_card_count > 0 ? '#67c23a' : '#909399'
|
||||
return h('span', { style: { color, fontWeight: 'bold' } }, row.bound_card_count)
|
||||
}
|
||||
prop: 'device_type',
|
||||
label: '设备类型',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
@@ -1130,6 +1182,12 @@
|
||||
return h(ElTag, { type: status.type }, () => status.text)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'status_name',
|
||||
label: '状态名称',
|
||||
width: 100,
|
||||
formatter: (row: Device) => row.status_name || '-'
|
||||
},
|
||||
{
|
||||
prop: 'online_status',
|
||||
label: '在线状态',
|
||||
@@ -1144,6 +1202,20 @@
|
||||
return h(ElTag, { type: status.type }, () => status.text)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'realname_policy',
|
||||
label: '实名策略',
|
||||
width: 150,
|
||||
formatter: (row: Device) => {
|
||||
const policy = row.realname_policy || ''
|
||||
const policyMap: Record<string, string> = {
|
||||
none: '无需实名',
|
||||
before_order: '先实名后充值/购买',
|
||||
after_order: '先充值/购买后实名'
|
||||
}
|
||||
return policyMap[policy] || (policy ? policy : '未知')
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'switch_mode',
|
||||
label: '切卡模式',
|
||||
@@ -1157,19 +1229,51 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'realname_policy',
|
||||
label: '实名认证策略',
|
||||
width: 150,
|
||||
prop: 'activated_at',
|
||||
label: '激活时间',
|
||||
width: 180,
|
||||
formatter: (row: Device) => (row.activated_at ? formatDateTime(row.activated_at) : '-')
|
||||
},
|
||||
{
|
||||
prop: 'manufacturer',
|
||||
label: '制造商',
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
prop: 'software_version',
|
||||
label: '软件版本',
|
||||
minWidth: 180,
|
||||
showOverflowTooltip: true,
|
||||
formatter: (row: Device) => row.software_version || '-'
|
||||
},
|
||||
{
|
||||
prop: 'max_sim_slots',
|
||||
label: '最大插槽数',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
prop: 'bound_card_count',
|
||||
label: '已绑定卡数',
|
||||
width: 110,
|
||||
formatter: (row: Device) => {
|
||||
const policy = row.realname_policy || ''
|
||||
const policyMap: Record<string, string> = {
|
||||
none: '无需实名',
|
||||
before_order: '先实名后充值/购买',
|
||||
after_order: '先充值/购买后实名'
|
||||
}
|
||||
return policyMap[policy] || (policy ? policy : '未知')
|
||||
const color = row.bound_card_count > 0 ? '#67c23a' : '#909399'
|
||||
return h('span', { style: { color, fontWeight: 'bold' } }, row.bound_card_count)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'sn',
|
||||
label: '序列号',
|
||||
minWidth: 120,
|
||||
showOverflowTooltip: true,
|
||||
formatter: (row: Device) => row.sn || '-'
|
||||
},
|
||||
{
|
||||
prop: 'batch_no',
|
||||
label: '批次号',
|
||||
minWidth: 180,
|
||||
showOverflowTooltip: true,
|
||||
formatter: (row: Device) => row.batch_no || '-'
|
||||
},
|
||||
{
|
||||
prop: 'last_online_time',
|
||||
label: '最后在线时间',
|
||||
@@ -1184,12 +1288,6 @@
|
||||
formatter: (row: Device) =>
|
||||
row.last_gateway_sync_at ? formatDateTime(row.last_gateway_sync_at) : '-'
|
||||
},
|
||||
{
|
||||
prop: 'batch_no',
|
||||
label: '批次号',
|
||||
minWidth: 180,
|
||||
formatter: (row: Device) => row.batch_no || '-'
|
||||
},
|
||||
{
|
||||
prop: 'created_at',
|
||||
label: '创建时间',
|
||||
@@ -1198,9 +1296,50 @@
|
||||
}
|
||||
])
|
||||
|
||||
// 搜索店铺(用于搜索表单)
|
||||
const searchShops = async (query: string) => {
|
||||
try {
|
||||
const params: any = {
|
||||
page: 1,
|
||||
page_size: 20
|
||||
}
|
||||
if (query) {
|
||||
params.shop_name = query
|
||||
}
|
||||
const res = await ShopService.getShops(params)
|
||||
if (res.code === 0) {
|
||||
shopOptions.value = res.data.items || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索店铺失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索套餐系列(用于搜索表单)
|
||||
const searchSeries = async (query: string) => {
|
||||
try {
|
||||
const params: any = {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
status: 1
|
||||
}
|
||||
if (query) {
|
||||
params.series_name = query
|
||||
}
|
||||
const res = await PackageSeriesService.getPackageSeries(params)
|
||||
if (res.code === 0) {
|
||||
searchSeriesOptions.value = res.data.items || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索套餐系列失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
let isFirstActivation = true
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
searchShops('')
|
||||
searchSeries('')
|
||||
})
|
||||
|
||||
// 当页面被 keep-alive 激活时自动刷新数据
|
||||
@@ -1223,7 +1362,11 @@
|
||||
status: searchForm.status,
|
||||
batch_no: searchForm.batch_no || undefined,
|
||||
device_type: searchForm.device_type || undefined,
|
||||
manufacturer: searchForm.manufacturer || undefined
|
||||
manufacturer: searchForm.manufacturer || undefined,
|
||||
shop_id: searchForm.shop_id || undefined,
|
||||
series_id: searchForm.series_id || undefined,
|
||||
created_at_start: searchForm.created_at_start || undefined,
|
||||
created_at_end: searchForm.created_at_end || undefined
|
||||
}
|
||||
const res = await DeviceService.getDevices(params)
|
||||
if (res.code === 0 && res.data) {
|
||||
@@ -1246,6 +1389,14 @@
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
// 处理日期范围
|
||||
if (searchForm.dateRange && Array.isArray(searchForm.dateRange)) {
|
||||
searchForm.created_at_start = searchForm.dateRange[0] || ''
|
||||
searchForm.created_at_end = searchForm.dateRange[1] || ''
|
||||
} else {
|
||||
searchForm.created_at_start = ''
|
||||
searchForm.created_at_end = ''
|
||||
}
|
||||
pagination.page = 1
|
||||
getTableData()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user