Переглянути джерело

Merge branch 'lining' of http://61.161.152.110:10101/r/electronic-map into yx

Koishi 3 роки тому
батько
коміт
56e4c9899a

+ 289 - 0
src/api/api.js

@@ -0,0 +1,289 @@
+import request from './zmaxios.js'
+
+
+//获取服务端公钥
+export const getPublickey = query => {
+        return request.get(`/info/publickey`);
+    }
+    // login
+export const loginRequest = params => {
+    return request.post("/user/login", params);
+};
+//register
+export const registerRequest = params => {
+    return request.post("/user/register", params);
+};
+// ----------------------------------------user------------------------------------------------
+export const getUserList = () => {
+    return request.get(`/user/get`);
+}
+export const editRequest = params => {
+    return request.post("/user/edit", params);
+};
+export const deleteUser = data => {
+        return request.delete(`/user/${data}`);
+    }
+    // ----------------------------------------user------------------------------------------------
+
+
+//获取所有风场
+export const fetchStationList = () => {
+    return request({
+        url: '/' + 'info/station',
+        method: 'get'
+    });
+};
+//根据风场id获取所有风机
+export const fetchWindturbineList = query => {
+    return request({
+        url: '/' + 'info/windturbine',
+        method: 'get',
+        params: {
+            stationId: query
+        }
+    });
+};
+// ----------------------------------------基础数据- 设备管理------------------------------------------------
+//查询全部设备型号接口
+export const device_list = () => {
+        return request.get(`/device/model/list`);
+    }
+    //获取结构tree
+export function tree(params) {
+    return request({
+        url: '/device/structure/tree/windturbine',
+        method: 'get',
+    });
+}
+//根据结构获取测点
+export function point(params) {
+    return request({
+        url: `/device/metrics/windturbine/${params}`,
+        method: 'get',
+    });
+}
+//测点新增
+export function metrics(params) {
+    return request.post(`/device/metrics/single`, params);
+}
+//测点删除
+export function delmetrics(params) {
+    return request.delete(`/device/metrics/single/delete/${params}`);
+}
+
+//tree新增 添加一个设备结构节点
+export function treeAdd(params) {
+    return request.post(`/device/structure`, params);
+}
+//tree删除 tree删除一个设备结构节点
+export function treeDel(params) {
+    return request.delete(`/device/structure/delete/${params}`);
+}
+
+
+// 故障模式
+// get All
+export const faultmode_windturbine = () => {
+        return request.get(`/device/faultmode/windturbine`);
+    }
+    // 根据 structurecode get
+export const faultmode_structurecode = params => {
+        return request.get(`/device/faultmode/windturbine/${params}`);
+    }
+    // 根据 id delete
+export const faultmode_delete = params => {
+    return request.delete(`/device/faultmode/delete/${params}`);
+}
+
+// 新增 修改
+export const faultmode_add_edit = data => {
+    return request.post(`/device/faultmode`, data);
+}
+
+// ----------------------------------------end 基础数据- 风机管理------------------------------------------------
+
+
+// ---------------------------------------- 报警配置- 自定义预警------------------------------------------------
+export function custombj_fetchTableData(params) {
+    return request.get(`/alertrule2/page/`, {
+        params: params
+    });
+}
+
+//根据场站编号,风机型号获取AI测点
+export const fetchAIPointList = (stationId, modelId) => {
+    return request({
+        url: '/' + 'info/testing_point_ai',
+        method: 'get',
+        params: {
+            stationId: stationId,
+            modelId: modelId
+        }
+    });
+};
+//根据场站编号,风机型号获取DI测点
+export const fetchDIPointList = (stationId, modelId) => {
+    return request({
+        url: '/' + 'info/testing_point_di',
+        method: 'get',
+        params: {
+            stationId: stationId,
+            modelId: modelId
+        }
+    });
+};
+//根据场站编号,获取电气DI测点
+export const fetchElectricDIPointList = (stationId) => {
+    return request({
+        url: '/' + 'info/electrical_point_di',
+        method: 'get',
+        params: {
+            stationId: stationId
+        }
+    });
+};
+//根据电气测点,获取测点信息
+export const fetchElectricDIPointByPointId = (pointId) => {
+    return request({
+        url: '/' + 'info/electrical_point_di/byId',
+        method: 'get',
+        params: {
+            pointId: pointId
+        }
+    });
+};
+
+//获取风机关联部件列表
+export const fetchRelatePart = () => {
+    return request({
+        url: '/' + 'info/windturbine_parts',
+        method: 'get',
+    });
+};
+//根据风场编号获取电气AI测点
+export const fetch_electrical_point_ai = (stationId) => {
+    return request({
+        url: '/' + 'info/electrical_point_ai',
+        method: 'get',
+        params: {
+            stationId: stationId
+        }
+    });
+};
+//根据风场编号获取电气DI测点
+export const fetch_electrical_point_di = (stationId) => {
+    return request({
+        url: '/' + 'info/electrical_point_di',
+        method: 'get',
+        params: {
+            stationId: stationId
+        }
+    });
+};
+//获取报警类型
+export const fetchWarningType = () => {
+    return request({
+        url: '/' + 'info/warning_type',
+        method: 'get',
+    });
+};
+//获取报警种类
+export const fetchWarningClassify = () => {
+    return request({
+        url: '/' + 'info/warning_classify',
+        method: 'get',
+    });
+};
+export const custombj_batchImport = list => {
+    return Axrequestios.post('/' + "alertrule2/save-batch", list);
+};
+export const custombj_postSave = form => {
+    return request.post('/' + "alertrule2/save", form)
+};
+
+//******************************end****************************************//
+
+
+//******************************升压站报警************************************//
+
+export const scadabj_fetchTableData = query => {
+    return request({
+        url: '/' + 'scadabj/page',
+        method: 'get',
+        params: query,
+        timeout: 20000,
+    });
+};
+export const scadabj_postSave = objData => {
+    return request.post('/' + "scadabj/save", objData);
+};
+export const scadabj_batchImport = list => {
+    return request.post('/' + "scadabj/save-batch", list);
+};
+//********************************************end********************************//\
+
+
+
+//******************************风机报警************************************//
+export const windturbinebj_fetchTableData = query => {
+    return request({
+        url: '/' + 'warning2/page',
+        method: 'get',
+        params: query,
+        timeout: 20000,
+    });
+};
+export const windturbinebj_postSave = form => {
+    return Axios.post('/' + 'warning2/save', form);
+};
+export const windturbinebj_batchImport = list => {
+    return Axios.post('/' + "warning2/save-batch", list);
+};
+
+export const fetchLeaf = () => {
+    return request({
+        url: '/' + 'warning2/page',
+        method: 'get',
+        params: {
+            pagenum: 1,
+            pagesize: 10000,
+            isLeaf: 0,
+        }
+    });
+};
+
+
+//根据风机型号获取DI测点统一编码相关数据 testingpointdi2
+export const getDIPointByModelId = query => {
+    return request({
+        url: '/' + 'info/testing_point_di',
+        method: 'get',
+        params: query
+    });
+};
+
+//******************************end*******************************************// 
+//******************************预警统计*******************************************//
+export const statistics_querymap = params => {
+    return request.get(`/alarm/count/querymap`, { params: params })
+        // return request.get(`/alarm/count/querymap?stationid=XS_FDC&datebegin=2021-10-12&dateend=2021-11-13`)
+};
+export const statistics_querybyname = params => {
+    return request.get('/alarm/count/querybyname', { params: params })
+};
+export const statistics_lineandproject = params => {
+    return request.get('/alarm/count/lineandproject', { params: params })
+};
+//******************************end*******************************************//
+
+//******************************预警分析*******************************************//
+export const warning_query_new = params => {
+    return request.get(`/alarm/count/query/new`, { params: params })
+};
+export const warning_detail = params => {
+    return request.get('/analysis/detail', { params: params })
+};
+// export const statistics_lineandproject = params => {
+//     return request.get('/alarm/count/lineandproject', { params: params })
+// };
+//******************************end*******************************************//

+ 61 - 0
src/api/zmaxios.js

@@ -0,0 +1,61 @@
+import axios from 'axios';
+import { ElMessage, ElMessageBox } from 'element-plus';
+
+// 配置新建一个 axios 实例
+const service = axios.create({
+    baseURL: 'http://192.168.1.14:8075',
+    timeout: 50000,
+    headers: { 'Content-Type': 'application/json' },
+});
+
+// 添加请求拦截器
+service.interceptors.request.use(
+    (config) => {
+        // 在发送请求之前做些什么 token
+        let token = sessionStorage.getItem('token')
+        if (token) {
+            config.headers.common['token'] = token;
+        }
+        return config
+    },
+    (error) => {
+        // 对请求错误做些什么
+        return Promise.reject(error);
+    }
+);
+
+// 添加响应拦截器
+service.interceptors.response.use(
+    (response) => {
+        // 对响应数据做点什么
+        const res = response.data;
+        if (res.code && res.code !== 0 && res.code == !200) {
+            // `token` 过期或者账号已在别处登录
+            if (res.code === 401 || res.code === 4001) {
+                localStorage.clear(); // 清除浏览器全部临时缓存
+                window.location.href = '/'; // 去登录页
+                ElMessageBox.alert('你已被登出,请重新登录', '提示', {})
+                    .then(() => {})
+                    .catch(() => {});
+            }
+            return Promise.reject(service.interceptors.response);
+        } else {
+            return response.data;
+        }
+    },
+    (error) => {
+        // 对响应错误做点什么
+        if (error.message.indexOf('timeout') != -1) {
+            ElMessage.error('网络超时');
+        } else if (error.message == 'Network Error') {
+            ElMessage.error('网络连接错误');
+        } else {
+            if (error.response.data) ElMessage.error(error.response.statusText);
+            else ElMessage.error('接口路径找不到');
+        }
+        return Promise.reject(error);
+    }
+);
+
+// 导出 axios 实例
+export default service;

+ 7 - 0
src/router/index.js

@@ -880,7 +880,14 @@ const routes = [{
 	name: 'knowledge7',
 	component: () =>
 		import('../views/Knowledge/Knowledge7.vue'),
+},
+{
+	path: '/device/device', //设备管理
+	name: 'device',
+	component: () =>
+		import('../views/device/device.vue'),
 }
+
 	/***********************************************************其他************************************************************ */
 	,
 {

+ 705 - 0
src/views/device/device.vue

@@ -0,0 +1,705 @@
+<template>
+  <div class="main deviceClass">
+    <el-card class="box-card-tree">
+      <button  class="btn green" style="margin-bottom:10px" @click="handleTreeAdd()"
+        >新增</button
+      >
+      <button
+        class="btn green"
+        @click="handleTreeDel()"
+        :disabled="state.isDel == ''"
+        >删除</button
+      >
+      <el-tree
+        :data="state.treedata"
+        :props="state.defaultProps"
+        node-key="id"
+        highlight-current
+        :default-expanded-keys="['23']"
+        @node-click="handleNodeClick"
+      />
+    </el-card>
+    <el-card class="box-card">
+      <el-tabs type="card" class="tab">
+        <el-tab-pane label="传感点">
+          <el-row :gutter="24" align="middle">
+            <el-col :span="2">
+              <button
+                 class="btn green"
+                style="margin-bottom: 10px"
+                @click="handleEdit(state.addFormData)"
+                :disabled='state.desc.code==""'
+                >新增</button
+              ></el-col
+            >
+            <el-col :span="5">
+              <el-input
+                v-model="state.SearchVal"
+                placeholder="筛选"
+                :prefix-icon="Search"
+                @input="fifterSearch()"
+                size="small"
+              />
+            </el-col>
+          </el-row>
+          <el-table
+            :data="state.fifterSearchTableData"
+            stripe
+            style="width: 100%"
+            height="700"
+          >
+            <el-table-column type="index" width="50" />
+            <el-table-column
+              prop="metriccode"
+              label="测点编码"
+            ></el-table-column>
+            <el-table-column label="名称">
+              <template #default="scope">
+                <el-popover placement="right" :width="260" trigger="click">
+                  <template #reference>
+                    <el-button type="text" style="color: #B3BDC0" size="small">{{
+                      scope.row.name
+                    }}</el-button>
+                  </template>
+                  <el-table :data="scope.row.deviceModelMetrics" max-height="400px">
+                    <el-table-column
+                      property="devicemodel"
+                      label="机型"
+                      align="center"
+                    ></el-table-column>
+                    <el-table-column
+                      property="uniformcode"
+                      label="统一编码"
+                      align="center"
+                    ></el-table-column>
+                    <el-table-column
+                      property="multiplier"
+                      label="倍率"
+                      align="center"
+                    ></el-table-column>
+                  </el-table>
+                </el-popover>
+              </template>
+            </el-table-column>
+
+            <el-table-column prop="unitname" label="单位"></el-table-column>
+            <el-table-column
+              prop="categorydata"
+              label="测点类型"
+            ></el-table-column>
+            <el-table-column
+              prop="categorysci"
+              label="物理类型"
+            ></el-table-column>
+            <el-table-column prop="description" label="描述"></el-table-column>
+            <el-table-column label="操作" width="180" align="center">
+              <template #default="scope">
+                <el-button
+                  type="text"
+                  style="color: #B3BDC0"
+                  @click="handleEdit(scope.row)"
+                  >编辑</el-button
+                >
+                <el-button
+                  type="text"
+                  style="color: #B3BDC0"
+                  @click="handleDelete(scope.row)"
+                  >删除</el-button
+                >
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+        <el-tab-pane label="故障模式">
+          <faultmode />
+        </el-tab-pane>
+        <el-tab-pane label="基本信息" style="width: 50%">
+          <el-form :model="state.desc" label-width="100px">
+            <el-form-item label="结构编码">
+              <el-input v-model="state.desc.code"></el-input>
+            </el-form-item>
+            <el-form-item label="上级节点">
+              <el-cascader
+                v-model="state.desc.parentcode"
+                :options="state.cascaderdata"
+                :props="{ checkStrictly: true, emitPath: false }"
+                :show-all-levels="false"
+                clearable
+              />
+            </el-form-item>
+            <el-form-item label="设备ID">
+              <el-input v-model="state.desc.deviceid" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="结构名称">
+              <el-input v-model="state.desc.name"></el-input>
+            </el-form-item>
+            <el-form-item label="结构英文名称">
+              <el-input v-model="state.desc.enname"></el-input>
+            </el-form-item>
+            <el-form-item label="描述">
+              <el-input
+                v-model="state.desc.description"
+                :rows="4"
+                clearable
+                type="textarea"
+              ></el-input>
+            </el-form-item>
+            <el-form-item label="序号">
+              <el-input v-model="state.desc.orderno"></el-input>
+            </el-form-item>
+            <el-form-item label="是否有效">
+              <el-switch
+              class="elswitch"
+                v-model="state.desc.enabled"
+                active-color="#13ce66"
+                inactive-color="#ff4949"
+              />
+            </el-form-item>
+          </el-form>
+          <button
+            style="float: right"
+             class="btn green"
+            @click="savedesc"
+            :disabled="state.desc.code == ''"
+            >保存</button
+          >
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+    <!-- 传感点编辑弹出框 -->
+    <el-dialog v-model="editVisible" width="40%" custom-class="modal">
+      <el-form :model="editFormData" label-width="80px">
+        <el-form-item label="指标">
+          <el-input v-model="editFormData.metriccode"></el-input>
+        </el-form-item>
+        <el-row :gutter="24">
+          <el-col :span="12">
+            <el-form-item label="名称">
+              <el-input v-model="editFormData.name"></el-input>
+            </el-form-item>
+          </el-col>
+
+          <el-col :span="12">
+            <el-form-item label="英文名称">
+              <el-input v-model="editFormData.enname"></el-input>
+            </el-form-item> </el-col
+        ></el-row>
+        <el-row :gutter="24">
+          <el-col :span="12">
+            <el-form-item label="标准单位">
+              <el-input
+                v-model="editFormData.unitname"
+              ></el-input> </el-form-item
+          ></el-col>
+
+          <el-col :span="12">
+            <el-form-item label="单位名称">
+              <el-input v-model="editFormData.unitnamecn"></el-input>
+            </el-form-item> </el-col
+        ></el-row>
+        <el-form-item label="描述">
+          <el-input
+            v-model="editFormData.description"
+            :rows="3"
+            type="textarea"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-row :gutter="24">
+          <el-col :span="12">
+            <el-form-item label="数据类型">
+              <el-select
+                v-model="editFormData.categorydata"
+                placeholder="Select"
+              >
+                <el-option
+                  v-for="item in state.options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                ></el-option>
+              </el-select> </el-form-item
+          ></el-col>
+          <el-col :span="12">
+            <el-form-item label="结构">
+              <el-cascader
+                v-model="editFormData.structurecode"
+                :options="state.cascaderdata"
+                :props="{ checkStrictly: true ,emitPath:false}"
+                clearable
+              /> </el-form-item
+          ></el-col>
+        </el-row>
+        <el-row :gutter="24">
+          <el-col :span="12">
+            <el-form-item label="科学类型">
+              <el-input
+                v-model="editFormData.categorysci"
+              ></el-input> </el-form-item
+          ></el-col>
+          <el-col :span="12"
+            ><el-form-item label="系统分类">
+              <el-input
+                v-model="editFormData.categorysys"
+              ></el-input> </el-form-item
+          ></el-col>
+        </el-row>
+
+        <el-form-item label="适配机型" class="deviceModelClass">
+        
+          <el-select
+            v-model="state.deviceModelSel"
+            style="margin-right: 20px"
+            placeholder="新增机型"
+            size="mini"
+          >
+            <el-option
+              v-for="item in state.deviceModel"
+              :key="item.code"
+              :label="item.code"
+              :value="item.code"
+            >
+            </el-option>
+          </el-select>
+            <button  class="btn green"  v-show="state.deviceModelSel !=''" size="mini" type="primary" @click="deviceModelAdd()"
+            >新增机型</button
+          >
+          <el-table
+            :data="editFormData.deviceModelMetrics"
+            style="width: 100%"
+            max-height="200px"
+          >
+            <el-table-column prop="devicemodel" label="机型" />
+            <el-table-column  label="倍率">
+              <template #default="scope">
+                <el-input v-model="scope.row.multiplier" size="mini" />
+              </template>
+            </el-table-column>
+            <el-table-column label="统一编码">
+              <template #default="scope">
+                <el-input v-model="scope.row.uniformcode" size="mini" />
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <button  class="btn green"  @click="editVisible = false">取 消</button>
+          <button  class="btn green"  type="primary" @click="saveEdit">确 定</button>
+        </span>
+      </template>
+    </el-dialog>
+    <!-- tree add 弹出框 -->
+    <el-dialog v-model="treeVisible" width="40%"  custom-class="modal">
+      <el-form :model="state.treeAddFormData" label-width="80px">
+        <el-row :gutter="24">
+          <el-col :span="12">
+            <el-form-item label="结构编码">
+              <el-input
+                v-model="state.treeAddFormData.code"
+              ></el-input> </el-form-item
+          ></el-col>
+          <el-col :span="12">
+            <el-form-item label="上级节点" label-width="100px">
+              <el-cascader
+                v-model="state.treeAddFormData.parentcode"
+                :options="state.cascaderdata"
+                :props="{ checkStrictly: true, emitPath: false }"
+                :show-all-levels="false"
+                clearable
+              /> </el-form-item
+          ></el-col>
+        </el-row>
+        <el-row :gutter="24">
+          <el-col :span="12">
+            <el-form-item label="结构名称">
+              <el-input
+                v-model="state.treeAddFormData.name"
+              ></el-input> </el-form-item
+          ></el-col>
+          <el-col :span="12">
+            <el-form-item label="结构英文名称" label-width="100px">
+              <el-input
+                v-model="state.treeAddFormData.enname"
+              ></el-input> </el-form-item
+          ></el-col>
+        </el-row>
+        <el-row :gutter="24">
+          <el-col :span="12"
+            ><el-form-item label="序号">
+              <el-input
+                v-model="state.treeAddFormData.orderno"
+              ></el-input> </el-form-item
+          ></el-col>
+          <el-col :span="4">
+            <el-form-item label="是否有效">
+               <el-switch 
+                v-model="state.treeAddFormData.enabled"
+                 class="elswitch"
+                active-color="#13ce66"
+                inactive-color="#ff4949"
+              />
+              </el-form-item
+          ></el-col>
+          <el-col :span="8">
+            <el-form-item label="设备ID">
+              <el-input
+                v-model="state.treeAddFormData.deviceid"
+                disabled
+              ></el-input> </el-form-item
+          ></el-col>
+        </el-row>
+        <el-form-item label="描述">
+          <el-input
+            v-model="state.treeAddFormData.description"
+            :rows="4"
+            clearable
+            type="textarea"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <button  class="btn green"  @click="treeVisible = false">取 消</button>
+          <button  class="btn green"  type="primary" @click="saveTreeAdd">确 定</button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import { ref, onMounted, reactive, provide, computed } from "vue";
+import { ElMessageBox, ElMessage, ElLoading } from "element-plus";
+import faultmode from "./faultmode.vue";
+import {
+  tree,
+  point,
+  metrics,
+  delmetrics,
+  treeAdd,
+  treeDel,
+  device_list,
+} from "@/api/api.js";
+let editVisible = ref(false); //传感点
+let treeVisible = ref(false); //传感点
+let editFormData = ref({});
+onMounted(() => {
+  getData();
+  getDeviceModel();
+});
+let state = reactive({
+  isDel: "", //是否能被删除
+  SearchVal: "",
+  treedata: [],
+  cascaderdata: [],
+  defaultProps: {
+    children: "children",
+    label: (a) => {
+      return a.node.name;
+    },
+  },
+  pointTableData: [],
+  fifterSearchTableData: [],
+  textarea: "",
+  textarea1: "",
+  treeCurClick: null,
+  addFormData: {
+    categorydata: "AI",
+    categoryres1: null,
+    categoryres2: null,
+    categoryres3: null,
+    categoryres4: null,
+    categoryres5: null,
+    categorysci: null,
+    categorysys: null,
+    description: null,
+    deviceid: "windturbine",
+    enname: null,
+    id:null,
+    metriccode: "",
+    name: "",
+    structurecode: "101010205",
+    unitname: null,
+    unitnamecn: null,
+    deviceModelMetrics: [],
+  },
+  treeAddFormData: {
+    code: "",
+    parentcode: "",
+    deviceid: "windturbine",
+    name: "",
+    enname: "",
+    description: "",
+    orderno: "",
+    enabled: true,
+  },
+  options: [
+    {
+      value: "AI",
+      label: "AI",
+    },
+    {
+      value: "DI",
+      label: "DI",
+    },
+    {
+      value: "CI",
+      label: "CI",
+    },
+  ],
+  desc: {
+    code: "",
+    parentcode: "",
+    deviceid: "",
+    name: "",
+    enname: "",
+    description: "",
+    orderno: "",
+    enabled: true,
+  },
+  treeDelVal: "",
+  deviceModel: [],
+  deviceModelSel: "",
+});
+
+// 父子传参
+provide(
+  "cascaderdata",
+  computed(() => state.cascaderdata)
+);
+//fifterSearch
+const fifterSearch = () => {
+  state.fifterSearchTableData = state.pointTableData.filter((e) => {
+    return (
+      e.name.includes(state.SearchVal) |
+      e.categorydata.includes(state.SearchVal) |
+      e.metriccode.includes(state.SearchVal)
+    );
+  });
+};
+// tree click
+const handleNodeClick = (data) => {
+  console.log(data);
+  state.isDel = data.children;
+  state.desc = data.node;
+  state.addFormData.structurecode = data.node.code
+  getPoint(data.node);
+};
+// 测点 编辑
+const handleEdit = (row) => {
+  editFormData.value = row;
+  editVisible.value = true;
+};
+// tree add
+const handleTreeAdd = () => {
+  treeVisible.value = true;
+};
+// tree Del
+const handleTreeDel = () => {
+  console.warn(state.desc);
+  if (state.isDel != null) {
+    ElMessage.error(`不能删除该节点!!`);
+    return;
+  }
+  ElMessageBox.confirm(`确定要删除 ${state.desc.name} 吗?`, "提示", {
+    type: "warning",
+  })
+    .then(async () => {
+      const res = await treeDel(state.desc.id);
+      console.warn(res);
+      if (res == 1) {
+        ElMessage.success(`删除成功!`);
+        getData();
+      } else {
+        ElMessage.warning(`删除失败!`);
+      }
+    })
+    .catch(() => {});
+};
+// delTreeBtn
+const delTreeBtn = async () => {
+  console.warn(state.treeDelVal);
+  const res = await treeDel(state.treeDelVal);
+  console.warn(res);
+  if (res == 1) {
+    ElMessage.success(`删除成功!`);
+    getData();
+  } else {
+    ElMessage.warning(`删除失败!`);
+  }
+  state.treeDelVal = "";
+};
+//保存tree add
+const saveTreeAdd = async () => {
+  const res = await treeAdd(state.treeAddFormData);
+  console.warn(res);
+  if (res.status == 20000) {
+    ElMessage.success(`操作成功!`);
+    treeVisible.value = false;
+    getData();
+  } else {
+    ElMessage.warning(res.msg);
+  }
+};
+
+// 测点 删除
+const handleDelete = (row) => {
+  // 二次确认删除
+  ElMessageBox.confirm("确定要删除吗?", "提示", {
+    type: "warning",
+  })
+    .then(async () => {
+      console.warn(row);
+      const res = await delmetrics(row.id);
+      console.warn(res);
+      if (res == 1) {
+        ElMessage.success(`删除成功!`);
+      } else {
+        ElMessage.success("删除失败");
+      }
+      getPoint(state.desc);
+    })
+    .catch(() => {});
+};
+// 保存编辑
+const saveEdit = async () => {
+  postmetrics();
+};
+//测点 add
+const postmetrics = async () => {
+  console.warn(editFormData.value);
+  const res = await metrics(editFormData.value);
+  console.warn(res);
+  if (res.status == 20000) {
+    ElMessage.success(`操作成功!`);
+    editVisible.value = false;
+  } else {
+    ElMessage.success(res.msg);
+  }
+  getPoint(state.desc);
+};
+// getData
+const getData = async () => {
+  const loading = ElLoading.service({
+    lock: true,
+    text: "数据加载中...",
+    background: "rgba(0, 0, 0, 0.5)",
+  });
+  const res = await tree();
+  loading.close();
+  console.warn(res);
+  state.treedata = res.children;
+  state.cascaderdata = cascaderforEach(res);
+  console.warn(state.cascaderdata);
+};
+//deviceModelAdd 新增机型
+const deviceModelAdd = async () => {
+  if (state.deviceModelSel == "") return;
+  console.warn();
+  let obj = {
+    deviceid: editFormData.value.deviceid,
+    devicemodel: state.deviceModelSel,
+    id: null,
+    metriccode: editFormData.value.metriccode,
+    multiplier: 0,
+    uniformcode: "",
+  };
+  editFormData.value.deviceModelMetrics.push(obj);
+};
+//getDeviceModel
+const getDeviceModel = async () => {
+  const res = await device_list();
+  state.deviceModel = res;
+  console.warn(res);
+};
+///// 基本信息
+
+const savedesc = async () => {
+  const res = await treeAdd(state.desc);
+  console.warn(res);
+  if (res.status == 20000) {
+    ElMessage.success(`操作成功!`);
+  } else {
+    ElMessage.success(res.msg);
+  }
+};
+
+///// 基本信息
+// getPoint
+const getPoint = async (node) => {
+  const res = await point(node.code);
+  console.warn(res);
+  state.pointTableData = res;
+  fifterSearch();
+};
+// 递归解析基础数据
+const cascaderforEach = (val) => {
+  if (val.children != null) {
+    val.children.forEach((v) => {
+      v["value"] = v.node.code;
+      v["label"] = v.node.name;
+      v["id"] = v.node.id;
+      cascaderforEach(v);
+    });
+    return val.children;
+  }
+};
+</script>
+<style lang="scss" scoped>
+.main {
+  display: flex;
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+  justify-content: space-between;
+  .box-card-tree {
+    width: 20%;
+    margin-right: 1%;
+    overflow: auto;
+  }
+  .box-card {
+    flex: 1;
+    .desc {
+      display: flex;
+      margin-bottom: 30px;
+      span {
+        width: 100px;
+      }
+    }
+  }
+}
+</style>
+<style lang="less" >
+
+.deviceModelClass {
+  .el-table__header tr,
+  .el-table__header th {
+    padding: 0;
+    height: 40px;
+  }
+  .el-table__body tr,
+  .el-table__body td {
+    padding: 0;
+    height: 40px;
+  }
+}
+.tab{
+  .el-tabs__item.is-active{
+    color:@green;
+  }
+  .el-tabs__item{
+      color: #b7b7b7;
+  }
+}
+.elswitch{
+.el-switch__input{
+    position: absolute!important;
+}
+}
+.deviceClass{
+  .el-row{
+    margin-bottom: 16px;
+  }
+}
+</style>

+ 262 - 0
src/views/device/faultmode.vue

@@ -0,0 +1,262 @@
+<template>
+  <div style="display: block">
+    <button
+       class="btn green"
+      style="margin-bottom: 10px"
+      @click="handleEdit(state.addFormData)"
+      >新增</button
+    >
+    <el-table
+      :data="state.faultmodeTableData"
+      stripe
+      style="width: 100%"
+      height="700"
+    >
+      <el-table-column type="index" width="50" />
+      <el-table-column prop="name" label="名称"></el-table-column>
+      <el-table-column prop="code" label="故障编码"></el-table-column>
+      <el-table-column label="频度" width="50">
+        <template #default="scope">
+          {{ rank(scope.row.occurence) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="严酷度" width="70">
+        <template #default="scope">
+          {{ rank(scope.row.severity) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="难检度" width="70">
+        <template #default="scope" >
+          {{ rank(scope.row.detection) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="cause" label="原因"></el-table-column>
+      <el-table-column prop="effects" label="导致结果"></el-table-column>
+      <el-table-column prop="measure" label="处理方法"></el-table-column>
+      <el-table-column label="操作" width="180" align="center">
+        <template #default="scope">
+          <el-button
+            type="text"
+                  style="color: #B3BDC0"
+            @click="handleEdit(scope.row)"
+            >编辑</el-button
+          >
+          <el-button
+            type="text"
+                  style="color: #B3BDC0"
+            @click="handleDelete(scope.row)"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 传感点编辑弹出框 -->
+    <el-dialog v-model="editVisible" width="40%"  custom-class="modal">
+      <el-form :model="editFormData" label-width="80px">
+        <el-form-item label="故障编码">
+          <el-input v-model="editFormData.code"></el-input>
+        </el-form-item>
+        <el-form-item label="名称">
+          <el-input v-model="editFormData.name"></el-input>
+        </el-form-item>
+        <el-form-item label="导致结果">
+          <el-input
+            v-model="editFormData.effects"
+            :rows="2"
+            clearable
+            type="textarea"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="原因">
+          <el-input
+            v-model="editFormData.cause"
+            :rows="2"
+            clearable
+            type="textarea"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="处理方法">
+          <el-input
+            v-model="editFormData.measure"
+            :rows="3"
+            clearable
+            type="textarea"
+          ></el-input>
+        </el-form-item>
+        <el-row :gutter="24">
+          <el-col :span="12">
+            <el-form-item label="严酷度">
+              <el-select v-model="editFormData.severity">
+                <el-option
+                  v-for="item in selectOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="频度">
+              <el-select v-model="editFormData.occurence">
+                <el-option
+                  v-for="item in selectOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option
+              ></el-select> </el-form-item
+          ></el-col>
+        </el-row>
+        <el-row :gutter="24">
+          <el-col :span="12"
+            ><el-form-item label="难检度">
+              <el-select v-model="editFormData.detection">
+                <el-option
+                  v-for="item in selectOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option
+              ></el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="结构">
+              <el-cascader
+                v-model="editFormData.structurecode"
+                :options="cascaderdata"
+                :props="{ checkStrictly: true }"
+                clearable
+              /> </el-form-item
+          ></el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <button   class="btn green" @click="editVisible = false">取 消</button>
+          <button   class="btn green" type="primary" @click="saveEdit">确 定</button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import { ref, onMounted, reactive, inject, warn } from "vue";
+import { ElMessageBox, ElMessage, ElLoading } from "element-plus";
+import {
+  faultmode_windturbine,
+  faultmode_structurecode,
+  faultmode_delete,
+  faultmode_add_edit,
+} from "@/api/api.js";
+let cascaderdata = inject("cascaderdata");
+console.warn(cascaderdata);
+let editVisible = ref(false);
+let editFormData = ref({});
+onMounted(() => {
+  getfaultmode();
+});
+const selectV = {
+  1: "I",
+  2: "II",
+  3: "III",
+  4: "IV",
+  5: "V",
+};
+const selectOptions = [
+  {
+    label: "I",
+    value: 1,
+  },
+  {
+    label: "II",
+    value: 2,
+  },
+  {
+    label: "III",
+    value: 3,
+  },
+  {
+    label: "IV",
+    value: 4,
+  },
+  {
+    label: "V",
+    value: 5,
+  },
+];
+const rank = (v) => {
+  return selectV[v] || "";
+};
+let state = reactive({
+  faultmodeTableData: [],
+  addFormData: {
+    code: "",
+    name: "",
+    effects: "",
+    cause: "",
+    measure: "",
+    severity: null,
+    occurence: null,
+    detection: null,
+    deviceid: "windturbine",
+    structurecode: "",
+    models: null,
+  },
+});
+// 新增 编辑
+const handleEdit = (row) => {
+  editFormData.value = row;
+  editVisible.value = true;
+};
+
+// 测点 删除
+const handleDelete = (row) => {
+  // 二次确认删除
+  ElMessageBox.confirm("确定要删除吗?", "提示", {
+    type: "warning",
+  })
+    .then(async () => {
+      console.warn(row);
+      const res = await faultmode_delete(row.id);
+      console.warn(res);
+      if (res == 1) {
+        ElMessage.success(`删除成功!`);
+      } else {
+        ElMessage.success("删除失败");
+      }
+      getfaultmode();
+    })
+    .catch(() => {});
+};
+// 保存编辑
+const saveEdit = async () => {
+  const res = await faultmode_add_edit(editFormData.value);
+  console.warn(res);
+  if (res.status == 20000) {
+    ElMessage.success(`操作成功!`);
+    editVisible.value = false;
+    getfaultmode();
+  } else {
+    ElMessage.success(res.msg);
+  }
+};
+// getData
+const getfaultmode = async () => {
+  const loading = ElLoading.service({
+    lock: true,
+    text: "数据加载中...",
+    background: "rgba(0, 0, 0, 0.5)",
+  });
+  const res = await faultmode_windturbine();
+  state.faultmodeTableData = res;
+  loading.close();
+  console.warn(res);
+};
+</script>
+<style lang="scss" scoped>
+</style>

+ 5 - 0
src/views/layout/Menu.vue

@@ -879,6 +879,11 @@ export default {
                   icon: "svg-wind-site",
                   path: "/others/ExportExcel",
                 },
+                {
+                  text: "设备管理",
+                  icon: "svg-wind-site",
+                  path: "/device/device",
+                },
               ],
             },
             {