fix: 套餐

This commit is contained in:
sexygoat
2026-04-29 11:29:53 +08:00
parent 686bddad79
commit 1dc4701540
44 changed files with 3912 additions and 150 deletions

View File

@@ -1,65 +1,143 @@
<template>
<ElDialog v-model="visible" title="设置切卡模式" width="500px">
<ElForm ref="formRef" :model="form" :rules="rules" label-width="80px">
<ElForm ref="formRef" :model="form" :rules="rules" label-width="96px">
<ElFormItem label="设备标识">
<span style="font-weight: bold; color: #409eff">{{ deviceIdentifier }}</span>
<span class="device-identifier">{{ deviceIdentifier || '-' }}</span>
</ElFormItem>
<ElFormItem label="当前模式">
<ElTag :type="currentMode === 0 ? 'success' : 'warning'">
{{ currentMode === 0 ? '自动切卡' : '手动切卡' }}
<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 style="font-size: 12px; color: #909399; line-height: 1.6">
<div class="mode-description">
<p>说明</p>
<p> <strong>自动切卡</strong>设备根据信号强度自动切换到最优的SIM</p>
<p> <strong>手动切卡</strong>需要手动触发切换SIM卡操作</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">确认设置</ElButton>
<ElButton
type="primary"
@click="handleConfirm"
:loading="confirmLoading"
:disabled="!canSubmit"
>
确认设置
</ElButton>
</template>
</ElDialog>
</template>
<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import { ElDialog, ElForm, ElFormItem, ElRadioGroup, ElRadio, ElTag } from 'element-plus'
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
currentMode?: number | string
cards?: SwitchModeCardOption[]
hasImei?: boolean
confirmLoading?: boolean
}
interface Emits {
(e: 'update:modelValue', value: boolean): void
(e: 'confirm', data: { switch_mode: number }): void
(e: 'confirm', data: { iot_card_id: number; switch_mode: 0 | 1 }): void
}
const props = withDefaults(defineProps<Props>(), {
currentMode: 0
currentMode: 0,
cards: () => [],
hasImei: false,
confirmLoading: false
})
const emit = defineEmits<Emits>()
const formRef = ref<FormInstance>()
const confirmLoading = ref(false)
const form = reactive({
const form = reactive<SwitchModeForm>({
iot_card_id: undefined,
switch_mode: 0
})
const rules: FormRules = {
const rules: FormRules<SwitchModeForm> = {
iot_card_id: [{ required: true, message: '请选择绑定卡', trigger: 'change' }],
switch_mode: [{ required: true, message: '请选择切卡模式', trigger: 'change' }]
}
@@ -68,27 +146,99 @@
set: (value) => emit('update:modelValue', value)
})
const currentMode = computed(() => Number(props.currentMode) ?? 0)
const currentModeValue = computed<0 | 1>(() =>
Number(props.currentMode) === 1 ? 1 : 0
)
watch(visible, (newVal) => {
if (newVal) {
form.switch_mode = Number(props.currentMode) ?? 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) return
if (!formRef.value || !canSubmit.value) return
try {
await formRef.value.validate()
emit('confirm', { switch_mode: form.switch_mode })
} catch (error) {
console.error('表单验证失败:', error)
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></style>
<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>