refactor(DeviceSnDetail): 重构设备详情页面为全功能详情视图

将侧边抽屉组件完全重构为独立的设备详情页面,包含设备截图轮播、分面板设备信息、应用列表、定位信息等模块,大幅扩展信息展示和交互能力。
This commit is contained in:
TongTongStudio
2026-08-08 10:35:26 +08:00
parent 96a0b12582
commit 39936e7634
3 changed files with 1868 additions and 99 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,83 @@
<template>
<div v-loading="loading" class="device-overview">
<!-- 基础信息 -->
<el-descriptions :column="1" border size="small" title="基础信息" class="mb-4">
<el-descriptions-item label="设备型号">
{{ detailData.snModel || "-" }}
</el-descriptions-item>
<el-descriptions-item label="设备昵称">
{{ detailData.snName || "-" }}
</el-descriptions-item>
<el-descriptions-item label="手机号码">
{{ detailData.snMobile || "-" }}
</el-descriptions-item>
<el-descriptions-item label="IMEI">
{{ detailData.snImei || "-" }}
</el-descriptions-item>
<el-descriptions-item label="设备类型">
{{ detailData.deviceType || "-" }}
</el-descriptions-item>
<el-descriptions-item label="来源">
{{ detailData.source || "-" }}
</el-descriptions-item>
<el-descriptions-item label="激活时间">
{{ detailData.activationTime || "-" }}
</el-descriptions-item>
<el-descriptions-item label="最后上线">
{{ detailData.lastOnline || "-" }}
</el-descriptions-item>
<el-descriptions-item label="状态">
<el-tag :type="detailData.status === 1 ? 'success' : 'info'">
{{ detailData.status === 1 ? "启用" : "禁用" }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="在线状态">
<el-tag :type="detailData.onlineStatus === 1 ? 'success' : 'info'" effect="dark" round>
{{ detailData.onlineStatus === 1 ? "在线" : "离线" }}
</el-tag>
</el-descriptions-item>
</el-descriptions>
<el-empty v-if="!loading && !detailData.serialno" description="暂无设备详情" />
</div>
</template>
<script setup lang="ts">
import DeviceAPI from "@/api/system/device";
import type { DeviceForm } from "@/api/system/device/types";
const props = defineProps<{
serialno?: string;
}>();
const detailData = ref<DeviceForm>({} as DeviceForm);
const loading = ref(false);
watch(
() => props.serialno,
(sn) => {
if (sn) fetchDetail(sn);
},
{ immediate: true }
);
async function fetchDetail(sn: string) {
loading.value = true;
try {
detailData.value = await DeviceAPI.getFormData(sn);
} catch (e) {
console.error("获取设备详情失败", e);
detailData.value = {} as DeviceForm;
} finally {
loading.value = false;
}
}
defineExpose({ fetchDetail });
</script>
<style scoped lang="scss">
.device-overview {
padding: 4px 8px;
}
</style>

View File

@@ -81,12 +81,20 @@
@return-click="handleReturnClick"
/>
</div>
<!-- 操作列详情 - 概览抽屉样式与编辑抽屉一致 -->
<el-drawer v-model="overviewVisible" title="查看" size="500px" destroy-on-close>
<DeviceSnOverView :serialno="selectedRow?.serialno" />
<template #footer>
<el-button @click="overviewVisible = false">关闭</el-button>
</template>
</el-drawer>
</div>
</template>
<script setup lang="ts">
import DeviceAPI from "@/api/system/device";
import type { IObject, PageModalInstance } from "@/components/DeviceSn/types";
import DeviceSnOverView from "@/components/DeviceSn/DeviceSnOverView.vue";
import usePage from "@/components/DeviceSn/usePage";
import addModalConfig from "./config/add";
import contentConfig from "./config/content";
@@ -119,13 +127,14 @@ function handleToolbarClick(name: string) {
function handleReturnClick() {
dialogVisible.value = false;
overviewVisible.value = false;
}
// 表格工具
const handleOperateClick = (data: IObject) => {
if (data.name === "detail") {
// 打开设备详情抽屉,读取常用参数
handleSerialnoClick(data.row);
selectedRow.value = data.row;
overviewVisible.value = true;
} else if (data.name === "edit") {
editModalConfig.drawer = { ...editModalConfig.drawer, title: "修改" };
handleEditClick(data.row, async () => {
@@ -210,6 +219,7 @@ const handleSerialnoClick = async (row: IObject) => {
};
const dialogVisible = ref(false);
const overviewVisible = ref(false);
const selectedRow = ref<IObject>({});
onMounted(() => {