fix: some
All checks were successful
构建并部署前端到测试环境 / deploy (push) Successful in 54s

This commit is contained in:
luo
2026-09-20 17:29:09 +08:00
parent 2c00341a7c
commit 9a6761e01d
26 changed files with 268 additions and 111 deletions

View File

@@ -1413,6 +1413,10 @@
content: '\e776';
}
:deep(.asset-label--associated-phones::before) {
content: '\e776';
}
:deep(.asset-label--operator-account::before) {
content: '\e70d';
}

View File

@@ -365,7 +365,6 @@
return
}
console.error('创建订单失败:', error)
ElMessage.error(normalizeApiError(error).message)
} finally {
loading.value = false
}

View File

@@ -836,7 +836,6 @@
console.error('设置限速失败:', error)
speedLimitDialogVisible.value = false
await nextTick()
ElMessage.error(normalizeApiError(error).message)
} finally {
speedTierSubmitting.value = false
}

View File

@@ -16,7 +16,7 @@ export interface AssetInfo {
iccid?: string
imei?: string
msisdn?: string
associated_phones?: string[] // 当前关联手机号(完整值)
associated_phones?: string[] // 当前关联手机号(按资产数据范围返回完整值)
carrier_type?: string
carrier_name?: string
real_name_status?: number

View File

@@ -142,34 +142,41 @@
</ElDialog>
<!-- CSV 解绑导入 -->
<ElDialog
<ElDrawer
v-model="importDialogVisible"
title="CSV 解绑导入"
width="520px"
direction="rtl"
size="50%"
:close-on-click-modal="false"
@closed="handleImportDialogClosed"
>
<div class="import-tips">
<span>模板表头:</span>
<ElButton link type="primary" @click="downloadTemplate">下载模板</ElButton>
<div class="import-tips-detail">
资产标识,备注(备注可选);支持 UTF-8(可带 BOM),非 UTF-8 按 GBK 解码;无行数上限。
</div>
</div>
<ElAlert type="info" :closable="false" style="margin-bottom: 20px">
<template #title>
<div class="import-tips">
<p><strong>导入说明:</strong></p>
<p>1. 请先下载 CSV 模板,按模板填写资产标识和备注。</p>
<p>2. 仅支持 UTF-8(可带 BOM)编码,非 UTF-8 文件按 GBK 解码。</p>
<p>3. 备注为可选字段,文件不限制数据行数,大小限制以服务端校验为准。</p>
<p>
4. 模板表头:资产标识,备注;
<ElButton link type="primary" @click="downloadTemplate">下载模板</ElButton>
</p>
</div>
</template>
</ElAlert>
<ElForm ref="importFormRef" :model="importForm" :rules="importRules" label-width="90px">
<ElFormItem label="CSV 文件" prop="file">
<ElUpload
<VoucherUpload
ref="uploadRef"
drag
:auto-upload="false"
:limit="1"
accept=".csv"
:on-change="handleFileChange"
:on-exceed="handleFileExceed"
>
<ElIcon class="el-icon--upload"><UploadFilled /></ElIcon>
<div class="el-upload__text">拖拽文件到此处,或<em>点击选择 .csv 文件</em></div>
</ElUpload>
v-model="importFileKeys"
voucher-name="CSV 文件"
:max-count="1"
purpose="phone_unbind_import"
content-type="text/csv"
accept=".csv,text/csv"
tip="仅支持 UTF-8 CSV(可带 BOM),大小限制以服务端校验为准"
@uploading-change="importUploading = $event"
/>
</ElFormItem>
<ElFormItem label="解除原因" prop="reason">
<ElInput
@@ -187,27 +194,24 @@
</ElForm>
<template #footer>
<ElButton @click="importDialogVisible = false">取消</ElButton>
<ElButton type="primary" :loading="importLoading" @click="confirmImport"
<ElButton
type="primary"
:loading="importLoading"
:disabled="importUploading || !importFileKeys.length"
@click="confirmImport"
>创建导入任务</ElButton
>
</template>
</ElDialog>
</ElDrawer>
</ArtTableFullScreen>
</template>
<script setup lang="ts">
import { computed, h, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import {
ElMessage,
ElTag,
FormInstance,
FormRules,
UploadFile,
UploadInstance
} from 'element-plus'
import { UploadFilled } from '@element-plus/icons-vue'
import { PhoneAssetAssociationService, StorageService } from '@/api/modules'
import { ElMessage, ElTag, FormInstance, FormRules } from 'element-plus'
import { PhoneAssetAssociationService } from '@/api/modules'
import VoucherUpload from '@/components/business/VoucherUpload.vue'
import { useAuth } from '@/composables/useAuth'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { formatDateTime } from '@/utils/business/format'
@@ -407,7 +411,6 @@
}
} catch (error) {
console.error('获取手机号资产关联列表失败:', error)
ElMessage.error(normalizeApiError(error).message || '获取手机号资产关联列表失败')
} finally {
loading.value = false
}
@@ -522,7 +525,6 @@
getTableData()
} catch (error) {
console.error('解除关联失败:', error)
ElMessage.error(normalizeApiError(error).message || '解除关联失败')
} finally {
unbindLoading.value = false
}
@@ -594,7 +596,6 @@
getTableData()
} catch (error) {
console.error('批量解绑失败:', error)
ElMessage.error(normalizeApiError(error).message || '批量解绑失败')
} finally {
batchUnbindLoading.value = false
}
@@ -604,10 +605,11 @@
const importDialogVisible = ref(false)
const importLoading = ref(false)
const uploadRef = ref<UploadInstance>()
const importUploading = ref(false)
const uploadRef = ref<InstanceType<typeof VoucherUpload>>()
const importFormRef = ref<FormInstance>()
const importFileKeys = ref<string[]>([])
const importForm = reactive({
file: null as File | null,
reason: '',
confirmed: false
})
@@ -615,7 +617,7 @@
file: [
{
validator: (_rule, _value, callback) => {
if (!importForm.file) callback(new Error('请选择 CSV 文件'))
if (!importFileKeys.value.length) callback(new Error('请选择 CSV 文件'))
else callback()
},
trigger: 'change'
@@ -637,7 +639,7 @@
}
const openImportDialog = () => {
importForm.file = null
importFileKeys.value = []
importForm.reason = ''
importForm.confirmed = false
importDialogVisible.value = true
@@ -645,22 +647,8 @@
const handleImportDialogClosed = () => {
uploadRef.value?.clearFiles()
}
const handleFileChange = (file: UploadFile) => {
const rawFile = file.raw
if (!rawFile) return
if (!rawFile.name.toLowerCase().endsWith('.csv')) {
ElMessage.error('解绑导入仅支持 .csv 文件')
uploadRef.value?.clearFiles()
importForm.file = null
return
}
importForm.file = rawFile
}
const handleFileExceed = () => {
ElMessage.warning('仅支持上传一个 CSV 文件')
importFileKeys.value = []
importUploading.value = false
}
const downloadTemplate = () => {
@@ -680,24 +668,12 @@
const confirmImport = async () => {
if (!(await importFormRef.value?.validate().catch(() => false))) return
const file = importForm.file
if (!file) return
const fileKey = importFileKeys.value[0]
if (!fileKey) return
importLoading.value = true
try {
const uploadUrlRes = await StorageService.getUploadUrl({
file_name: file.name,
content_type: 'text/csv',
purpose: 'phone_unbind_import'
})
if (uploadUrlRes.code !== 0 || !uploadUrlRes.data) {
ElMessage.error(uploadUrlRes.msg || '获取上传地址失败')
return
}
const { upload_url, file_key } = uploadUrlRes.data
await StorageService.uploadFile(upload_url, file, 'text/csv')
const res = await PhoneAssetAssociationService.createUnbindImport({
file_key,
file_key: fileKey,
reason: importForm.reason.trim(),
confirmed: importForm.confirmed
})
@@ -710,7 +686,6 @@
goUnbindImportTasks()
} catch (error) {
console.error('创建解绑导入任务失败:', error)
ElMessage.error(normalizeApiError(error).message || '创建解绑导入任务失败')
} finally {
importLoading.value = false
}
@@ -737,13 +712,12 @@
}
.import-tips {
margin-bottom: 12px;
font-size: 13px;
color: var(--el-text-color-secondary);
.import-tips-detail {
margin-top: 4px;
line-height: 1.6;
p {
margin: 0;
line-height: 1.8;
}
}
</style>

View File

@@ -349,7 +349,6 @@
}
} catch (error) {
console.error('获取设备批量任务目标失败:', error)
ElMessage.error(normalizeApiError(error).message)
} finally {
targetLoading.value = false
}
@@ -425,7 +424,6 @@
taskListTotal.value = res.data.total || 0
} catch (error) {
console.error('获取设备批量任务失败:', error)
ElMessage.error(normalizeApiError(error).message)
} finally {
taskListLoading.value = false
}
@@ -527,7 +525,6 @@
ElMessage.success(`任务已创建:${res.data.task_no}`)
} catch (error) {
console.error('创建设备批量任务失败:', error)
ElMessage.error(normalizeApiError(error).message)
} finally {
submitting.value = false
}

View File

@@ -408,7 +408,6 @@
}
} catch (error) {
console.error(error)
ElMessage.error(normalizeApiError(error).message)
} finally {
loading.value = false
}
@@ -539,7 +538,6 @@
})
} catch (error: any) {
console.error('设备导入失败:', error)
ElMessage.error(normalizeApiError(error).message || error.message || '设备导入失败')
} finally {
uploading.value = false
}

View File

@@ -35,11 +35,6 @@
{{ row.asset_type ? (row.asset_type === 'iot_card' ? '物联网卡' : '设备') : '-' }}
</template>
</ElTableColumn>
<ElTableColumn prop="asset_id" label="资产ID" width="100">
<template #default="{ row }">
{{ row.asset_id ? row.asset_id : '-' }}
</template>
</ElTableColumn>
<ElTableColumn prop="status" label="行状态" width="90">
<template #default="{ row }">
<ElTag :type="row.status === 3 ? 'success' : 'danger'" size="small">
@@ -130,7 +125,6 @@
startPollingIfNeeded()
} catch (error) {
console.error('获取解绑导入任务详情失败:', error)
ElMessage.error(normalizeApiError(error).message || '获取解绑导入任务详情失败')
} finally {
loading.value = false
}

View File

@@ -219,7 +219,6 @@
}
} catch (error) {
console.error('获取解绑导入任务列表失败:', error)
ElMessage.error(normalizeApiError(error).message || '获取解绑导入任务列表失败')
} finally {
loading.value = false
}

View File

@@ -19,7 +19,7 @@ export const BILL_STATUS = {
CLOSED: 3
} as const
/** 申请状态:0 审批中 / 1 已通过 / 2 已驳回 / 3 已撤销或已关闭 */
/** 申请状态:0 审批中 / 1 已通过 / 2 已驳回 / 3 已关闭 */
export const APPLICATION_STATUS = {
PENDING: 0,
APPROVED: 1,
@@ -77,7 +77,7 @@ export const APPLICATION_STATUS_OPTIONS = [
{ label: '审批中', value: APPLICATION_STATUS.PENDING },
{ label: '已通过', value: APPLICATION_STATUS.APPROVED },
{ label: '已驳回', value: APPLICATION_STATUS.REJECTED },
{ label: '已撤销或已关闭', value: APPLICATION_STATUS.REVOKED }
{ label: '已关闭', value: APPLICATION_STATUS.REVOKED }
]
/**

View File

@@ -4,7 +4,6 @@
<ArtSearchBar
v-model:filter="searchForm"
:items="searchFormItems"
label-width="90"
:show-expand="false"
@reset="handleReset"
@search="handleSearch"
@@ -36,7 +35,7 @@
:total="pagination.total"
:marginTop="10"
:actions="getActions"
:actionsWidth="150"
:actionsWidth="120"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
@@ -199,7 +198,7 @@
packageOptions.value.map((item) => ({ label: item.package_name, value: item.id }))
},
{
label: '启用状态',
label: '状态',
prop: 'enabled',
type: 'select',
config: { clearable: true, placeholder: '全部' },
@@ -236,7 +235,7 @@
},
{
prop: 'enabled',
label: '启用状态',
label: '状态',
width: 100,
formatter: (row: PackageTrafficAlertRuleItem) =>
h(
@@ -264,7 +263,7 @@
{ label: '套餐名称', prop: 'package_name' },
{ label: '当前真流量额度', prop: 'real_data_mb' },
{ label: '预警阈值', prop: 'threshold_percent' },
{ label: '启用状态', prop: 'enabled' },
{ label: '状态', prop: 'enabled' },
{ label: '备注', prop: 'remark' },
{ label: '更新时间', prop: 'updated_at' }
]
@@ -289,7 +288,6 @@
}
} catch (error) {
console.error('获取真流量预警规则列表失败:', error)
ElMessage.error(normalizeApiError(error).message || '获取真流量预警规则列表失败')
} finally {
loading.value = false
}
@@ -375,7 +373,6 @@
}
} catch (error) {
console.error('更新真流量预警规则失败:', error)
ElMessage.error(normalizeApiError(error).message || '操作失败')
}
}
@@ -472,7 +469,6 @@
}
} catch (error) {
console.error('保存真流量预警规则失败:', error)
ElMessage.error(normalizeApiError(error).message || '操作失败')
} finally {
submitting.value = false
}

View File

@@ -394,7 +394,6 @@
}
} catch (error) {
console.error('获取真流量达量预警记录失败:', error)
ElMessage.error(normalizeApiError(error).message || '获取真流量达量预警记录失败')
} finally {
loading.value = false
}
@@ -506,7 +505,6 @@
}
} catch (error) {
console.error('创建真流量达量预警导出任务失败:', error)
ElMessage.error(normalizeApiError(error).message || '创建导出任务失败')
} finally {
exportSubmitting.value = false
}

View File

@@ -226,7 +226,6 @@
}
const PAGE_OPTIONS: Array<{ label: string; value: H5PopupPage }> = [
{ label: '首页', value: 'home' },
{ label: '资产详情', value: 'asset_detail' },
{ label: '套餐购买', value: 'package_purchase' },
{ label: '资产钱包充值', value: 'asset_wallet_recharge' }
]
@@ -441,7 +440,6 @@
}
} catch (error) {
console.error('获取运营弹窗配置列表失败:', error)
ElMessage.error(normalizeApiError(error).message || '获取运营弹窗配置列表失败')
} finally {
loading.value = false
}
@@ -513,7 +511,6 @@
}
} catch (error) {
console.error('启用运营弹窗配置失败:', error)
ElMessage.error(normalizeApiError(error).message || '启用失败')
}
}
@@ -537,7 +534,6 @@
}
} catch (error) {
console.error('停用运营弹窗配置失败:', error)
ElMessage.error(normalizeApiError(error).message || '停用失败')
}
}
@@ -748,7 +744,6 @@
}
} catch (error) {
console.error('保存运营弹窗配置失败:', error)
ElMessage.error(normalizeApiError(error).message || '保存失败')
} finally {
formLoading.value = false
}