Files
one-pipe-system/src/views/asset-management/asset-information/components/dialogs/SwitchModeDialog.vue
sexygoat 1990a3ccba
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m4s
fix: bug
2026-05-11 15:51:50 +08:00

245 lines
5.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<ElDialog v-model="visible" title="设置切卡模式" width="500px">
<ElForm ref="formRef" :model="form" :rules="rules" label-width="96px">
<ElFormItem label="设备标识">
<span class="device-identifier">{{ deviceIdentifier || '-' }}</span>
</ElFormItem>
<ElFormItem label="当前模式">
<ElTag :type="currentModeValue === 0 ? 'success' : 'warning'">
{{ currentModeValue === 0 ? '自动切卡' : '手动切卡' }}
</ElTag>
</ElFormItem>
<ElAlert
v-if="!hasImei"
type="warning"
:closable="false"
show-icon
title="设备未配置 IMEI无法设置切卡模式"
style="margin-bottom: 16px"
/>
<ElAlert
v-else-if="availableCards.length === 0"
type="warning"
:closable="false"
show-icon
title="暂无绑定卡,无法设置切卡模式"
style="margin-bottom: 16px"
/>
<ElFormItem label="绑定卡" prop="iot_card_id">
<ElSelect
v-model="form.iot_card_id"
style="width: 100%"
placeholder="请选择绑定卡"
:disabled="!canSubmit"
>
<ElOption
v-for="card in availableCards"
:key="card.iot_card_id"
:label="getCardLabel(card)"
:value="card.iot_card_id"
/>
</ElSelect>
<div class="field-tip">请选择一张绑定卡</div>
</ElFormItem>
<ElFormItem label="切卡模式" prop="switch_mode">
<ElRadioGroup v-model="form.switch_mode">
<ElRadio :value="0">自动切卡</ElRadio>
<ElRadio :value="1">手动切卡</ElRadio>
</ElRadioGroup>
</ElFormItem>
<ElFormItem>
<div class="mode-description">
<p>说明</p>
<p> <strong>自动切卡</strong>设备根据信号强度自动切换到最优的 SIM </p>
<p> <strong>手动切卡</strong>需要手动触发切换 SIM 卡操作</p>
</div>
</ElFormItem>
</ElForm>
<template #footer>
<ElButton @click="handleCancel">取消</ElButton>
<ElButton
type="primary"
@click="handleConfirm"
:loading="confirmLoading"
:disabled="!canSubmit"
>
确认设置
</ElButton>
</template>
</ElDialog>
</template>
<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import {
ElAlert,
ElButton,
ElDialog,
ElForm,
ElFormItem,
ElOption,
ElRadio,
ElRadioGroup,
ElSelect,
ElTag
} from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
interface SwitchModeCardOption {
iot_card_id: number
iccid: string
slot_position?: number
carrier_name?: string
msisdn?: string
network_status?: number
real_name_status?: number
is_current?: boolean
}
interface SwitchModeForm {
iot_card_id?: number
switch_mode: 0 | 1
}
interface Props {
modelValue: boolean
deviceIdentifier: string
currentMode?: number | string
cards?: SwitchModeCardOption[]
hasImei?: boolean
confirmLoading?: boolean
}
interface Emits {
(e: 'update:modelValue', value: boolean): void
(e: 'confirm', data: { iot_card_id: number; switch_mode: 0 | 1 }): void
}
const props = withDefaults(defineProps<Props>(), {
currentMode: 0,
cards: () => [],
hasImei: false,
confirmLoading: false
})
const emit = defineEmits<Emits>()
const formRef = ref<FormInstance>()
const form = reactive<SwitchModeForm>({
iot_card_id: undefined,
switch_mode: 0
})
const rules: FormRules<SwitchModeForm> = {
iot_card_id: [{ required: true, message: '请选择绑定卡', trigger: 'change' }],
switch_mode: [{ required: true, message: '请选择切卡模式', trigger: 'change' }]
}
const visible = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
})
const currentModeValue = computed<0 | 1>(() => (Number(props.currentMode) === 1 ? 1 : 0))
const availableCards = computed(() => props.cards || [])
const canSubmit = computed(() => props.hasImei && availableCards.value.length > 0)
const syncFormState = () => {
form.switch_mode = currentModeValue.value
const selectedStillExists = availableCards.value.some(
(card) => card.iot_card_id === form.iot_card_id
)
if (!selectedStillExists) {
form.iot_card_id = availableCards.value[0]?.iot_card_id
}
}
watch(
() => props.modelValue,
(newValue) => {
if (newValue) {
syncFormState()
return
}
formRef.value?.clearValidate()
}
)
watch(
() => [props.cards, props.currentMode] as const,
() => {
if (visible.value) {
syncFormState()
}
},
{ deep: true }
)
const getCardLabel = (card: SwitchModeCardOption) => {
const parts = [`卡槽 ${card.slot_position ?? '-'}`, card.iccid]
if (card.carrier_name) {
parts.push(card.carrier_name)
}
if (card.is_current) {
parts.push('当前使用')
}
return parts.join(' / ')
}
const handleCancel = () => {
visible.value = false
}
const handleConfirm = async () => {
if (!formRef.value || !canSubmit.value) return
try {
await formRef.value.validate()
emit('confirm', {
iot_card_id: form.iot_card_id!,
switch_mode: form.switch_mode
})
} catch {
// Element Plus validation rejection is expected when required fields are missing.
}
}
</script>
<style lang="scss" scoped>
.device-identifier {
font-weight: 600;
color: var(--el-color-primary);
}
.field-tip {
margin-top: 6px;
font-size: 12px;
line-height: 1.5;
color: var(--el-text-color-secondary);
}
.mode-description {
font-size: 12px;
line-height: 1.6;
color: var(--el-text-color-secondary);
}
.mode-description p {
margin: 0;
}
</style>