From 0b2008314be7ab3d1f0c59aa7ce2a21468a08c7b Mon Sep 17 00:00:00 2001
From: linwe <872216996@qq.com>
Date: Sat, 12 Oct 2024 16:39:43 +0800
Subject: [PATCH] 新增设备管理

---
 src/api/device/workspaces.js   |   50 +++++
 src/views/device/addDevice.vue |  525 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 575 insertions(+), 0 deletions(-)

diff --git a/src/api/device/workspaces.js b/src/api/device/workspaces.js
new file mode 100644
index 0000000..c4f72ce
--- /dev/null
+++ b/src/api/device/workspaces.js
@@ -0,0 +1,50 @@
+import request from '@/axios';
+
+export const getList = (current, size, params) => {
+    return request({
+        url: '/drone-yw/manage/api/v1/workspaces/page',
+        method: 'get',
+        params: {
+            ...params,
+            current,
+            size,
+        },
+    });
+};
+
+export const remove = ids => {
+    return request({
+        url: '/drone-yw/manage/api/v1/workspaces/delete',
+        method: 'post',
+        params: {
+            ids,
+        },
+    });
+};
+
+export const add = row => {
+    return request({
+        url: '/drone-yw/manage/api/v1/workspaces/add',
+        method: 'post',
+        data: row,
+    });
+};
+
+export const update = row => {
+    return request({
+        url: '/drone-yw/manage/api/v1/workspaces/update',
+        method: 'post',
+        data: row,
+    });
+};
+
+
+export const getDetail = id => {
+    return request({
+        url: '/drone-yw/manage/api/v1/workspaces/selectById',
+        method: 'get',
+        params: {
+            id,
+        },
+    });
+};
diff --git a/src/views/device/addDevice.vue b/src/views/device/addDevice.vue
new file mode 100644
index 0000000..430cdeb
--- /dev/null
+++ b/src/views/device/addDevice.vue
@@ -0,0 +1,525 @@
+<template>
+    <basic-container>
+        <avue-crud :option="option" :table-loading="loading" :data="data" v-model:page="page" ref="crud" @row-del="rowDel"
+            v-model="form" :permission="permissionList" @row-update="rowUpdate" @row-save="rowSave"
+            :before-open="beforeOpen" @search-change="searchChange" @search-reset="searchReset"
+            @selection-change="selectionChange" @current-change="currentChange" @size-change="sizeChange"
+            @refresh-change="refreshChange" @on-load="onLoad" @tree-load="treeLoad">
+
+            <template #menu="scope">
+                <el-button type="primary" text icon="el-icon-plus" @click.stop="copyInfo(scope.row, scope.index)"
+                    v-if="userInfo.role_name.includes('admin')">复制信息
+                </el-button>
+            </template>
+        </avue-crud>
+    </basic-container>
+</template>
+  
+<script>
+import {
+    getList,
+    remove,
+    update,
+    add,
+    getDetail,
+} from '@/api/device/workspaces';
+
+import { getLazyTree } from '@/api/base/region';
+
+import { mapGetters } from 'vuex';
+import { getWebsocketUrl } from '@/websocket/util/config';
+import ConnectWebSocket from '@/websocket';
+import { $Clipboard } from "@smallwei/avue";
+
+export default {
+    components: {
+    },
+
+    data() {
+        return {
+            // 用于记录已经创建的websocket,防止重复创建
+            webSocketIdSet: new Set(),
+            // 用于保存多组websocket
+            websocketMap: new Map(),
+            scheduleNum: 0,
+            webSocket: '',
+            devicePerShareVisible: false,
+            remoteDebuggingShow: false,
+            curDeviceInfo: {},
+            firmwareManageVisible: false,
+            percentageNum: 0,
+            firmwareBox: false,
+            firmwareInfo: {},
+            form: {},
+            query: {},
+            firmwareVersion: '',
+            loading: true,
+            page: {
+                pageSize: 10,
+                currentPage: 1,
+                total: 0,
+            },
+            selectionList: [],
+            option: {
+                lazy: true,
+                tree: true,
+                height: '460',
+                calcHeight: 32,
+                dialogWidth: 1050,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 6,
+                border: true,
+                index: true,
+                viewBtn: true,
+                selection: false,
+                excelBtn: false,
+                addBtn: true,
+                dialogClickModal: false,
+                grid: false,
+                column: [
+                    {
+                        label: '工作空间名称',
+                        prop: 'workspace_name',
+                        editDisabled: true,
+                        searchLabelWidth: 130,
+                        search: true,
+                        // searchSpan: 4,
+                        labelWidth: 130,
+                        rules: [
+                            {
+                                required: true,
+                                message: '请输入工作空间名称',
+                                trigger: 'blur',
+                            },
+                        ],
+                    },
+                    {
+                        label: '工作空间描述',
+                        prop: 'workspace_desc',
+                        labelWidth: 130,
+                        // search: true,
+                        searchSpan: 4,
+                        // editDisabled: true,
+                        rules: [
+                            {
+                                required: true,
+                                message: '请输入工作空间描述',
+                                trigger: 'blur',
+                            },
+                        ],
+                    },
+                    {
+                        label: '平台名称',
+                        prop: 'platform_name',
+                        labelWidth: 130,
+                        editDisabled: true,
+                        rules: [
+                            {
+                                required: false,
+                                message: '请输入平台名称',
+                                trigger: 'blur',
+                            },
+                        ],
+                    },
+
+                    {
+                        label: '所属单位',
+                        prop: 'dept_id',
+                        type: 'tree',
+                        defaultExpandAll: true,
+                        labelWidth: 130,
+                        dicUrl: '/blade-system/dept/getTree',
+                        props: {
+                            label: 'name',
+                            value: 'id',
+                        },
+                        rules: [
+                            {
+                                required: true,
+                                message: '请输入所属单位',
+                                trigger: 'blur',
+                            },
+                        ],
+                    },
+                    {
+                        label: '绑定编号',
+                        prop: 'bind_code',
+                        labelWidth: 130,
+                        editDisabled: true,
+                        rules: [
+                            {
+                                required: false,
+                                message: '请输入绑定编号',
+                                trigger: 'blur',
+                            },
+                        ],
+                    },
+                    {
+                        label: '创建时间',
+                        prop: 'create_time',
+                        addDisplay: false,
+                        editDisplay: false,
+                        type: 'date',
+                        labelWidth: 130,
+                        width: 160,
+                        format: 'YYYY-MM-DD HH:mm:ss',
+
+                    },
+
+                ],
+            },
+            data: [],
+            DeviceFirmwareTypeEnum: {
+                // 普通升级
+                ToUpgraded: 3,
+                // 一致性升级
+                ConsistencyUpgrade: 2,
+            },
+            DeviceFirmwareStatusEnum: {
+                None: 1, // 无需升级
+                ToUpgraded: 2, // 待升级
+                ConsistencyUpgrade: 3, // 一致性升级
+                DuringUpgrade: 4, // 升级中
+            },
+        };
+    },
+    computed: {
+        ...mapGetters(['userInfo', 'permission']),
+        permissionList() {
+            return {
+                addBtn: this.validData(this.permission.airport_add, false),
+                viewBtn: this.validData(this.permission.airport_view, true),
+                delBtn: this.validData(this.permission.airport_delete, false),
+                editBtn: this.validData(this.permission.airport_edit, false),
+            };
+        },
+        ids() {
+            let ids = [];
+            this.selectionList.forEach(ele => {
+                ids.push(ele.id);
+            });
+            return ids.join(',');
+        },
+    },
+    destroyed() {
+        this.websocketMap.forEach((k, v) => {
+            if (null != v) {
+                v.close()
+                this.websocketMap.delete(k)
+                this.webSocketIdSet.delete(k)
+            }
+        });
+    },
+    methods: {
+
+        copyInfo(row, index) {
+            let params = `host: tcp://139.196.74.78:1883   账号:drone  密码:123456  组织id:${row.bing_id}  设备码:${row.bind_code}  机场名称:${row.workspace_name}   aircrattName:${row.workspace_desc}`;
+            $Clipboard({
+                text: params,
+            }).then(() => {
+                this.$message.success("复制成功");
+            }).catch(() => {
+                this.$message.error("复制失败");
+            });
+        },
+
+        // 关闭所有的webscoket
+        closeAllWebsoket() {
+            this.websocketMap.forEach((k, v) => {
+                if (null != v) {
+                    v.close()
+                    this.websocketMap.delete(k)
+                    this.webSocketIdSet.delete(k)
+                }
+            });
+        },
+        // 连接webSocket
+        connectWebSocket(data) {
+            const webSocketId = data.workspace_id
+            if (!this.webSocketIdSet.has(webSocketId)) {
+                // 防止重复连接
+                this.webSocketIdSet.add(webSocketId);
+                const webSorketUrl = getWebsocketUrl() + '&workspace-id=' + data.workspace_id;
+                // 监听ws 消息
+                this.useConnectWebSocket(webSocketId, webSorketUrl);
+            }
+        },
+        useConnectWebSocket(webSocketId, url) {
+            const websocket = new ConnectWebSocket(url);
+            // 加入 webscoket map
+            this.websocketMap.set(webSocketId, websocket)
+            websocket?.registerMessageHandler(this.messageHandler);
+            websocket?.initSocket();
+        },
+        async messageHandler(payload) {
+            console.log(payload, 7777);
+
+            if (!payload) {
+                return;
+            }
+            if (payload.biz_code != "ota_progress") {
+                return;
+            }
+            var data = payload.data;
+            this.data.forEach(e => {
+                if (e.device_sn == data.sn && data.output.status == 'in_progress') {
+                    e.firmware_progress = data.output.progress.percent;
+                }
+
+                if (e.device_sn == data.sn && data.output.status == 'ok') {
+                    // 升级完成修改状态
+                    e.firmware_status = 1
+                    const webscoket = this.websocketMap.get(e.workspace_id);
+                    // 关闭
+                    webscoket?.close();
+                    //删除对应的webscoket
+                    this.websocketMap.delete(e.workspace_id);
+                    this.webSocketIdSet.delete(e.workspace_id);
+                }
+            });
+        },
+        init() {
+            this.onLoad(this.page);
+        },
+        // 打开权限分享页面
+        handleOpenDevicePerShare(row) {
+            var that = this;
+            this.devicePerShareVisible = true;
+            this.$nextTick(() => {
+                that.$refs.devicePerShare.init(row);
+            });
+        },
+
+        handleOpenRemoteDebugging(row) {
+            this.curDeviceInfo = row;
+            this.remoteDebuggingShow = true;
+        },
+
+        // 打开固件管理页面
+        handleOpenFirmwarm(row) {
+            var that = this;
+            this.firmwareManageVisible = true;
+            this.$nextTick(() => {
+                that.$refs.firmwareManage.init(row);
+            });
+        },
+        // 升级固件按钮事件
+        updateFirmware(row) {
+            if (row.status == 0) {
+                this.$message({
+                    type: 'warning',
+                    message: '设备不在线!',
+                });
+                return;
+            }
+            var that = this;
+            this.firmwareBox = true;
+            const param = {
+                device_name: row.device_name,
+            };
+            // 获取固件最新版本信息
+            getDeviceUpgradeInfo(param).then(res => {
+                const data = res.data.data;
+                if (data.length === 0) {
+                    return;
+                }
+                that.firmwareVersion = data[0].product_version;
+                that.firmwareInfo['device_name'] = row.device_name;
+                that.firmwareInfo['sn'] = row.device_sn;
+                that.firmwareInfo['product_version'] = data[0].product_version;
+                // 1-普通升级,2-一致性升级;
+                that.firmwareInfo['firmware_upgrade_type'] =
+                    row.firmware_status === that.DeviceFirmwareStatusEnum.ToUpgraded
+                        ? that.DeviceFirmwareTypeEnum.ToUpgraded
+                        : that.DeviceFirmwareTypeEnum.ConsistencyUpgrade;
+                that.firmwareInfo['workspaceId'] = row.workspace_id;
+            });
+        },
+        // 确定升级固件版本
+        updateFirmwareConfirm() {
+            var that = this;
+            var arr = [];
+            arr.push(that.firmwareInfo);
+            ota(that.firmwareInfo.workspaceId, arr).then(res => {
+                that.firmwareVersion = '';
+                that.firmwareInfo = {};
+                that.firmwareBox = false;
+                this.$message({
+                    type: 'success',
+                    message: '操作成功!',
+                });
+                this.onLoad(this.page);
+                done();
+            });
+        },
+        rowSave(row, done, loading) {
+            add(row).then(
+                () => {
+                    this.onLoad(this.page);
+                    this.$message({
+                        type: 'success',
+                        message: '操作成功!',
+                    });
+                    done();
+                },
+                error => {
+                    window.console.log(error);
+                    loading();
+                }
+            );
+        },
+        rowUpdate(row, index, done, loading) {
+            update(row).then(
+                () => {
+                    this.onLoad(this.page);
+                    this.$message({
+                        type: 'success',
+                        message: '操作成功!',
+                    });
+                    done();
+                },
+                error => {
+                    window.console.log(error);
+                    loading();
+                }
+            );
+        },
+        rowDel(row) {
+            this.$confirm('确定将选择数据删除?', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+            })
+                .then(() => {
+                    return remove(row.id);
+                })
+                .then(() => {
+                    this.onLoad(this.page);
+                    this.$message({
+                        type: 'success',
+                        message: '操作成功!',
+                    });
+                });
+        },
+        searchReset() {
+            this.query = {};
+            this.onLoad(this.page);
+        },
+        searchChange(params, done) {
+            this.query = params;
+            this.page.currentPage = 1;
+            this.onLoad(this.page, params);
+            done();
+        },
+        selectionChange(list) {
+            this.selectionList = list;
+        },
+        selectionClear() {
+            this.selectionList = [];
+            this.$refs.crud.toggleSelection();
+        },
+        handleDelete() {
+            if (this.selectionList.length === 0) {
+                this.$message.warning('请选择至少一条数据');
+                return;
+            }
+            this.$confirm('确定将选择数据删除?', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+            })
+                .then(() => {
+                    return remove(this.ids);
+                })
+                .then(() => {
+                    this.onLoad(this.page);
+                    this.$message({
+                        type: 'success',
+                        message: '操作成功!',
+                    });
+                    this.$refs.crud.toggleSelection();
+                });
+        },
+        beforeOpen(done, type) {
+            if (['edit', 'view'].includes(type)) {
+                getDetail(this.form.id).then(res => {
+                    this.form = res.data.data;
+                });
+            }
+            done();
+        },
+        currentChange(currentPage) {
+            this.page.currentPage = currentPage;
+        },
+        sizeChange(pageSize) {
+            this.page.pageSize = pageSize;
+        },
+        refreshChange() {
+            this.onLoad(this.page, this.query);
+        },
+        onLoad(page, params = {}) {
+            this.closeAllWebsoket()
+            const { releaseTimeRange } = this.query;
+            let values = {
+                ...params,
+                ...this.query,
+            };
+            if (releaseTimeRange) {
+                values = {
+                    ...values,
+                    releaseTime_datege: releaseTimeRange[0],
+                    releaseTime_datelt: releaseTimeRange[1],
+                };
+                values.releaseTimeRange = null;
+            }
+            values['type'] = 1;
+            this.loading = true;
+            getList(page.currentPage, page.pageSize, values).then(res => {
+                const data = res.data.data;
+                this.page.total = data.total;
+                data.records.forEach(e => {
+                    e['hasChildren'] = e.has_children;
+                    if (e.firmware_status == 4) {
+                        this.connectWebSocket(e);
+                    }
+                });
+                this.data = data.records;
+                this.loading = false;
+                this.selectionClear();
+            });
+        },
+        treeLoad(tree, treeNode, resolve) {
+            var params = {
+                childSn: tree.child_sn,
+            };
+            getList(1, 10, params).then(res => {
+                const data = res.data.data.records;
+                resolve(data);
+            });
+        },
+    },
+};
+</script>
+  
+<style lang="scss" scoped>
+.firmware_status {
+    background-color: aqua;
+    border-radius: 4px;
+}
+
+.firmware_status:hover {
+    cursor: pointer;
+    /* color: aqua; */
+}
+
+.active-element {
+    cursor: pointer;
+
+    &:hover {
+        background-color: #409eff;
+        border-color: #409eff;
+    }
+}
+</style>
+  
\ No newline at end of file

--
Gitblit v1.9.3