feat: 新增导入字段,显示实名认证策略字段
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m9s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m9s
This commit is contained in:
@@ -56,6 +56,7 @@ export interface AssetResolveResponse {
|
|||||||
series_id: number // 套餐系列 ID
|
series_id: number // 套餐系列 ID
|
||||||
series_name: string // 套餐系列名称
|
series_name: string // 套餐系列名称
|
||||||
real_name_status: RealNameStatus // 实名状态:0 未实名 / 1 已实名
|
real_name_status: RealNameStatus // 实名状态:0 未实名 / 1 已实名
|
||||||
|
realname_policy?: string // 实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)
|
||||||
network_status?: NetworkStatus // 网络状态:0 停机 / 1 开机(仅 card)
|
network_status?: NetworkStatus // 网络状态:0 停机 / 1 开机(仅 card)
|
||||||
current_package: string // 当前套餐名称(无则空)
|
current_package: string // 当前套餐名称(无则空)
|
||||||
package_total_mb: number // 当前套餐总虚流量 MB
|
package_total_mb: number // 当前套餐总虚流量 MB
|
||||||
@@ -110,6 +111,7 @@ export interface AssetBoundCard {
|
|||||||
msisdn: string // 手机号
|
msisdn: string // 手机号
|
||||||
network_status: NetworkStatus // 网络状态
|
network_status: NetworkStatus // 网络状态
|
||||||
real_name_status: RealNameStatus // 实名状态
|
real_name_status: RealNameStatus // 实名状态
|
||||||
|
realname_policy?: string // 实名认证策略
|
||||||
slot_position: number // 插槽位置
|
slot_position: number // 插槽位置
|
||||||
is_current?: boolean // 是否为设备当前使用的卡
|
is_current?: boolean // 是否为设备当前使用的卡
|
||||||
}
|
}
|
||||||
@@ -165,6 +167,7 @@ export interface AssetRealtimeStatusResponse {
|
|||||||
// ===== 卡专属字段 =====
|
// ===== 卡专属字段 =====
|
||||||
network_status?: NetworkStatus // 网络状态(仅 card)
|
network_status?: NetworkStatus // 网络状态(仅 card)
|
||||||
real_name_status?: RealNameStatus // 实名状态(仅 card)
|
real_name_status?: RealNameStatus // 实名状态(仅 card)
|
||||||
|
realname_policy?: string // 实名认证策略(仅 card)
|
||||||
current_month_usage_mb?: number // 本月已用流量 MB(仅 card)
|
current_month_usage_mb?: number // 本月已用流量 MB(仅 card)
|
||||||
last_sync_time?: string // 最后同步时间(仅 card)
|
last_sync_time?: string // 最后同步时间(仅 card)
|
||||||
|
|
||||||
|
|||||||
@@ -154,10 +154,18 @@ export interface RecallDevicesResponse {
|
|||||||
|
|
||||||
// ========== 设备导入相关 ==========
|
// ========== 设备导入相关 ==========
|
||||||
|
|
||||||
|
// 实名认证策略枚举
|
||||||
|
export enum RealnamePolicy {
|
||||||
|
NONE = 'none', // 无需实名
|
||||||
|
BEFORE_ORDER = 'before_order', // 先实名后充值/购买
|
||||||
|
AFTER_ORDER = 'after_order' // 先充值/购买后实名
|
||||||
|
}
|
||||||
|
|
||||||
// 批量导入设备请求参数
|
// 批量导入设备请求参数
|
||||||
export interface ImportDeviceRequest {
|
export interface ImportDeviceRequest {
|
||||||
file_key: string // 对象存储文件路径(通过 /storage/upload-url 获取)
|
file_key: string // 对象存储文件路径(通过 /storage/upload-url 获取)
|
||||||
batch_no?: string // 批次号
|
batch_no?: string // 批次号
|
||||||
|
realname_policy?: RealnamePolicy // 实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名),默认 none
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量导入设备响应
|
// 批量导入设备响应
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ export interface PackageResponse {
|
|||||||
virtual_data_mb?: number // 虚流量额度(MB)
|
virtual_data_mb?: number // 虚流量额度(MB)
|
||||||
virtual_ratio?: number // 虚流量比例(real_data_mb / virtual_data_mb)。启用虚流量时计算,否则为 1.0
|
virtual_ratio?: number // 虚流量比例(real_data_mb / virtual_data_mb)。启用虚流量时计算,否则为 1.0
|
||||||
enable_virtual_data?: boolean // 是否启用虚流量
|
enable_virtual_data?: boolean // 是否启用虚流量
|
||||||
expiry_base?: ExpiryBase // 到期计时基准: from_activation(实名后开始计时) / from_purchase(购买即开始计时)
|
expiry_base?: ExpiryBase // 到期计时基准: from_activation(实名激活时起算) / from_purchase(购买时起算)
|
||||||
cost_price?: number // 成本价(分)
|
cost_price?: number // 成本价(分)
|
||||||
suggested_retail_price?: number // 建议零售价(分)
|
suggested_retail_price?: number // 建议零售价(分)
|
||||||
current_commission_rate?: string // 当前返佣比例(仅代理用户可见)
|
current_commission_rate?: string // 当前返佣比例(仅代理用户可见)
|
||||||
@@ -160,7 +160,7 @@ export interface CreatePackageRequest {
|
|||||||
real_data_mb?: number | null // 真流量额度(MB),可选
|
real_data_mb?: number | null // 真流量额度(MB),可选
|
||||||
virtual_data_mb?: number | null // 虚流量额度(MB),可选
|
virtual_data_mb?: number | null // 虚流量额度(MB),可选
|
||||||
enable_virtual_data?: boolean // 是否启用虚流量,可选
|
enable_virtual_data?: boolean // 是否启用虚流量,可选
|
||||||
expiry_base?: ExpiryBase | null // 到期计时基准: from_activation(实名后开始计时) / from_purchase(购买即开始计时),可选
|
expiry_base?: ExpiryBase | null // 到期计时基准: from_activation(实名激活时起算) / from_purchase(购买时起算),可选
|
||||||
cost_price: number // 成本价(分),必填
|
cost_price: number // 成本价(分),必填
|
||||||
suggested_retail_price?: number | null // 建议零售价(分),可选
|
suggested_retail_price?: number | null // 建议零售价(分),可选
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,43 +49,45 @@
|
|||||||
<ElDialog
|
<ElDialog
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
:title="dialogType === 'add' ? '新增企业客户' : '编辑企业客户'"
|
:title="dialogType === 'add' ? '新增企业客户' : '编辑企业客户'"
|
||||||
width="40%"
|
width="50%"
|
||||||
>
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="100px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||||
<ElFormItem label="企业编号" prop="enterprise_code">
|
|
||||||
<div style="display: flex; gap: 8px">
|
|
||||||
<ElInput
|
|
||||||
v-model="form.enterprise_code"
|
|
||||||
placeholder="请输入企业编号或点击生成"
|
|
||||||
:disabled="dialogType === 'edit'"
|
|
||||||
clearable
|
|
||||||
style="flex: 1"
|
|
||||||
/>
|
|
||||||
<CodeGeneratorButton
|
|
||||||
v-if="dialogType === 'add'"
|
|
||||||
code-type="enterprise"
|
|
||||||
@generated="handleCodeGenerated"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ElFormItem>
|
|
||||||
<ElRow :gutter="20">
|
<ElRow :gutter="20">
|
||||||
|
<ElCol :span="12">
|
||||||
|
<ElFormItem label="企业编号" prop="enterprise_code">
|
||||||
|
<ElInput
|
||||||
|
v-model="form.enterprise_code"
|
||||||
|
placeholder="请输入企业编号或点击生成"
|
||||||
|
:disabled="dialogType === 'edit'"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<ElButton v-if="dialogType === 'add'" @click="handleGenerateEnterpriseCode"
|
||||||
|
>生成编码</ElButton
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</ElInput>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="企业名称" prop="enterprise_name">
|
<ElFormItem label="企业名称" prop="enterprise_name">
|
||||||
<ElInput v-model="form.enterprise_name" placeholder="请输入企业名称" />
|
<ElInput v-model="form.enterprise_name" placeholder="请输入企业名称" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
<ElRow :gutter="20">
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="法人代表" prop="legal_person">
|
<ElFormItem label="法人代表" prop="legal_person">
|
||||||
<ElInput v-model="form.legal_person" placeholder="请输入法人代表" />
|
<ElInput v-model="form.legal_person" placeholder="请输入法人代表" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
|
||||||
<ElRow :gutter="20">
|
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="营业执照号" prop="business_license">
|
<ElFormItem label="营业执照号" prop="business_license">
|
||||||
<ElInput v-model="form.business_license" placeholder="请输入营业执照号" />
|
<ElInput v-model="form.business_license" placeholder="请输入营业执照号" />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
<ElRow :gutter="20">
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="所在地区" prop="region">
|
<ElFormItem label="所在地区" prop="region">
|
||||||
<ElCascader
|
<ElCascader
|
||||||
@@ -99,8 +101,6 @@
|
|||||||
/>
|
/>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
|
||||||
<ElRow :gutter="20">
|
|
||||||
<!-- 只有非代理账号才显示归属店铺选择 -->
|
<!-- 只有非代理账号才显示归属店铺选择 -->
|
||||||
<ElCol :span="12" v-if="!isAgentAccount">
|
<ElCol :span="12" v-if="!isAgentAccount">
|
||||||
<ElFormItem label="归属店铺" prop="owner_shop_id">
|
<ElFormItem label="归属店铺" prop="owner_shop_id">
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
import { useAuth } from '@/composables/useAuth'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/store/modules/user'
|
||||||
import CodeGeneratorButton from '@/components/business/CodeGeneratorButton.vue'
|
import { generateEnterpriseCode } from '@/utils/codeGenerator'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
import { regionData } from '@/utils/constants/regionData'
|
import { regionData } from '@/utils/constants/regionData'
|
||||||
|
|
||||||
@@ -742,8 +742,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理企业编码生成
|
// 处理企业编码生成
|
||||||
const handleCodeGenerated = (code: string) => {
|
const handleGenerateEnterpriseCode = () => {
|
||||||
form.enterprise_code = code
|
form.enterprise_code = generateEnterpriseCode()
|
||||||
|
ElMessage.success('编码生成成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
|
|||||||
@@ -37,6 +37,9 @@
|
|||||||
{{ getRealNameStatusName(cardInfo?.real_name_status) }}
|
{{ getRealNameStatusName(cardInfo?.real_name_status) }}
|
||||||
</ElTag>
|
</ElTag>
|
||||||
</ElDescriptionsItem>
|
</ElDescriptionsItem>
|
||||||
|
<ElDescriptionsItem label="实名认证策略">
|
||||||
|
{{ getRealnamePolicyName(cardInfo?.realname_policy) }}
|
||||||
|
</ElDescriptionsItem>
|
||||||
|
|
||||||
<ElDescriptionsItem label="店铺">{{ cardInfo?.shop_name || '-' }}</ElDescriptionsItem>
|
<ElDescriptionsItem label="店铺">{{ cardInfo?.shop_name || '-' }}</ElDescriptionsItem>
|
||||||
<ElDescriptionsItem label="套餐系列">{{ cardInfo?.series_name || '-' }}</ElDescriptionsItem>
|
<ElDescriptionsItem label="套餐系列">{{ cardInfo?.series_name || '-' }}</ElDescriptionsItem>
|
||||||
@@ -92,6 +95,9 @@
|
|||||||
{{ getRealNameStatusName(currentCard?.real_name_status) }}
|
{{ getRealNameStatusName(currentCard?.real_name_status) }}
|
||||||
</ElTag>
|
</ElTag>
|
||||||
</ElDescriptionsItem>
|
</ElDescriptionsItem>
|
||||||
|
<ElDescriptionsItem label="实名认证策略">
|
||||||
|
{{ getRealnamePolicyName(cardInfo?.realname_policy) }}
|
||||||
|
</ElDescriptionsItem>
|
||||||
<ElDescriptionsItem label="设备名称">{{ cardInfo?.device_name || '-' }}</ElDescriptionsItem>
|
<ElDescriptionsItem label="设备名称">{{ cardInfo?.device_name || '-' }}</ElDescriptionsItem>
|
||||||
<ElDescriptionsItem label="在线状态">
|
<ElDescriptionsItem label="在线状态">
|
||||||
<ElTag :type="getOnlineStatusType(cardInfo?.online_status)" size="small">
|
<ElTag :type="getOnlineStatusType(cardInfo?.online_status)" size="small">
|
||||||
@@ -167,9 +173,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
<ElTableColumn prop="msisdn" label="MSISDN" min-width="140" />
|
<ElTableColumn prop="msisdn" label="MSISDN" min-width="120" />
|
||||||
<ElTableColumn prop="carrier_name" label="运营商" width="120" />
|
<ElTableColumn prop="carrier_name" label="运营商" min-width="120" />
|
||||||
<ElTableColumn prop="slot_position" label="卡槽位置" align="center" width="130">
|
<ElTableColumn prop="slot_position" label="卡槽位置" width="130">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div style="display: flex; gap: 10px; align-items: center; justify-content: center">
|
<div style="display: flex; gap: 10px; align-items: center; justify-content: center">
|
||||||
<span>SIM-{{ scope.row.slot_position }}</span>
|
<span>SIM-{{ scope.row.slot_position }}</span>
|
||||||
@@ -177,20 +183,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
<ElTableColumn label="网络状态" align="center" width="100">
|
<ElTableColumn label="网络状态" width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<ElTag :type="scope.row.network_status === 1 ? 'success' : 'danger'" size="small">
|
<ElTag :type="scope.row.network_status === 1 ? 'success' : 'danger'" size="small">
|
||||||
{{ scope.row.network_status === 1 ? '正常' : '停机' }}
|
{{ scope.row.network_status === 1 ? '正常' : '停机' }}
|
||||||
</ElTag>
|
</ElTag>
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
<ElTableColumn label="实名状态" align="center" width="100">
|
<ElTableColumn label="实名状态" width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<ElTag :type="getRealNameStatusType(scope.row.real_name_status)" size="small">
|
<ElTag :type="getRealNameStatusType(scope.row.real_name_status)" size="small">
|
||||||
{{ getRealNameStatusName(scope.row.real_name_status) }}
|
{{ getRealNameStatusName(scope.row.real_name_status) }}
|
||||||
</ElTag>
|
</ElTag>
|
||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="实名认证策略" width="180">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getRealnamePolicyName(scope.row.realname_policy) }}
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
<ElTableColumn label="实名时间" width="180">
|
<ElTableColumn label="实名时间" width="180">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ scope.row.real_name_at ? formatDateTime(scope.row.real_name_at) : '-' }}
|
{{ scope.row.real_name_at ? formatDateTime(scope.row.real_name_at) : '-' }}
|
||||||
@@ -511,6 +522,7 @@
|
|||||||
formatDuration,
|
formatDuration,
|
||||||
getRealNameStatusName,
|
getRealNameStatusName,
|
||||||
getRealNameStatusType,
|
getRealNameStatusType,
|
||||||
|
getRealnamePolicyName,
|
||||||
getAssetStatusName,
|
getAssetStatusName,
|
||||||
getAssetStatusType,
|
getAssetStatusType,
|
||||||
getOnlineStatusName,
|
getOnlineStatusName,
|
||||||
|
|||||||
@@ -65,6 +65,17 @@ export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
|||||||
return map[status] || 'info'
|
return map[status] || 'info'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取实名认证策略名称
|
||||||
|
const getRealnamePolicyName = (policy?: string) => {
|
||||||
|
if (!policy) return '-'
|
||||||
|
const policyMap: Record<string, string> = {
|
||||||
|
none: '无需实名',
|
||||||
|
before_order: '先实名后充值/购买',
|
||||||
|
after_order: '先充值/购买后实名'
|
||||||
|
}
|
||||||
|
return policyMap[policy] || policy
|
||||||
|
}
|
||||||
|
|
||||||
// 获取资产状态名称
|
// 获取资产状态名称
|
||||||
const getAssetStatusName = (status?: number) => {
|
const getAssetStatusName = (status?: number) => {
|
||||||
if (status === undefined || status === null) return '未知'
|
if (status === undefined || status === null) return '未知'
|
||||||
@@ -232,6 +243,7 @@ export function useAssetFormatters(deviceRealtime?: Ref<any>) {
|
|||||||
formatIccidWithDashes,
|
formatIccidWithDashes,
|
||||||
getRealNameStatusName,
|
getRealNameStatusName,
|
||||||
getRealNameStatusType,
|
getRealNameStatusType,
|
||||||
|
getRealnamePolicyName,
|
||||||
getAssetStatusName,
|
getAssetStatusName,
|
||||||
getAssetStatusType,
|
getAssetStatusType,
|
||||||
getOnlineStatusName,
|
getOnlineStatusName,
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export function useAssetInfo() {
|
|||||||
series_id: data.series_id,
|
series_id: data.series_id,
|
||||||
series_name: data.series_name,
|
series_name: data.series_name,
|
||||||
real_name_status: data.real_name_status,
|
real_name_status: data.real_name_status,
|
||||||
|
realname_policy: data.realname_policy,
|
||||||
real_name_at: data.real_name_at,
|
real_name_at: data.real_name_at,
|
||||||
activated_at: data.activated_at,
|
activated_at: data.activated_at,
|
||||||
created_at: data.created_at,
|
created_at: data.created_at,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export interface AssetInfo {
|
|||||||
msisdn?: string
|
msisdn?: string
|
||||||
carrier_name?: string
|
carrier_name?: string
|
||||||
real_name_status?: number
|
real_name_status?: number
|
||||||
|
realname_policy?: string
|
||||||
network_status?: string
|
network_status?: string
|
||||||
current_month_used_data?: number
|
current_month_used_data?: number
|
||||||
device_type?: string
|
device_type?: string
|
||||||
@@ -35,6 +36,7 @@ export interface BindingCard {
|
|||||||
is_current: boolean
|
is_current: boolean
|
||||||
status?: number
|
status?: number
|
||||||
carrier_name?: string
|
carrier_name?: string
|
||||||
|
realname_policy?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设备实时信息接口
|
// 设备实时信息接口
|
||||||
|
|||||||
@@ -77,6 +77,37 @@
|
|||||||
</ElButton>
|
</ElButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ElRow :gutter="20">
|
||||||
|
<ElCol :span="12">
|
||||||
|
<ElFormItem label="批次号" prop="batch_no">
|
||||||
|
<ElInput
|
||||||
|
v-model="importForm.batch_no"
|
||||||
|
placeholder="请输入批次号或点击生成"
|
||||||
|
:maxlength="100"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<ElButton @click="handleGenerateBatchNo">生成编码</ElButton>
|
||||||
|
</template>
|
||||||
|
</ElInput>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
<ElCol :span="12">
|
||||||
|
<ElFormItem label="实名认证策略">
|
||||||
|
<ElSelect
|
||||||
|
v-model="importForm.realname_policy"
|
||||||
|
placeholder="默认无需实名"
|
||||||
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<ElOption label="无需实名" value="none" />
|
||||||
|
<ElOption label="先实名后充值/购买" value="before_order" />
|
||||||
|
<ElOption label="先充值/购买后实名" value="after_order" />
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
|
||||||
<ElUpload
|
<ElUpload
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
drag
|
drag
|
||||||
@@ -122,6 +153,7 @@
|
|||||||
import { StorageService } from '@/api/modules/storage'
|
import { StorageService } from '@/api/modules/storage'
|
||||||
import type { DeviceImportTask, DeviceImportTaskStatus } from '@/types/api/device'
|
import type { DeviceImportTask, DeviceImportTaskStatus } from '@/types/api/device'
|
||||||
import { RoutesAlias } from '@/router/routesAlias'
|
import { RoutesAlias } from '@/router/routesAlias'
|
||||||
|
import { generatePackageCode } from '@/utils/codeGenerator'
|
||||||
|
|
||||||
defineOptions({ name: 'DeviceTask' })
|
defineOptions({ name: 'DeviceTask' })
|
||||||
|
|
||||||
@@ -134,6 +166,10 @@
|
|||||||
const fileList = ref<File[]>([])
|
const fileList = ref<File[]>([])
|
||||||
const uploading = ref(false)
|
const uploading = ref(false)
|
||||||
const importDialogVisible = ref(false)
|
const importDialogVisible = ref(false)
|
||||||
|
const importForm = reactive({
|
||||||
|
batch_no: '',
|
||||||
|
realname_policy: '' as '' | 'none' | 'before_order' | 'after_order'
|
||||||
|
})
|
||||||
|
|
||||||
// 搜索表单初始值
|
// 搜索表单初始值
|
||||||
const initialSearchState = {
|
const initialSearchState = {
|
||||||
@@ -507,9 +543,18 @@
|
|||||||
fileList.value = []
|
fileList.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成批次号
|
||||||
|
const handleGenerateBatchNo = () => {
|
||||||
|
const code = generatePackageCode().replace('PKG', 'DEV')
|
||||||
|
importForm.batch_no = code
|
||||||
|
ElMessage.success('批次号生成成功')
|
||||||
|
}
|
||||||
|
|
||||||
// 取消导入
|
// 取消导入
|
||||||
const handleCancelImport = () => {
|
const handleCancelImport = () => {
|
||||||
clearFiles()
|
clearFiles()
|
||||||
|
importForm.batch_no = ''
|
||||||
|
importForm.realname_policy = ''
|
||||||
importDialogVisible.value = false
|
importDialogVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,7 +593,8 @@
|
|||||||
ElMessage.info('正在创建导入任务...')
|
ElMessage.info('正在创建导入任务...')
|
||||||
const importRes = await DeviceService.importDevices({
|
const importRes = await DeviceService.importDevices({
|
||||||
file_key,
|
file_key,
|
||||||
batch_no: `DEV-${Date.now()}`
|
batch_no: importForm.batch_no || undefined,
|
||||||
|
realname_policy: importForm.realname_policy || undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
if (importRes.code !== 0) {
|
if (importRes.code !== 0) {
|
||||||
|
|||||||
@@ -119,35 +119,72 @@
|
|||||||
</ElButton>
|
</ElButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ElFormItem label="运营商" required style="margin-bottom: 20px">
|
<ElRow :gutter="20">
|
||||||
<ElSelect
|
<ElCol :span="12">
|
||||||
v-model="selectedCarrierId"
|
<ElFormItem label="运营商" required>
|
||||||
placeholder="请输入运营商名称搜索"
|
<ElSelect
|
||||||
style="width: 100%"
|
v-model="selectedCarrierId"
|
||||||
filterable
|
placeholder="请输入运营商名称搜索"
|
||||||
remote
|
style="width: 100%"
|
||||||
:remote-method="handleCarrierSearch"
|
filterable
|
||||||
:loading="carrierLoading"
|
remote
|
||||||
clearable
|
:remote-method="handleCarrierSearch"
|
||||||
>
|
:loading="carrierLoading"
|
||||||
<ElOption
|
clearable
|
||||||
v-for="carrier in carrierList"
|
>
|
||||||
:key="carrier.id"
|
<ElOption
|
||||||
:label="carrier.carrier_name"
|
v-for="carrier in carrierList"
|
||||||
:value="carrier.id"
|
:key="carrier.id"
|
||||||
/>
|
:label="carrier.carrier_name"
|
||||||
</ElSelect>
|
:value="carrier.id"
|
||||||
</ElFormItem>
|
/>
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
<ElCol :span="12">
|
||||||
|
<ElFormItem label="卡业务类型">
|
||||||
|
<ElSelect
|
||||||
|
v-model="selectedCardCategory"
|
||||||
|
placeholder="请选择卡业务类型"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<ElOption label="普通卡" value="normal" />
|
||||||
|
<ElOption label="行业卡" value="industry" />
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
|
||||||
<ElFormItem label="卡业务类型" style="margin-bottom: 20px">
|
<ElRow :gutter="20">
|
||||||
<ElSelect v-model="selectedCardCategory" placeholder="请选择卡业务类型" style="width: 100%">
|
<ElCol :span="12">
|
||||||
<ElOption label="普通卡" value="normal" />
|
<ElFormItem label="批次号" prop="batch_no">
|
||||||
<ElOption label="行业卡" value="industry" />
|
<ElInput
|
||||||
</ElSelect>
|
v-model="importForm.batch_no"
|
||||||
<div style="margin-top: 4px; font-size: 12px; color: var(--el-text-color-secondary)">
|
placeholder="请输入批次号或点击生成"
|
||||||
默认为普通卡,可选择行业卡
|
:maxlength="100"
|
||||||
</div>
|
clearable
|
||||||
</ElFormItem>
|
>
|
||||||
|
<template #append>
|
||||||
|
<ElButton @click="handleGenerateBatchNo">生成编码</ElButton>
|
||||||
|
</template>
|
||||||
|
</ElInput>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
<ElCol :span="12">
|
||||||
|
<ElFormItem label="实名认证策略">
|
||||||
|
<ElSelect
|
||||||
|
v-model="importForm.realname_policy"
|
||||||
|
placeholder="默认无需实名"
|
||||||
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<ElOption label="无需实名" value="none" />
|
||||||
|
<ElOption label="先实名后充值/购买" value="before_order" />
|
||||||
|
<ElOption label="先充值/购买后实名" value="after_order" />
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
|
||||||
<ElUpload
|
<ElUpload
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
@@ -200,6 +237,7 @@
|
|||||||
import { useAuth } from '@/composables/useAuth'
|
import { useAuth } from '@/composables/useAuth'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
import { StorageService } from '@/api/modules/storage'
|
import { StorageService } from '@/api/modules/storage'
|
||||||
|
import { generatePackageCode } from '@/utils/codeGenerator'
|
||||||
import { RoutesAlias } from '@/router/routesAlias'
|
import { RoutesAlias } from '@/router/routesAlias'
|
||||||
import type { IotCardImportTask, IotCardImportTaskStatus } from '@/types/api/card'
|
import type { IotCardImportTask, IotCardImportTaskStatus } from '@/types/api/card'
|
||||||
import type { Carrier } from '@/types/api'
|
import type { Carrier } from '@/types/api'
|
||||||
@@ -224,6 +262,10 @@
|
|||||||
const failDataLoading = ref(false)
|
const failDataLoading = ref(false)
|
||||||
const failedItems = ref<any[]>([])
|
const failedItems = ref<any[]>([])
|
||||||
const currentFailTask = ref<IotCardImportTask | null>(null)
|
const currentFailTask = ref<IotCardImportTask | null>(null)
|
||||||
|
const importForm = reactive({
|
||||||
|
batch_no: '',
|
||||||
|
realname_policy: '' as '' | 'none' | 'before_order' | 'after_order'
|
||||||
|
})
|
||||||
|
|
||||||
// 搜索表单初始值
|
// 搜索表单初始值
|
||||||
const initialSearchState = {
|
const initialSearchState = {
|
||||||
@@ -682,10 +724,19 @@
|
|||||||
selectedCarrierId.value = undefined
|
selectedCarrierId.value = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成批次号
|
||||||
|
const handleGenerateBatchNo = () => {
|
||||||
|
const code = generatePackageCode().replace('PKG', 'IOT')
|
||||||
|
importForm.batch_no = code
|
||||||
|
ElMessage.success('批次号生成成功')
|
||||||
|
}
|
||||||
|
|
||||||
// 取消导入
|
// 取消导入
|
||||||
const handleCancelImport = () => {
|
const handleCancelImport = () => {
|
||||||
clearFiles()
|
clearFiles()
|
||||||
selectedCardCategory.value = 'normal' // 重置为默认值
|
selectedCardCategory.value = 'normal'
|
||||||
|
importForm.batch_no = ''
|
||||||
|
importForm.realname_policy = ''
|
||||||
importDialogVisible.value = false
|
importDialogVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -755,8 +806,9 @@
|
|||||||
const importRes = await CardService.importIotCards({
|
const importRes = await CardService.importIotCards({
|
||||||
carrier_id: selectedCarrierId.value,
|
carrier_id: selectedCarrierId.value,
|
||||||
file_key,
|
file_key,
|
||||||
batch_no: `IOT-${Date.now()}`,
|
batch_no: importForm.batch_no || undefined,
|
||||||
card_category: selectedCardCategory.value // 新增卡业务类型
|
card_category: selectedCardCategory.value,
|
||||||
|
realname_policy: importForm.realname_policy || undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
if (importRes.code !== 0) {
|
if (importRes.code !== 0) {
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
label: '到期计时基准',
|
label: '到期计时基准',
|
||||||
formatter: (_, data) => {
|
formatter: (_, data) => {
|
||||||
if (!data.expiry_base) return '--'
|
if (!data.expiry_base) return '--'
|
||||||
return data.expiry_base === 'from_activation' ? '实名后开始计时' : '购买即开始计时'
|
return data.expiry_base === 'from_activation' ? '实名激活时起算' : '购买时起算'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,35 +47,36 @@
|
|||||||
<ElDialog
|
<ElDialog
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
:title="dialogType === 'add' ? '新增套餐' : '编辑套餐'"
|
:title="dialogType === 'add' ? '新增套餐' : '编辑套餐'"
|
||||||
width="45%"
|
width="50%"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@closed="handleDialogClosed"
|
@closed="handleDialogClosed"
|
||||||
>
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||||
<ElRow :gutter="20">
|
<ElRow :gutter="20">
|
||||||
<ElCol :span="24">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="套餐编码" prop="package_code">
|
<ElFormItem label="套餐编码" prop="package_code">
|
||||||
<div style="display: flex; gap: 8px">
|
<ElInput
|
||||||
<ElInput
|
v-model="form.package_code"
|
||||||
v-model="form.package_code"
|
placeholder="请输入套餐编码或点击生成"
|
||||||
placeholder="请输入套餐编码或点击生成"
|
:disabled="dialogType === 'edit'"
|
||||||
:disabled="dialogType === 'edit'"
|
clearable
|
||||||
clearable
|
>
|
||||||
/>
|
<template #append>
|
||||||
<ElButton v-if="dialogType === 'add'" @click="handleGeneratePackageCode">
|
<ElButton v-if="dialogType === 'add'" @click="handleGeneratePackageCode"
|
||||||
生成编码
|
>生成编码</ElButton
|
||||||
</ElButton>
|
>
|
||||||
</div>
|
</template>
|
||||||
|
</ElInput>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
|
||||||
|
|
||||||
<ElRow :gutter="20">
|
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="套餐名称" prop="package_name">
|
<ElFormItem label="套餐名称" prop="package_name">
|
||||||
<ElInput v-model="form.package_name" placeholder="请输入套餐名称" clearable />
|
<ElInput v-model="form.package_name" placeholder="请输入套餐名称" clearable />
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
|
||||||
|
<ElRow :gutter="20">
|
||||||
<ElCol :span="12">
|
<ElCol :span="12">
|
||||||
<ElFormItem label="所属系列" prop="series_id">
|
<ElFormItem label="所属系列" prop="series_id">
|
||||||
<ElSelect
|
<ElSelect
|
||||||
@@ -248,8 +249,8 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
clearable
|
clearable
|
||||||
>
|
>
|
||||||
<ElOption label="实名后开始计时" value="from_activation" />
|
<ElOption label="实名激活时起算" value="from_activation" />
|
||||||
<ElOption label="购买即开始计时" value="from_purchase" />
|
<ElOption label="购买时起算" value="from_purchase" />
|
||||||
</ElSelect>
|
</ElSelect>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
|
|||||||
@@ -48,25 +48,23 @@
|
|||||||
<ElDialog
|
<ElDialog
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
:title="dialogType === 'add' ? '新增套餐系列' : '编辑套餐系列'"
|
:title="dialogType === 'add' ? '新增套餐系列' : '编辑套餐系列'"
|
||||||
width="45%"
|
width="30%"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
>
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||||
<ElFormItem label="系列编码" prop="series_code">
|
<ElFormItem label="系列编码" prop="series_code">
|
||||||
<div style="display: flex; gap: 8px">
|
<ElInput
|
||||||
<ElInput
|
v-model="form.series_code"
|
||||||
v-model="form.series_code"
|
placeholder="请输入系列编码或点击生成"
|
||||||
placeholder="请输入系列编码或点击生成"
|
:disabled="dialogType === 'edit'"
|
||||||
:disabled="dialogType === 'edit'"
|
clearable
|
||||||
clearable
|
>
|
||||||
style="flex: 1"
|
<template #append>
|
||||||
/>
|
<ElButton v-if="dialogType === 'add'" @click="handleGenerateSeriesCode"
|
||||||
<CodeGeneratorButton
|
>生成编码</ElButton
|
||||||
v-if="dialogType === 'add'"
|
>
|
||||||
code-type="series"
|
</template>
|
||||||
@generated="handleCodeGenerated"
|
</ElInput>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="系列名称" prop="series_name">
|
<ElFormItem label="系列名称" prop="series_name">
|
||||||
<ElInput v-model="form.series_name" placeholder="请输入系列名称" clearable />
|
<ElInput v-model="form.series_name" placeholder="请输入系列名称" clearable />
|
||||||
@@ -383,7 +381,7 @@
|
|||||||
import type { SearchFormItem } from '@/types'
|
import type { SearchFormItem } from '@/types'
|
||||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
import { useAuth } from '@/composables/useAuth'
|
||||||
import CodeGeneratorButton from '@/components/business/CodeGeneratorButton.vue'
|
import { generateSeriesCode } from '@/utils/codeGenerator'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
import {
|
import {
|
||||||
CommonStatus,
|
CommonStatus,
|
||||||
@@ -872,12 +870,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理编码生成
|
// 处理编码生成
|
||||||
const handleCodeGenerated = (code: string) => {
|
const handleGenerateSeriesCode = () => {
|
||||||
form.series_code = code
|
form.series_code = generateSeriesCode()
|
||||||
// 清除该字段的验证错误提示
|
// 清除该字段的验证错误提示
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate('series_code')
|
formRef.value?.clearValidate('series_code')
|
||||||
})
|
})
|
||||||
|
ElMessage.success('编码生成成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除套餐系列
|
// 删除套餐系列
|
||||||
|
|||||||
@@ -209,7 +209,7 @@
|
|||||||
<ElDialog
|
<ElDialog
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
:title="dialogType === 'add' ? '新增代理系列授权' : '编辑代理系列授权'"
|
:title="dialogType === 'add' ? '新增代理系列授权' : '编辑代理系列授权'"
|
||||||
width="45%"
|
width="40%"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@closed="handleDialogClosed"
|
@closed="handleDialogClosed"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -58,15 +58,15 @@
|
|||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="12" v-if="dialogType === 'add'">
|
<ElCol :span="12" v-if="dialogType === 'add'">
|
||||||
<ElFormItem label="店铺编号" prop="shop_code">
|
<ElFormItem label="店铺编号" prop="shop_code">
|
||||||
<div style="display: flex; gap: 8px">
|
<ElInput
|
||||||
<ElInput
|
v-model="formData.shop_code"
|
||||||
v-model="formData.shop_code"
|
placeholder="请输入店铺编号或点击生成"
|
||||||
placeholder="请输入店铺编号或点击生成"
|
clearable
|
||||||
clearable
|
>
|
||||||
style="flex: 1"
|
<template #append>
|
||||||
/>
|
<ElButton @click="handleGenerateShopCode">生成编码</ElButton>
|
||||||
<CodeGeneratorButton code-type="shop" @generated="handleCodeGenerated" />
|
</template>
|
||||||
</div>
|
</ElInput>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
</ElRow>
|
||||||
@@ -286,7 +286,7 @@
|
|||||||
import type { FormRules } from 'element-plus'
|
import type { FormRules } from 'element-plus'
|
||||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
import { useAuth } from '@/composables/useAuth'
|
||||||
import CodeGeneratorButton from '@/components/business/CodeGeneratorButton.vue'
|
import { generateShopCode } from '@/utils/codeGenerator'
|
||||||
import { ShopService, RoleService } from '@/api/modules'
|
import { ShopService, RoleService } from '@/api/modules'
|
||||||
import type { SearchFormItem } from '@/types'
|
import type { SearchFormItem } from '@/types'
|
||||||
import type { ShopResponse, ShopRoleResponse } from '@/types/api'
|
import type { ShopResponse, ShopRoleResponse } from '@/types/api'
|
||||||
@@ -646,12 +646,13 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 处理编码生成
|
// 处理编码生成
|
||||||
const handleCodeGenerated = (code: string) => {
|
const handleGenerateShopCode = () => {
|
||||||
formData.shop_code = code
|
formData.shop_code = generateShopCode()
|
||||||
// 清除该字段的验证错误提示
|
// 清除该字段的验证错误提示
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate('shop_code')
|
formRef.value?.clearValidate('shop_code')
|
||||||
})
|
})
|
||||||
|
ElMessage.success('编码生成成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理地区选择变化
|
// 处理地区选择变化
|
||||||
|
|||||||
@@ -49,20 +49,18 @@
|
|||||||
>
|
>
|
||||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||||
<ElFormItem label="运营商编码" prop="carrier_code">
|
<ElFormItem label="运营商编码" prop="carrier_code">
|
||||||
<div style="display: flex; gap: 8px">
|
<ElInput
|
||||||
<ElInput
|
v-model="form.carrier_code"
|
||||||
v-model="form.carrier_code"
|
placeholder="请输入运营商编码或点击生成"
|
||||||
placeholder="请输入运营商编码或点击生成"
|
:disabled="dialogType === 'edit'"
|
||||||
:disabled="dialogType === 'edit'"
|
clearable
|
||||||
clearable
|
>
|
||||||
style="flex: 1"
|
<template #append>
|
||||||
/>
|
<ElButton v-if="dialogType === 'add'" @click="handleGenerateCarrierCode"
|
||||||
<CodeGeneratorButton
|
>生成编码</ElButton
|
||||||
v-if="dialogType === 'add'"
|
>
|
||||||
code-type="carrier"
|
</template>
|
||||||
@generated="handleCodeGenerated"
|
</ElInput>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="运营商名称" prop="carrier_name">
|
<ElFormItem label="运营商名称" prop="carrier_name">
|
||||||
<ElInput v-model="form.carrier_name" placeholder="请输入运营商名称" />
|
<ElInput v-model="form.carrier_name" placeholder="请输入运营商名称" />
|
||||||
@@ -154,7 +152,7 @@
|
|||||||
import type { SearchFormItem } from '@/types'
|
import type { SearchFormItem } from '@/types'
|
||||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
import { useAuth } from '@/composables/useAuth'
|
||||||
import CodeGeneratorButton from '@/components/business/CodeGeneratorButton.vue'
|
import { generateCarrierCode } from '@/utils/codeGenerator'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
import {
|
import {
|
||||||
CommonStatus,
|
CommonStatus,
|
||||||
@@ -498,12 +496,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理编码生成
|
// 处理编码生成
|
||||||
const handleCodeGenerated = (code: string) => {
|
const handleGenerateCarrierCode = () => {
|
||||||
form.carrier_code = code
|
form.carrier_code = generateCarrierCode()
|
||||||
// 清除该字段的验证错误提示
|
// 清除该字段的验证错误提示
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
formRef.value?.clearValidate('carrier_code')
|
formRef.value?.clearValidate('carrier_code')
|
||||||
})
|
})
|
||||||
|
ElMessage.success('编码生成成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除运营商
|
// 删除运营商
|
||||||
|
|||||||
Reference in New Issue
Block a user