This commit is contained in:
@@ -1,148 +1,148 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { getUserInfo } from '@/api/auth'
|
import { getUserInfo } from '@/api/auth'
|
||||||
import type { UserInfo } from '@/api/auth'
|
import type { UserInfo } from '@/api/auth'
|
||||||
import { getEnterpriseCards, getEnterpriseDevices } from '@/api/enterprise'
|
import { getEnterpriseCards, getEnterpriseDevices } from '@/api/enterprise'
|
||||||
import { getCarriers } from '@/api/carrier'
|
import { getCarriers } from '@/api/carrier'
|
||||||
import type { CarrierInfo } from '@/api/carrier'
|
import type { CarrierInfo } from '@/api/carrier'
|
||||||
import { stopAsset, startAsset } from '@/api/assets'
|
import { stopAsset, startAsset } from '@/api/assets'
|
||||||
import Skeleton from '@/components/Skeleton.vue'
|
import Skeleton from '@/components/Skeleton.vue'
|
||||||
import SimplePicker from '@/components/SimplePicker.vue'
|
import SimplePicker from '@/components/SimplePicker.vue'
|
||||||
import { formatTime, formatDataSize } from '@/utils/format'
|
import { formatTime, formatDataSize } from '@/utils/format'
|
||||||
import { get } from '@/utils/request'
|
import { get } from '@/utils/request'
|
||||||
|
|
||||||
// 卡片信息接口
|
// 卡片信息接口
|
||||||
interface CardInfo {
|
interface CardInfo {
|
||||||
id: number
|
id : number
|
||||||
iccid: string
|
iccid : string
|
||||||
imsi?: string
|
imsi ?: string
|
||||||
msisdn?: string
|
msisdn ?: string
|
||||||
virtual_no?: string
|
virtual_no ?: string
|
||||||
virtual_number?: string // 企业端字段
|
virtual_number ?: string // 企业端字段
|
||||||
status?: number
|
status ?: number
|
||||||
status_name?: string
|
status_name ?: string
|
||||||
activation_status?: number
|
activation_status ?: number
|
||||||
network_status?: number
|
network_status ?: number
|
||||||
network_status_name?: string
|
network_status_name ?: string
|
||||||
real_name_status?: number
|
real_name_status ?: number
|
||||||
carrier_name?: string
|
carrier_name ?: string
|
||||||
carrier_type?: string
|
carrier_type ?: string
|
||||||
operator?: string // 企业端字段
|
operator ?: string // 企业端字段
|
||||||
supplier?: string
|
supplier ?: string
|
||||||
batch_no?: string
|
batch_no ?: string
|
||||||
series_name?: string
|
series_name ?: string
|
||||||
shop_name?: string
|
shop_name ?: string
|
||||||
data_usage_mb?: number
|
data_usage_mb ?: number
|
||||||
current_month_usage_mb?: number
|
current_month_usage_mb ?: number
|
||||||
accumulated_recharge?: number
|
accumulated_recharge ?: number
|
||||||
created_at?: string
|
created_at ?: string
|
||||||
updated_at?: string
|
updated_at ?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设备信息接口
|
// 设备信息接口
|
||||||
interface DeviceInfo {
|
interface DeviceInfo {
|
||||||
id?: number
|
id ?: number
|
||||||
device_id?: number // 企业端字段
|
device_id ?: number // 企业端字段
|
||||||
device_name?: string
|
device_name ?: string
|
||||||
device_model?: string
|
device_model ?: string
|
||||||
device_type?: string
|
device_type ?: string
|
||||||
manufacturer?: string
|
manufacturer ?: string
|
||||||
imei?: string
|
imei ?: string
|
||||||
sn?: string
|
sn ?: string
|
||||||
virtual_no?: string
|
virtual_no ?: string
|
||||||
status?: number
|
status ?: number
|
||||||
status_name?: string
|
status_name ?: string
|
||||||
online_status?: number
|
online_status ?: number
|
||||||
bound_card_count?: number
|
bound_card_count ?: number
|
||||||
card_count?: number // 企业端字段
|
card_count ?: number // 企业端字段
|
||||||
max_sim_slots?: number
|
max_sim_slots ?: number
|
||||||
switch_mode?: string
|
switch_mode ?: string
|
||||||
series_name?: string
|
series_name ?: string
|
||||||
shop_name?: string
|
shop_name ?: string
|
||||||
software_version?: string
|
software_version ?: string
|
||||||
accumulated_recharge?: number
|
accumulated_recharge ?: number
|
||||||
activated_at?: string
|
activated_at ?: string
|
||||||
authorized_at?: string // 企业端字段
|
authorized_at ?: string // 企业端字段
|
||||||
last_online_time?: string
|
last_online_time ?: string
|
||||||
created_at?: string
|
created_at ?: string
|
||||||
updated_at?: string
|
updated_at ?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户信息
|
// 用户信息
|
||||||
const userInfo = ref<UserInfo | null>(null)
|
const userInfo = ref<UserInfo | null>(null)
|
||||||
|
|
||||||
// 获取单卡列表(代理端)
|
// 获取单卡列表(代理端)
|
||||||
function getStandaloneCards(params: any) {
|
function getStandaloneCards(params : any) {
|
||||||
return get<{ items: CardInfo[], page: number, size: number, total: number }>('/api/admin/iot-cards/standalone', { params })
|
return get<{ items : CardInfo[], page : number, size : number, total : number }>('/api/admin/iot-cards/standalone', { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取设备列表(代理端)
|
// 获取设备列表(代理端)
|
||||||
function getDevices(params: any) {
|
function getDevices(params : any) {
|
||||||
return get<{ items: DeviceInfo[], page: number, size: number, total: number }>('/api/admin/devices', { params })
|
return get<{ items : DeviceInfo[], page : number, size : number, total : number }>('/api/admin/devices', { params })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 企业ID (企业端使用)
|
// 企业ID (企业端使用)
|
||||||
const enterpriseId = ref<number>(0)
|
const enterpriseId = ref<number>(0)
|
||||||
|
|
||||||
// 资产类型
|
// 资产类型
|
||||||
type AssetType = 'card' | 'device'
|
type AssetType = 'card' | 'device'
|
||||||
|
|
||||||
// 统一的资产项
|
// 统一的资产项
|
||||||
interface AssetItem {
|
interface AssetItem {
|
||||||
id: string
|
id : string
|
||||||
type: AssetType
|
type : AssetType
|
||||||
name: string
|
name : string
|
||||||
status: string
|
status : string
|
||||||
statusColor: string
|
statusColor : string
|
||||||
detail: string
|
detail : string
|
||||||
raw: CardInfo | DeviceInfo
|
raw : CardInfo | DeviceInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前标签
|
// 当前标签
|
||||||
const activeTab = ref<'card' | 'device'>('card')
|
const activeTab = ref<'card' | 'device'>('card')
|
||||||
// 资产列表
|
// 资产列表
|
||||||
const cardList = ref<CardInfo[]>([])
|
const cardList = ref<CardInfo[]>([])
|
||||||
const deviceList = ref<DeviceInfo[]>([])
|
const deviceList = ref<DeviceInfo[]>([])
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
// 分页
|
// 分页
|
||||||
const cardPage = ref(1)
|
const cardPage = ref(1)
|
||||||
const devicePage = ref(1)
|
const devicePage = ref(1)
|
||||||
const cardHasMore = ref(true)
|
const cardHasMore = ref(true)
|
||||||
const deviceHasMore = ref(true)
|
const deviceHasMore = ref(true)
|
||||||
const pageSize = 20
|
const pageSize = 20
|
||||||
// 搜索和筛选
|
// 搜索和筛选
|
||||||
const searchType = ref<'iccid' | 'virtual'>('iccid')
|
const searchType = ref<'iccid' | 'virtual'>('iccid')
|
||||||
const searchKeyword = ref('')
|
const searchKeyword = ref('')
|
||||||
const carrierFilter = ref<number | undefined>(undefined)
|
const carrierFilter = ref<number | undefined>(undefined)
|
||||||
const statusFilter = ref<number | undefined>(undefined)
|
const statusFilter = ref<number | undefined>(undefined)
|
||||||
const showCarrierPicker = ref(false)
|
const showCarrierPicker = ref(false)
|
||||||
const showStatusPicker = ref(false)
|
const showStatusPicker = ref(false)
|
||||||
const showSearchTypePicker = ref(false)
|
const showSearchTypePicker = ref(false)
|
||||||
// 运营商列表
|
// 运营商列表
|
||||||
const carrierList = ref<CarrierInfo[]>([])
|
const carrierList = ref<CarrierInfo[]>([])
|
||||||
// 运营商选择器选项
|
// 运营商选择器选项
|
||||||
const carrierOptions = computed(() => [
|
const carrierOptions = computed(() => [
|
||||||
{ label: '全部运营商', value: undefined },
|
{ label: '全部运营商', value: undefined },
|
||||||
...carrierList.value.map(c => ({ label: c.carrier_name, value: c.id }))
|
...carrierList.value.map(c => ({ label: c.carrier_name, value: c.id }))
|
||||||
])
|
])
|
||||||
// 状态选择器选项
|
// 状态选择器选项
|
||||||
const statusOptions = [
|
const statusOptions = [
|
||||||
{ label: '全部状态', value: undefined },
|
{ label: '全部状态', value: undefined },
|
||||||
{ label: '在库', value: 1 },
|
{ label: '在库', value: 1 },
|
||||||
{ label: '已分销', value: 2 },
|
{ label: '已分销', value: 2 },
|
||||||
{ label: '已激活', value: 3 },
|
{ label: '已激活', value: 3 },
|
||||||
{ label: '已停用', value: 4 }
|
{ label: '已停用', value: 4 }
|
||||||
]
|
]
|
||||||
// 搜索类型选项
|
// 搜索类型选项
|
||||||
const searchTypeOptions = [
|
const searchTypeOptions = [
|
||||||
{ label: 'ICCID', value: 'iccid' },
|
{ label: 'ICCID', value: 'iccid' },
|
||||||
{ label: '虚拟号', value: 'virtual' }
|
{ label: '虚拟号', value: 'virtual' }
|
||||||
]
|
]
|
||||||
|
|
||||||
// 合并后的资产列表
|
// 合并后的资产列表
|
||||||
const assetList = computed<AssetItem[]>(() => {
|
const assetList = computed<AssetItem[]>(() => {
|
||||||
const cards: AssetItem[] = cardList.value.map(card => ({
|
const cards : AssetItem[] = cardList.value.map(card => ({
|
||||||
id: String(card.id),
|
id: String(card.id),
|
||||||
type: 'card' as AssetType,
|
type: 'card' as AssetType,
|
||||||
name: card.iccid,
|
name: card.iccid,
|
||||||
@@ -154,7 +154,7 @@ const assetList = computed<AssetItem[]>(() => {
|
|||||||
raw: card,
|
raw: card,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const devices: AssetItem[] = deviceList.value.map(device => ({
|
const devices : AssetItem[] = deviceList.value.map(device => ({
|
||||||
id: String(device.id || device.device_id),
|
id: String(device.id || device.device_id),
|
||||||
type: 'device' as AssetType,
|
type: 'device' as AssetType,
|
||||||
name: device.device_name || '-',
|
name: device.device_name || '-',
|
||||||
@@ -169,11 +169,11 @@ const assetList = computed<AssetItem[]>(() => {
|
|||||||
if (activeTab.value === 'card') return cards
|
if (activeTab.value === 'card') return cards
|
||||||
if (activeTab.value === 'device') return devices
|
if (activeTab.value === 'device') return devices
|
||||||
return cards
|
return cards
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// 获取企业ID(企业端使用)
|
// 获取企业ID(企业端使用)
|
||||||
async function getEnterpriseId() {
|
async function getEnterpriseId() {
|
||||||
if (enterpriseId.value) return enterpriseId.value
|
if (enterpriseId.value) return enterpriseId.value
|
||||||
|
|
||||||
const cachedUserInfo = uni.getStorageSync('user_info')
|
const cachedUserInfo = uni.getStorageSync('user_info')
|
||||||
@@ -188,10 +188,10 @@ async function getEnterpriseId() {
|
|||||||
}
|
}
|
||||||
enterpriseId.value = apiUserInfo.enterprise_id
|
enterpriseId.value = apiUserInfo.enterprise_id
|
||||||
return enterpriseId.value
|
return enterpriseId.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载IoT卡列表(兼容企业端和代理端)
|
// 加载IoT卡列表(兼容企业端和代理端)
|
||||||
async function loadCards(isRefresh = false) {
|
async function loadCards(isRefresh = false) {
|
||||||
if (loading.value || (!cardHasMore.value && !isRefresh)) return
|
if (loading.value || (!cardHasMore.value && !isRefresh)) return
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -203,7 +203,7 @@ async function loadCards(isRefresh = false) {
|
|||||||
cardHasMore.value = true
|
cardHasMore.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const params: any = {
|
const params : any = {
|
||||||
page: cardPage.value,
|
page: cardPage.value,
|
||||||
page_size: pageSize,
|
page_size: pageSize,
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ async function loadCards(isRefresh = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let cardsData: any
|
let cardsData : any
|
||||||
|
|
||||||
// 根据用户类型调用不同接口
|
// 根据用户类型调用不同接口
|
||||||
if (userInfo.value?.user_type === 3) {
|
if (userInfo.value?.user_type === 3) {
|
||||||
@@ -247,7 +247,7 @@ async function loadCards(isRefresh = false) {
|
|||||||
cardHasMore.value = newItems.length >= pageSize
|
cardHasMore.value = newItems.length >= pageSize
|
||||||
cardPage.value++
|
cardPage.value++
|
||||||
}
|
}
|
||||||
catch (error: any) {
|
catch (error : any) {
|
||||||
console.error('加载IoT卡列表失败:', error)
|
console.error('加载IoT卡列表失败:', error)
|
||||||
if (error instanceof Error && error.message && !error.statusCode) {
|
if (error instanceof Error && error.message && !error.statusCode) {
|
||||||
uni.$u.toast(error.message)
|
uni.$u.toast(error.message)
|
||||||
@@ -256,10 +256,10 @@ async function loadCards(isRefresh = false) {
|
|||||||
finally {
|
finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载设备列表(兼容企业端和代理端)
|
// 加载设备列表(兼容企业端和代理端)
|
||||||
async function loadDevices(isRefresh = false) {
|
async function loadDevices(isRefresh = false) {
|
||||||
if (loading.value || (!deviceHasMore.value && !isRefresh)) return
|
if (loading.value || (!deviceHasMore.value && !isRefresh)) return
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -271,7 +271,7 @@ async function loadDevices(isRefresh = false) {
|
|||||||
deviceHasMore.value = true
|
deviceHasMore.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const params: any = {
|
const params : any = {
|
||||||
page: devicePage.value,
|
page: devicePage.value,
|
||||||
page_size: pageSize,
|
page_size: pageSize,
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ async function loadDevices(isRefresh = false) {
|
|||||||
params.status = statusFilter.value
|
params.status = statusFilter.value
|
||||||
}
|
}
|
||||||
|
|
||||||
let devicesData: any
|
let devicesData : any
|
||||||
|
|
||||||
// 根据用户类型调用不同接口
|
// 根据用户类型调用不同接口
|
||||||
if (userInfo.value?.user_type === 3) {
|
if (userInfo.value?.user_type === 3) {
|
||||||
@@ -307,7 +307,7 @@ async function loadDevices(isRefresh = false) {
|
|||||||
deviceHasMore.value = newItems.length >= pageSize
|
deviceHasMore.value = newItems.length >= pageSize
|
||||||
devicePage.value++
|
devicePage.value++
|
||||||
}
|
}
|
||||||
catch (error: any) {
|
catch (error : any) {
|
||||||
console.error('加载设备列表失败:', error)
|
console.error('加载设备列表失败:', error)
|
||||||
if (error instanceof Error && error.message && !error.statusCode) {
|
if (error instanceof Error && error.message && !error.statusCode) {
|
||||||
uni.$u.toast(error.message)
|
uni.$u.toast(error.message)
|
||||||
@@ -316,69 +316,69 @@ async function loadDevices(isRefresh = false) {
|
|||||||
finally {
|
finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载更多
|
// 加载更多
|
||||||
function loadMore() {
|
function loadMore() {
|
||||||
if (activeTab.value === 'card') {
|
if (activeTab.value === 'card') {
|
||||||
loadCards()
|
loadCards()
|
||||||
} else {
|
} else {
|
||||||
loadDevices()
|
loadDevices()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新列表
|
// 刷新列表
|
||||||
function refreshList() {
|
function refreshList() {
|
||||||
if (activeTab.value === 'card') {
|
if (activeTab.value === 'card') {
|
||||||
loadCards(true)
|
loadCards(true)
|
||||||
} else {
|
} else {
|
||||||
loadDevices(true)
|
loadDevices(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载运营商列表
|
// 加载运营商列表
|
||||||
async function loadCarriers() {
|
async function loadCarriers() {
|
||||||
try {
|
try {
|
||||||
const response = await getCarriers({ page: 1, page_size: 100 })
|
const response = await getCarriers({ page: 1, page_size: 100 })
|
||||||
carrierList.value = response?.items || []
|
carrierList.value = response?.items || []
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载运营商列表失败:', error)
|
console.error('加载运营商列表失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择运营商
|
// 选择运营商
|
||||||
function onCarrierConfirm(option: { label: string, value: any }) {
|
function onCarrierConfirm(option : { label : string, value : any }) {
|
||||||
carrierFilter.value = option.value
|
carrierFilter.value = option.value
|
||||||
refreshList()
|
refreshList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择状态
|
// 选择状态
|
||||||
function onStatusConfirm(option: { label: string, value: any }) {
|
function onStatusConfirm(option : { label : string, value : any }) {
|
||||||
statusFilter.value = option.value
|
statusFilter.value = option.value
|
||||||
refreshList()
|
refreshList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择搜索类型
|
// 选择搜索类型
|
||||||
function onSearchTypeConfirm(option: { label: string, value: any }) {
|
function onSearchTypeConfirm(option : { label : string, value : any }) {
|
||||||
searchType.value = option.value
|
searchType.value = option.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前选中的运营商名称
|
// 获取当前选中的运营商名称
|
||||||
const selectedCarrierName = computed(() => {
|
const selectedCarrierName = computed(() => {
|
||||||
if (carrierFilter.value === undefined) return '运营商'
|
if (carrierFilter.value === undefined) return '运营商'
|
||||||
const option = carrierOptions.value.find(o => o.value === carrierFilter.value)
|
const option = carrierOptions.value.find(o => o.value === carrierFilter.value)
|
||||||
return option?.label || '运营商'
|
return option?.label || '运营商'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取当前选中的状态名称
|
// 获取当前选中的状态名称
|
||||||
const selectedStatusName = computed(() => {
|
const selectedStatusName = computed(() => {
|
||||||
if (statusFilter.value === undefined) return '状态'
|
if (statusFilter.value === undefined) return '状态'
|
||||||
const option = statusOptions.find(o => o.value === statusFilter.value)
|
const option = statusOptions.find(o => o.value === statusFilter.value)
|
||||||
return option?.label || '状态'
|
return option?.label || '状态'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 查看资产详情
|
// 查看资产详情
|
||||||
function viewAssetDetail(asset: AssetItem) {
|
function viewAssetDetail(asset : AssetItem) {
|
||||||
if (asset.type === 'card') {
|
if (asset.type === 'card') {
|
||||||
const card = asset.raw as CardInfo
|
const card = asset.raw as CardInfo
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
@@ -390,16 +390,13 @@ function viewAssetDetail(asset: AssetItem) {
|
|||||||
url: `/pages/agent-system/asset-search/index?virtual_no=${device.virtual_no}`,
|
url: `/pages/agent-system/asset-search/index?virtual_no=${device.virtual_no}`,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换标签
|
// 切换标签
|
||||||
function changeTab(tab: 'card' | 'device') {
|
function changeTab(tab : 'card' | 'device') {
|
||||||
if (activeTab.value === tab) return
|
if (activeTab.value === tab) return
|
||||||
|
|
||||||
activeTab.value = tab
|
activeTab.value = tab
|
||||||
searchKeyword.value = ''
|
|
||||||
carrierFilter.value = undefined
|
|
||||||
statusFilter.value = undefined
|
|
||||||
|
|
||||||
// 切换后加载对应数据
|
// 切换后加载对应数据
|
||||||
if (tab === 'card' && cardList.value.length === 0) {
|
if (tab === 'card' && cardList.value.length === 0) {
|
||||||
@@ -407,10 +404,10 @@ function changeTab(tab: 'card' | 'device') {
|
|||||||
} else if (tab === 'device' && deviceList.value.length === 0) {
|
} else if (tab === 'device' && deviceList.value.length === 0) {
|
||||||
loadDevices(true)
|
loadDevices(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设备停机
|
// 设备停机
|
||||||
async function handleStopDevice(asset: AssetItem, event: Event) {
|
async function handleStopDevice(asset : AssetItem, event : Event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
const device = asset.raw as DeviceInfo
|
const device = asset.raw as DeviceInfo
|
||||||
@@ -440,7 +437,7 @@ async function handleStopDevice(asset: AssetItem, event: Event) {
|
|||||||
refreshList()
|
refreshList()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error : any) {
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
// 错误信息已经在拦截器中通过 toast 显示了,这里不需要重复显示
|
// 错误信息已经在拦截器中通过 toast 显示了,这里不需要重复显示
|
||||||
console.error('设备停机失败:', error)
|
console.error('设备停机失败:', error)
|
||||||
@@ -448,10 +445,10 @@ async function handleStopDevice(asset: AssetItem, event: Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设备复机
|
// 设备复机
|
||||||
async function handleStartDevice(asset: AssetItem, event: Event) {
|
async function handleStartDevice(asset : AssetItem, event : Event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
const device = asset.raw as DeviceInfo
|
const device = asset.raw as DeviceInfo
|
||||||
@@ -473,7 +470,7 @@ async function handleStartDevice(asset: AssetItem, event: Event) {
|
|||||||
uni.$u.toast('复机成功')
|
uni.$u.toast('复机成功')
|
||||||
// 刷新列表
|
// 刷新列表
|
||||||
refreshList()
|
refreshList()
|
||||||
} catch (error: any) {
|
} catch (error : any) {
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
// 错误信息已经在拦截器中通过 toast 显示了,这里不需要重复显示
|
// 错误信息已经在拦截器中通过 toast 显示了,这里不需要重复显示
|
||||||
console.error('设备复机失败:', error)
|
console.error('设备复机失败:', error)
|
||||||
@@ -481,10 +478,10 @@ async function handleStartDevice(asset: AssetItem, event: Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单卡停机
|
// 单卡停机
|
||||||
async function handleStopCard(asset: AssetItem, event: Event) {
|
async function handleStopCard(asset : AssetItem, event : Event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
const card = asset.raw as CardInfo
|
const card = asset.raw as CardInfo
|
||||||
@@ -506,7 +503,7 @@ async function handleStopCard(asset: AssetItem, event: Event) {
|
|||||||
uni.$u.toast('停机成功')
|
uni.$u.toast('停机成功')
|
||||||
// 刷新列表
|
// 刷新列表
|
||||||
refreshList()
|
refreshList()
|
||||||
} catch (error: any) {
|
} catch (error : any) {
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
// 错误信息已经在拦截器中通过 toast 显示了,这里不需要重复显示
|
// 错误信息已经在拦截器中通过 toast 显示了,这里不需要重复显示
|
||||||
console.error('单卡停机失败:', error)
|
console.error('单卡停机失败:', error)
|
||||||
@@ -514,10 +511,10 @@ async function handleStopCard(asset: AssetItem, event: Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单卡复机
|
// 单卡复机
|
||||||
async function handleStartCard(asset: AssetItem, event: Event) {
|
async function handleStartCard(asset : AssetItem, event : Event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
const card = asset.raw as CardInfo
|
const card = asset.raw as CardInfo
|
||||||
@@ -539,7 +536,7 @@ async function handleStartCard(asset: AssetItem, event: Event) {
|
|||||||
uni.$u.toast('复机成功')
|
uni.$u.toast('复机成功')
|
||||||
// 刷新列表
|
// 刷新列表
|
||||||
refreshList()
|
refreshList()
|
||||||
} catch (error: any) {
|
} catch (error : any) {
|
||||||
uni.hideLoading()
|
uni.hideLoading()
|
||||||
// 错误信息已经在拦截器中通过 toast 显示了,这里不需要重复显示
|
// 错误信息已经在拦截器中通过 toast 显示了,这里不需要重复显示
|
||||||
console.error('单卡复机失败:', error)
|
console.error('单卡复机失败:', error)
|
||||||
@@ -547,18 +544,18 @@ async function handleStartCard(asset: AssetItem, event: Event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 滚动事件处理
|
// 滚动事件处理
|
||||||
function onScroll(e: any) {
|
function onScroll(e : any) {
|
||||||
const { scrollTop, scrollHeight, clientHeight } = e.target
|
const { scrollTop, scrollHeight, clientHeight } = e.target
|
||||||
// 当滚动到底部附近时加载更多
|
// 当滚动到底部附近时加载更多
|
||||||
if (scrollHeight - scrollTop - clientHeight < 100) {
|
if (scrollHeight - scrollTop - clientHeight < 100) {
|
||||||
loadMore()
|
loadMore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 1. 加载用户信息(判断是企业端还是代理端)
|
// 1. 加载用户信息(判断是企业端还是代理端)
|
||||||
try {
|
try {
|
||||||
const user = await getUserInfo()
|
const user = await getUserInfo()
|
||||||
@@ -572,35 +569,25 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// 3. 默认加载IoT卡列表
|
// 3. 默认加载IoT卡列表
|
||||||
loadCards()
|
loadCards()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="bg-page safe-area-bottom min-h-screen flex flex-col">
|
<view class="bg-page min-h-screen">
|
||||||
<!-- 搜索区域 -->
|
<!-- 搜索区域 -->
|
||||||
<view class="bg-white px-4 pt-4 pb-3 mb-3">
|
<view class="bg-white px-4 pb-3 mb-3 fixed top-0 left-0 right-0 z-50"
|
||||||
|
style="padding-top: constant(safe-area-inset-top); padding-top: env(safe-area-inset-top);">
|
||||||
<!-- 搜索框 -->
|
<!-- 搜索框 -->
|
||||||
<view class="relative flex items-center">
|
<view class="relative flex items-center">
|
||||||
<input
|
<input v-model="searchKeyword"
|
||||||
v-model="searchKeyword"
|
|
||||||
class="flex-1 h-10 bg-[#f1f5f9] rounded-full pl-4 pr-12 text-sm text-[#1e293b] placeholder-[#94a3b8]"
|
class="flex-1 h-10 bg-[#f1f5f9] rounded-full pl-4 pr-12 text-sm text-[#1e293b] placeholder-[#94a3b8]"
|
||||||
:placeholder="searchType === 'iccid' ? '搜索ICCID' : '搜索虚拟号'"
|
:placeholder="searchType === 'iccid' ? '搜索ICCID' : '搜索虚拟号'" @confirm="refreshList" />
|
||||||
@confirm="refreshList"
|
<view class="absolute right-1 flex items-center">
|
||||||
/>
|
<view v-if="searchKeyword" class="w-8 h-8 flex items-center justify-center text-[#94a3b8]"
|
||||||
<view
|
@click="searchKeyword = ''">
|
||||||
class="absolute right-1 flex items-center"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
v-if="searchKeyword"
|
|
||||||
class="w-8 h-8 flex items-center justify-center text-[#94a3b8]"
|
|
||||||
@click="searchKeyword = ''"
|
|
||||||
>
|
|
||||||
<i class="i-mdi-close-circle text-lg" />
|
<i class="i-mdi-close-circle text-lg" />
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view class="w-8 h-8 flex items-center justify-center text-brand" @click="refreshList">
|
||||||
class="w-8 h-8 flex items-center justify-center text-brand"
|
|
||||||
@click="refreshList"
|
|
||||||
>
|
|
||||||
<i class="i-mdi-magnify text-xl" />
|
<i class="i-mdi-magnify text-xl" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -610,97 +597,73 @@ onMounted(async () => {
|
|||||||
<view class="flex items-center gap-2 mt-3 flex-wrap">
|
<view class="flex items-center gap-2 mt-3 flex-wrap">
|
||||||
|
|
||||||
<view class="flex bg-[#f1f5f9] rounded-full flex-shrink-0">
|
<view class="flex bg-[#f1f5f9] rounded-full flex-shrink-0">
|
||||||
<view
|
<view class="px-3 py-1.5 text-12px font-medium transition-all rounded-full"
|
||||||
class="px-3 py-1.5 text-12px font-medium transition-all rounded-full"
|
:class="activeTab === 'card' ? 'bg-brand text-white' : 'text-[#64748b]'" @click="changeTab('card')">
|
||||||
:class="activeTab === 'card' ? 'bg-brand text-white' : 'text-[#64748b]'"
|
|
||||||
@click="changeTab('card')"
|
|
||||||
>
|
|
||||||
IoT卡
|
IoT卡
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view class="px-3 py-1.5 text-12px font-medium transition-all rounded-full"
|
||||||
class="px-3 py-1.5 text-12px font-medium transition-all rounded-full"
|
:class="activeTab === 'device' ? 'bg-brand text-white' : 'text-[#64748b]'" @click="changeTab('device')">
|
||||||
:class="activeTab === 'device' ? 'bg-brand text-white' : 'text-[#64748b]'"
|
|
||||||
@click="changeTab('device')"
|
|
||||||
>
|
|
||||||
设备
|
设备
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view
|
<view class="flex items-center gap-1 px-3 py-1.5 bg-[#f8fafc] rounded-full flex-shrink-0"
|
||||||
class="flex items-center gap-1 px-3 py-1.5 bg-[#f8fafc] rounded-full flex-shrink-0"
|
@click="showSearchTypePicker = true">
|
||||||
@click="showSearchTypePicker = true"
|
|
||||||
>
|
|
||||||
<text class="text-12px" :class="searchType !== 'iccid' ? 'text-brand font-medium' : 'text-[#64748b]'">
|
<text class="text-12px" :class="searchType !== 'iccid' ? 'text-brand font-medium' : 'text-[#64748b]'">
|
||||||
{{ searchType === 'iccid' ? 'ICCID' : '虚拟号' }}
|
{{ searchType === 'iccid' ? 'ICCID' : '虚拟号' }}
|
||||||
</text>
|
</text>
|
||||||
<i class="i-mdi-chevron-down text-12px text-[#94a3b8]" />
|
<i class="i-mdi-chevron-down text-12px text-[#94a3b8]" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view
|
<view class="flex items-center gap-1.5 px-3 py-1.5 bg-[#f8fafc] rounded-full flex-shrink-0 max-w-36"
|
||||||
class="flex items-center gap-1.5 px-3 py-1.5 bg-[#f8fafc] rounded-full flex-shrink-0 max-w-36"
|
@click="showCarrierPicker = true">
|
||||||
@click="showCarrierPicker = true"
|
<text class="text-12px truncate"
|
||||||
>
|
:class="carrierFilter !== undefined ? 'text-brand font-medium' : 'text-[#64748b]'">
|
||||||
<text class="text-12px truncate" :class="carrierFilter !== undefined ? 'text-brand font-medium' : 'text-[#64748b]'">
|
|
||||||
{{ selectedCarrierName }}
|
{{ selectedCarrierName }}
|
||||||
</text>
|
</text>
|
||||||
<i class="i-mdi-chevron-down text-12px text-[#94a3b8] flex-shrink-0" />
|
<i class="i-mdi-chevron-down text-12px text-[#94a3b8] flex-shrink-0" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view
|
<view class="flex items-center gap-1.5 px-3 py-1.5 bg-[#f8fafc] rounded-full flex-shrink-0"
|
||||||
class="flex items-center gap-1.5 px-3 py-1.5 bg-[#f8fafc] rounded-full flex-shrink-0"
|
@click="showStatusPicker = true">
|
||||||
@click="showStatusPicker = true"
|
|
||||||
>
|
|
||||||
<text class="text-12px" :class="statusFilter !== undefined ? 'text-brand font-medium' : 'text-[#64748b]'">
|
<text class="text-12px" :class="statusFilter !== undefined ? 'text-brand font-medium' : 'text-[#64748b]'">
|
||||||
{{ selectedStatusName }}
|
{{ selectedStatusName }}
|
||||||
</text>
|
</text>
|
||||||
<i class="i-mdi-chevron-down text-12px text-[#94a3b8]" />
|
<i class="i-mdi-chevron-down text-12px text-[#94a3b8]" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view
|
<view v-if="carrierFilter !== undefined || statusFilter !== undefined"
|
||||||
v-if="carrierFilter !== undefined || statusFilter !== undefined"
|
|
||||||
class="flex items-center gap-1 px-2 py-1.5 rounded-full bg-[#ff4d4f]/10 text-[#ff4d4f] flex-shrink-0"
|
class="flex items-center gap-1 px-2 py-1.5 rounded-full bg-[#ff4d4f]/10 text-[#ff4d4f] flex-shrink-0"
|
||||||
@click="carrierFilter = undefined; statusFilter = undefined; refreshList()"
|
@click="carrierFilter = undefined; statusFilter = undefined; refreshList()">
|
||||||
>
|
|
||||||
<i class="i-mdi-close text-12px" />
|
<i class="i-mdi-close text-12px" />
|
||||||
<text class="text-12px font-medium">清除</text>
|
<text class="text-12px font-medium">清除</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 列表内容区域 -->
|
||||||
|
<view class="safe-area-bottom min-h-screen flex flex-col pt-28">
|
||||||
<!-- 加载状态 -->
|
<!-- 加载状态 -->
|
||||||
<Skeleton v-if="loading && assetList.length === 0" type="list" />
|
<Skeleton v-if="loading && assetList.length === 0" type="list" />
|
||||||
|
|
||||||
<!-- 资产列表 -->
|
<!-- 资产列表 -->
|
||||||
<view
|
<view v-else class="flex-1 overflow-y-auto min-h-0" @scroll="onScroll">
|
||||||
v-else
|
|
||||||
class="flex-1 overflow-y-auto min-h-0"
|
|
||||||
@scroll="onScroll"
|
|
||||||
>
|
|
||||||
<view v-if="assetList.length > 0" class="px-4 pb-4">
|
<view v-if="assetList.length > 0" class="px-4 pb-4">
|
||||||
<view
|
<view v-for="asset in assetList" :key="`${asset.type}-${asset.id}`"
|
||||||
v-for="asset in assetList"
|
|
||||||
:key="`${asset.type}-${asset.id}`"
|
|
||||||
class="bg-white rounded-16px shadow-[0_2px_12px_rgba(0,0,0,0.06)] p-4 mb-3 cursor-pointer"
|
class="bg-white rounded-16px shadow-[0_2px_12px_rgba(0,0,0,0.06)] p-4 mb-3 cursor-pointer"
|
||||||
@click="viewAssetDetail(asset)"
|
@click="viewAssetDetail(asset)">
|
||||||
>
|
|
||||||
<!-- 顶部区域:左侧状态+名称,右侧类型标签 -->
|
<!-- 顶部区域:左侧状态+名称,右侧类型标签 -->
|
||||||
<view class="flex items-start justify-between mb-3">
|
<view class="flex items-start justify-between mb-3">
|
||||||
<view class="flex items-center gap-2 flex-1 min-w-0">
|
<view class="flex items-center gap-2 flex-1 min-w-0">
|
||||||
<view
|
<view class="w-2 h-2 rounded-full mt-1 flex-shrink-0" :style="{ backgroundColor: asset.statusColor }" />
|
||||||
class="w-2 h-2 rounded-full mt-1 flex-shrink-0"
|
|
||||||
:style="{ backgroundColor: asset.statusColor }"
|
|
||||||
/>
|
|
||||||
<text class="text-15px font-600 text-[#212121] truncate">
|
<text class="text-15px font-600 text-[#212121] truncate">
|
||||||
{{ asset.name }}
|
{{ asset.name }}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view class="px-2 py-1 rounded-6px text-11px font-500 flex-shrink-0 ml-2" :style="{
|
||||||
class="px-2 py-1 rounded-6px text-11px font-500 flex-shrink-0 ml-2"
|
|
||||||
:style="{
|
|
||||||
backgroundColor: asset.type === 'card' ? '#e6f4ff' : '#f5f5f5',
|
backgroundColor: asset.type === 'card' ? '#e6f4ff' : '#f5f5f5',
|
||||||
color: asset.type === 'card' ? 'var(--brand-primary)' : '#666',
|
color: asset.type === 'card' ? 'var(--brand-primary)' : '#666',
|
||||||
}"
|
}">
|
||||||
>
|
|
||||||
{{ asset.type === 'card' ? 'IoT卡' : '设备' }}
|
{{ asset.type === 'card' ? 'IoT卡' : '设备' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -715,10 +678,7 @@ onMounted(async () => {
|
|||||||
<!-- 底部区域:状态标签 + 操作按钮 -->
|
<!-- 底部区域:状态标签 + 操作按钮 -->
|
||||||
<view class="flex items-center justify-between pt-3 border-t border-[#f5f5f5]">
|
<view class="flex items-center justify-between pt-3 border-t border-[#f5f5f5]">
|
||||||
<view class="flex items-center gap-1">
|
<view class="flex items-center gap-1">
|
||||||
<view
|
<view class="w-1.5 h-1.5 rounded-full" :style="{ backgroundColor: asset.statusColor }" />
|
||||||
class="w-1.5 h-1.5 rounded-full"
|
|
||||||
:style="{ backgroundColor: asset.statusColor }"
|
|
||||||
/>
|
|
||||||
<text class="text-13px font-500" :style="{ color: asset.statusColor }">
|
<text class="text-13px font-500" :style="{ color: asset.statusColor }">
|
||||||
{{ asset.status }}
|
{{ asset.status }}
|
||||||
</text>
|
</text>
|
||||||
@@ -730,30 +690,26 @@ onMounted(async () => {
|
|||||||
<template v-if="(asset.raw as CardInfo).network_status === 0">
|
<template v-if="(asset.raw as CardInfo).network_status === 0">
|
||||||
<view
|
<view
|
||||||
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#52c41a] text-white shadow-sm shadow-[#52c41a]/30 active:scale-95 transition-transform"
|
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#52c41a] text-white shadow-sm shadow-[#52c41a]/30 active:scale-95 transition-transform"
|
||||||
@click="handleStartCard(asset, $event)"
|
@click="handleStartCard(asset, $event)">
|
||||||
>
|
|
||||||
复机
|
复机
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="(asset.raw as CardInfo).network_status === 1">
|
<template v-else-if="(asset.raw as CardInfo).network_status === 1">
|
||||||
<view
|
<view
|
||||||
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#ff4d4f] text-white shadow-sm shadow-[#ff4d4f]/30 active:scale-95 transition-transform"
|
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#ff4d4f] text-white shadow-sm shadow-[#ff4d4f]/30 active:scale-95 transition-transform"
|
||||||
@click="handleStopCard(asset, $event)"
|
@click="handleStopCard(asset, $event)">
|
||||||
>
|
|
||||||
停机
|
停机
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<view
|
<view
|
||||||
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#ff4d4f] text-white shadow-sm shadow-[#ff4d4f]/30 active:scale-95 transition-transform"
|
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#ff4d4f] text-white shadow-sm shadow-[#ff4d4f]/30 active:scale-95 transition-transform"
|
||||||
@click="handleStopCard(asset, $event)"
|
@click="handleStopCard(asset, $event)">
|
||||||
>
|
|
||||||
停机
|
停机
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#52c41a] text-white shadow-sm shadow-[#52c41a]/30 active:scale-95 transition-transform"
|
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#52c41a] text-white shadow-sm shadow-[#52c41a]/30 active:scale-95 transition-transform"
|
||||||
@click="handleStartCard(asset, $event)"
|
@click="handleStartCard(asset, $event)">
|
||||||
>
|
|
||||||
复机
|
复机
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -763,14 +719,12 @@ onMounted(async () => {
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<view
|
<view
|
||||||
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#ff4d4f] text-white shadow-sm shadow-[#ff4d4f]/30 active:scale-95 transition-transform"
|
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#ff4d4f] text-white shadow-sm shadow-[#ff4d4f]/30 active:scale-95 transition-transform"
|
||||||
@click="handleStopDevice(asset, $event)"
|
@click="handleStopDevice(asset, $event)">
|
||||||
>
|
|
||||||
停机
|
停机
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#52c41a] text-white shadow-sm shadow-[#52c41a]/30 active:scale-95 transition-transform"
|
class="px-3 py-1.5 rounded-10px text-12px font-medium bg-[#52c41a] text-white shadow-sm shadow-[#52c41a]/30 active:scale-95 transition-transform"
|
||||||
@click="handleStartDevice(asset, $event)"
|
@click="handleStartDevice(asset, $event)">
|
||||||
>
|
|
||||||
复机
|
复机
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -785,7 +739,8 @@ onMounted(async () => {
|
|||||||
<i class="i-mdi-loading animate-spin text-xl text-brand mr-2" />
|
<i class="i-mdi-loading animate-spin text-xl text-brand mr-2" />
|
||||||
<text class="text-sm text-[#64748b]">加载中...</text>
|
<text class="text-sm text-[#64748b]">加载中...</text>
|
||||||
</view>
|
</view>
|
||||||
<view v-else-if="!((activeTab === 'card' && cardHasMore) || (activeTab === 'device' && deviceHasMore))" class="py-4 text-center">
|
<view v-else-if="!((activeTab === 'card' && cardHasMore) || (activeTab === 'device' && deviceHasMore))"
|
||||||
|
class="py-4 text-center">
|
||||||
<text class="text-sm text-[#94a3b8]">没有更多了</text>
|
<text class="text-sm text-[#94a3b8]">没有更多了</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -801,27 +756,15 @@ onMounted(async () => {
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 运营商选择器 -->
|
<!-- 运营商选择器 -->
|
||||||
<SimplePicker
|
<SimplePicker v-model:show="showCarrierPicker" :options="carrierOptions" title="选择运营商"
|
||||||
v-model:show="showCarrierPicker"
|
@confirm="onCarrierConfirm" />
|
||||||
:options="carrierOptions"
|
|
||||||
title="选择运营商"
|
|
||||||
@confirm="onCarrierConfirm"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 状态选择器 -->
|
<!-- 状态选择器 -->
|
||||||
<SimplePicker
|
<SimplePicker v-model:show="showStatusPicker" :options="statusOptions" title="选择状态" @confirm="onStatusConfirm" />
|
||||||
v-model:show="showStatusPicker"
|
|
||||||
:options="statusOptions"
|
|
||||||
title="选择状态"
|
|
||||||
@confirm="onStatusConfirm"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 搜索类型选择器 -->
|
<!-- 搜索类型选择器 -->
|
||||||
<SimplePicker
|
<SimplePicker v-model:show="showSearchTypePicker" :options="searchTypeOptions" title="选择搜索类型"
|
||||||
v-model:show="showSearchTypePicker"
|
@confirm="onSearchTypeConfirm" />
|
||||||
:options="searchTypeOptions"
|
</view>
|
||||||
title="选择搜索类型"
|
|
||||||
@confirm="onSearchTypeConfirm"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user