This commit is contained in:
@@ -99,7 +99,7 @@
|
||||
ElMessage.success('操作成功')
|
||||
} catch (error) {
|
||||
console.error('批量操作失败:', error)
|
||||
ElMessage.error('操作失败')
|
||||
console.log('操作失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
@@ -166,7 +166,9 @@
|
||||
label: '用户类型',
|
||||
width: 110,
|
||||
formatter: (row: PlatformAccount) => {
|
||||
return h(ElTag, { type: getUserTypeTag(row.user_type) }, () => getUserTypeName(row.user_type))
|
||||
return h(ElTag, { type: getUserTypeTag(row.user_type) }, () =>
|
||||
getUserTypeName(row.user_type)
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -30,130 +30,130 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElCard } from 'element-plus'
|
||||
import { ElCard } from 'element-plus'
|
||||
|
||||
export interface DetailField {
|
||||
label: string // 字段标签
|
||||
prop?: string // 数据属性路径,支持点号分隔的嵌套路径,如 'one_time_commission_config.enable'
|
||||
formatter?: (value: any, data: any) => string // 自定义格式化函数
|
||||
render?: (data: any) => any // 自定义渲染函数,返回 VNode
|
||||
fullWidth?: boolean // 是否占据整行
|
||||
}
|
||||
|
||||
export interface DetailSection {
|
||||
title: string // 分组标题
|
||||
fields: DetailField[] // 字段列表
|
||||
columns?: 1 | 2 // 列数,默认2列
|
||||
}
|
||||
|
||||
interface Props {
|
||||
sections: DetailSection[] // 详情页分组配置
|
||||
data: any // 详情数据
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
/**
|
||||
* 根据点号分隔的路径获取嵌套对象的值
|
||||
*/
|
||||
const getNestedValue = (obj: any, path: string): any => {
|
||||
if (!path) return obj
|
||||
return path.split('.').reduce((acc, part) => acc?.[part], obj)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化字段值
|
||||
*/
|
||||
const formatFieldValue = (field: DetailField, data: any): string => {
|
||||
const value = field.prop ? getNestedValue(data, field.prop) : data
|
||||
|
||||
// 如果有自定义格式化函数
|
||||
if (field.formatter) {
|
||||
return field.formatter(value, data)
|
||||
export interface DetailField {
|
||||
label: string // 字段标签
|
||||
prop?: string // 数据属性路径,支持点号分隔的嵌套路径,如 'one_time_commission_config.enable'
|
||||
formatter?: (value: any, data: any) => string // 自定义格式化函数
|
||||
render?: (data: any) => any // 自定义渲染函数,返回 VNode
|
||||
fullWidth?: boolean // 是否占据整行
|
||||
}
|
||||
|
||||
// 默认处理
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
export interface DetailSection {
|
||||
title: string // 分组标题
|
||||
fields: DetailField[] // 字段列表
|
||||
columns?: 1 | 2 // 列数,默认2列
|
||||
}
|
||||
|
||||
return String(value)
|
||||
}
|
||||
interface Props {
|
||||
sections: DetailSection[] // 详情页分组配置
|
||||
data: any // 详情数据
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
/**
|
||||
* 根据点号分隔的路径获取嵌套对象的值
|
||||
*/
|
||||
const getNestedValue = (obj: any, path: string): any => {
|
||||
if (!path) return obj
|
||||
return path.split('.').reduce((acc, part) => acc?.[part], obj)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化字段值
|
||||
*/
|
||||
const formatFieldValue = (field: DetailField, data: any): string => {
|
||||
const value = field.prop ? getNestedValue(data, field.prop) : data
|
||||
|
||||
// 如果有自定义格式化函数
|
||||
if (field.formatter) {
|
||||
return field.formatter(value, data)
|
||||
}
|
||||
|
||||
// 默认处理
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '-'
|
||||
}
|
||||
|
||||
return String(value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail-container {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.detail-section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
.detail-container {
|
||||
max-height: 70vh;
|
||||
padding: 4px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
}
|
||||
.detail-section {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.section-fields {
|
||||
display: grid;
|
||||
gap: 16px 24px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.single-column {
|
||||
grid-template-columns: 1fr;
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&.double-column {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.field-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
min-height: 32px;
|
||||
|
||||
&.full-width {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
flex-shrink: 0;
|
||||
width: 140px;
|
||||
font-weight: 500;
|
||||
color: var(--el-text-color-regular);
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
flex: 1;
|
||||
color: var(--el-text-color-primary);
|
||||
line-height: 32px;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.section-fields {
|
||||
&.double-column {
|
||||
display: grid;
|
||||
gap: 16px 24px;
|
||||
|
||||
&.single-column {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
&.double-column {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.field-item {
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
min-height: 32px;
|
||||
|
||||
&.full-width {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
width: 100%;
|
||||
margin-bottom: 4px;
|
||||
flex-shrink: 0;
|
||||
width: 140px;
|
||||
font-weight: 500;
|
||||
line-height: 32px;
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
|
||||
.field-value {
|
||||
flex: 1;
|
||||
line-height: 32px;
|
||||
color: var(--el-text-color-primary);
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <= 768px) {
|
||||
.section-fields {
|
||||
&.double-column {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.field-item {
|
||||
flex-direction: column;
|
||||
|
||||
.field-label {
|
||||
width: 100%;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
user-select: none;
|
||||
transition: background-color 0.15s ease;
|
||||
|
||||
&:hover:not(.is-disabled):not(.no-permission) {
|
||||
&:hover:not(.is-disabled, .no-permission) {
|
||||
background-color: rgba(var(--art-gray-200-rgb), 0.7);
|
||||
}
|
||||
|
||||
@@ -267,8 +267,8 @@
|
||||
.menu-label {
|
||||
color: var(--el-text-color-secondary);
|
||||
text-align: center;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
<style scoped lang="scss">
|
||||
.table-context-menu-hint {
|
||||
position: fixed;
|
||||
padding: 4px 10px;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
z-index: 9999;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
background-color: rgb(0 0 0 / 80%);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px rgb(0 0 0 / 15%);
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<template>
|
||||
<ElDialog v-model="visible" title="设置WiFi" width="500px" @close="handleClose">
|
||||
<ElForm
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
label-width="120px"
|
||||
>
|
||||
<ElForm ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
||||
<ElFormItem label="设备信息">
|
||||
<span style="font-weight: bold; color: #409eff">{{ deviceInfo }}</span>
|
||||
</ElFormItem>
|
||||
@@ -96,23 +91,29 @@
|
||||
]
|
||||
})
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
visible.value = val
|
||||
if (val) {
|
||||
// 重置表单
|
||||
formData.enabled = 1
|
||||
formData.ssid = ''
|
||||
formData.password = ''
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
visible.value = val
|
||||
if (val) {
|
||||
// 重置表单
|
||||
formData.enabled = 1
|
||||
formData.ssid = ''
|
||||
formData.password = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
watch(visible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
watch(() => props.loading, (val) => {
|
||||
confirmLoading.value = val
|
||||
})
|
||||
watch(
|
||||
() => props.loading,
|
||||
(val) => {
|
||||
confirmLoading.value = val
|
||||
}
|
||||
)
|
||||
|
||||
const handleClose = () => {
|
||||
formRef.value?.resetFields()
|
||||
@@ -122,7 +123,7 @@
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
if (valid) {
|
||||
emit('confirm', {
|
||||
enabled: formData.enabled,
|
||||
ssid: formData.ssid,
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<template>
|
||||
<ElDialog v-model="visible" title="设置限速" width="500px" @close="handleClose">
|
||||
<ElForm
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
label-width="120px"
|
||||
>
|
||||
<ElForm ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
||||
<ElFormItem label="设备信息">
|
||||
<span style="font-weight: bold; color: #409eff">{{ deviceInfo }}</span>
|
||||
</ElFormItem>
|
||||
@@ -17,7 +12,7 @@
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<div style="color: #909399; font-size: 12px; margin-top: 4px">单位: KB/s</div>
|
||||
<div style=" margin-top: 4px; font-size: 12px;color: #909399">单位: KB/s</div>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="上行速率" prop="upload_speed">
|
||||
<ElInputNumber
|
||||
@@ -27,7 +22,7 @@
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<div style="color: #909399; font-size: 12px; margin-top: 4px">单位: KB/s</div>
|
||||
<div style=" margin-top: 4px; font-size: 12px;color: #909399">单位: KB/s</div>
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
@@ -75,22 +70,28 @@
|
||||
upload_speed: [{ required: true, message: '请输入上行速率', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
visible.value = val
|
||||
if (val) {
|
||||
// 重置表单
|
||||
formData.download_speed = 1024
|
||||
formData.upload_speed = 512
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
visible.value = val
|
||||
if (val) {
|
||||
// 重置表单
|
||||
formData.download_speed = 1024
|
||||
formData.upload_speed = 512
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
watch(visible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
watch(() => props.loading, (val) => {
|
||||
confirmLoading.value = val
|
||||
})
|
||||
watch(
|
||||
() => props.loading,
|
||||
(val) => {
|
||||
confirmLoading.value = val
|
||||
}
|
||||
)
|
||||
|
||||
const handleClose = () => {
|
||||
formRef.value?.resetFields()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ElDialog v-model="visible" title="切换SIM卡" width="600px" @close="handleClose">
|
||||
<div v-if="loading" style="text-align: center; padding: 40px">
|
||||
<div v-if="loading" style=" padding: 40px;text-align: center">
|
||||
<ElIcon class="is-loading" :size="40"><Loading /></ElIcon>
|
||||
<div style="margin-top: 16px">加载设备绑定的卡列表中...</div>
|
||||
</div>
|
||||
@@ -42,7 +42,7 @@
|
||||
:label="`${card.iccid} - 插槽${card.slot_position} - ${card.carrier_name}`"
|
||||
:value="card.iccid"
|
||||
>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
<span>{{ card.iccid }}</span>
|
||||
<ElTag size="small" style="margin-left: 10px">插槽{{ card.slot_position }}</ElTag>
|
||||
</div>
|
||||
@@ -123,13 +123,16 @@
|
||||
target_iccid: [{ required: true, message: '请选择目标ICCID', trigger: 'change' }]
|
||||
})
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
visible.value = val
|
||||
if (val) {
|
||||
// 重置表单
|
||||
formData.target_iccid = ''
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
visible.value = val
|
||||
if (val) {
|
||||
// 重置表单
|
||||
formData.target_iccid = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
watch(visible, (val) => {
|
||||
emit('update:modelValue', val)
|
||||
|
||||
Reference in New Issue
Block a user