feat(DeviceSn): 添加设备组件并更新本地接口地址

This commit is contained in:
2026-07-30 17:13:38 +08:00
parent 1ff46bc33b
commit 742b32490f
22 changed files with 3767 additions and 2 deletions

View File

@@ -0,0 +1,735 @@
<template>
<div class="device-detail">
<!-- 设备头部信息 -->
<div class="device-header">
<div class="device-info">
<img :src="deviceImage" alt="设备图片" class="device-image" />
<div class="info-content">
<div class="info-row">
<span class="device-name">{{ deviceData.snName }}</span>
<el-tag type="success" size="small">
{{ deviceData.onlineStatus == 1 ? "在线" : "离线" }}
</el-tag>
</div>
<div class="info-grid">
<div class="info-item">
<span class="label">序列号</span>
<span class="value">{{ props.serialno }}</span>
</div>
<div class="info-item">
<span class="label">IMEI</span>
<span class="value">{{ deviceData.imei }}</span>
</div>
<div class="info-item">
<span class="label">设备所有者</span>
<span class="value">{{ deviceData.owner }}</span>
</div>
<div class="info-item">
<span class="label">所属部门</span>
<span class="value">{{ deviceData.department }}</span>
</div>
<div class="info-item">
<span class="label">分组</span>
<span class="value">{{ deviceData.group }}</span>
</div>
<div class="info-item">
<span class="label">设备类型</span>
<span class="value">{{ deviceData.deviceType }}</span>
</div>
<div class="info-item">
<span class="label">设备来源</span>
<span class="value">{{ deviceData.source }}</span>
</div>
<div class="info-item">
<span class="label">激活时间</span>
<span class="value">{{ deviceData.activationTime }}</span>
</div>
<div class="info-item">
<span class="label">最后上线</span>
<span class="value">{{ deviceData.lastOnline }}</span>
</div>
<div class="info-item">
<span class="label">设备编号</span>
<span class="value">{{ deviceData.deviceSn }}</span>
</div>
</div>
</div>
</div>
<!-- 操作按钮 -->
<div class="action-buttons">
<el-button @click="handleReturn">
<el-icon><Back /></el-icon>
返回
</el-button>
<el-button @click="handleRefresh">
<el-icon><Refresh /></el-icon>
刷新
</el-button>
<el-button type="primary" @click="handleEdit">
<el-icon><Edit /></el-icon>
编辑
</el-button>
<div class="secondary-actions">
<el-button text @click="handleRemoteLock">
<el-icon><Lock /></el-icon>
远程锁定
</el-button>
<el-button text @click="handleLostMode">
<el-icon><Warning /></el-icon>
丢失模式
</el-button>
<el-button text @click="handleWipeDevice">
<el-icon><Delete /></el-icon>
清除设备
</el-button>
<el-button text @click="handleRestartDevice">
<el-icon><RefreshRight /></el-icon>
重启设备
</el-button>
<el-button text @click="handleSyncDevice">
<el-icon><Refresh /></el-icon>
同步设备
</el-button>
<el-dropdown trigger="click" @command="handleMoreActions">
<el-button text>
更多操作
<el-icon><ArrowDown /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="assign">分配设备</el-dropdown-item>
<el-dropdown-item command="transfer">转移设备</el-dropdown-item>
<el-dropdown-item command="batch">批量操作</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</div>
<!-- 标签页内容 -->
<div class="tabs-container">
<el-tabs v-model="activeTab" class="device-tabs">
<el-tab-pane label="设备信息" name="deviceInfo">
<div class="tab-content">
<!-- 基本信息 -->
<div class="info-section">
<h3 class="section-title">基本信息</h3>
<el-descriptions :column="2" border>
<el-descriptions-item label="设备名称">
{{ basicInfo.deviceName }}
</el-descriptions-item>
<el-descriptions-item label="设备型号">
{{ basicInfo.deviceModel }}
</el-descriptions-item>
<el-descriptions-item label="操作系统">{{ basicInfo.os }}</el-descriptions-item>
<el-descriptions-item label="操作系统版本号">
{{ basicInfo.osVersion }}
</el-descriptions-item>
<el-descriptions-item label="设备语言">
{{ basicInfo.language }}
</el-descriptions-item>
<el-descriptions-item label="时区">{{ basicInfo.timezone }}</el-descriptions-item>
<el-descriptions-item label="设备标识(IMEI)">
{{ basicInfo.imei }}
</el-descriptions-item>
<el-descriptions-item label="蓝牙地址">
{{ basicInfo.bluetoothMac }}
</el-descriptions-item>
<el-descriptions-item label="Wi-Fi MAC地址">
{{ basicInfo.wifiMac }}
</el-descriptions-item>
<el-descriptions-item label="设备颜色">{{ basicInfo.color }}</el-descriptions-item>
<el-descriptions-item label="设备容量">
{{ basicInfo.capacity }}
</el-descriptions-item>
<el-descriptions-item label="可用容量">
{{ basicInfo.availableCapacity }}
</el-descriptions-item>
<el-descriptions-item label="内存容量">
{{ basicInfo.memoryCapacity }}
</el-descriptions-item>
<el-descriptions-item label="可用内存">
{{ basicInfo.availableMemory }}
</el-descriptions-item>
<el-descriptions-item label="电池电量">
{{ basicInfo.batteryLevel }}
</el-descriptions-item>
<el-descriptions-item label="电池健康度">
{{ basicInfo.batteryHealth }}
</el-descriptions-item>
<el-descriptions-item label="设备重量">{{ basicInfo.weight }}</el-descriptions-item>
<el-descriptions-item label="设备尺寸">
{{ basicInfo.dimensions }}
</el-descriptions-item>
<el-descriptions-item
label="SIM卡状态
"
>
{{ basicInfo.simStatus }}
</el-descriptions-item>
<el-descriptions-item label="电话号码">
{{ basicInfo.phoneNumber }}
</el-descriptions-item>
<el-descriptions-item label="ICCID">
{{ basicInfo.iccid }}
</el-descriptions-item>
<el-descriptions-item label="MEID">
{{ basicInfo.meid }}
</el-descriptions-item>
</el-descriptions>
</div>
<!-- 硬件信息 -->
<div class="info-section">
<h3 class="section-title">硬件信息</h3>
<el-descriptions :column="2" border>
<el-descriptions-item label="处理器">
{{ hardwareInfo.processor }}
</el-descriptions-item>
<el-descriptions-item label="处理器核心数">
{{ hardwareInfo.processorCores }}
</el-descriptions-item>
<el-descriptions-item label="GPU">
{{ hardwareInfo.gpu }}
</el-descriptions-item>
<el-descriptions-item label="屏幕尺寸">
{{ hardwareInfo.screenSize }}
</el-descriptions-item>
<el-descriptions-item label="屏幕分辨率">
{{ hardwareInfo.screenResolution }}
</el-descriptions-item>
<el-descriptions-item label="屏幕像素密度">
{{ hardwareInfo.screenDensity }}
</el-descriptions-item>
<el-descriptions-item label="摄像头">
{{ hardwareInfo.camera }}
</el-descriptions-item>
<el-descriptions-item label="设备传感器">
{{ hardwareInfo.sensors }}
</el-descriptions-item>
<el-descriptions-item label="NFC">
{{ hardwareInfo.nfc }}
</el-descriptions-item>
<el-descriptions-item label="Face ID">
{{ hardwareInfo.faceId }}
</el-descriptions-item>
</el-descriptions>
</div>
<!-- 网络信息 -->
<div class="info-section">
<h3 class="section-title">网络信息</h3>
<el-descriptions :column="2" border>
<el-descriptions-item label="当前网络">
{{ networkInfo.currentNetwork }}
</el-descriptions-item>
<el-descriptions-item label="运营商">
{{ networkInfo.carrier }}
</el-descriptions-item>
<el-descriptions-item label="信号强度">
{{ networkInfo.signalStrength }}
</el-descriptions-item>
<el-descriptions-item label="IP地址">
{{ networkInfo.ipAddress }}
</el-descriptions-item>
<el-descriptions-item label="Wi-Fi名称">
{{ networkInfo.wifiName }}
</el-descriptions-item>
<el-descriptions-item label="Wi-Fi MAC地址">
{{ networkInfo.wifiMac }}
</el-descriptions-item>
<el-descriptions-item label="蜂窝网络类型">
{{ networkInfo.cellularType }}
</el-descriptions-item>
<el-descriptions-item label="漫游状态">
{{ networkInfo.roamingStatus }}
</el-descriptions-item>
</el-descriptions>
</div>
<!-- 安全信息 -->
<div class="info-section">
<h3 class="section-title">安全信息</h3>
<el-descriptions :column="2" border>
<el-descriptions-item label="锁屏密码">
{{ securityInfo.lockScreenPassword }}
</el-descriptions-item>
<el-descriptions-item label="密码复杂度">
{{ securityInfo.passwordComplexity }}
</el-descriptions-item>
<el-descriptions-item label="数据保护">
{{ securityInfo.dataProtection }}
</el-descriptions-item>
<el-descriptions-item label="查找我的iPhone">
{{ securityInfo.findMyIPhone }}
</el-descriptions-item>
<el-descriptions-item label="设备加密">
{{ securityInfo.deviceEncryption }}
</el-descriptions-item>
<el-descriptions-item label="越狱状态">
{{ securityInfo.jailbreakStatus }}
</el-descriptions-item>
<el-descriptions-item label="受监管状态">
{{ securityInfo.supervisedStatus }}
</el-descriptions-item>
<el-descriptions-item label="最后安全扫描时间">
{{ securityInfo.lastSecurityScan }}
</el-descriptions-item>
<el-descriptions-item label="安全补丁版本">
{{ securityInfo.securityPatchVersion }}
</el-descriptions-item>
</el-descriptions>
</div>
<!-- 其他信息 -->
<div class="info-section">
<h3 class="section-title">其他信息</h3>
<el-descriptions :column="2" border>
<el-descriptions-item label="购买日期">
{{ otherInfo.purchaseDate }}
</el-descriptions-item>
<el-descriptions-item label="保修到期日">
{{ otherInfo.warrantyExpiry }}
</el-descriptions-item>
<el-descriptions-item label="设备来源">{{ otherInfo.source }}</el-descriptions-item>
<el-descriptions-item label="分配日期">
{{ otherInfo.assignDate }}
</el-descriptions-item>
<el-descriptions-item label="备注">{{ otherInfo.remark }}</el-descriptions-item>
<el-descriptions-item label="标签">{{ otherInfo.tags }}</el-descriptions-item>
<el-descriptions-item label="自定义字段1">
{{ otherInfo.customField1 }}
</el-descriptions-item>
<el-descriptions-item label="自定义字段2">
{{ otherInfo.customField2 }}
</el-descriptions-item>
</el-descriptions>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="应用信息" name="appInfo">
<div class="ta,b-content">
<el-empty description="应用信息加载中..." />
</div>
</el-tab-pane>
<el-tab-pane label="策略信息" name="policyInfo">
<div class="tab-content">
<el-empty description="策略信息加载中..." />
</div>
</el-tab-pane>
<el-tab-pane label="合规状态" name="complianceInfo">
<div class="tab-content">
<el-empty description="合规状态加载中..." />
</div>
</el-tab-pane>
<el-tab-pane label="操作日志" name="operationLog">
<div class="tab-content">
<el-empty description="操作日志加载中..." />
</div>
</el-tab-pane>
<el-tab-pane label="定位信息" name="locationInfo">
<div class="tab-content">
<el-empty description="定位信息加载中..." />
</div>
,
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script setup lang="ts">
import DeviceAPI from "@/api/system/device";
import { ref, reactive, watch, onMounted } from "vue";
import {
Back,
Edit,
Refresh,
Lock,
Warning,
Delete,
RefreshRight,
ArrowDown,
} from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
onMounted(() => {
if (props.serialno) {
loadDeviceDetail(props.serialno);
}
});
// 接收传入的 props
interface Props {
modelValue?: boolean; // 控制对话框显示隐藏
serialno?: string; // 传递的设备序列号
}
const props = withDefaults(defineProps<Props>(), {
modelValue: false,
serialno: "",
});
// 定义自定义事件
const emit = defineEmits<{
"update:modelValue": [boolean];
returnClick: [];
}>();
// 监听 serialno 变化,加载对应的数据
watch(
() => props.serialno,
async (newSerialno) => {
if (newSerialno) {
await loadDeviceDetail(newSerialno);
}
},
{ immediate: true }
);
// 加载设备详情的方法
const loadDeviceDetail = async (serialno: string) => {
try {
// 调用 API 获取设备详细信息
const response = await DeviceAPI.getFormData(serialno);
// 更新 deviceData 等响应式数据
if (response) {
Object.assign(deviceData, {
snName: response.snName,
onlineStatus: response.onlineStatus,
deviceSn: response.serialno || serialno,
imei: response.snImei,
department: response.department,
group: response.group,
deviceType: response.deviceType,
source: response.source,
activationTime: response.activationTime,
lastOnline: response.lastOnline,
});
}
} catch (error) {
ElMessage.error("加载设备详情失败");
console.error("Error loading device detail:", error);
}
};
// 设备数据
const deviceData = reactive({
snName: "iPhone 15 Pro Max",
onlineStatus: 1,
owner: "张三",
department: "销售部",
group: "华东区域 / 上海分公司",
deviceType: "iOS",
source: "企业注册",
activationTime: "2024-02-18 09:32:21",
lastOnline: "10:15:42",
deviceSn: "550e8400-e29b-41d4-a716-446655440000",
imei: "35455016276432",
serialNumber: "H0FJXOY7XO",
});
// 设备图片
const deviceImage = ref("./src/assets/images/iphone-17-pro.webp");
// 标签页
const activeTab = ref("deviceInfo");
// 基本信息
const basicInfo = reactive({
deviceName: "iPhone 15 Pro Max",
deviceModel: "iPhone16,2",
os: "iOS 17.4.1",
osVersion: "21E236",
language: "zh-Hans-CN",
timezone: "Asia/Shanghai",
imei: "00008110-001C195E3EA1802E",
bluetoothMac: "90:81:5B:1B:4A:7F",
wifiMac: "90:81:5B:1B:4A:7F",
color: "原色钛金属",
capacity: "256 GB",
availableCapacity: "128.35 GB (50.1%)",
memoryCapacity: "8 GB",
availableMemory: "3.12 GB (39.0%)",
batteryLevel: "87%",
batteryHealth: "98%",
weight: "221 g",
dimensions: "159.9 x 76.7 x 8.25 mm",
simStatus: "单卡",
phoneNumber: "+86 138 0000 0000",
iccid: "8986 0112 3456 7890 1234",
meid: "35455016276543",
});
// 硬件信息
const hardwareInfo = reactive({
processor: "A17 Pro",
processorCores: "6",
gpu: "Apple GPU",
screenSize: "6.7 英寸",
screenResolution: "2796 x 1290",
screenDensity: "4,60 ppi",
camera: "后置三摄 48MP + 12MP + 12MP前置 12MP",
sensors: "加速度计,陀螺仪,指南针,气压计,距离传感器,环境光传感器,面容 ID",
nfc: "支持",
faceId: "支持",
});
// 网络信息
const networkInfo = reactive({
currentNetwork: "Wi-Fi",
carrier: "中国移动",
signalStrength: "强",
ipAddress: "192.168.1.102",
wifiName: "Office-WiFi",
wifiMac: "90:81:5B:1B:4A:7F",
cellularType: "5G",
roamingStatus: "否",
});
// 安全信息
const securityInfo = reactive({
lockScreenPassword: "已设置",
passwordComplexity: "高",
dataProtection: "已开启",
findMyIPhone: "已开启",
deviceEncryption: "已开启",
jailbreakStatus: "否",
supervisedStatus: "是",
lastSecurityScan: "2024-05-23 09:50:11",
securityPatchVersion: "iOS 17.4.1 (21E236)",
});
// 其他信息
const otherInfo = reactive({
purchaseDate: "2024-02-10",
warrantyExpiry: "2025-02-09",
source: "企业注册",
assignDate: "2024-02-18",
remark: "销售部员工配发设备",
tags: "重要设备,外勤设备",
customField1: "-",
customField2: "-",
});
// 更新返回按钮事件
const handleReturn = () => {
emit("update:modelValue", false); // 隐藏对话框
emit("returnClick"); // 触发返回事件
};
const handleEdit = () => {
ElMessage.success("编辑功能");
};
const handleRefresh = () => {
loadDeviceDetail(props.serialno).then(() => {
ElMessage.success("刷新数据成功");
});
};
const handleRemoteLock = () => {
ElMessageBox.confirm("确定要远程锁定该设备吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
ElMessage.success("远程锁定指令已发送");
})
.catch(() => {});
};
const handleLostMode = () => {
ElMessageBox.confirm("确定要开启丢失模式吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
ElMessage.success("丢失模式已开启");
})
.catch(() => {});
};
const handleWipeDevice = () => {
ElMessageBox.confirm("确定要清除该设备数据吗?此操作不可逆!", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "error",
})
.then(() => {
ElMessage.success("清除设备指令已发送");
})
.catch(() => {});
};
const handleRestartDevice = () => {
ElMessageBox.confirm("确定要重启该设备吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
ElMessage.success("重启设备指令已发送");
})
.catch(() => {});
};
const handleSyncDevice = () => {
ElMessage.success("同步设备指令已发送");
};
const handleMoreActions = (command: string) => {
switch (command) {
case "assign":
ElMessage.success("分配设备功能");
break;
case "transfer":
ElMessage.success("转移设备功能");
break;
case "batch":
ElMessage.success("批量操作功能");
break;
}
};
</script>
<style scoped lang="scss">
.device-detail {
min-height: calc(100vh - 84px);
padding: 20px;
background: #f5f7fa;
.device-header {
padding: 20px;
margin-bottom: 20px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
.device-info {
display: flex;
gap: 20px;
margin-bottom: 20px;
.device-image {
width: 120px;
height: 240px;
object-fit: cover;
background: #f5f7fa;
border-radius: 8px;
}
.info-content {
flex: 1;
.info-row {
display: flex;
gap: 12px;
align-items: center;
margin-bottom: 16px;
.device-name {
font-size: 20px;
font-weight: 600;
color: #303133;
}
}
.info-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
.info-item {
display: flex;
align-items: center;
.label {
min-width: 80px;
font-size: 13px;
color: #909399;
}
.value {
font-size: 13px;
color: #303133;
}
}
}
}
}
.action-buttons {
display: flex;
gap: 12px;
align-items: center;
padding-top: 16px;
border-top: 1px solid #ebeef5;
.secondary-actions {
display: flex;
gap: 8px;
align-items: center;
margin-left: auto;
}
}
}
.tabs-container {
padding: 20px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
.device-tabs {
:deep(.el-tabs__header) {
margin-bottom: 20px;
}
:deep(.el-tabs__content) {
padding-top: 0;
}
}
.tab-content {
.info-section {
margin-bottom: 24px;
&:last-child {
margin-bottom: 0;
}
.section-title {
display: inline-block;
padding-bottom: 8px;
margin-bottom: 16px;
font-size: 16px;
font-weight: 600;
color: #303133;
border-bottom: 2px solid #409eff;
}
}
}
}
}
</style>