This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 认证模块 API
|
||||
*/
|
||||
import { get, post } from '@/utils/request'
|
||||
import { get, post, put } from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 登录请求参数
|
||||
@@ -104,8 +104,5 @@ export function refreshToken(refresh_token: string) {
|
||||
* PUT /api/auth/password
|
||||
*/
|
||||
export function changePassword(data: ChangePasswordParams) {
|
||||
return post<void>('/api/auth/password', {
|
||||
data,
|
||||
method: 'PUT',
|
||||
})
|
||||
return put<void>('/api/auth/password', { data })
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{
|
||||
"path": "pages/agent-system/home/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "卡管H5",
|
||||
"navigationBarTitleText": "代理企业端H5",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -112,12 +112,13 @@ const cardHasMore = ref(true)
|
||||
const deviceHasMore = ref(true)
|
||||
const pageSize = 20
|
||||
// 搜索和筛选
|
||||
const iccidKeyword = ref('')
|
||||
const virtualNoKeyword = ref('')
|
||||
const searchType = ref<'iccid' | 'virtual'>('iccid')
|
||||
const searchKeyword = ref('')
|
||||
const carrierFilter = ref<number | undefined>(undefined)
|
||||
const statusFilter = ref<number | undefined>(undefined)
|
||||
const showCarrierPicker = ref(false)
|
||||
const showStatusPicker = ref(false)
|
||||
const showSearchTypePicker = ref(false)
|
||||
// 运营商列表
|
||||
const carrierList = ref<CarrierInfo[]>([])
|
||||
// 运营商选择器选项
|
||||
@@ -133,6 +134,11 @@ const statusOptions = [
|
||||
{ label: '已激活', value: 3 },
|
||||
{ label: '已停用', value: 4 }
|
||||
]
|
||||
// 搜索类型选项
|
||||
const searchTypeOptions = [
|
||||
{ label: 'ICCID', value: 'iccid' },
|
||||
{ label: '虚拟号', value: 'virtual' }
|
||||
]
|
||||
|
||||
// 合并后的资产列表
|
||||
const assetList = computed<AssetItem[]>(() => {
|
||||
@@ -209,11 +215,12 @@ async function loadCards(isRefresh = false) {
|
||||
if (statusFilter.value !== undefined) {
|
||||
params.status = statusFilter.value
|
||||
}
|
||||
if (iccidKeyword.value) {
|
||||
params.iccid = iccidKeyword.value
|
||||
}
|
||||
if (virtualNoKeyword.value) {
|
||||
params.virtual_no = virtualNoKeyword.value
|
||||
if (searchKeyword.value) {
|
||||
if (searchType.value === 'iccid') {
|
||||
params.iccid = searchKeyword.value
|
||||
} else {
|
||||
params.virtual_no = searchKeyword.value
|
||||
}
|
||||
}
|
||||
|
||||
let cardsData: any
|
||||
@@ -269,8 +276,8 @@ async function loadDevices(isRefresh = false) {
|
||||
page_size: pageSize,
|
||||
}
|
||||
|
||||
if (virtualNoKeyword.value) {
|
||||
params.virtual_no = virtualNoKeyword.value
|
||||
if (searchKeyword.value) {
|
||||
params.virtual_no = searchKeyword.value
|
||||
}
|
||||
if (statusFilter.value !== undefined) {
|
||||
params.status = statusFilter.value
|
||||
@@ -351,6 +358,11 @@ function onStatusConfirm(option: { label: string, value: any }) {
|
||||
refreshList()
|
||||
}
|
||||
|
||||
// 选择搜索类型
|
||||
function onSearchTypeConfirm(option: { label: string, value: any }) {
|
||||
searchType.value = option.value
|
||||
}
|
||||
|
||||
// 获取当前选中的运营商名称
|
||||
const selectedCarrierName = computed(() => {
|
||||
if (carrierFilter.value === undefined) return '运营商'
|
||||
@@ -385,8 +397,7 @@ function changeTab(tab: 'card' | 'device') {
|
||||
if (activeTab.value === tab) return
|
||||
|
||||
activeTab.value = tab
|
||||
iccidKeyword.value = ''
|
||||
virtualNoKeyword.value = ''
|
||||
searchKeyword.value = ''
|
||||
carrierFilter.value = undefined
|
||||
statusFilter.value = undefined
|
||||
|
||||
@@ -565,104 +576,98 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="bg-page safe-area-bottom min-h-screen">
|
||||
<!-- 搜索和筛选 -->
|
||||
<view class="safe-area-top px-4 pt-4 pb-3">
|
||||
<!-- IoT卡搜索和筛选 -->
|
||||
<view v-if="activeTab === 'card'">
|
||||
<!-- ICCID搜索 -->
|
||||
<view class="bg-white rounded-full px-4 py-2 flex items-center mb-2">
|
||||
<i class="i-mdi-credit-card text-lg text-[#94a3b8] mr-2" />
|
||||
<input
|
||||
v-model="iccidKeyword"
|
||||
class="flex-1 text-sm text-[#1e293b]"
|
||||
placeholder="ICCID"
|
||||
/>
|
||||
<i
|
||||
v-if="iccidKeyword"
|
||||
class="i-mdi-close-circle text-lg text-[#94a3b8] ml-2"
|
||||
@click="iccidKeyword = ''"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 虚拟号搜索 -->
|
||||
<view class="bg-white rounded-full px-4 py-2 flex items-center mb-2">
|
||||
<i class="i-mdi-phone text-lg text-[#94a3b8] mr-2" />
|
||||
<input
|
||||
v-model="virtualNoKeyword"
|
||||
class="flex-1 text-sm text-[#1e293b]"
|
||||
placeholder="虚拟号"
|
||||
/>
|
||||
<i
|
||||
v-if="virtualNoKeyword"
|
||||
class="i-mdi-close-circle text-lg text-[#94a3b8] ml-2"
|
||||
@click="virtualNoKeyword = ''"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 筛选条件 -->
|
||||
<view class="flex items-center gap-2 mb-2">
|
||||
<!-- 运营商 -->
|
||||
<view class="flex-1 bg-white rounded-full px-3 py-2 flex items-center" @click="showCarrierPicker = true">
|
||||
<text class="flex-1 text-sm text-[#1e293b]">{{ selectedCarrierName }}</text>
|
||||
<i class="i-mdi-chevron-down text-lg text-[#94a3b8]" />
|
||||
<view class="bg-page safe-area-bottom min-h-screen flex flex-col">
|
||||
<!-- 搜索区域 -->
|
||||
<view class="bg-white px-4 pt-4 pb-3">
|
||||
<!-- 搜索框 -->
|
||||
<view class="relative flex items-center">
|
||||
<input
|
||||
v-model="searchKeyword"
|
||||
class="flex-1 h-10 bg-[#f1f5f9] rounded-full pl-4 pr-12 text-sm text-[#1e293b] placeholder-[#94a3b8]"
|
||||
:placeholder="searchType === 'iccid' ? '搜索ICCID' : '搜索虚拟号'"
|
||||
@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]"
|
||||
@click="searchKeyword = ''"
|
||||
>
|
||||
<i class="i-mdi-close-circle text-lg" />
|
||||
</view>
|
||||
|
||||
<!-- 状态 -->
|
||||
<view class="flex-1 bg-white rounded-full px-3 py-2 flex items-center" @click="showStatusPicker = true">
|
||||
<text class="flex-1 text-sm text-[#1e293b]">{{ selectedStatusName }}</text>
|
||||
<i class="i-mdi-chevron-down text-lg text-[#94a3b8]" />
|
||||
<view
|
||||
class="w-8 h-8 flex items-center justify-center text-brand"
|
||||
@click="refreshList"
|
||||
>
|
||||
<i class="i-mdi-magnify text-xl" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 搜索按钮 -->
|
||||
<view class="bg-brand rounded-full py-2.5 text-center" @click="refreshList">
|
||||
<text class="text-sm font-500 text-white">搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 设备搜索 -->
|
||||
<view v-else>
|
||||
<view class="bg-white rounded-full px-4 py-2 flex items-center mb-2">
|
||||
<i class="i-mdi-phone text-lg text-[#94a3b8] mr-2" />
|
||||
<input
|
||||
v-model="virtualNoKeyword"
|
||||
class="flex-1 text-sm text-[#1e293b]"
|
||||
placeholder="虚拟号"
|
||||
/>
|
||||
<i
|
||||
v-if="virtualNoKeyword"
|
||||
class="i-mdi-close-circle text-lg text-[#94a3b8] ml-2"
|
||||
@click="virtualNoKeyword = ''"
|
||||
/>
|
||||
<!-- 筛选和类型切换 -->
|
||||
<view class="flex items-center gap-2 mt-3 flex-wrap">
|
||||
|
||||
<view
|
||||
class="flex items-center gap-1 px-3 py-1.5 bg-[#f8fafc] rounded-full flex-shrink-0"
|
||||
@click="showSearchTypePicker = true"
|
||||
>
|
||||
<text class="text-12px" :class="searchType !== 'iccid' ? 'text-brand font-medium' : 'text-[#64748b]'">
|
||||
{{ searchType === 'iccid' ? 'ICCID' : '虚拟号' }}
|
||||
</text>
|
||||
<i class="i-mdi-chevron-down text-12px text-[#94a3b8]" />
|
||||
</view>
|
||||
|
||||
<!-- 搜索按钮 -->
|
||||
<view class="bg-brand rounded-full py-2.5 text-center" @click="refreshList">
|
||||
<text class="text-sm font-500 text-white">搜索</text>
|
||||
<view
|
||||
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"
|
||||
>
|
||||
<text class="text-12px truncate" :class="carrierFilter !== undefined ? 'text-brand font-medium' : 'text-[#64748b]'">
|
||||
{{ selectedCarrierName }}
|
||||
</text>
|
||||
<i class="i-mdi-chevron-down text-12px text-[#94a3b8] flex-shrink-0" />
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="flex items-center gap-1.5 px-3 py-1.5 bg-[#f8fafc] rounded-full flex-shrink-0"
|
||||
@click="showStatusPicker = true"
|
||||
>
|
||||
<text class="text-12px" :class="statusFilter !== undefined ? 'text-brand font-medium' : 'text-[#64748b]'">
|
||||
{{ selectedStatusName }}
|
||||
</text>
|
||||
<i class="i-mdi-chevron-down text-12px text-[#94a3b8]" />
|
||||
</view>
|
||||
|
||||
<view
|
||||
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"
|
||||
@click="carrierFilter = undefined; statusFilter = undefined; refreshList()"
|
||||
>
|
||||
<i class="i-mdi-close text-12px" />
|
||||
<text class="text-12px font-medium">清除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 筛选标签 -->
|
||||
<view class="px-4 pb-3">
|
||||
<view class="bg-white rounded-full p-1 flex items-center">
|
||||
<!-- IoT卡 -->
|
||||
<view
|
||||
class="flex-1 py-2 rounded-full transition-fast text-center"
|
||||
:class="activeTab === 'card' ? 'bg-brand' : ''"
|
||||
@click="changeTab('card')"
|
||||
>
|
||||
<text class="text-sm font-500" :class="activeTab === 'card' ? 'text-white' : 'text-[#64748b]'">IoT卡</text>
|
||||
</view>
|
||||
|
||||
<!-- 设备 -->
|
||||
<view
|
||||
class="flex-1 py-2 rounded-full transition-fast text-center"
|
||||
:class="activeTab === 'device' ? 'bg-brand' : ''"
|
||||
@click="changeTab('device')"
|
||||
>
|
||||
<text class="text-sm font-500" :class="activeTab === 'device' ? 'text-white' : 'text-[#64748b]'">设备</text>
|
||||
<!-- 卡片/设备标签 -->
|
||||
<view class="bg-white px-4 pb-3">
|
||||
<view class="border-t border-[#f1f5f9] pt-3">
|
||||
<view class="bg-[#f1f5f9] rounded-full p-1 flex">
|
||||
<view
|
||||
class="flex-1 py-2 rounded-full text-center transition-all"
|
||||
:class="activeTab === 'card' ? 'bg-white shadow-sm text-[#1e293b] font-medium' : 'text-[#64748b]'"
|
||||
@click="changeTab('card')"
|
||||
>
|
||||
<text class="text-sm">IoT卡</text>
|
||||
</view>
|
||||
<view
|
||||
class="flex-1 py-2 rounded-full text-center transition-all"
|
||||
:class="activeTab === 'device' ? 'bg-white shadow-sm text-[#1e293b] font-medium' : 'text-[#64748b]'"
|
||||
@click="changeTab('device')"
|
||||
>
|
||||
<text class="text-sm">设备</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -673,8 +678,7 @@ onMounted(async () => {
|
||||
<!-- 资产列表 -->
|
||||
<view
|
||||
v-else
|
||||
class="overflow-y-auto"
|
||||
:style="{ height: activeTab === 'card' ? 'calc(100vh - 380px)' : 'calc(100vh - 280px)' }"
|
||||
class="flex-1 overflow-y-auto min-h-0"
|
||||
@scroll="onScroll"
|
||||
>
|
||||
<view v-if="assetList.length > 0" class="px-4 pb-4">
|
||||
@@ -730,36 +734,32 @@ onMounted(async () => {
|
||||
<template v-if="asset.type === 'card'">
|
||||
<template v-if="(asset.raw as CardInfo).network_status === 0">
|
||||
<view
|
||||
class="px-3 py-1 rounded-lg"
|
||||
style="background: #52c41a; color: white;"
|
||||
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)"
|
||||
>
|
||||
<text class="text-12px font-500">复机</text>
|
||||
复机
|
||||
</view>
|
||||
</template>
|
||||
<template v-else-if="(asset.raw as CardInfo).network_status === 1">
|
||||
<view
|
||||
class="px-3 py-1 rounded-lg"
|
||||
style="background: #ff4d4f; color: white;"
|
||||
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)"
|
||||
>
|
||||
<text class="text-12px font-500">停机</text>
|
||||
停机
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view
|
||||
class="px-3 py-1 rounded-lg"
|
||||
style="background: #ff4d4f; color: white;"
|
||||
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)"
|
||||
>
|
||||
<text class="text-12px font-500">停机</text>
|
||||
停机
|
||||
</view>
|
||||
<view
|
||||
class="px-3 py-1 rounded-lg"
|
||||
style="background: #52c41a; color: white;"
|
||||
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)"
|
||||
>
|
||||
<text class="text-12px font-500">复机</text>
|
||||
复机
|
||||
</view>
|
||||
</template>
|
||||
</template>
|
||||
@@ -767,18 +767,16 @@ onMounted(async () => {
|
||||
<!-- 设备操作按钮 -->
|
||||
<template v-else>
|
||||
<view
|
||||
class="px-3 py-1 rounded-lg"
|
||||
style="background: #ff4d4f; color: white;"
|
||||
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)"
|
||||
>
|
||||
<text class="text-12px font-500">停机</text>
|
||||
停机
|
||||
</view>
|
||||
<view
|
||||
class="px-3 py-1 rounded-lg"
|
||||
style="background: #52c41a; color: white;"
|
||||
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)"
|
||||
>
|
||||
<text class="text-12px font-500">复机</text>
|
||||
复机
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -802,7 +800,7 @@ onMounted(async () => {
|
||||
<view class="bg-white rounded-2xl py-12 flex flex-col items-center">
|
||||
<i class="i-mdi-package-variant-closed text-6xl text-[#cbd5e1] mb-3" />
|
||||
<text class="text-base text-[#64748b] mb-1">暂无数据</text>
|
||||
<text class="text-sm text-[#94a3b8]">{{ iccidKeyword || virtualNoKeyword ? '未找到相关结果' : '暂无资产数据' }}</text>
|
||||
<text class="text-sm text-[#94a3b8]">{{ searchKeyword ? '未找到相关结果' : '暂无资产数据' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -822,5 +820,13 @@ onMounted(async () => {
|
||||
title="选择状态"
|
||||
@confirm="onStatusConfirm"
|
||||
/>
|
||||
|
||||
<!-- 搜索类型选择器 -->
|
||||
<SimplePicker
|
||||
v-model:show="showSearchTypePicker"
|
||||
:options="searchTypeOptions"
|
||||
title="选择搜索类型"
|
||||
@confirm="onSearchTypeConfirm"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user