This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<ArtSearchBar
|
||||
v-model:filter="formFilters"
|
||||
:items="formItems"
|
||||
label-width="120"
|
||||
:label-width="90"
|
||||
@reset="handleReset"
|
||||
@search="handleSearch"
|
||||
></ArtSearchBar>
|
||||
@@ -42,6 +42,22 @@
|
||||
>
|
||||
批量设置套餐系列
|
||||
</ElButton>
|
||||
<ElButton
|
||||
type="primary"
|
||||
:disabled="selectedCards.length === 0"
|
||||
@click="showEnterpriseCardAuthorizeDialog"
|
||||
v-permission="'iot_card:authorize_enterprise'"
|
||||
>
|
||||
授权卡给企业
|
||||
</ElButton>
|
||||
<ElButton
|
||||
type="warning"
|
||||
:disabled="selectedCards.length === 0"
|
||||
@click="showEnterpriseCardRecallDialog"
|
||||
v-permission="'iot_card:recall_enterprise_authorization'"
|
||||
>
|
||||
回收卡授权
|
||||
</ElButton>
|
||||
<ElButton type="primary" @click="showExportDialog" v-permission="'iot_card:export'">
|
||||
导出
|
||||
</ElButton>
|
||||
@@ -357,6 +373,350 @@
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 企业卡授权对话框 -->
|
||||
<ElDialog
|
||||
v-model="enterpriseCardAuthorizeDialogVisible"
|
||||
title="授权卡给企业"
|
||||
width="640px"
|
||||
@close="handleEnterpriseCardAuthorizeDialogClose"
|
||||
>
|
||||
<ElForm
|
||||
ref="enterpriseCardAuthorizeFormRef"
|
||||
:model="enterpriseCardAuthorizeForm"
|
||||
:rules="enterpriseCardAuthorizeRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<ElFormItem label="授权企业" prop="enterprise_id">
|
||||
<ElSelect
|
||||
v-model="enterpriseCardAuthorizeForm.enterprise_id"
|
||||
placeholder="请选择或搜索企业"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="handleSearchEnterprise"
|
||||
:loading="enterpriseLoading"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in enterpriseOptions"
|
||||
:key="item.id"
|
||||
:label="item.enterprise_name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="选卡方式" prop="selection_type">
|
||||
<ElRadioGroup v-model="enterpriseCardAuthorizeForm.selection_type">
|
||||
<ElRadio label="list">ICCID列表</ElRadio>
|
||||
<ElRadio label="range">号段范围</ElRadio>
|
||||
<ElRadio label="filter">筛选条件</ElRadio>
|
||||
</ElRadioGroup>
|
||||
</ElFormItem>
|
||||
<ElFormItem
|
||||
v-if="enterpriseCardAuthorizeForm.selection_type === CardSelectionType.LIST"
|
||||
label="ICCID列表"
|
||||
>
|
||||
<div>已选择 {{ selectedCards.length }} 张卡</div>
|
||||
</ElFormItem>
|
||||
<ElFormItem
|
||||
v-if="enterpriseCardAuthorizeForm.selection_type === CardSelectionType.RANGE"
|
||||
label="起始ICCID"
|
||||
prop="iccid_start"
|
||||
>
|
||||
<ElInput
|
||||
v-model="enterpriseCardAuthorizeForm.iccid_start"
|
||||
placeholder="请输入起始ICCID"
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem
|
||||
v-if="enterpriseCardAuthorizeForm.selection_type === CardSelectionType.RANGE"
|
||||
label="结束ICCID"
|
||||
prop="iccid_end"
|
||||
>
|
||||
<ElInput
|
||||
v-model="enterpriseCardAuthorizeForm.iccid_end"
|
||||
placeholder="请输入结束ICCID"
|
||||
/>
|
||||
</ElFormItem>
|
||||
<div
|
||||
v-if="
|
||||
enterpriseCardAuthorizeForm.selection_type === CardSelectionType.RANGE &&
|
||||
enterpriseCardAuthorizeRangeCountText
|
||||
"
|
||||
class="range-allocation-hint range-allocation-hint--card-form"
|
||||
>
|
||||
共授权{{ enterpriseCardAuthorizeRangeCountText }}张卡
|
||||
</div>
|
||||
<template
|
||||
v-if="enterpriseCardAuthorizeForm.selection_type === CardSelectionType.FILTER"
|
||||
>
|
||||
<ElFormItem label="运营商">
|
||||
<ElSelect
|
||||
v-model="enterpriseCardAuthorizeForm.carrier_id"
|
||||
placeholder="请选择或搜索运营商"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="handleSearchAllocateCarrier"
|
||||
:loading="allocateCarrierLoading"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in allocateCarrierOptions"
|
||||
:key="item.id"
|
||||
:label="item.carrier_name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="店铺">
|
||||
<ElCascader
|
||||
v-model="enterpriseCardAuthorizeForm.shop_id_path"
|
||||
:options="shopCascadeOptions"
|
||||
:props="shopCascadeProps"
|
||||
placeholder="请选择店铺"
|
||||
style="width: 100%"
|
||||
clearable
|
||||
filterable
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="批次号">
|
||||
<ElSelect
|
||||
v-model="enterpriseCardAuthorizeForm.batch_no"
|
||||
placeholder="请选择或搜索批次号"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="handleSearchAllocateBatchNo"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in allocateBatchNoOptions"
|
||||
:key="item.id"
|
||||
:label="item.batch_no"
|
||||
:value="item.batch_no"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="ICCID">
|
||||
<ElInput v-model="enterpriseCardAuthorizeForm.iccid" placeholder="请输入ICCID" />
|
||||
</ElFormItem>
|
||||
</template>
|
||||
<ElFormItem label="备注">
|
||||
<ElInput
|
||||
v-model="enterpriseCardAuthorizeForm.remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注信息"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="enterpriseCardAuthorizeDialogVisible = false">取消</ElButton>
|
||||
<ElButton
|
||||
type="primary"
|
||||
@click="handleEnterpriseCardAuthorize"
|
||||
:loading="enterpriseCardAuthorizeLoading"
|
||||
>
|
||||
确认授权
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 企业卡授权回收对话框 -->
|
||||
<ElDialog
|
||||
v-model="enterpriseCardRecallDialogVisible"
|
||||
title="回收卡授权"
|
||||
width="640px"
|
||||
@close="handleEnterpriseCardRecallDialogClose"
|
||||
>
|
||||
<ElForm
|
||||
ref="enterpriseCardRecallFormRef"
|
||||
:model="enterpriseCardRecallForm"
|
||||
:rules="enterpriseCardRecallRules"
|
||||
label-width="120px"
|
||||
>
|
||||
<ElFormItem label="授权企业" prop="enterprise_id">
|
||||
<ElSelect
|
||||
v-model="enterpriseCardRecallForm.enterprise_id"
|
||||
placeholder="请选择或搜索企业"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="handleSearchEnterprise"
|
||||
:loading="enterpriseLoading"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in enterpriseOptions"
|
||||
:key="item.id"
|
||||
:label="item.enterprise_name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="选卡方式" prop="selection_type">
|
||||
<ElRadioGroup v-model="enterpriseCardRecallForm.selection_type">
|
||||
<ElRadio label="list">ICCID列表</ElRadio>
|
||||
<ElRadio label="range">号段范围</ElRadio>
|
||||
<ElRadio label="filter">筛选条件</ElRadio>
|
||||
</ElRadioGroup>
|
||||
</ElFormItem>
|
||||
<ElFormItem
|
||||
v-if="enterpriseCardRecallForm.selection_type === CardSelectionType.LIST"
|
||||
label="ICCID列表"
|
||||
>
|
||||
<div>已选择 {{ selectedCards.length }} 张卡</div>
|
||||
</ElFormItem>
|
||||
<ElFormItem
|
||||
v-if="enterpriseCardRecallForm.selection_type === CardSelectionType.RANGE"
|
||||
label="起始ICCID"
|
||||
prop="iccid_start"
|
||||
>
|
||||
<ElInput
|
||||
v-model="enterpriseCardRecallForm.iccid_start"
|
||||
placeholder="请输入起始ICCID"
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem
|
||||
v-if="enterpriseCardRecallForm.selection_type === CardSelectionType.RANGE"
|
||||
label="结束ICCID"
|
||||
prop="iccid_end"
|
||||
>
|
||||
<ElInput v-model="enterpriseCardRecallForm.iccid_end" placeholder="请输入结束ICCID" />
|
||||
</ElFormItem>
|
||||
<div
|
||||
v-if="
|
||||
enterpriseCardRecallForm.selection_type === CardSelectionType.RANGE &&
|
||||
enterpriseCardRecallRangeCountText
|
||||
"
|
||||
class="range-allocation-hint range-allocation-hint--card-form"
|
||||
>
|
||||
共回收{{ enterpriseCardRecallRangeCountText }}张卡
|
||||
</div>
|
||||
<template v-if="enterpriseCardRecallForm.selection_type === CardSelectionType.FILTER">
|
||||
<ElFormItem label="运营商">
|
||||
<ElSelect
|
||||
v-model="enterpriseCardRecallForm.carrier_id"
|
||||
placeholder="请选择或搜索运营商"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="handleSearchAllocateCarrier"
|
||||
:loading="allocateCarrierLoading"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in allocateCarrierOptions"
|
||||
:key="item.id"
|
||||
:label="item.carrier_name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="批次号">
|
||||
<ElSelect
|
||||
v-model="enterpriseCardRecallForm.batch_no"
|
||||
placeholder="请选择或搜索批次号"
|
||||
clearable
|
||||
filterable
|
||||
remote
|
||||
:remote-method="handleSearchAllocateBatchNo"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in allocateBatchNoOptions"
|
||||
:key="item.id"
|
||||
:label="item.batch_no"
|
||||
:value="item.batch_no"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="ICCID">
|
||||
<ElInput v-model="enterpriseCardRecallForm.iccid" placeholder="请输入ICCID" />
|
||||
</ElFormItem>
|
||||
</template>
|
||||
<ElFormItem label="备注">
|
||||
<ElInput
|
||||
v-model="enterpriseCardRecallForm.remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注信息"
|
||||
/>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="enterpriseCardRecallDialogVisible = false">取消</ElButton>
|
||||
<ElButton
|
||||
type="primary"
|
||||
@click="handleEnterpriseCardRecall"
|
||||
:loading="enterpriseCardRecallLoading"
|
||||
>
|
||||
确认回收
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 企业卡授权操作结果 -->
|
||||
<ElDialog
|
||||
v-model="enterpriseCardResultDialogVisible"
|
||||
:title="enterpriseCardResultTitle"
|
||||
width="700px"
|
||||
>
|
||||
<ElDescriptions :column="2" border>
|
||||
<ElDescriptionsItem label="成功数">
|
||||
<ElTag type="success">{{ enterpriseCardOperationResult.success_count }}</ElTag>
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="失败数">
|
||||
<ElTag type="danger">{{ enterpriseCardOperationResult.fail_count }}</ElTag>
|
||||
</ElDescriptionsItem>
|
||||
</ElDescriptions>
|
||||
<div
|
||||
v-if="
|
||||
enterpriseCardOperationResult.failed_items &&
|
||||
enterpriseCardOperationResult.failed_items.length > 0
|
||||
"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<ElDivider content-position="left">失败项详情</ElDivider>
|
||||
<ElTable :data="enterpriseCardOperationResult.failed_items" border max-height="300">
|
||||
<ElTableColumn prop="iccid" label="ICCID" width="200" />
|
||||
<ElTableColumn prop="reason" label="失败原因" />
|
||||
</ElTable>
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
enterpriseCardOperationResult.recalled_devices &&
|
||||
enterpriseCardOperationResult.recalled_devices.length > 0
|
||||
"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<ElDivider content-position="left">连带回收设备</ElDivider>
|
||||
<ElTable :data="enterpriseCardOperationResult.recalled_devices" border max-height="220">
|
||||
<ElTableColumn prop="virtual_no" label="设备虚拟号" width="180" />
|
||||
<ElTableColumn prop="card_count" label="关联卡数" width="100" />
|
||||
<ElTableColumn label="ICCID列表">
|
||||
<template #default="{ row }">
|
||||
{{ row.iccids?.join(', ') || '-' }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</ElTable>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton type="primary" @click="enterpriseCardResultDialogVisible = false"
|
||||
>确定</ElButton
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 批量设置套餐系列绑定对话框 -->
|
||||
<ElDialog
|
||||
v-model="seriesBindingDialogVisible"
|
||||
@@ -652,7 +1012,8 @@
|
||||
ShopService,
|
||||
PackageSeriesService,
|
||||
AssetService,
|
||||
CarrierService
|
||||
CarrierService,
|
||||
EnterpriseService
|
||||
} from '@/api/modules'
|
||||
import { ElMessage, ElTag, ElIcon, ElMessageBox } from 'element-plus'
|
||||
import { Loading } from '@element-plus/icons-vue'
|
||||
@@ -677,6 +1038,8 @@
|
||||
} from '@/types/api/card'
|
||||
import { CardSelectionType } from '@/types/api/card'
|
||||
import type { PackageSeriesResponse } from '@/types/api'
|
||||
import type { EnterpriseItem } from '@/types/api/enterprise'
|
||||
import type { AllocateCardsResponse, RecallCardsResponse } from '@/types/api/enterpriseCard'
|
||||
import OperationLogsDialog from '@/components/business/OperationLogsDialog.vue'
|
||||
|
||||
defineOptions({ name: 'StandaloneCardList' })
|
||||
@@ -704,6 +1067,27 @@
|
||||
fail_count: 0,
|
||||
failed_items: null
|
||||
})
|
||||
const enterpriseCardAuthorizeDialogVisible = ref(false)
|
||||
const enterpriseCardRecallDialogVisible = ref(false)
|
||||
const enterpriseCardResultDialogVisible = ref(false)
|
||||
const enterpriseCardAuthorizeLoading = ref(false)
|
||||
const enterpriseCardRecallLoading = ref(false)
|
||||
const enterpriseCardResultTitle = ref('')
|
||||
const enterpriseCardAuthorizeFormRef = ref<FormInstance>()
|
||||
const enterpriseCardRecallFormRef = ref<FormInstance>()
|
||||
const enterpriseOptions = ref<EnterpriseItem[]>([])
|
||||
const enterpriseLoading = ref(false)
|
||||
const enterpriseCardOperationResult = ref<
|
||||
Partial<AllocateCardsResponse & RecallCardsResponse> & {
|
||||
success_count: number
|
||||
fail_count: number
|
||||
}
|
||||
>({
|
||||
success_count: 0,
|
||||
fail_count: 0,
|
||||
failed_items: null,
|
||||
recalled_devices: null
|
||||
})
|
||||
|
||||
// 操作审计日志弹窗
|
||||
const operationLogsDialogVisible = ref(false)
|
||||
@@ -727,6 +1111,29 @@
|
||||
batch_no: ''
|
||||
})
|
||||
const seriesBindingForm = reactive(createInitialSeriesBindingState())
|
||||
const createInitialEnterpriseCardAuthorizeState = () => ({
|
||||
enterprise_id: undefined as number | undefined,
|
||||
selection_type: CardSelectionType.LIST,
|
||||
iccid_start: '',
|
||||
iccid_end: '',
|
||||
carrier_id: undefined as number | undefined,
|
||||
shop_id_path: undefined as number[] | undefined,
|
||||
batch_no: '',
|
||||
iccid: '',
|
||||
remark: ''
|
||||
})
|
||||
const createInitialEnterpriseCardRecallState = () => ({
|
||||
enterprise_id: undefined as number | undefined,
|
||||
selection_type: CardSelectionType.LIST,
|
||||
iccid_start: '',
|
||||
iccid_end: '',
|
||||
carrier_id: undefined as number | undefined,
|
||||
batch_no: '',
|
||||
iccid: '',
|
||||
remark: ''
|
||||
})
|
||||
const enterpriseCardAuthorizeForm = reactive(createInitialEnterpriseCardAuthorizeState())
|
||||
const enterpriseCardRecallForm = reactive(createInitialEnterpriseCardRecallState())
|
||||
const parseNumericStringToBigInt = (value: string): bigint | null => {
|
||||
const normalizedValue = value.trim()
|
||||
if (!normalizedValue || !/^\d+$/.test(normalizedValue)) {
|
||||
@@ -761,9 +1168,54 @@
|
||||
const recallRangeCountText = computed(() =>
|
||||
getFormattedRangeCountText(recallForm.iccid_start, recallForm.iccid_end)
|
||||
)
|
||||
const enterpriseCardAuthorizeRangeCountText = computed(() =>
|
||||
getFormattedRangeCountText(
|
||||
enterpriseCardAuthorizeForm.iccid_start,
|
||||
enterpriseCardAuthorizeForm.iccid_end
|
||||
)
|
||||
)
|
||||
const enterpriseCardRecallRangeCountText = computed(() =>
|
||||
getFormattedRangeCountText(
|
||||
enterpriseCardRecallForm.iccid_start,
|
||||
enterpriseCardRecallForm.iccid_end
|
||||
)
|
||||
)
|
||||
const seriesBindingRangeCountText = computed(() =>
|
||||
getFormattedRangeCountText(seriesBindingForm.iccid_start, seriesBindingForm.iccid_end)
|
||||
)
|
||||
const createEnterpriseCardRules = (form: { selection_type: CardSelectionType }) =>
|
||||
reactive<FormRules>({
|
||||
enterprise_id: [{ required: true, message: '请选择企业', trigger: 'change' }],
|
||||
selection_type: [{ required: true, message: '请选择选卡方式', trigger: 'change' }],
|
||||
iccid_start: [
|
||||
{
|
||||
required: true,
|
||||
validator: (_rule, value, callback) => {
|
||||
if (form.selection_type === CardSelectionType.RANGE && !value) {
|
||||
callback(new Error('请输入起始ICCID'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
iccid_end: [
|
||||
{
|
||||
required: true,
|
||||
validator: (_rule, value, callback) => {
|
||||
if (form.selection_type === CardSelectionType.RANGE && !value) {
|
||||
callback(new Error('请输入结束ICCID'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
const enterpriseCardAuthorizeRules = createEnterpriseCardRules(enterpriseCardAuthorizeForm)
|
||||
const enterpriseCardRecallRules = createEnterpriseCardRules(enterpriseCardRecallForm)
|
||||
const seriesBindingRules = reactive<FormRules>({
|
||||
selection_type: [{ required: true, message: '请选择选卡方式', trigger: 'change' }],
|
||||
series_id: [{ required: true, message: '请选择套餐系列', trigger: 'change' }],
|
||||
@@ -921,6 +1373,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearchEnterprise = async (query?: string) => {
|
||||
try {
|
||||
enterpriseLoading.value = true
|
||||
const params = {
|
||||
page: 1,
|
||||
page_size: 20,
|
||||
enterprise_name: query || undefined,
|
||||
status: 1
|
||||
}
|
||||
const res = await EnterpriseService.getEnterprises(params)
|
||||
if (res.code === 0) {
|
||||
enterpriseOptions.value = res.data.items || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索企业失败:', error)
|
||||
} finally {
|
||||
enterpriseLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索套餐系列(用于搜索栏)
|
||||
const handleSearchSeries = async (query: string) => {
|
||||
try {
|
||||
@@ -1043,10 +1515,25 @@
|
||||
label: 'label',
|
||||
children: 'children'
|
||||
}
|
||||
const loadTopLevelShopCascadeOptions = async () => {
|
||||
try {
|
||||
const res = await ShopService.getShopsCascade({ parent_id: undefined })
|
||||
if (res.code === 0) {
|
||||
shopCascadeOptions.value = (res.data || []).map((item: any) => ({
|
||||
value: item.id,
|
||||
label: item.shop_name,
|
||||
leaf: !item.has_children
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载顶级店铺失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索表单初始值
|
||||
const initialSearchState: {
|
||||
status: undefined | number
|
||||
network_status: undefined | number
|
||||
iccid: string
|
||||
carrier_name: string
|
||||
msisdn: string
|
||||
@@ -1057,9 +1544,12 @@
|
||||
has_active_package: undefined | boolean
|
||||
is_distributed: undefined | number
|
||||
is_standalone: undefined | boolean
|
||||
authorized_enterprise_id: undefined | number
|
||||
is_authorized_to_enterprise: undefined | boolean
|
||||
[key: string]: any
|
||||
} = {
|
||||
status: undefined,
|
||||
network_status: undefined,
|
||||
iccid: '',
|
||||
carrier_name: '',
|
||||
msisdn: '',
|
||||
@@ -1070,6 +1560,8 @@
|
||||
has_active_package: undefined,
|
||||
is_distributed: undefined,
|
||||
is_standalone: undefined,
|
||||
authorized_enterprise_id: undefined,
|
||||
is_authorized_to_enterprise: undefined,
|
||||
is_replaced: undefined,
|
||||
iccid_start: '',
|
||||
iccid_end: ''
|
||||
@@ -1184,7 +1676,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '运营商名称',
|
||||
label: '运营商',
|
||||
prop: 'carrier_name',
|
||||
type: 'select',
|
||||
config: {
|
||||
@@ -1216,6 +1708,19 @@
|
||||
{ label: '已停用', value: 4 }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '网络状态',
|
||||
prop: 'network_status',
|
||||
type: 'select',
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '全部'
|
||||
},
|
||||
options: () => [
|
||||
{ label: '停机', value: 0 },
|
||||
{ label: '正常', value: 1 }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '卡虚拟号',
|
||||
prop: 'virtual_no',
|
||||
@@ -1235,7 +1740,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '绑定设备虚拟号',
|
||||
label: '设备虚拟号',
|
||||
prop: 'device_virtual_no',
|
||||
type: 'input',
|
||||
config: {
|
||||
@@ -1279,7 +1784,7 @@
|
||||
}))
|
||||
},
|
||||
{
|
||||
label: '是否已分销',
|
||||
label: '分销状态',
|
||||
prop: 'is_distributed',
|
||||
type: 'select',
|
||||
config: {
|
||||
@@ -1292,7 +1797,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '是否绑定设备',
|
||||
label: '是否绑设备',
|
||||
prop: 'is_standalone',
|
||||
type: 'select',
|
||||
config: {
|
||||
@@ -1305,7 +1810,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '是否有换卡记录',
|
||||
label: '有无换卡',
|
||||
prop: 'is_replaced',
|
||||
type: 'select',
|
||||
config: {
|
||||
@@ -1318,7 +1823,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'ICCID起始号',
|
||||
label: '起始号',
|
||||
prop: 'iccid_start',
|
||||
type: 'input',
|
||||
config: {
|
||||
@@ -1327,7 +1832,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'ICCID结束号',
|
||||
label: '结束号',
|
||||
prop: 'iccid_end',
|
||||
type: 'input',
|
||||
config: {
|
||||
@@ -1339,7 +1844,7 @@
|
||||
|
||||
// 搜索表单配置
|
||||
baseFormItems.splice(8, 0, {
|
||||
label: '是否有生效套餐',
|
||||
label: '有效套餐',
|
||||
prop: 'has_active_package',
|
||||
type: 'select',
|
||||
config: {
|
||||
@@ -1351,6 +1856,37 @@
|
||||
{ label: '否', value: false }
|
||||
]
|
||||
})
|
||||
baseFormItems.splice(9, 0, {
|
||||
label: '授权企业',
|
||||
prop: 'authorized_enterprise_id',
|
||||
type: 'select',
|
||||
config: {
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
remote: true,
|
||||
remoteMethod: handleSearchEnterprise,
|
||||
loading: enterpriseLoading.value,
|
||||
placeholder: '请选择或搜索企业'
|
||||
},
|
||||
options: () =>
|
||||
enterpriseOptions.value.map((enterprise) => ({
|
||||
label: enterprise.enterprise_name,
|
||||
value: enterprise.id
|
||||
}))
|
||||
})
|
||||
baseFormItems.splice(10, 0, {
|
||||
label: '授权状态',
|
||||
prop: 'is_authorized_to_enterprise',
|
||||
type: 'select',
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '全部'
|
||||
},
|
||||
options: () => [
|
||||
{ label: '已授权', value: true },
|
||||
{ label: '未授权', value: false }
|
||||
]
|
||||
})
|
||||
|
||||
const formItems: SearchFormItem[] = baseFormItems
|
||||
|
||||
@@ -1999,6 +2535,175 @@
|
||||
})
|
||||
}
|
||||
|
||||
const getInferredCardEnterpriseId = () => {
|
||||
const filterEnterpriseId = formFilters.authorized_enterprise_id
|
||||
if (filterEnterpriseId) return filterEnterpriseId
|
||||
|
||||
const selectedEnterpriseIds = Array.from(
|
||||
new Set(
|
||||
selectedCards.value
|
||||
.map((card) => card.authorized_enterprise_id)
|
||||
.filter((id): id is number => typeof id === 'number')
|
||||
)
|
||||
)
|
||||
|
||||
return selectedEnterpriseIds.length === 1 ? selectedEnterpriseIds[0] : undefined
|
||||
}
|
||||
|
||||
const resetEnterpriseCardAuthorizeForm = () => {
|
||||
Object.assign(enterpriseCardAuthorizeForm, createInitialEnterpriseCardAuthorizeState(), {
|
||||
selection_type:
|
||||
selectedCards.value.length > 0 ? CardSelectionType.LIST : CardSelectionType.FILTER,
|
||||
carrier_id: undefined,
|
||||
shop_id_path: undefined,
|
||||
batch_no: formFilters.batch_no || '',
|
||||
iccid: formFilters.iccid || ''
|
||||
})
|
||||
}
|
||||
|
||||
const resetEnterpriseCardRecallForm = () => {
|
||||
Object.assign(enterpriseCardRecallForm, createInitialEnterpriseCardRecallState(), {
|
||||
enterprise_id: getInferredCardEnterpriseId(),
|
||||
selection_type:
|
||||
selectedCards.value.length > 0 ? CardSelectionType.LIST : CardSelectionType.FILTER,
|
||||
carrier_id: undefined,
|
||||
batch_no: formFilters.batch_no || '',
|
||||
iccid: formFilters.iccid || ''
|
||||
})
|
||||
}
|
||||
|
||||
const showEnterpriseCardAuthorizeDialog = async () => {
|
||||
resetEnterpriseCardAuthorizeForm()
|
||||
await Promise.all([
|
||||
handleSearchEnterprise(),
|
||||
loadAllocateCarrierOptions(),
|
||||
loadAllocateBatchNoOptions(),
|
||||
loadTopLevelShopCascadeOptions()
|
||||
])
|
||||
enterpriseCardAuthorizeDialogVisible.value = true
|
||||
enterpriseCardAuthorizeFormRef.value?.clearValidate()
|
||||
}
|
||||
|
||||
const showEnterpriseCardRecallDialog = async () => {
|
||||
resetEnterpriseCardRecallForm()
|
||||
await Promise.all([
|
||||
handleSearchEnterprise(),
|
||||
loadAllocateCarrierOptions(),
|
||||
loadAllocateBatchNoOptions()
|
||||
])
|
||||
enterpriseCardRecallDialogVisible.value = true
|
||||
enterpriseCardRecallFormRef.value?.clearValidate()
|
||||
}
|
||||
|
||||
const handleEnterpriseCardAuthorizeDialogClose = () => {
|
||||
Object.assign(enterpriseCardAuthorizeForm, createInitialEnterpriseCardAuthorizeState())
|
||||
enterpriseCardAuthorizeFormRef.value?.resetFields()
|
||||
}
|
||||
|
||||
const handleEnterpriseCardRecallDialogClose = () => {
|
||||
Object.assign(enterpriseCardRecallForm, createInitialEnterpriseCardRecallState())
|
||||
enterpriseCardRecallFormRef.value?.resetFields()
|
||||
}
|
||||
|
||||
const appendEnterpriseCardFilterParams = (params: Record<string, unknown>, form: any) => {
|
||||
if (form.carrier_id) params.carrier_id = form.carrier_id
|
||||
if (Array.isArray(form.shop_id_path) && form.shop_id_path.length > 0) {
|
||||
params.shop_id = form.shop_id_path[form.shop_id_path.length - 1]
|
||||
}
|
||||
if (form.batch_no) params.batch_no = form.batch_no
|
||||
if (form.iccid) params.iccid = form.iccid
|
||||
}
|
||||
|
||||
const buildEnterpriseCardParams = (form: any) => {
|
||||
const params: Record<string, unknown> = {
|
||||
selection_type: form.selection_type,
|
||||
remark: form.remark || undefined
|
||||
}
|
||||
|
||||
if (form.selection_type === CardSelectionType.LIST) {
|
||||
const iccids = selectedCards.value.map((card) => card.iccid)
|
||||
if (!iccids.length) {
|
||||
ElMessage.warning('列表模式下请先选择卡')
|
||||
return null
|
||||
}
|
||||
params.iccids = iccids
|
||||
} else if (form.selection_type === CardSelectionType.RANGE) {
|
||||
params.iccid_start = form.iccid_start
|
||||
params.iccid_end = form.iccid_end
|
||||
} else {
|
||||
appendEnterpriseCardFilterParams(params, form)
|
||||
}
|
||||
|
||||
Object.keys(params).forEach((key) => {
|
||||
if (params[key] === undefined || params[key] === '') delete params[key]
|
||||
})
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
const applyEnterpriseCardOperationSuccess = async (
|
||||
title: string,
|
||||
result: AllocateCardsResponse | RecallCardsResponse
|
||||
) => {
|
||||
enterpriseCardOperationResult.value = result
|
||||
enterpriseCardResultTitle.value = title
|
||||
enterpriseCardResultDialogVisible.value = true
|
||||
selectedCards.value = []
|
||||
await getTableData()
|
||||
}
|
||||
|
||||
const handleEnterpriseCardAuthorize = async () => {
|
||||
if (!enterpriseCardAuthorizeFormRef.value) return
|
||||
|
||||
await enterpriseCardAuthorizeFormRef.value.validate(async (valid) => {
|
||||
if (!valid) return
|
||||
const params = buildEnterpriseCardParams(enterpriseCardAuthorizeForm)
|
||||
if (!params) return
|
||||
|
||||
enterpriseCardAuthorizeLoading.value = true
|
||||
try {
|
||||
const res = await EnterpriseService.allocateCards(
|
||||
enterpriseCardAuthorizeForm.enterprise_id!,
|
||||
params as any
|
||||
)
|
||||
if (res.code === 0) {
|
||||
enterpriseCardAuthorizeDialogVisible.value = false
|
||||
await applyEnterpriseCardOperationSuccess('授权卡给企业结果', res.data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('授权卡给企业失败:', error)
|
||||
} finally {
|
||||
enterpriseCardAuthorizeLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleEnterpriseCardRecall = async () => {
|
||||
if (!enterpriseCardRecallFormRef.value) return
|
||||
|
||||
await enterpriseCardRecallFormRef.value.validate(async (valid) => {
|
||||
if (!valid) return
|
||||
const params = buildEnterpriseCardParams(enterpriseCardRecallForm)
|
||||
if (!params) return
|
||||
|
||||
enterpriseCardRecallLoading.value = true
|
||||
try {
|
||||
const res = await EnterpriseService.recallCards(
|
||||
enterpriseCardRecallForm.enterprise_id!,
|
||||
params as any
|
||||
)
|
||||
if (res.code === 0) {
|
||||
enterpriseCardRecallDialogVisible.value = false
|
||||
await applyEnterpriseCardOperationSuccess('回收卡授权结果', res.data)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('回收卡授权失败:', error)
|
||||
} finally {
|
||||
enterpriseCardRecallLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 显示套餐系列绑定对话框
|
||||
const showSeriesBindingDialog = async () => {
|
||||
Object.assign(seriesBindingForm, createInitialSeriesBindingState(), {
|
||||
@@ -2118,47 +2823,6 @@
|
||||
})
|
||||
}
|
||||
|
||||
// 清除卡套餐系列绑定
|
||||
const handleClearCardSeries = async () => {
|
||||
if (selectedCards.value.length === 0) {
|
||||
ElMessage.warning('请先选择要清除关联的卡')
|
||||
return
|
||||
}
|
||||
|
||||
ElMessageBox.confirm(
|
||||
`确定要清除所选 ${selectedCards.value.length} 张卡的套餐系列关联吗?`,
|
||||
'确认清除',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
try {
|
||||
const res = await CardService.batchSetCardSeriesBinding({
|
||||
selection_type: CardSelectionType.LIST,
|
||||
iccids: selectedCards.value.map((card) => card.iccid),
|
||||
series_id: 0
|
||||
})
|
||||
if (res.code === 0) {
|
||||
if (res.data.fail_count === 0) {
|
||||
ElMessage.success('清除关联成功')
|
||||
} else {
|
||||
ElMessage.warning(`部分失败:${res.data.failed_items?.[0]?.reason || '未知原因'}`)
|
||||
}
|
||||
selectedCards.value = []
|
||||
await getTableData()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('清除关联失败:', error)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
|
||||
// IoT卡操作处理函数
|
||||
const handleCardOperation = (command: string, iccid: string, row?: any) => {
|
||||
switch (command) {
|
||||
@@ -2258,33 +2922,6 @@
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
|
||||
// 手动停用 IoT 卡(资产层面的停用)
|
||||
const handleManualDeactivate = (iccid: string) => {
|
||||
ElMessageBox.confirm(
|
||||
`确定要手动停用卡片 ${iccid} 吗?此操作将在资产管理层面停用该卡。`,
|
||||
'确认手动停用',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
try {
|
||||
const res = await AssetService.deactivateAsset(iccid)
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('手动停用成功')
|
||||
await getTableData()
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('手动停用失败:', error)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Reference in New Issue
Block a user