Browse Source

功能上传

SunZehao 6 months ago
parent
commit
8d94cb3abe
51 changed files with 173331 additions and 219 deletions
  1. 8 4
      .env.development
  2. 12 11
      .env.production
  3. 4 0
      package.json
  4. 2 0
      public/index.html
  5. 3 3
      src/App.vue
  6. 27 0
      src/assets/db.json
  7. BIN
      src/assets/images/indexCom/fengji.png
  8. BIN
      src/assets/images/noData.png
  9. 24 0
      src/assets/jb.json
  10. BIN
      src/assets/menuImg/tree_shuaxing.png
  11. 12 0
      src/assets/nx.json
  12. 16 0
      src/components/generatingCapacityComponent/SubmitBtn.vue
  13. 232 0
      src/components/generatingCapacityComponent/excel.vue
  14. 194 0
      src/components/generatingCapacityComponent/table.vue
  15. 491 0
      src/components/generatingCapacityComponent/tree.vue
  16. 3159 0
      src/components/generatingCapacityComponent/treeJson.json
  17. 347 0
      src/components/generatingCapacityComponent/treeStyle.vue
  18. 213 191
      src/components/headerNavSta/index.vue
  19. 1 0
      src/components/other/healthReport/index.vue
  20. 7 0
      src/main.js
  21. 60 8
      src/router/index.js
  22. 27 0
      src/tools/partten.js
  23. 121 0
      src/views/IntegratedAlarm/DetailMatrix/dataJson.json
  24. 1964 0
      src/views/IntegratedAlarm/DetailMatrix/index.vue
  25. 816 0
      src/views/IntegratedAlarm/reliability/partsTemperatureAnalyse/index.vue
  26. 396 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/barChart.json
  27. 235 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/barChart.vue
  28. 386 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/barLineChart.vue
  29. 398 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/current-scatter-chart.json
  30. 426 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/current-scatter-chart.vue
  31. 70875 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/data.json
  32. 25045 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/data.json
  33. 1 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/leaflet.canvas-markers.js
  34. 531 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/leafletMap.vue
  35. 205 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/posChart.vue
  36. 399 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateAnalysis.json
  37. 200 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateCom/chart.vue
  38. 46416 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateCom/data.json
  39. 234 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateCom/lineChart.vue
  40. 185 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateCom/scatterSingleChart.vue
  41. 1 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/stationPos.json
  42. 52 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/components/table.vue
  43. 1843 0
      src/views/economicsOperation/stationAnalyse/posAnalysis/index.vue
  44. 360 0
      src/views/economicsOperation/thematicAnalysis/windAnalysis/components/barLineChart.vue
  45. 16502 0
      src/views/economicsOperation/thematicAnalysis/windAnalysis/components/data.json
  46. 119 0
      src/views/economicsOperation/thematicAnalysis/windAnalysis/components/search.vue
  47. 90 0
      src/views/economicsOperation/thematicAnalysis/windAnalysis/components/table.vue
  48. 642 0
      src/views/economicsOperation/thematicAnalysis/windAnalysis/index.vue
  49. 39 0
      src/views/nxReport/czjbbb/index.vue
  50. 11 2
      src/views/nxReport/czzyb/index.vue
  51. 0 0
      src/views/nxReport/xmjbbb/index.vue

+ 8 - 4
.env.development

@@ -12,18 +12,22 @@ VUE_APP_DIALOG_NUM = 8
 VUE_APP_DIALOG_POINT = contextmenu
 # 智慧检修
 # VUE_APP_NEW_WISDOM=http://10.81.3.162:8170
-VUE_APP_NEW_WISDOM=http://123.60.219.66:48080
+# VUE_APP_NEW_WISDOM=http://123.60.219.66:48080
+VUE_APP_NEW_WISDOM=http://10.220.1.245:48080
 # 综合报警
-VUE_APP_ALARM=http://123.60.219.66:48080
+# VUE_APP_ALARM=http://123.60.219.66:48080
+VUE_APP_ALARM=http://10.220.1.245:48080
 # 登录
-VUE_APP_VUE_LOGIN_URL=http://123.60.219.66:48080
+# VUE_APP_VUE_LOGIN_URL=http://123.60.219.66:48080
+VUE_APP_VUE_LOGIN_URL=http://10.220.1.245:48080
 # VUE_APP_TEST=http://10.81.3.155:9002
 # VUE_APP_WS=ws://10.81.3.155:9002
 # # VUE_APP_TEST=http://192.168.1.101:9002
 
 
 # # VUE_APP_API=http://192.168.1.116:6060
-VUE_APP_API=http://120.46.128.147:6060
+# VUE_APP_API=http://120.46.128.147:6060
+VUE_APP_API=http://10.220.1.245:6060
 # # VUE_APP_API=http://192.168.1.109:6060
 
 

+ 12 - 11
.env.production

@@ -3,10 +3,10 @@
 # VUE_APP_WS='ws://123.60.223.250:48080'
 # VUE_APP_ADAPTERURL=http://123.60.223.250:48080
 
-VUE_APP_API=http://123.60.219.66:48080
-VUE_APP_TEST=http://123.60.219.66:48080
-VUE_APP_WS='ws://123.60.219.66:48080'
-VUE_APP_ADAPTERURL=http://123.60.219.66:48080
+VUE_APP_API=http://10.220.1.8:48080
+VUE_APP_TEST=http://10.220.1.8:48080
+VUE_APP_WS='ws://10.220.1.8:48080'
+VUE_APP_ADAPTERURL=http://10.220.1.8:48080
 
 
 # 趋势对比数据条数
@@ -16,15 +16,16 @@ VUE_APP_DIALOG_NUM = 8
 VUE_APP_DIALOG_POINT = contextmenu
 # 智慧检修
 # VUE_APP_NEW_WISDOM=http://10.81.3.162:8170
-# VUE_APP_NEW_WISDOM=http://123.60.223.250:48080
-VUE_APP_NEW_WISDOM=http://123.60.219.66:48080
+VUE_APP_NEW_WISDOM=http://10.220.1.8:48080
+# VUE_APP_NEW_WISDOM=http://123.60.219.66:48080
 # 综合报警
-# VUE_APP_ALARM=http://123.60.223.250:48080
-VUE_APP_ALARM=http://123.60.219.66:48080
+VUE_APP_ALARM=http://10.220.1.8:48080
+# VUE_APP_ALARM=http://123.60.219.66:48080
 # 登录
-# VUE_APP_VUE_LOGIN_URL=http://123.60.223.250:48080
-VUE_APP_VUE_LOGIN_URL=http://123.60.219.66:48080
-VUE_APP_API=http://120.46.128.147:6060
+VUE_APP_VUE_LOGIN_URL=http://10.220.1.8:48080
+# VUE_APP_VUE_LOGIN_URL=http://123.60.219.66:48080
+# VUE_APP_API=http://120.46.128.147:6060
+VUE_APP_API=http://10.220.1.8:6060
 # VUE_APP_TEST=http://10.81.3.155:9002
 # VUE_APP_WS='ws://10.81.3.155:9002'
 # VUE_APP_ADAPTERURL=http://10.81.3.155:8011

+ 4 - 0
package.json

@@ -18,6 +18,7 @@
     "@arcgis/core": "^4.19.3",
     "@element-plus/icons-vue": "^0.2.4",
     "@open-wc/webpack-import-meta-loader": "^0.4.7",
+    "@panzhiyue/leaflet-canvaslabel": "^1.2.0",
     "@vue/runtime-core": "^3.3.9",
     "animate.css": "3.5",
     "axios": "^0.21.1",
@@ -44,6 +45,9 @@
     "jspdf": "^2.3.1",
     "jszip": "^3.7.1",
     "jszip-utils": "^0.1.0",
+    "leaflet": "^1.9.4",
+    "leaflet-canvas-marker": "^0.2.0",
+    "leaflet-contextmenu": "^1.4.0",
     "papaparse": "^5.3.1",
     "pizzip": "^3.1.4",
     "stompjs": "^2.3.3",

+ 2 - 0
public/index.html

@@ -9,6 +9,8 @@
   <meta name="viewport" content="width=device-width,initial-scale=1.0">
   <link rel="icon" href="<%= BASE_URL %>kb_icon.png">
   <link rel="stylesheet" href="./static/Cesium/Widgets/widgets.css">
+  <link href="https://cdn.bootcdn.net/ajax/libs/leaflet/1.7.1/leaflet.min.css" rel="stylesheet">
+  <link href="https://cdn.bootcdn.net/ajax/libs/leaflet-contextmenu/1.4.0/leaflet.contextmenu.css" rel="stylesheet">
   <script type="text/javascript">
     window.onload = function () {
       if (!!window.ActiveXObject || "ActiveXObject" in window) {

+ 3 - 3
src/App.vue

@@ -13,8 +13,8 @@
         <div class="header-title" @click="handleClickJump()">
           <!-- <img v-if="$store.state.themeName === 'dark'" src="./assets/projectLogo.png" alt="" />
         <img v-if="$store.state.themeName === 'light'" src="./assets/light-projectLogo.png" alt="" /> -->
-        <!-- <img src="./assets/logonx.png" alt="" /> -->
-          <span
+        <img src="./assets/logonx.png" alt="" />
+          <!-- <span
             :style="
               $store.state.themeName === 'dark'
                 ? 'color:#fff; font-size:18px;font-family: SimHei'
@@ -22,7 +22,7 @@
             "
           >
             &gt;&gt;&nbsp;演示平台</span
-          >
+          > -->
         </div>
         <div class="header-menu-body">
           <Header />

File diff suppressed because it is too large
+ 27 - 0
src/assets/db.json


BIN
src/assets/images/indexCom/fengji.png


BIN
src/assets/images/noData.png


File diff suppressed because it is too large
+ 24 - 0
src/assets/jb.json


BIN
src/assets/menuImg/tree_shuaxing.png


File diff suppressed because it is too large
+ 12 - 0
src/assets/nx.json


+ 16 - 0
src/components/generatingCapacityComponent/SubmitBtn.vue

@@ -0,0 +1,16 @@
+<script setup name="SubmitBtn">
+const props = defineProps({
+	desc: {
+		type: String,
+		default: ''
+	},
+	type: {
+		type: String,
+		default: 'primary'
+	}
+})
+</script>
+<template>
+	<!-- <div class="h-[24px] flex justify-center items-center text-white bg-[rgba(0,70,199,0.5)] px-[15px] cursor-pointer text-[14px] rounded-[13px]">{{props.desc}}</div> -->
+	<el-button :type="type">{{props.desc}}</el-button>
+</template>

File diff suppressed because it is too large
+ 232 - 0
src/components/generatingCapacityComponent/excel.vue


File diff suppressed because it is too large
+ 194 - 0
src/components/generatingCapacityComponent/table.vue


+ 491 - 0
src/components/generatingCapacityComponent/tree.vue

@@ -0,0 +1,491 @@
+<template>
+    <div class="treeData" :style="{ height: height }">
+        <div class="treeSeach">
+            <el-input v-model="filterText" class="treeseachCl" placeholder="输入关键字过滤" :suffix-icon="Search" />
+            <div class="treeShuax" @click="refreshFn">
+                <img :src="tree_shuaxing" />
+            </div>
+        </div>
+        <div class="treeMain">
+            <div class="treeMainTit">
+                <span>数据</span>
+            </div>
+            <!-- <div v-for="node in data" :key="node.id" class="treeMainMsg">
+                <span>{{node.label}}</span>
+                <tree-node :node="node.children" :data="data" :show-checkbox="showCheckbox"
+                    :dropdownMenu="dropdownMenu">
+                </tree-node>
+            </div> -->
+            <el-tree :data="data" :props="defaultProps" :default-expanded-keys="defaultExpandedKeys" highlight-current
+                icon="none" :filter-node-method="filterNode" ref="tree" @node-click="funCurrentChange"
+                :show-checkbox="showCheckbox" @check="funCheckChange" node-key="id" :expand-on-click-node="true"
+                :current-node-key="activeNode" :class="showCheckbox ? 'elTreeSty' : ''">
+                <template #default="{ node, data }">
+                    <div class="dashedSty">
+                        <span class="hasMore_shu" :style="
+                node.id !==
+                node.parent.childNodes[node.parent.childNodes.length - 1].id
+                  ? 'height: 30px'
+                  : 'height: 18px'
+              " :styel="shuFn(node, data)"></span>
+                        <span class="hasMore_heng"></span>
+                    </div>
+
+                    <el-dropdown ref="dropdown1" size="small" trigger="contextmenu" @command="funCommand" :class="
+              !node.expanded || (node.isLeaf && !node.isCurrent)
+                ? ''
+                : 'eldropdownCla'
+            ">
+                        <span class="el-dropdown-link" :class="
+                node.isCurrent || activeNode === data.id
+                  ? 'changenodeLabel'
+                  : 'nodeLabel'
+              ">
+                            {{ node.label }}
+                        </span>
+                        <!-- <span>{{ node.label }}</span> -->
+                        <template #dropdown>
+                            <el-dropdown-menu>
+                                <el-dropdown-item class="text-[#409EFF]" v-if="dropdownMenu.includes('save')"
+                                    :command="{ type: 'save', data, node }">保存</el-dropdown-item>
+                                <el-dropdown-item class="text-[#409EFF]" v-if="
+                    data.childs &&
+                    data.childs.length &&
+                    dropdownMenu.includes('export')
+                  " :command="{ type: 'export', data, node }">导出
+                                </el-dropdown-item>
+                                <el-dropdown-item class="text-[#F56C6C]" v-if="dropdownMenu.includes('delete')"
+                                    :command="{ type: 'delete', data, node }">删除</el-dropdown-item>
+                            </el-dropdown-menu>
+                        </template>
+                    </el-dropdown>
+                </template>
+                <template #empty>
+                    <div class="nodata">
+                        <img :src="nodata" alt="" />
+                        <p class="nodataText">暂无数据,敬请期待</p>
+                    </div>
+                </template>
+            </el-tree>
+        </div>
+    </div>
+</template>
+<script>
+    // // import httpRequest from "@/utils/request.js";
+    import tree_shuaxing from "@assets/menuImg/tree_shuaxing.png";
+    import nodata from "@assets/images/noData.png";
+    import TreeNode from "./treeStyle.vue";
+    import {
+        Search
+    } from "@element-plus/icons-vue";
+    import DAYJS from "dayjs";
+    export default {
+        components: {
+            TreeNode,
+        },
+        props: {
+            data: {
+                type: Array,
+                default: () => {
+                    return [];
+                },
+            },
+            height: {
+                type: String,
+                default: () => {
+                    return "";
+                },
+            },
+            type: {
+                type: String,
+                default: () => {
+                    return "wind";
+                },
+            },
+            currentNodeKey: {
+                type: String,
+                default: () => {
+                    return "";
+                },
+            },
+            dropdownMenu: {
+                type: Array,
+                default: () => {
+                    return ["export", "delete"];
+                },
+            },
+            showCheckbox: {
+                type: Boolean,
+                default: () => {
+                    return false;
+                },
+            },
+        },
+
+        data() {
+            return {
+                // treeJson: treeJson,
+                treeJsonArr: [],
+                filterText: "",
+                Search: Search,
+                nodata: nodata,
+                tree_shuaxing: tree_shuaxing,
+                defaultProps: {
+                    children: "children",
+                    label: "label",
+                },
+                activeNode: "",
+                defaultExpandedKeys: [],
+            };
+        },
+        watch: {
+            filterText(val) {
+                this.$refs.tree.filter(val);
+            },
+
+            currentNodeKey(value) {
+                this.activeNode = value;
+                const node = this.getTreeItem(value, this.data[0]) || null;
+                this.$refs.tree.setChecked(node, true);
+            },
+
+            data(value) {
+                this.defaultExpandedKeys = this.getDefaultExpandedKey([], value);
+            },
+        },
+
+        created() {
+            this.defaultExpandedKeys = this.getDefaultExpandedKey([], this.data || []);
+        },
+
+        mounted() {
+            // this.treeJsonFn()
+        },
+
+        methods: {
+            getDefaultExpandedKey(defaultExpandedKey = [], data = []) {
+                data.forEach((ele) => {
+                    if (/(\d{1,2})月(\d{1,2})日/.test(ele.label)) {
+                        const monthReg = new RegExp(`${DAYJS().format("MM")}月`);
+                        if (monthReg.test(ele.label)) {
+                            defaultExpandedKey.push(ele.id);
+                        }
+                    } else {
+                        if (ele.children.length) {
+                            return this.getDefaultExpandedKey(defaultExpandedKey, ele.children);
+                        }
+                    }
+                });
+                return defaultExpandedKey;
+            },
+            treeJsonFn() {
+                this.treeJsonArr = this.funRepeatMap(this.treeJson.data);
+            },
+
+            funRepeatMap(arr, type = "prepare") {
+                return arr.map((o) => {
+                    if (o.children) {
+                        const findIndex = o.children.findIndex((p) => !!p.type);
+                        if (findIndex !== -1) {
+                            o.childs = o.children;
+                            o.children = [];
+                        }
+                    }
+                    return {
+                        ...o,
+                        children: o.children ? this.funRepeatMap(o.children, type) : [],
+                    };
+                });
+            },
+
+            getTreeItem(id = "", data = {}) {
+                if (!id) {
+                    return {};
+                }
+
+                if (data.id === id) {
+                    return data;
+                } else {
+                    if (data.children.length) {
+                        for (let i = 0; i < data.children.length; i++) {
+                            const ele = data.children[i];
+                            if (ele.id === id) {
+                                return ele;
+                            } else {
+                                if (ele.children.length) {
+                                    return this.getTreeItem(id, ele);
+                                } else {
+                                    return {};
+                                }
+                            }
+                        }
+                    } else {
+                        return {};
+                    }
+                }
+            },
+
+            shuFn(node, data) {
+                // debugger
+            },
+
+            filterNode(value, data) {
+                if (!value) return true;
+                return data.label.indexOf(value) !== -1;
+            },
+
+            refreshFn() {
+                this.$emit("refresh");
+            },
+
+            funCurrentChange(current, currentNode) {
+                this.activeNode = current.id || "";
+                this.$emit("currentChange", {
+                    current,
+                    currentNode,
+                });
+            },
+
+            async funCommand({
+                type,
+                data,
+                node
+            }) {
+                switch (type) {
+                    case "save":
+                        /**该保存功能目前暂用于风电场, combine页 */
+                        if (this.type !== "wind") {
+                            return false;
+                        }
+                        ElMessageBox.confirm("确认保存当前节点的拟合功率?", "保存", {
+                            confirmButtonText: "确认",
+                            cancelButtonText: "取消",
+                            type: "warning",
+                        }).then(async () => {
+                            let saveArr = [];
+                            const repeatArr = (arr, saveArr) => {
+                                for (const unit of arr) {
+                                    if (unit.childs.length) {
+                                        saveArr.push(...unit.childs.map((o) => o.id));
+                                    } else if (unit.children.length) {
+                                        repeatArr(unit.children, saveArr);
+                                    }
+                                }
+                            };
+                            if (data.childs.length) {
+                                saveArr = data.childs.map((o) => o.id);
+                            } else if (data.children.length) {
+                                repeatArr(data.children, saveArr);
+                            }
+                            let res = {
+                                code: 500,
+                            };
+                            res = await httpRequest.get("/power/fitting/curve/save", {
+                                params: {
+                                    ids: saveArr.join(","),
+                                },
+                            }); //删除当前节点
+
+                            if (res.code === 200) {
+                                ElMessage.success(res.msg);
+                            }
+                        });
+                        break;
+                    case "export":
+                        ElMessageBox.confirm("确认导出当前节点的所有数据?", "导出", {
+                            confirmButtonText: "确认",
+                            cancelButtonText: "取消",
+                            type: "warning",
+                        }).then(() => {
+                            const a = document.createElement("a");
+                            let childs = [];
+                            childs =
+                                this.type === "wind" ?
+                                data.childs.map((o) => o.id) :
+                                data.childs.map((o) => o.path);
+                            const url =
+                                this.type === "wind" ?
+                                "/data/option/download?ids=" :
+                                "/export/files?filename=";
+                            a.href =
+                                // config.baseURL + url + childs.join(",");
+                                process.env.VUE_APP_GENERAT_URL + url + childs.join(",");
+                            a.download = "";
+                            a.target = "_blank";
+                            a.click();
+
+                            // let that = this
+                            // let childs = []
+                            // childs = this.type === 'wind' ? data.childs.map((o) => o.id) : data.childs.map(
+                            //     (o) => o.path)
+                            // let params = {
+                            //     ids: childs.join(",")
+                            // }
+                            // apiGetExportMsg(params).then(datas => {
+                            //     let blob = new Blob([datas], {
+                            //         type: `application/vnd.ms-excel;charset=utf-8`
+                            //     })
+                            //     saveAs(blob)
+                            // }).catch((r) => {
+                            //     console.error(r)
+                            // })
+                        });
+                        break;
+                    case "delete":
+                        ElMessageBox.confirm("确认删除当前节点的所有数据?", "删除", {
+                            confirmButtonText: "确认",
+                            cancelButtonText: "取消",
+                            type: "warning",
+                        }).then(async () => {
+                            let deleteArr = [];
+                            const repeatArr = (arr, deleteArr) => {
+                                for (const unit of arr) {
+                                    if (unit.childs.length) {
+                                        deleteArr.push(
+                                            ...unit.childs.map((o) =>
+                                                this.type === "wind" ? o.id : o.path
+                                            )
+                                        );
+                                    } else if (unit.children.length) {
+                                        repeatArr(unit.children, deleteArr);
+                                    }
+                                }
+                            };
+                            if (data.childs.length) {
+                                deleteArr = data.childs.map((o) =>
+                                    this.type === "wind" ? o.id : o.path
+                                );
+                            } else if (data.children.length) {
+                                repeatArr(data.children, deleteArr);
+                            }
+                            let res = {
+                                code: 500,
+                            };
+                            if (this.type === "wind") {
+                                res = await httpRequest.get("/data/option/delete", {
+                                    params: {
+                                        ids: deleteArr.join(","),
+                                    },
+                                }); //删除当前节点
+                            } else {
+                                res = await httpRequest.delete("/delete/files", {
+                                    data: {
+                                        filename: deleteArr.join(","),
+                                    },
+                                }); //删除当前节点
+                            }
+                            if (res.code === 200) {
+                                ElMessage.success(res.msg);
+                                this.$emit("refresh");
+                            }
+                        });
+
+                        break;
+                }
+            },
+
+            funCheckChange(current, checkedNodes) {
+                this.$emit("checkChange", {
+                    current,
+                    checkedNodes,
+                });
+            },
+        },
+    };
+</script>
+<style lang="less">
+    .treeData {
+        overflow-y: auto;
+
+        .eldropdownCla {
+            .changenodeLabel {}
+
+            .nodeLabel {}
+        }
+
+        .treeSeach {
+            width: 100%;
+            display: flex;
+            margin-bottom: 5px;
+
+            .treeseachCl {
+                height: 30px;
+                position: relative;
+                top: -7px;
+            }
+
+            .treeShuax {
+                cursor: pointer;
+                margin-left: 5px;
+                height: 30px;
+                width: 30px;
+                background: #5473e8;
+                border-radius: 2px;
+                text-align: center;
+
+                img {
+                    width: 25px;
+                    height: 25px;
+
+                    position: relative;
+                    top: 2px;
+                    left: -1px;
+                }
+            }
+        }
+
+        .treeMain {
+            .treeMainTit {
+                width: calc(100% - 10px);
+                height: 22px;
+                background: #1e3f9a;
+                color: #fff;
+                font-size: 12px;
+                padding: 3px 0 0 10px;
+            }
+
+            .treeMainMsg {
+                span {
+                    font-family: Microsoft YaHei;
+                    font-weight: 400;
+                    font-size: 14px;
+                    color: #fff;
+                    line-height: 30px;
+                }
+            }
+
+            .el-tree {
+                background: transparent;
+                color: #fff;
+                height: 100%;
+
+                .el-tree-node {
+                    .el-tree-node__content {
+                        .el-dropdown {
+                            .nodeLabel {
+                                color: #fff;
+                            }
+                        }
+                    }
+                }
+
+                .is-current {
+                    width: 100%;
+                    background: none !important;
+                }
+
+                .el-tree__empty-block {
+                    img {
+                        margin-top: 20px;
+                    }
+
+                    .nodataText {
+                        line-height: 50px;
+                        font-size: 14px;
+                        color: #fff;
+                    }
+                }
+            }
+        }
+    }
+</style>

File diff suppressed because it is too large
+ 3159 - 0
src/components/generatingCapacityComponent/treeJson.json


+ 347 - 0
src/components/generatingCapacityComponent/treeStyle.vue

@@ -0,0 +1,347 @@
+<template>
+    <div>
+        <div v-for="(child, index) in node" :key="child.id" style="margin-left: 20px" class="treeStyle">
+            <div style="display: flex" :id="child.id">
+                <div class="dashedSty">
+                    <span class="hasMore_shu" :style="index+1 !== node.length ? 'height: 30px' : 'height: 18px'"></span>
+                    <span class="hasMore_heng"></span>
+                </div>
+                <div style="display: flex;cursor:pointer">
+                    <div v-if="showCheckbox">
+                        <div class="changeradio" v-if="child.showCheck" @click.stop="funCheckChange(child, node)">
+                            <el-icon><Select /></el-icon>
+                        </div>
+                        <div class="radio" v-else @click.stop="funCheckChange(child, node)"></div>
+                    </div>
+                    <!-- <span :class="child.showSpan ? 'changenodeLabel' : 'nodeLabel'"
+                        @click.stop="funCurrentChange(child, node)">{{child.label}}</span> -->
+                    <el-dropdown ref="dropdown1" size="small" trigger="contextmenu" @command="funCommand"
+                        style="margin-right: 30px"
+                        :class="!node.expanded || (node.isLeaf && !node.isCurrent) ? '' : 'eldropdownCla'">
+                        <span :class="child.showSpan ? 'changenodeLabel' : 'nodeLabel'"
+                            @click.stop="funCurrentChange(child, node)">{{child.label}}</span>
+                        <template #dropdown>
+                            <el-dropdown-menu>
+                                <el-dropdown-item class="text-[#409EFF]" v-if="dropdownMenu.includes('save')"
+                                    :command="{ type: 'save', child, node }">保存</el-dropdown-item>
+                                <el-dropdown-item class="text-[#409EFF]"
+                                    v-if="child.childs && child.childs.length && dropdownMenu.includes('export')"
+                                    :command="{ type: 'export', child, node }">导出
+                                </el-dropdown-item>
+                                <el-dropdown-item class="text-[#F56C6C]" v-if="dropdownMenu.includes('delete')"
+                                    :command="{ type: 'delete', child, node }">删除</el-dropdown-item>
+                            </el-dropdown-menu>
+                        </template>
+                    </el-dropdown>
+                </div>
+            </div>
+            <tree-node :node="child.children" :data="node" v-if="child.children.length>0" :show-checkbox="showCheckbox">
+            </tree-node>
+        </div>
+
+    </div>
+</template>
+
+<script>
+    export default {
+        name: 'treeNode',
+        props: {
+            node: {
+                type: Array,
+                default: () => {
+                    return [];
+                },
+            },
+            data: {
+                type: Object,
+                default: () => {
+                    return {};
+                },
+            },
+            showCheckbox: {
+                type: Boolean,
+                default: () => {
+                    return false;
+                },
+            },
+            dropdownMenu: {
+                type: Array,
+                default: () => {
+                    return ['export',
+                        'delete',
+                    ];
+                },
+            },
+        },
+        data() {
+            return {};
+        },
+        methods: {
+            funCurrentChange(current, node) {
+                if (current && node && node.length > 0) {
+                    node.forEach(it => {
+                        it.showSpan = false
+                        if (it.id === current.id) {
+                            it.showSpan = !it.showSpan
+                        }
+
+                        function childFn(it) {
+                            if (it.children && it.children.length > 0) {
+                                it.children.forEach(iv => {
+                                    iv.showSpan = false
+                                    childFn(iv)
+                                })
+                            }
+                        }
+                        childFn(it)
+                    })
+                }
+                if (this.data && this.data.length > 0) {
+                    this.data.map(o => {
+                        o.showSpan = false
+                    })
+                }
+                this.$parent.funCurrentChange(current, null)
+            },
+            funCheckChange(current, node) {
+                if (current && node && node.length > 0) {
+                    node.forEach(it => {
+                        it.showCheck = false
+                        if (it.id === current.id) {
+                            it.showCheck = !it.showCheck
+                        }
+
+                        function childFn(it) {
+                            if (it.children && it.children.length > 0) {
+                                it.children.forEach(iv => {
+                                    iv.showCheck = false
+                                    childFn(iv)
+                                })
+                            }
+                        }
+                        childFn(it)
+                    })
+                }
+                if (this.data && this.data.length > 0) {
+                    this.data.map(o => {
+                        o.showCheck = false
+                    })
+                }
+                this.$parent.funCheckChange(current, current)
+            },
+            async funCommand({
+                type,
+                data,
+                node
+            }) {
+                switch (type) {
+                    case 'save':
+                        /**该保存功能目前暂用于风电场, combine页 */
+                        if (this.type !== 'wind') {
+                            return false
+                        }
+                        ElMessageBox.confirm("确认保存当前节点的拟合功率?", "保存", {
+                            confirmButtonText: "确认",
+                            cancelButtonText: "取消",
+                            type: "warning",
+                        }).then(async () => {
+                            let saveArr = [];
+                            const repeatArr = (arr, saveArr) => {
+                                for (const unit of arr) {
+                                    if (unit.childs.length) {
+                                        saveArr.push(...unit.childs.map((o) => o.id));
+                                    } else if (unit.children.length) {
+                                        repeatArr(unit.children, saveArr);
+                                    }
+                                }
+                            };
+                            if (data.childs.length) {
+                                saveArr = data.childs.map((o) => o.id);
+                            } else if (data.children.length) {
+                                repeatArr(data.children, saveArr);
+                            }
+                            let res = {
+                                code: 500
+                            }
+                            res = await httpRequest.get("/power/fitting/curve/save", {
+                                params: {
+                                    ids: saveArr.join(",")
+                                },
+                            }); //删除当前节点
+
+                            if (res.code === 200) {
+                                ElMessage.success(res.msg);
+                            }
+                        });
+                        break;
+                    case "export":
+                        ElMessageBox.confirm("确认导出当前节点的所有数据?", "导出", {
+                            confirmButtonText: "确认",
+                            cancelButtonText: "取消",
+                            type: "warning",
+                        }).then(() => {
+                            debugger
+
+                            const a = document.createElement("a");
+                            let childs = []
+                            childs = this.type === 'wind' ? data.childs.map((o) => o.id) : data.childs.map(
+                                (o) => o.path)
+                            const url = this.type === 'wind' ? '/data/option/download?ids=' :
+                                '/export/files?filename='
+                            a.href =
+                                // config.baseURL + url + childs.join(",");
+                                process.env.VUE_APP_GENERAT_URL + url + childs.join(",");
+                            a.download = "";
+                            a.target = '_blank'
+                            a.click();
+                        });
+                        break;
+                    case "delete":
+                        ElMessageBox.confirm("确认删除当前节点的所有数据?", "删除", {
+                            confirmButtonText: "确认",
+                            cancelButtonText: "取消",
+                            type: "warning",
+                        }).then(async () => {
+                            let deleteArr = [];
+                            const repeatArr = (arr, deleteArr) => {
+                                for (const unit of arr) {
+                                    if (unit.childs.length) {
+                                        deleteArr.push(...unit.childs.map((o) => this.type ===
+                                            'wind' ? o.id : o.path));
+                                    } else if (unit.children.length) {
+                                        repeatArr(unit.children, deleteArr);
+                                    }
+                                }
+                            };
+                            if (data.childs.length) {
+                                deleteArr = data.childs.map((o) => this.type === 'wind' ? o.id : o
+                                    .path);
+                            } else if (data.children.length) {
+                                repeatArr(data.children, deleteArr);
+                            }
+                            let res = {
+                                code: 500
+                            }
+                            if (this.type === 'wind') {
+                                res = await httpRequest.get("/data/option/delete", {
+                                    params: {
+                                        ids: deleteArr.join(",")
+                                    },
+                                }); //删除当前节点
+                            } else {
+                                res = await httpRequest.delete("/delete/files", {
+                                    data: {
+                                        filename: deleteArr.join(",")
+                                    },
+                                }); //删除当前节点
+                            }
+                            if (res.code === 200) {
+                                ElMessage.success(res.msg);
+                                this.$emit("refresh");
+                            }
+                        });
+
+                        break;
+                }
+            },
+        }
+    };
+</script>
+<style lang="less">
+    .treeStyle {
+        height: 30px;
+
+        .radio {
+            position: relative;
+            top: 10px;
+            width: 14px;
+            height: 14px;
+            background: #CBCCD1;
+            border-radius: 3px;
+            border: 1px solid #7C808C;
+            margin-right: 10px;
+        }
+
+        .changeradio {
+            position: relative;
+            top: 10px;
+            width: 15px;
+            height: 15px;
+            background: #5473E8;
+            border-radius: 3px;
+            margin-right: 10px;
+
+            .el-icon {
+                position: absolute;
+                top: 4px;
+                left: 2px;
+                color: #fff;
+                width: 10px;
+                height: 8px;
+            }
+        }
+
+        .nodeLabel {
+            position: relative;
+            top: 2px;
+            font-family: Microsoft YaHei;
+            font-weight: 400;
+            font-size: 14px;
+            color: #121212;
+            line-height: 30px;
+            width: 100%;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            overflow: hidden;
+        }
+
+        .changenodeLabel {
+            position: relative;
+            top: 2px;
+            font-family: Microsoft YaHei;
+            font-weight: 400;
+            font-size: 14px;
+            color: #5473E8;
+            line-height: 30px;
+            padding: 0 10px 0 0;
+            background: #FFFFFF;
+            box-shadow: 0px 0px 3px 0px rgba(83, 86, 94, 0.23);
+            border-radius: 5px;
+            border: 1px solid rgba(84, 115, 232, 0.3);
+            width: 100%;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            overflow: hidden;
+        }
+
+        img {
+            width: 30px;
+            height: 30px;
+        }
+
+        .dashedSty {
+            width: 20px;
+            height: 30px;
+            position: relative;
+
+            .hasMore_shu {
+                position: absolute;
+                top: 0;
+                left: 5px;
+                display: inline-block;
+                width: 1px;
+                height: 30px;
+                border-left: 1px dashed #565D70;
+            }
+
+            .hasMore_heng {
+                width: 10px;
+                height: 1px;
+                position: absolute;
+                top: 17px;
+                left: 7px;
+                border-top: 1px dashed #565D70;
+            }
+        }
+    }
+</style>

+ 213 - 191
src/components/headerNavSta/index.vue

@@ -1,23 +1,15 @@
 <template>
-  <div class="heeaderNav">
-    <div class="tab-box">
-      <div
-        class="tab-item"
-        v-for="(tab, index) of tabs"
-        :key="index"
-        :class="{ active1: activeTab == tab.id }"
-        @click.stop="headerCheck(tab.id, tab.show)"
-      >
-        <span
-          class="svg-icon svg-icon-sm"
-          :class="activeTab == tab.id ? 'svg-icon-green' : 'svg-icon-write'"
-        >
-          <SvgIcon :svgid="tab.icon"></SvgIcon>
-        </span>
-        <span>{{ tab.text }}</span>
-      </div>
-    </div>
-    <!-- <div class="rightTitle" v-if="wpId != 'KGDL_FGS'">
+    <div class="heeaderNav">
+        <div class="tab-box">
+            <div class="tab-item" v-for="(tab, index) of tabs" :key="index" :class="{ active1: activeTab == tab.id }"
+                @click.stop="headerCheck(tab.id, tab.show)">
+                <span class="svg-icon svg-icon-sm" :class="activeTab == tab.id ? 'svg-icon-green' : 'svg-icon-write'">
+                    <SvgIcon :svgid="tab.icon"></SvgIcon>
+                </span>
+                <span>{{ tab.text }}</span>
+            </div>
+        </div>
+        <!-- <div class="rightTitle" v-if="wpId != 'KGDL_FGS'">
       <div
         class="all-enterprise"
         :class="{ active1: enterpriseIndex == 'all' }"
@@ -47,191 +39,221 @@
         <span>{{ item.aname }}</span>
       </div>
     </div> -->
-  </div>
+    </div>
 </template>
 
 <script>
-import SvgIcon from "@/components/coms/icon/svg-icon.vue";
-import { headerCompany } from "@/api/headerNav/header.js";
-export default {
-  name: "HeaderNavSta", //全景监视标题栏
-  props: {
-    isAll: {
-      type: Boolean,
-      default: false,
-    },
-    wpId: {
-      type: String,
-      default: "",
-    },
-    companyid: { type: String, default: "SXJ_RGN" },
-    currents: { type: Number, default: 0 },
-  },
-  components: { SvgIcon },
-  data() {
-    return {
-      OrganizationList: [],
-      activeTab: -1,
-      headerIndexs: -1,
-      wpIds: "",
-      tabs: [
-        // {
-        //   icon: "svg-all",
-        //   text: "全部",
-        //   show: "all",
-        //   id: 0,
-        // },
-        {
-          icon: "svg-wind-site",
-          text: "风电",
-          show: "fc",
-          id: -1,
+    import SvgIcon from "@/components/coms/icon/svg-icon.vue";
+    import {
+        headerCompany
+    } from "@/api/headerNav/header.js";
+    export default {
+        name: "HeaderNavSta", //全景监视标题栏
+        props: {
+            isAll: {
+                type: Boolean,
+                default: false,
+            },
+            wpId: {
+                type: String,
+                default: "",
+            },
+            companyid: {
+                type: String,
+                default: "SXJ_RGN"
+            },
+            currents: {
+                type: Number,
+                default: 0
+            },
+        },
+        components: {
+            SvgIcon
+        },
+        data() {
+            return {
+                OrganizationList: [],
+                activeTab: -1,
+                headerIndexs: -1,
+                wpIds: "",
+                tabs: [
+                    // {
+                    //   icon: "svg-all",
+                    //   text: "全部",
+                    //   show: "all",
+                    //   id: 0,
+                    // },
+                    {
+                        icon: "svg-wind-site",
+                        text: "风电",
+                        show: "fc",
+                        id: -1,
+                    },
+                    // {
+                    //   icon: "svg-photovoltaic",
+                    //   text: "光伏",
+                    //   show: "gf",
+                    //   id: -2,
+                    // },
+                ],
+                enterpriseIndex: "all",
+                companyName: "山西",
+                showType: "all",
+                childNode: [],
+                regionList: [{
+                        name: "全国",
+                        key: "KGDL_FGS"
+                    },
+                    {
+                        name: "山西",
+                        key: "SXJ_RGN"
+                    },
+                    {
+                        name: "内蒙",
+                        key: "NMM_RGN"
+                    },
+                ],
+            };
+        },
+        created() {
+            this.$nextTick(() => {
+                this.$emit("firstRender", this.activeTab, this.showType, this.wpId);
+            });
         },
-        {
-          icon: "svg-photovoltaic",
-          text: "光伏",
-          show: "gf",
-          id: -2,
+        watch: {
+            wpId: {
+                handler(val) {
+                    let region = this.regionList.find((item) => item.key == val);
+                    if ((val && (region || this.currents == 1)) || this.isAll) {
+                        this.getOrganizationList();
+                    }
+                },
+                immediate: true,
+            },
+        },
+        methods: {
+            getOrganizationList() {
+                if (this.currents == 1 && this.wpId.includes("SXJ")) {
+                    headerCompany({
+                        regionid: "SXJ_RGN"
+                    }).then(({
+                        data
+                    }) => {
+                        this.childNode = data.data;
+                    });
+                } else {
+                    headerCompany({
+                        regionid: this.wpId
+                    }).then(({
+                        data
+                    }) => {
+                        this.childNode = data.data;
+                    });
+                }
+            },
+            handleClickEnterprise(enterprise, name) {
+                this.companyName = name;
+                this.enterpriseIndex = enterprise;
+                this.$emit("typeFlag", this.showType, this.enterpriseIndex);
+                this.$emit(
+                    "firstRender",
+                    this.activeTab,
+                    this.showType,
+                    enterprise == "all" ? "SXJ_RGN" : enterprise,
+                    enterprise == "all" ? "清洁能源" : name
+                );
+            },
+            headerCheck(index, showType) {
+                this.activeTab = index;
+                this.showType = showType;
+                this.$emit(
+                    "firstRender",
+                    this.activeTab,
+                    this.showType,
+                    this.wpId,
+                    this.wpId == "KGDL_FGS" ? "" : this.companyName
+                );
+                this.$emit("typeFlag", this.showType, this.enterpriseIndex);
+            },
         },
-      ],
-      enterpriseIndex: "all",
-      companyName: "山西",
-      showType: "all",
-      childNode: [],
-      regionList: [
-        { name: "全国", key: "KGDL_FGS" },
-        { name: "山西", key: "SXJ_RGN" },
-        { name: "内蒙", key: "NMM_RGN" },
-      ],
     };
-  },
-  created() {
-    this.$nextTick(() => {
-      this.$emit("firstRender", this.activeTab, this.showType, this.wpId);
-    });
-  },
-  watch: {
-    wpId: {
-      handler(val) {
-        let region = this.regionList.find((item) => item.key == val);
-        if ((val && (region || this.currents == 1)) || this.isAll) {
-          this.getOrganizationList();
-        }
-      },
-      immediate: true,
-    },
-  },
-  methods: {
-    getOrganizationList() {
-      if (this.currents == 1 && this.wpId.includes("SXJ")) {
-        headerCompany({ regionid: "SXJ_RGN" }).then(({ data }) => {
-          this.childNode = data.data;
-        });
-      } else {
-        headerCompany({ regionid: this.wpId }).then(({ data }) => {
-          this.childNode = data.data;
-        });
-      }
-    },
-    handleClickEnterprise(enterprise, name) {
-      this.companyName = name;
-      this.enterpriseIndex = enterprise;
-      this.$emit("typeFlag", this.showType, this.enterpriseIndex);
-      this.$emit(
-        "firstRender",
-        this.activeTab,
-        this.showType,
-        enterprise == "all" ? "SXJ_RGN" : enterprise,
-        enterprise == "all" ? "清洁能源" : name
-      );
-    },
-    headerCheck(index, showType) {
-      this.activeTab = index;
-      this.showType = showType;
-      this.$emit(
-        "firstRender",
-        this.activeTab,
-        this.showType,
-        this.wpId,
-        this.wpId == "KGDL_FGS" ? "" : this.companyName
-      );
-      this.$emit("typeFlag", this.showType, this.enterpriseIndex);
-    },
-  },
-};
 </script>
 
 <style lang="less" scoped>
-.heeaderNav {
-  height: 35px;
-  display: flex;
-  align-items: center;
-  margin: 16px 0 16px 20px;
-}
-.tab-box {
-  display: inline-block;
-  z-index: 2;
-  display: flex;
+    .heeaderNav {
+        height: 35px;
+        display: flex;
+        align-items: center;
+        margin: 16px 0 16px 20px;
+    }
 
-  .tab-item {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 14px;
-    font-family: Microsoft YaHei;
-    cursor: pointer;
-    padding: 3px 14px;
-    margin-right: 5px;
+    .tab-box {
+        display: inline-block;
+        z-index: 2;
+        display: flex;
 
-    &.active1 {
-      color: @green;
-      position: relative;
-      background: rgba(84, 183, 90, 0.16);
-      border-radius: 16px;
+        .tab-item {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-size: 14px;
+            font-family: Microsoft YaHei;
+            cursor: pointer;
+            padding: 3px 14px;
+            margin-right: 5px;
 
-      &::after {
-        content: "";
-        position: absolute;
-        width: 100%;
-        height: 0.463vh;
-        border-top: 0;
-        left: 0;
-        bottom: 0;
-        box-sizing: border-box;
-      }
-    }
+            &.active1 {
+                color: @green;
+                position: relative;
+                background: rgba(84, 183, 90, 0.16);
+                border-radius: 16px;
+
+                &::after {
+                    content: "";
+                    position: absolute;
+                    width: 100%;
+                    height: 0.463vh;
+                    border-top: 0;
+                    left: 0;
+                    bottom: 0;
+                    box-sizing: border-box;
+                }
+            }
 
-    .svg-icon {
-      margin-right: 12px;
-      margin-top: 2px;
+            .svg-icon {
+                margin-right: 12px;
+                margin-top: 2px;
+            }
+        }
     }
-  }
-}
 
-.rightTitle {
-  display: flex;
-  margin-left: 72px;
-  z-index: 5;
-  .active1 {
-    // background: rgba(84, 183, 90, 0.4);
-    color: #05bb4c;
-  }
-  div {
-    display: flex;
-    padding: 0 14px;
-    align-items: center;
-    height: 25px;
-    line-height: 25px;
-    font-size: 15px;
-    font-family: Microsoft YaHei;
-    background: rgba(84, 183, 90, 0.16);
-    border-radius: 16px;
-    text-align: center;
-    margin-right: 15px;
-    cursor: pointer;
-    .svg-icon {
-      margin-right: 12px;
+    .rightTitle {
+        display: flex;
+        margin-left: 72px;
+        z-index: 5;
+
+        .active1 {
+            // background: rgba(84, 183, 90, 0.4);
+            color: #05bb4c;
+        }
+
+        div {
+            display: flex;
+            padding: 0 14px;
+            align-items: center;
+            height: 25px;
+            line-height: 25px;
+            font-size: 15px;
+            font-family: Microsoft YaHei;
+            background: rgba(84, 183, 90, 0.16);
+            border-radius: 16px;
+            text-align: center;
+            margin-right: 15px;
+            cursor: pointer;
+
+            .svg-icon {
+                margin-right: 12px;
+            }
+        }
     }
-  }
-}
-</style>
+</style>

+ 1 - 0
src/components/other/healthReport/index.vue

@@ -2229,6 +2229,7 @@ export default {
 
   .pdfDom {
     padding: 30px 50px;
+    color: #c0ccda;
   }
 
   .title {

+ 7 - 0
src/main.js

@@ -21,6 +21,12 @@ import * as echarts from 'echarts'
 // 引入基础工具
 import basicTool from "@tools/basicTool";
 
+import L from "leaflet"
+import "leaflet/dist/leaflet.css"
+import "leaflet-contextmenu"
+import "leaflet-canvas-marker"
+import icon from "leaflet/dist/images/marker-icon.png" // 引入leaflet默认图标
+
 import animated from "animate.css";
 import { ElMessage } from "element-plus";
 import "./nxfStyle.less";
@@ -94,6 +100,7 @@ window.__STATICVUE__.use(ElementPlus, { locale });
 app._context.components.ElDialog["props"].closeOnClickModal.default = false;
 window.__STATICVUE__.use(store);
 window.__STATICVUE__.use(router);
+window.__STATICVUE__.use(L);
 window.__STATICVUE__.use(animated);
 
 window.__STATICVUE__.config.globalProperties.API = axios; //全局注册

+ 60 - 8
src/router/index.js

@@ -41,7 +41,17 @@ export const asyncRoutes = [
       icon: "",
       permissions: ["jn_integratedAlarm"],
     },
-    children: [
+        children: [
+            // {
+            //     path: "detailmatrix", // 明细矩阵
+            //     name: "DetailMatrix",
+            //     component: () => import("@/views/IntegratedAlarm/DetailMatrix"),
+            //     meta: {
+            //       title: "矩阵提醒",
+            //       icon: "svg-mx-matrix",
+            //       permissions: ["jn_mxjz"],
+            //     },
+            //   },
       {
         path: "safe", // 综合报警
         name: "safe",
@@ -137,7 +147,18 @@ export const asyncRoutes = [
               icon: "",
               permissions: ["jn_reliability_bjfx"],
             },
-          },
+            },
+            // {
+            //     path: "partsTemperatureAnalyse", // 各出力部件温度分析
+            //     name: "partsTemperatureAnalyse",
+            //     component: () =>
+            //       import("@/views/IntegratedAlarm/reliability/partsTemperatureAnalyse"),
+            //     meta: {
+            //       title: "各出力部件温度分析",
+            //       icon: "",
+            //       permissions: ["jn_reliability_bjfx"],
+            //     },
+            //   },
         ],
       },
       {
@@ -423,7 +444,18 @@ export const asyncRoutes = [
               icon: "",
               permissions: ["jn_ztfx_dlfx"],
             },
-          },
+            },
+            // {
+            //     path: "windAnalysis",
+            //     component: () =>
+            //       import("@/views/economicsOperation/thematicAnalysis/windAnalysis"),
+            //     name: "windAnalysis",
+            //     meta: {
+            //       title: "损失电量分析",
+            //       icon: "",
+            //       permissions: ["jn_ztfx_dlfx"],
+            //     },
+            // },
         ],
       },
       //整站分析
@@ -475,7 +507,18 @@ export const asyncRoutes = [
               icon: "",
               permissions: ["jn_czfx_fgzyfx"],
             },
-          },
+            },
+            // {
+            //     path: "posAnalysis",
+            //     component: () =>
+            //       import("@/views/economicsOperation/stationAnalyse/posAnalysis/index.vue"),
+            //     name: "posAnalysis",
+            //     meta: {
+            //       title: "微观选址分析",
+            //         icon: "",
+            //         permissions: ["jn_czfx_fgzyfx"],
+            //     },
+            //   },
         ],
       },
       //机组分析
@@ -883,15 +926,24 @@ export const asyncRoutes = [
             },
         },
         {
-            path: "pjfs",
-            name: "pjfs",
-            component: () => import("@/views/nxReport/pjfs"),
+            path: "czjbbb",
+            name: "czjbbb",
+            component: () => import("@/views/nxReport/czjbbb"),
             meta: {
-                title: "集控中心风速电量统计表",
+                title: "场站级别报表",
                 icon: "svg-预警记录",
             },
         },
         {
+            path: "xmjbbb",
+            name: "xmjbbb",
+            component: () => import("@/views/nxReport/xmjbbb"),
+            meta: {
+                title: "项目级别报表",
+                icon: "svg-报表管理",
+            },
+        },
+        {
             path: "czzyb",
             name: "czzyb",
             component: () => import("@/views/nxReport/czzyb"),

+ 27 - 0
src/tools/partten.js

@@ -0,0 +1,27 @@
+// Color 常量
+const color = [
+    { key: "green", value: "#05BB4C" },
+    { key: "yellow", value: "#F8DE5B" },
+    { key: "gray", value: "#606769" },
+    { key: "grayl", value: "#B3BDC0" },
+    { key: "purple", value: "#4B55AE" },
+    { key: "orange", value: "#e17e23" },
+    { key: "blue", value: "#1a93cf" },
+    { key: "red", value: "#BA3237" },
+    { key: "pink", value: "#c531c7" },
+	{ key: "cyan", value: "#1cbbb4" },
+	{ key: "brown", value: "#a5673f" },
+	{ key: "mauve", value: "#9c26b0" },
+	{ key: "white", value: "#fff" },
+];
+
+function getColor(key) {
+    if (!key)
+        key = "green"
+    return color.find((t) => { return t.key == key }).value;
+}
+
+export default {
+    color,
+    getColor
+}

+ 121 - 0
src/views/IntegratedAlarm/DetailMatrix/dataJson.json

@@ -0,0 +1,121 @@
+{
+    "code": 0,
+    "sourceMapData": {
+        "jrts": 25,
+        "djts": 21,
+        "bwts": 15,
+        "gzts": 38,
+        "jxts": 15,
+        "xdts": 17,
+        "slts": 29,
+        "lxts": 38,
+
+        "dfts": 25,
+        "zcyx": 25,
+        "gztj": 25,
+        "jxtj": 25,
+        "xdjcl": 25,
+        "dwsl": 25,
+        "lx": 25,
+
+        "sdtj": 25,
+        "jclyx": 25,
+        "gzsl": 25,
+        "jxsl": 25,
+        "xdtj": 25,
+        "hjsl": 25,
+        "wz": 25
+    },
+    "showMatrixListdata": [
+        {
+            "wpname": "测试1",
+            "czlx": "-1",
+            "jrts": 25,
+            "djts": 21,
+            "bwts": 15,
+            "gzts": 38,
+            "jxts": 15,
+            "xdts": 17,
+            "slts": 29,
+            "lxts": 38,
+            "spped": 14,
+            "ycgl": 21556,
+            "bzgl": 1254,
+            "llgl": 125445,
+            "sjgl": 1254,
+            "wtlist": []
+        },
+        {
+            "wpname": "测试2",
+            "czlx": "-1",
+            "jrts": 25,
+            "djts": 21,
+            "bwts": 15,
+            "gzts": 38,
+            "jxts": 15,
+            "xdts": 17,
+            "slts": 29,
+            "lxts": 38,
+            "spped": 14,
+            "ycgl": 21556,
+            "bzgl": 1254,
+            "llgl": 125445,
+            "sjgl": 1254,
+            "wtlist": []
+        },
+        {
+            "wpname": "测试3",
+            "czlx": "-1",
+            "jrts": 25,
+            "djts": 21,
+            "bwts": 15,
+            "gzts": 38,
+            "jxts": 15,
+            "xdts": 17,
+            "slts": 29,
+            "lxts": 38,
+            "spped": 14,
+            "ycgl": 21556,
+            "bzgl": 1254,
+            "llgl": 125445,
+            "sjgl": 1254,
+            "wtlist": []
+        },
+        {
+            "wpname": "测试4",
+            "czlx": "-1",
+            "jrts": 25,
+            "djts": 21,
+            "bwts": 15,
+            "gzts": 38,
+            "jxts": 15,
+            "xdts": 17,
+            "slts": 29,
+            "lxts": 38,
+            "spped": 14,
+            "ycgl": 21556,
+            "bzgl": 1254,
+            "llgl": 125445,
+            "sjgl": 1254,
+            "wtlist": []
+        },
+        {
+            "wpname": "测试5",
+            "czlx": "-1",
+            "jrts": 25,
+            "djts": 21,
+            "bwts": 15,
+            "gzts": 38,
+            "jxts": 15,
+            "xdts": 17,
+            "slts": 29,
+            "lxts": 38,
+            "spped": 14,
+            "ycgl": 21556,
+            "bzgl": 1254,
+            "llgl": 125445,
+            "sjgl": 1254,
+            "wtlist": []
+        }
+    ]
+}

File diff suppressed because it is too large
+ 1964 - 0
src/views/IntegratedAlarm/DetailMatrix/index.vue


+ 816 - 0
src/views/IntegratedAlarm/reliability/partsTemperatureAnalyse/index.vue

@@ -0,0 +1,816 @@
+<template>
+  <div class="history-warning">
+    <div class="form-wrapper">
+      <div class="search-wrapper">
+        <div class="search-item">
+          <span class="label">场站:</span>
+          <div class="search-content">
+            <el-select
+              v-model="state.stationId"
+              clearable
+              size="mini"
+              placeholder="全部"
+              popper-class="select"
+              @change="getWindturbineList"
+            >
+              <el-option
+                v-for="item in stationList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+              ></el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="search-item">
+          <span class="label">型号:</span>
+          <div class="search-content">
+            <el-select
+              v-model="state.modelId"
+              clearable
+              size="mini"
+              placeholder="全部"
+              popper-class="select"
+            >
+              <el-option
+                v-for="item in modelList"
+                :key="item.id"
+                :value="item.id"
+                :label="item.name"
+              >
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="search-item">
+          <span class="label">部件:</span>
+          <div class="search-content">
+            <el-select
+              v-model="state.components"
+              clearable
+              size="mini"
+              placeholder="全部"
+              popper-class="select"
+            >
+              <el-option
+                v-for="item in componentList"
+                :key="item.id"
+                :value="item.nemCode"
+                :label="item.name"
+              >
+              </el-option>
+            </el-select>
+          </div>
+        </div>
+        <div class="search-item">
+          <span class="label">日期:</span>
+          <div class="search-content">
+            <el-date-picker
+              v-model="state.dateTime"
+              size="mini"
+              type="datetimerange"
+              range-separator="-"
+              format="YYYY-MM-DD HH:mm:ss"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              start-placeholder="开始"
+              end-placeholder="结束"
+              popper-class="date-select"
+            >
+            </el-date-picker>
+          </div>
+        <el-button class="buttons" round size="mini">查询</el-button>
+        </div>
+      </div>
+      <div class="btns">
+        <el-button
+          size="mini"
+          class="buttons"
+          @click="export2Excel"
+          round
+        >
+          导出</el-button
+        >
+      </div>
+    </div>
+
+    <div class="table-wrapper">
+      <div class="leftContent">
+        <span>{{ pageTitle }}</span>
+      </div>
+      <el-table
+        size="mini"
+        :data="state.tableData"
+        height="calc(100% - 35px - 55px)"
+        style="width: 100%"
+        stripe
+      >
+        <el-table-column label="部件功率统计表">
+            <el-table-column label="机组"
+                prop="projectname"
+                width="200"
+                header-align="center"
+                align="center"
+            >
+                <template #default="scope">
+                    <el-button type="text" style="color: #05bb4c">{{scope.row.projectname}}</el-button>
+                </template>
+            </el-table-column>
+            <el-table-column label="0kw-150kw">
+                <el-table-column
+                    v-for="item in state.tableHeader"
+                    :label="item.title"
+                    :prop="item.code"
+                    :key="item.code"
+                    :width="item.width || ''"
+                    show-overflow-tooltip
+                    align="center"
+                >
+                </el-table-column>
+            </el-table-column>
+            <el-table-column label="150kw-300kw">
+                <el-table-column
+                    v-for="item in state.tableHeader1"
+                    :label="item.title"
+                    :prop="item.code"
+                    :key="item.code"
+                    :width="item.width || ''"
+                    show-overflow-tooltip
+                    align="center"
+                >
+                </el-table-column>
+            </el-table-column>
+            <el-table-column label="300kw-450kw">
+                <el-table-column
+                    v-for="item in state.tableHeader2"
+                    :label="item.title"
+                    :prop="item.code"
+                    :key="item.code"
+                    :width="item.width || ''"
+                    show-overflow-tooltip
+                    align="center"
+                >
+                </el-table-column>
+            </el-table-column>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-wrapper">
+        <el-pagination
+          layout="total, sizes, prev, pager, next"
+          :current-page="query.page"
+          :page-size="query.limit"
+          :page-sizes="[21, 100, 500, 1000]"
+          :total="query.pageTotal"
+          @size-change="
+            (value) => {
+              query.page = 1;
+              query.limit = value;
+              getAlarmHistoryt();
+            }
+          "
+          @current-change="handlePageChange"
+        ></el-pagination>
+      </div>
+    </div>
+    <HealthReport ref="healthReportRef"></HealthReport>
+  </div>
+</template>
+
+<script setup name="partsTemperatureAnalyse">
+import { getStation } from "@/api/performance";
+import { getApiequipmentListByWp } from "@/api/monthlyPerformanceAnalysis.js";
+import { watch, reactive, nextTick, computed, onMounted, ref } from "vue";
+import { useRouter, useRoute } from "vue-router";
+import BASE from "@/tools/basicTool.js";
+import dayjs from "dayjs";
+import HealthReport from "@com/other/healthReport/index.vue";
+import {
+  alarm_history,
+  new_alarm_history,
+  fetchWindturbineList,
+  fetchModel,
+  fetchRelatePartAndAlarmType,
+  getWpList,
+  confirmAlart,
+} from "@/api/zhbj/index.js";
+import { ElMessageBox, ElMessage } from "element-plus";
+import { outExportExcel } from "@/tools/excel/exportExcel.js"; //引入文件
+import { useStore } from "vuex";
+const pageTitle = "各出力部件温度分析";
+const store = useStore();
+
+const route = useRoute();
+
+const healthReportRef = ref()
+
+onMounted(() => {
+  state.dateTime = [
+    dayjs().startOf("day").format("YYYY-MM-DD HH:mm:ss"),
+    dayjs().format("YYYY-MM-DD HH:mm:ss"),
+  ];
+  if (route.query.deviceType != "booststation") {
+    state.deviceId = route.query.deviceId || "";
+    state.alarmId = route.query.alarmId || "";
+    state.modelId = route.query.modelId || "";
+  } else {
+    state.stationName = route.query.deviceId;
+    state.deviceId = "";
+    state.alarmId = route.query.alarmId || "";
+  }
+
+  getAlarmHistoryt()
+  //   if (route.query.ts) {
+  //     state.dateTime = [
+  //       `${dayjs(Number(route.query.ts)).format("YYYY-MM-DD")} 00:00:00`,
+  //       dayjs(Number(route.query.ts)).format("YYYY-MM-DD HH:mm:ss"),
+  //     ];
+  //   }
+  // getStationList(); //场站
+  getequipmentmodel_list(); //机型
+  getfetchRelatePart(); //部件
+});
+// 机型
+const getequipmentmodel_list = async () => {
+  const { data } = await fetchModel();
+  state.modelListAll = data;
+};
+//所属部件
+const getfetchRelatePart = async () => {
+  const { data } = await fetchRelatePartAndAlarmType();
+  state.fetchListAll = data;
+};
+
+const confirmItem = (alarmItem) => {
+  ElMessageBox("您确定要执行此操作吗?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  })
+    .then(() => {
+      confirmAlart(alarmItem)
+        .then((res) => {
+          if (res.code === 200) {
+            ElMessage.success("确认成功");
+            store.commit("removeWarning", alarmItem);
+            getAlarmHistoryt();
+          }
+        })
+        .catch(() => {
+          ElMessage.error("确认失败,请重试");
+        });
+    })
+    .catch(() => {});
+};
+
+const getColumnStyle = (columnItem) => {
+  let style = "color:";
+  if (columnItem.endts) {
+    style += " #05bb4c";
+  } else {
+    style += "var(--el-color-danger)";
+  }
+  return style;
+};
+
+const state = reactive({
+  stationId: "",
+  stationName: "",
+  alarmId: "",
+  windturbineList: [],
+  deviceId: "",
+  modelListAll: {},
+  fetchListAll: {},
+  modelId: "", //型号
+  components: "", //部件
+  description: "", //描述
+  dateTime: [],
+  startDate: null,
+  endDate: null,
+  tableData: [],
+  isshowwindturbineName: true,
+  ts: "",
+  tableHeader: [
+    { title: "发电机U相绕组温度", code: "U_150", width: "150" },
+    { title: "发电机V相绕组温度", code: "V_150", width: "150" },
+    { title: "发电机W相绕组温度", code: "W_150", width: "150" },
+    { title: "发电机冷却风温度", code: "X_150", width: "180" },
+    { title: "发电机轴承温度A", code: "A_150", width: "150" }
+  ],
+  tableHeader1: [
+    { title: "发电机U相绕组温度", code: "U_300", width: "150" },
+    { title: "发电机V相绕组温度", code: "V_300", width: "150" },
+    { title: "发电机W相绕组温度", code: "W_300", width: "150" },
+    { title: "发电机冷却风温度", code: "X_300", width: "180" },
+    { title: "发电机轴承温度A", code: "A_300", width: "150" }
+  ],
+  tableHeader2: [
+    { title: "发电机U相绕组温度", code: "U_450", width: "150" },
+    { title: "发电机V相绕组温度", code: "V_450", width: "150" },
+    { title: "发电机W相绕组温度", code: "W_450", width: "150" },
+    { title: "发电机冷却风温度", code: "X_450", width: "180" },
+    { title: "发电机轴承温度A", code: "A_450", width: "150" }
+  ],
+});
+// 场站列表/升压站列表
+const stationList = ref([]);
+//获取场站列表
+const getStationList = async () => {
+  const { data } = await getStation({
+    companyids: 0,
+    type: state.typeVal == "windturbine" ? -1 : -2,
+  });
+
+  stationList.value = data.data;
+
+  state.stationId = stationList.value[0]?.id;
+  getWindturbineList();
+  //   if (state.deviceId && state.typeVal != "booststation") {
+  //     let station = data.data.find((i) => {
+  //       let st = i.id.split("_")[2];
+  //       let dt = state.deviceId.split("_")[2];
+  //       if (st == dt) {
+  //         return i;
+  //       }
+  //     });
+  //     state.stationId = station?.id;
+  //   } else if (state.typeVal == "booststation") {
+  //     let station = data.data.find((i) => i.name == state.stationName);
+  //     state.stationId = station ? station?.id : data.data[0]?.id;
+  //   } else {
+  //     state.stationId = data.data[0]?.id;
+  //   }
+
+  //   state.stationId = route.query.stationId || state.stationId;
+  //   route.query.stationId ? (state.modelId = modelList.value?.[0]?.id || "") : "";
+  if (stationList.value.length) {
+  }
+};
+
+// watch(
+//   () => stationList,
+//   (val, old) => {
+//     val?.value?.length &&
+//       nextTick(async () => {
+//         await getWindturbineList();
+//       });
+//   },
+//   {
+//     deep: true,
+//     immediate: true,
+//   }
+// );
+watch(
+  () => route,
+  (val, old) => {
+    // if (route.query.deviceType != "booststation") {
+    //   state.deviceId = route.query.deviceId || "";
+    //   state.alarmId = route.query.alarmId || "";
+    //   state.modelId = route.query.modelId || "";
+    // } else {
+    //   state.stationName = route.query.deviceId;
+    //   state.deviceId = "";
+    //   state.alarmId = route.query.alarmId || "";
+    // }
+    state.isshowwindturbineName =
+      state.typeVal == "booststation" ? false : true;
+    getStationList();
+  },
+  {
+    deep: true,
+    immediate: true,
+  }
+);
+//型号列表
+const modelList = computed(() => {
+  return [
+    {
+      id: "SEC-W02B-1250kW",
+      nemCode: "SEC-W02B-1250kW",
+      name: "SEC-W02B-1250kW",
+      aname: "SEC-W02B-1250kW",
+      description: "DI",
+      powerProduction: 1250,
+      windturbineManufacturerId: "SHDQ_MF",
+      photo: null,
+      unit: null,
+      cutinwindSpeed: 3,
+      ratedwindSpeed: 11,
+      cutoutwindSpeed: "25",
+      sweptArea: 5800,
+      equipmentCategory: "F",
+    },
+  ];
+  //   if (state.typeVal != "booststation") {
+  //     if (state.stationId == "") {
+  //       return [];
+  //     } else {
+  //       state.modelId = route.query.deviceId ? route.query.modelId : "";
+  //       return state.modelListAll[state.stationId];
+  //     }
+  //   } else {
+  //     return [];
+  //   }
+});
+//部件列表
+const componentList = computed(() => {
+  return [
+    {
+      id: "1",
+      category: "alertrule_category",
+      nemCode: "YP",
+      name: "叶片",
+      orderNumber: 1,
+      enable: 1,
+    },
+    {
+      id: "2",
+      category: "alertrule_category",
+      nemCode: "LG",
+      name: "轮毂",
+      orderNumber: 2,
+      enable: 1,
+    },
+    {
+      id: "3",
+      category: "alertrule_category",
+      nemCode: "TJ",
+      name: "塔架",
+      orderNumber: 3,
+      enable: 1,
+    },
+    {
+      id: "4",
+      category: "alertrule_category",
+      nemCode: "JC",
+      name: "机舱",
+      orderNumber: 4,
+      enable: 1,
+    },
+    {
+      id: "5",
+      category: "alertrule_category",
+      nemCode: "KZXT",
+      name: "控制系统",
+      orderNumber: 5,
+      enable: 1,
+    },
+    {
+      id: "6",
+      category: "alertrule_category",
+      nemCode: "BJXT",
+      name: "变桨系统",
+      orderNumber: 6,
+      enable: 1,
+    },
+    {
+      id: "7",
+      category: "alertrule_category",
+      nemCode: "PHXT",
+      name: "偏航系统",
+      orderNumber: 7,
+      enable: 1,
+    },
+    {
+      id: "8",
+      category: "alertrule_category",
+      nemCode: "CLX",
+      name: "齿轮箱",
+      orderNumber: 8,
+      enable: 1,
+    },
+    {
+      id: "9",
+      category: "alertrule_category",
+      nemCode: "FDJ",
+      name: "发电机",
+      orderNumber: 9,
+      enable: 1,
+    },
+    {
+      id: "10",
+      category: "alertrule_category",
+      nemCode: "BPQ",
+      name: "变频器",
+      orderNumber: 10,
+      enable: 1,
+    },
+    {
+      id: "11",
+      category: "alertrule_category",
+      nemCode: "YYXT",
+      name: "液压系统",
+      orderNumber: 11,
+      enable: 1,
+    },
+    {
+      id: "12",
+      category: "alertrule_category",
+      nemCode: "FZXT",
+      name: "辅助系统",
+      orderNumber: 12,
+      enable: 1,
+    },
+    {
+      id: "13",
+      category: "alertrule_category",
+      nemCode: "CFXT",
+      name: "测风系统",
+      orderNumber: 13,
+      enable: 1,
+    },
+    {
+      id: "14",
+      category: "alertrule_category",
+      nemCode: "DWXT",
+      name: "电网系统",
+      orderNumber: 14,
+      enable: 1,
+    },
+    {
+      id: "15",
+      category: "alertrule_category",
+      nemCode: "TDG",
+      name: "塔底柜",
+      orderNumber: 15,
+      enable: 1,
+    },
+    {
+      id: "16",
+      category: "alertrule_category",
+      nemCode: "CDL",
+      name: "传动链",
+      orderNumber: 16,
+      enable: 1,
+    },
+    {
+      id: "17",
+      category: "alertrule_category",
+      nemCode: "QT",
+      name: "其他",
+      orderNumber: 17,
+      enable: 1,
+    },
+    {
+      id: "42",
+      category: "alertrule_category",
+      nemCode: "CGQ",
+      name: "传感器",
+      orderNumber: 19,
+      enable: 1,
+    },
+    {
+      id: "41",
+      category: "alertrule_category",
+      nemCode: "BYQ",
+      name: "变压器",
+      orderNumber: 18,
+      enable: 1,
+    },
+    {
+      id: "44",
+      category: "alertrule_category",
+      nemCode: "ZZ",
+      name: "主轴",
+      orderNumber: 20,
+      enable: 1,
+    },
+  ];
+  //   if (state.typeVal != "booststation") {
+  //     if (state.stationId == "") {
+  //       return [];
+  //     } else {
+  //       if (state.stationId.includes("FDC")) {
+  //         return state.fetchListAll?.fjbj;
+  //       } else {
+  //         return state.fetchListAll?.gfbj;
+  //       }
+  //     }
+  //   } else {
+  //     return [];
+  //   }
+});
+//get 风机
+const getWindturbineList = async () => {
+  state.deviceId = "";
+
+  //   const { data } = await getApiequipmentListByWp({ wpid: state.stationId });
+
+  state.windturbineList = [
+    {
+      id: "SXJ_KGDL_XWT_F_WT_0001_EQ",
+      nemCode: "#1",
+      windpowerstationId: "SXJ_KGDL_XWT_FDC_STA",
+      longitude: 112.415335,
+      latitude: 40.281307,
+      modelId: "SEC-W02B-1250kW",
+      status: "NULL",
+      projectId: "SXJ_KGDL_XWTF01_EG",
+      lineId: "SXJ_KGDL_XWTF01_LN",
+      firstIntegratedTime: "2008-07-27T16:00:00.000+0000",
+      photo: "NULL",
+      name: "01号风机",
+      aname: "#1",
+      isStandard: 1,
+      regionId: "SXJ_RGN",
+      companyId: "SXJ_KGDL_FLFD_ZGS",
+      isable: 1,
+      equipmentCategory: -1,
+      parentId: "NULL",
+      squareId: "NULL",
+      spare1: "WT",
+      spare2: "1",
+      spare3: "NULL",
+      spare4: "NULL",
+      orderNum: 271,
+      substationId: "SXJ_KGDL_XWTF01_SBS",
+    },
+  ];
+  //   state.modelId = modelList.value?.[0]?.id || "";
+  await getAlarmHistoryt();
+};
+const query = reactive({
+  page: 1,
+  limit: 21,
+  pageTotal: null,
+});
+
+const export2Excel = () =>{
+    healthReportRef.value.dialogVisible = true
+}
+
+// 获取历史记录表
+const getAlarmHistoryt = async () => {
+  //   if (route.params.deviceId && route.params.alarmId) {
+  //     state.stationId = "";
+  //   }
+  //   BASE.showLoading();
+  //   let params = {
+  //     pageNum: query.page,
+  //     pageSize: query.limit,
+  //     alarmId: state.alarmId,
+  //     alarmType: state.typeVal,
+  //     stationid: state.stationId,
+  //     deviceid: state.typeVal == "booststation" ? "" : state.deviceId,
+  //     modelId: state.typeVal == "booststation" ? "" : state.modelId,
+  //     components: state.components,
+  //     description: state.description,
+  //     begin: state.dateTime[0],
+  //     end: state.dateTime[1],
+  //   };
+  //   const { data } = await alarm_history(params);
+  //   BASE.closeLoading();
+  //   query.pageTotal = data?.total;
+  //   data?.ls?.forEach((ele) => {
+  //     ele.isCloseName = ele.endts ? "已解除" : "未解除";
+  //     ele.alarmTypeName =
+  //       ele.alarmType === "booststation"
+  //         ? "升压站"
+  //         : ele.alarmType === "windturbine"
+  //         ? "风机"
+  //         : ele.alarmType === "inverter"
+  //         ? "光伏"
+  //         : "";
+  //     ele.endtsName = ele.endts > 0 ? formatTime(ele.endts) : "--";
+  //   });
+  //   state.tableData = data?.ls;
+  state.tableData = new Array(20).fill({
+    modelId: "SEC-W02B-1250kW",
+    projectid: "SXJ_KGDL_XWTF01_EG",
+    projectname: "一期项目",
+    U_150: 52.1,
+    V_150: 48.9,
+    W_150: 47.1,
+    X_150: 58.5,
+    A_150: 52.2,
+    U_300: 55.8,
+    V_300: 48.3,
+    W_300: 53.1,
+    X_300: 57.2,
+    A_300: 54.5,
+    U_450: 52.3,
+    V_450: 46.1,
+    W_450: 48.5,
+    X_450: 49.8,
+    A_450: 51.2
+  });
+};
+
+
+// 分页导航
+const handlePageChange = (val) => {
+  query.page = val;
+  getAlarmHistoryt();
+};
+// 时间格式化
+const formatTime = (val) => {
+  return dayjs(val).format("YYYY-MM-DD HH:mm:ss");
+};
+// 格式化
+const obj = {
+  1: "低级",
+  2: "低中级",
+  3: "中级",
+  4: "中高级",
+  5: "高级",
+  booststation: "升压站",
+  inverter: "光伏",
+  windturbine: "风机",
+};
+const messageTypeObj = {
+  1: "触发",
+  3: "解除",
+};
+const tableFilter = (val) => {
+  return obj[val];
+};
+const messageTypeFilter = (val) => {
+  return messageTypeObj[val];
+};
+</script>
+
+<style scoped lang="less">
+p {
+  padding: 0;
+  margin: 0;
+}
+.history-warning {
+  height: 100%;
+  width: 100%;
+  padding: 0 20px;
+  padding-bottom: 10px;
+  .form-wrapper ::v-deep {
+    display: flex;
+    flex-direction: column;
+    padding-top: 10px;
+    position: relative;
+    .search-wrapper {
+      display: flex;
+      align-items: center;
+      font-size: 14px;
+      font-family: Microsoft YaHei;
+      font-weight: 400;
+      color: #b3b3b3;
+      margin-bottom: 10px;
+      .search-item {
+        display: flex;
+        margin-right: 10px;
+        max-width: 450px;
+        align-items: center;
+        .label {
+          margin-right: 10px;
+          text-align: right;
+          white-space: nowrap;
+          // width: 60px;
+        }
+        .search-content {
+          flex: 1;
+        }
+      }
+    }
+
+    .btns {
+      display: flex;
+      justify-content: flex-end;
+      margin-right: 10px;
+      position: absolute;
+      right: 0;
+      top: 53px;
+    }
+
+    .buttons {
+        margin-left: 10px;
+      background-color: rgba(5, 187, 76, 0.2);
+      border: 1px solid #3b6c53;
+      color: #b3b3b3;
+      font-size: 14px;
+
+      &:hover {
+        background-color: rgba(5, 187, 76, 0.5);
+        color: #ffffff;
+      }
+    }
+  }
+  .table-wrapper {
+    height: calc(100% - 43px);
+    width: 100%;
+    .leftContent {
+      width: 242px;
+      height: 41px;
+      display: flex;
+      align-items: center;
+      background: url("~@/assets/imgs/title_left_bg1.png") no-repeat;
+
+      span {
+        font-size: 16px;
+        font-family: Microsoft YaHei;
+        font-weight: 400;
+        color: #05bb4c;
+        margin-left: 25px;
+      }
+    }
+    .pagination-wrapper :deep {
+      text-align: right;
+      margin-top: 10px;
+    }
+  }
+}
+</style>

+ 396 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/barChart.json

@@ -0,0 +1,396 @@
+{
+    "color": [
+        "#db60c8",
+        "#c12e34",
+        "#e6b600d9",
+        "#0098d9",
+        "#465a83",
+        "#005eaa",
+        "#cda819",
+        "#32a487"
+    ],
+    "backgroundColor": "rgba(0,0,0,0)",
+    "textStyle": {},
+    "title": {
+        "textStyle": {
+            "color": "#000"
+        },
+        "subtextStyle": {
+            "color": "#000"
+        }
+    },
+    "line": {
+        "itemStyle": {
+            "borderWidth": 1
+        },
+        "lineStyle": {
+            "width": 2
+        },
+        "symbolSize": 4,
+        "symbol": "emptyCircle",
+        "smooth": false
+    },
+    "radar": {
+        "itemStyle": {
+            "borderWidth": 1
+        },
+        "lineStyle": {
+            "width": 2
+        },
+        "symbolSize": 4,
+        "symbol": "emptyCircle",
+        "smooth": false
+    },
+    "bar": {
+        "itemStyle": {
+            "barBorderWidth": 0,
+            "barBorderColor": "#ccc"
+        },
+        "barMaxWidth": 50
+    },
+    "pie": {
+        "itemStyle": {
+            "borderWidth": 0,
+            "borderColor": "#ccc"
+        }
+    },
+    "scatter": {
+        "itemStyle": {
+            "borderWidth": 0,
+            "borderColor": "#ccc"
+        }
+    },
+    "boxplot": {
+        "itemStyle": {
+            "borderWidth": 0,
+            "borderColor": "#ccc"
+        }
+    },
+    "parallel": {
+        "itemStyle": {
+            "borderWidth": 0,
+            "borderColor": "#ccc"
+        }
+    },
+    "sankey": {
+        "itemStyle": {
+            "borderWidth": 0,
+            "borderColor": "#ccc"
+        }
+    },
+    "funnel": {
+        "itemStyle": {
+            "borderWidth": 0,
+            "borderColor": "#ccc"
+        }
+    },
+    "gauge": {
+        "itemStyle": {
+            "borderWidth": 0,
+            "borderColor": "#ccc"
+        }
+    },
+    "candlestick": {
+        "itemStyle": {
+            "color": "#c12e34",
+            "color0": "#2b821d",
+            "borderColor": "#c12e34",
+            "borderColor0": "#2b821d",
+            "borderWidth": 1
+        }
+    },
+    "graph": {
+        "itemStyle": {
+            "borderWidth": 0,
+            "borderColor": "#ccc"
+        },
+        "lineStyle": {
+            "width": 1,
+            "color": "#aaaaaa"
+        },
+        "symbolSize": 4,
+        "symbol": "emptyCircle",
+        "smooth": false,
+        "color": [
+            "#c12e34",
+            "#e6b600",
+            "#0098d9",
+            "#50ec39",
+            "#005eaa",
+            "#339ca8",
+            "#cda819",
+            "#32a487"
+        ],
+        "label": {
+            "color": "#eeeeee"
+        }
+    },
+    "map": {
+        "itemStyle": {
+            "areaColor": "#ddd",
+            "borderColor": "#eee",
+            "borderWidth": 0.5
+        },
+        "label": {
+            "color": "#c12e34"
+        },
+        "emphasis": {
+            "itemStyle": {
+                "areaColor": "#e6b600",
+                "borderColor": "#ddd",
+                "borderWidth": 1
+            },
+            "label": {
+                "color": "#c12e34"
+            }
+        }
+    },
+    "geo": {
+        "itemStyle": {
+            "areaColor": "#ddd",
+            "borderColor": "#eee",
+            "borderWidth": 0.5
+        },
+        "label": {
+            "color": "#c12e34"
+        },
+        "emphasis": {
+            "itemStyle": {
+                "areaColor": "#e6b600",
+                "borderColor": "#ddd",
+                "borderWidth": 1
+            },
+            "label": {
+                "color": "#c12e34"
+            }
+        }
+    },
+    "categoryAxis": {
+        "axisLine": {
+            "show": true,
+            "lineStyle": {
+                "color": "#838383"
+            }
+        },
+        "axisTick": {
+            "show": true,
+            "lineStyle": {
+                "color": "#838383"
+            }
+        },
+        "axisLabel": {
+            "show": true,
+            "color": "#838383"
+        },
+        "splitLine": {
+            "show": false,
+            "lineStyle": {
+                "color": [
+                    "#ccc"
+                ]
+            }
+        },
+        "splitArea": {
+            "show": false,
+            "areaStyle": {
+                "color": [
+                    "rgba(250,250,250,0.3)",
+                    "rgba(200,200,200,0.3)"
+                ]
+            }
+        }
+    },
+    "valueAxis": {
+        "axisLine": {
+            "show": true,
+            "lineStyle": {
+                "color": "#838383"
+            }
+        },
+        "axisTick": {
+            "show": true,
+            "lineStyle": {
+                "color": "#838383"
+            }
+        },
+        "axisLabel": {
+            "show": true,
+            "color": "#838383"
+        },
+        "splitLine": {
+            "show": true,
+            "lineStyle": {
+                "color": [
+                    "#ccc"
+                ]
+            }
+        },
+        "splitArea": {
+            "show": false,
+            "areaStyle": {
+                "color": [
+                    "rgba(250,250,250,0.3)",
+                    "rgba(200,200,200,0.3)"
+                ]
+            }
+        }
+    },
+    "logAxis": {
+        "axisLine": {
+            "show": true,
+            "lineStyle": {
+                "color": "#838383"
+            }
+        },
+        "axisTick": {
+            "show": true,
+            "lineStyle": {
+                "color": "#838383"
+            }
+        },
+        "axisLabel": {
+            "show": true,
+            "color": "#838383"
+        },
+        "splitLine": {
+            "show": true,
+            "lineStyle": {
+                "color": [
+                    "#ccc"
+                ]
+            }
+        },
+        "splitArea": {
+            "show": false,
+            "areaStyle": {
+                "color": [
+                    "rgba(250,250,250,0.3)",
+                    "rgba(200,200,200,0.3)"
+                ]
+            }
+        }
+    },
+    "timeAxis": {
+        "axisLine": {
+            "show": true,
+            "lineStyle": {
+                "color": "#838383"
+            }
+        },
+        "axisTick": {
+            "show": true,
+            "lineStyle": {
+                "color": "#838383"
+            }
+        },
+        "axisLabel": {
+            "show": true,
+            "color": "#838383"
+        },
+        "splitLine": {
+            "show": true,
+            "lineStyle": {
+                "color": [
+                    "#ccc"
+                ]
+            }
+        },
+        "splitArea": {
+            "show": false,
+            "areaStyle": {
+                "color": [
+                    "rgba(250,250,250,0.3)",
+                    "rgba(200,200,200,0.3)"
+                ]
+            }
+        }
+    },
+    "toolbox": {
+        "iconStyle": {
+            "borderColor": "#06467c"
+        },
+        "emphasis": {
+            "iconStyle": {
+                "borderColor": "#4187c2"
+            }
+        }
+    },
+    "legend": {
+        "textStyle": {
+            "color": "#838383"
+        }
+    },
+    "tooltip": {
+        "axisPointer": {
+            "lineStyle": {
+                "color": "#cccccc",
+                "width": 1
+            },
+            "crossStyle": {
+                "color": "#cccccc",
+                "width": 1
+            }
+        }
+    },
+    "timeline": {
+        "lineStyle": {
+            "color": "#005eaa",
+            "width": 1
+        },
+        "itemStyle": {
+            "color": "#005eaa",
+            "borderWidth": 1
+        },
+        "controlStyle": {
+            "color": "#005eaa",
+            "borderColor": "#005eaa",
+            "borderWidth": 0.5
+        },
+        "checkpointStyle": {
+            "color": "#005eaa",
+            "borderColor": "#316bc2"
+        },
+        "label": {
+            "color": "#005eaa"
+        },
+        "emphasis": {
+            "itemStyle": {
+                "color": "#005eaa"
+            },
+            "controlStyle": {
+                "color": "#005eaa",
+                "borderColor": "#005eaa",
+                "borderWidth": 0.5
+            },
+            "label": {
+                "color": "#005eaa"
+            }
+        }
+    },
+    "visualMap": {
+        "color": [
+            "#1790cf",
+            "#a2d4e6"
+        ]
+    },
+    "dataZoom": {
+        "backgroundColor": "rgba(47,69,84,0)",
+        "dataBackgroundColor": "rgba(47,69,84,0.3)",
+        "fillerColor": "rgba(167,183,204,0.4)",
+        "handleColor": "#a7b7cc",
+        "handleSize": "100%",
+        "textStyle": {
+            "color": "#838383B3B3B3"
+        }
+    },
+    "markPoint": {
+        "label": {
+            "color": "#eeeeee"
+        },
+        "emphasis": {
+            "label": {
+                "color": "#eeeeee"
+            }
+        }
+    }
+}

+ 235 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/barChart.vue

@@ -0,0 +1,235 @@
+<script setup>
+import util from "@tools/util";
+import chartTheme from "./barChart.json";
+import { ref, toRaw, computed, onMounted, watch, nextTick } from "vue";
+import { useStore } from "vuex";
+import * as echarts from "echarts";
+const chartId = "chart-" + util.newGUID(); //chartId
+const chartIns = ref(null); //chart 实例
+const emits = defineEmits(["getSelected"]);
+const props = defineProps({
+  xAxis: {
+    type: Object,
+    required: true,
+    default: () => ({}),
+  },
+  yAxis: {
+    type: Array,
+    required: false,
+  },
+  series: {
+    type: Array,
+    required: true,
+  },
+  dataset: {
+    type: Array,
+    required: false,
+    default: () => [],
+  },
+  height: {
+    type: String,
+    required: false,
+    default: "500px",
+  },
+  width: {
+    type: String,
+    required: false,
+    default: "500px",
+  },
+  title: {
+    type: String,
+    required: false,
+  },
+  subtext: {
+    type: String,
+    required: false,
+  },
+  brush: {
+    type: Boolean,
+    required: false,
+    default: false,
+  },
+  theme: {
+    type: Boolean,
+    default: false,
+  },
+  echartsTheme: {
+    type: String,
+    default: "",
+  },
+});
+
+/**定义option */
+const option = computed({
+  get() {
+    return {
+      backgroundColor: "",
+      color: [
+        "rgb(50,93,171)",
+        "#0098d980",
+        "#626c91",
+        "#a0a7e6",
+        "#c4ebad",
+        "#96dee8",
+      ],
+      title: {
+        text: props.title || "",
+        subtext: props.subtext || "",
+        top: -6,
+        right: 360,
+      },
+      xAxis: props.xAxis || {},
+      yAxis: props.yAxis || {},
+      brush: {
+        seriesIndex: [1],
+        yAxisIndex: 0,
+        transformable: true,
+        throttleType: "debounce",
+        throttleDelay: 1000,
+        removeOnClick: true,
+        brushType: props.brush ? "polygon" : false,
+        brushMode: "multiple",
+        brushStyle: {
+          borderWidth: 1,
+          borderColor: "#ff2424",
+        },
+      },
+      toolbox: {
+        show: props.brush,
+      },
+      tooltip: {
+        confine: true,
+        trigger: "axis",
+      },
+      dataset: props.dataset || [],
+      series: props.series || [],
+      legend: {
+        right: "120",
+        top: "5",
+        itemWidth: 6,
+      },
+      grid: {
+        top: 80,
+        left: 40,
+        right: 40,
+        bottom: 40,
+      },
+      dataZoom: [
+        {
+          type: "inside", //图表下方的伸缩条
+          show: false, //是否显示
+          realtime: true, //拖动时,是否实时更新系列的视图
+          start: 0, //伸缩条开始位置(1-100),可以随时更改
+          end: 100, //伸缩条结束位置(1-100),可以随时更改
+        },
+        {
+          type: "slider", //图表下方的伸缩条
+          show: false, //是否显示
+          realtime: true, //拖动时,是否实时更新系列的视图
+          start: 0, //伸缩条开始位置(1-100),可以随时更改
+          end: 100, //伸缩条结束位置(1-100),可以随时更改
+        },
+      ],
+    };
+  },
+  set(val) {},
+});
+watch(
+  () => option,
+  (newVal, oldVal) => {
+    if (chartIns.value) {
+      const echartIns = toRaw(chartIns.value);
+      echartIns.setOption(toRaw(newVal.value));
+    }
+  },
+  {
+    deep: true,
+  }
+);
+
+watch([() => props.width, () => props.height], (newVal, oldVal) => {
+  if (chartIns.value) {
+    const echartIns = toRaw(chartIns.value);
+    nextTick(() => echartIns.resize());
+  }
+});
+const store = useStore();
+const collapse = computed({
+  get() {
+    return store.state.collapse;
+  },
+  set(val) {},
+});
+watch(collapse, (val) => {
+  if (chartIns.value) {
+    setTimeout(() => {
+      chartIns.value.resize();
+    }, 300);
+  }
+});
+const funBrushChange = (flag) => {
+  const echartIns = toRaw(chartIns.value);
+  echartIns.dispatchAction({
+    type: "takeGlobalCursor",
+    // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+    key: "brush",
+    brushOption: {
+      seriesIndex: [1],
+      yAxisIndex: 0,
+      transformable: true,
+      throttleType: "debounce",
+      throttleDelay: 1000,
+      removeOnClick: true,
+      brushType: flag ? "polygon" : false,
+      brushMode: "multiple",
+      brushStyle: {
+        borderWidth: 1,
+        color: "rgba(255,36,36,0.2)",
+        borderColor: "#ff2424",
+      },
+    },
+  });
+  echartIns.off("brushSelected");
+  echartIns.on("brushSelected", (params) => {
+    emits("getSelected", params.batch || []);
+  });
+};
+watch(
+  () => props.brush,
+  (newVal, oldVal) => funBrushChange(newVal)
+);
+
+onMounted(() => {
+  nextTick(() => {
+    init();
+  });
+});
+
+watch(
+  () => props.echartsTheme,
+  (newVal, oldVal) => init()
+);
+
+const init = () => {
+  echarts.registerTheme("chartTheme", chartTheme);
+  const echartIns = echarts.init(
+    document.getElementById(chartId),
+    props.echartsTheme
+  );
+  document.getElementById(chartId).removeAttribute("_echarts_instance_")
+    ? document.getElementById(chartId).removeAttribute("_echarts_instance_")
+    : "";
+  chartIns.value = echartIns;
+  echartIns.setOption(option.value);
+  funBrushChange(props.brush);
+  window.addEventListener("resize", () => {
+    echartIns.resize();
+  });
+};
+</script>
+<template>
+  <div
+    :id="chartId"
+    :style="{ height: props.height, width: props.width }"
+  ></div>
+</template>

+ 386 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/barLineChart.vue

@@ -0,0 +1,386 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@/helper/util.js";
+import partten from "@/helper/partten.js";
+import * as echarts from "echarts";
+
+export default {
+  name: "multiple-bar-chart",
+  componentName: "multiple-bar-chart",
+  props: {
+    width: {
+      type: String,
+      default: "100%",
+    },
+    height: {
+      type: String,
+      default: "800px",
+    },
+    // 传入数据
+    bardata: {
+      type: Object,
+      default: () => {
+        return {
+          area: [
+            "风场1",
+            "风场2",
+            "风场3",
+            "风场4",
+            "风场5",
+            "风场6",
+            "风场7",
+            "风场8",
+            "风场9",
+          ],
+          legend: [
+            "实际电量",
+            "计划检修损失",
+            "非计划检修损失",
+            "限电损失",
+            "受累损失",
+            "性能损失",
+            "理论发电量",
+          ],
+          data: [
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+          ],
+        };
+      },
+    },
+    lineData: {
+      type: Array,
+      default: () => [200, 350, 400, 500, 600, 700, 800, 900, 1200],
+    },
+    lineName: {
+      type: String,
+      default: "损失电量",
+    },
+    // 单位
+    units: {
+      type: Array,
+      default: () => ["(万KWh)", "(风速)"],
+    },
+    // 显示 legend
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 颜色
+    color: {
+      type: Array,
+      default: () => [
+        "#323E6F",
+        "#e17e23",
+        "#ba3237",
+        "#c531c7",
+        "#ffffff",
+        "#EDEB2F",
+      ],
+    },
+    // 每页显示个数
+    pageSize: {
+      type: Number,
+      default: 20,
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      themeName: "light",
+      areaData: [],
+    };
+  },
+  methods: {
+    initChart() {
+      let chart = echarts.init(this.$el);
+      this.chart = chart;
+      let option = {
+        color: this.color,
+        grid: {
+          left: 40,
+          right: 40,
+          bottom: 16,
+          top: 16,
+          containLabel: true,
+        },
+        legend: {
+          show: this.showLegend,
+          data: this.bardata.legend,
+          right: 56,
+          // icon: "ract",
+          itemWidth: 8,
+          itemHeight: 8,
+          inactiveColor:
+            this.themeName === "dark" ? partten.getColor("gray") : "#838383",
+          textStyle: {
+            color:
+              this.themeName === "dark" ? partten.getColor("grayl") : "#838383",
+            fontSize: 12,
+          },
+        },
+        tooltip: {
+          trigger: "axis",
+          backgroundColor: true
+            ? "rgba(255,255,255,0.9)"
+            : "rgba(255,255,255,0.9)",
+          borderColor:
+            this.themeName === "dark" ? partten.getColor("gray") : "#838383",
+          textStyle: {
+            color: this.themeName === "dark" ? "#fff" : "#838383",
+            fontSize: util.vh(16),
+          },
+        },
+        dataZoom: [
+          {
+            type: "inside",
+            start: 0,
+            end: this.end,
+            yAxisIndex: [0],
+          },
+          {
+            start: 0,
+            end: this.end,
+            top: 20,
+            bottom: 40,
+            yAxisIndex: [0],
+            backgroundColor: "transparent",
+            // handleIcon: "path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
+            handleStyle: {
+              color:
+                this.themeName === "dark"
+                  ? partten.getColor("green")
+                  : partten.getColor("blue"),
+            },
+            moveHandleSize: 0,
+            // dataBackground: {
+            //   lineStyle: {
+            //     color: partten.getColor("gray"),
+            //   },
+            //   areaStyle: {
+            //     color: partten.getColor("gray"),
+            //   },
+            // },
+            // selectedDataBackground: {
+            //   lineStyle: {
+            //     color: partten.getColor("yellow"),
+            //   },
+            //   areaStyle: {
+            //     color: partten.getColor("yellow"),
+            //   },
+            // },
+            fillerColor: "transparent",
+            textStyle: {
+              color:
+                this.themeName === "dark"
+                  ? partten.getColor("grayl")
+                  : "#838383",
+            },
+            borderColor:
+              this.themeName === "dark" ? partten.getColor("gray") : "#838383",
+            brushSelect: false,
+          },
+        ],
+        yAxis: [
+          {
+            type: "category",
+            axisLabel: {
+              color:
+                this.themeName === "dark"
+                  ? partten.getColor("gray")
+                  : "#838383",
+            },
+            inverse: true,
+            // minInterval: 10,
+            // maxInterval: 10,
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            data: this.areaData,
+          },
+        ],
+        xAxis: [
+          {
+            type: "value",
+            name: "万kWh",
+            axisLabel: {
+              color:
+                this.themeName === "dark"
+                  ? partten.getColor("gray")
+                  : "#838383",
+              // formatter: "{value}万kWh",
+            },
+            axisLine: {
+              type: "dashed",
+              lineStyle: {
+                color:
+                  this.themeName === "dark"
+                    ? partten.getColor("gray")
+                    : "#838383",
+              },
+              width: 5,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                type: "dashed",
+                dashOffset: 10,
+                color: this.themeName === "dark" ? "#5a6162" : "#838383" + 80,
+              },
+            },
+          },
+          {
+            type: "value",
+            name: "",
+            axisLabel: {
+              show: false,
+              // formatter: "{value}万kWh",
+              // color: partten.getColor("gray"),
+            },
+            axisLine: {
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        series: [],
+      };
+
+      if (this.bardata && this.bardata.legend)
+        // bar data
+        for (var i = 0; i < this.bardata.legend.length; i++) {
+          option.series.push({
+            name: this.bardata.legend[i].name,
+            type: "bar",
+            stack: "总量",
+            barWidth: 16,
+            label: {
+              show: false,
+              position: "insideRight",
+            },
+            data: this.bardata.data[i],
+          });
+        }
+
+      // line data
+      if (this.lineData.length > 0) {
+        option.series.push({
+          name: "理论发电量",
+          type: "line",
+          data: this.lineData,
+          smooth: false, //平滑展示
+          xAxisIndex: 1,
+          lineStyle: {
+            color:
+              this.themeName === "dark"
+                ? partten.getColor("green")
+                : partten.getColor("blue"),
+          },
+          itemStyle: {
+            color:
+              this.themeName === "dark"
+                ? partten.getColor("green")
+                : partten.getColor("blue"),
+          },
+        });
+      }
+      chart.setOption(option);
+      chart.resize();
+    },
+  },
+  created() {
+    this.id = "pie-chart-" + util.newGUID();
+    if (this.bardata.area && this.bardata.area.length < this.pageSize) {
+      this.areaData = this.bardata.area;
+      for (let i = this.bardata.area.length; i <= this.pageSize; i++) {
+        this.areaData.push("");
+      }
+    }
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  beforeUpdate() {
+    this.areaData = this.bardata.area;
+  },
+  beforeUpdate() {
+    this.areaData = this.bardata.area;
+  },
+  activated() {
+    this.$nextTick(() => {
+      this.$el.style.width = this.width;
+      this.$el.style.height = this.height;
+      this.initChart();
+    });
+  },
+  computed: {
+    collapse() {
+      return this.$store.state.collapse;
+    },
+    legend() {
+      return this.bardata.legend;
+    },
+    end() {
+      var result = 20;
+      if (this.areaData) {
+        result = parseInt((this.pageSize / this.areaData.length) * 100);
+      }
+      return result;
+    },
+  },
+  watch: {
+    collapse(val) {
+      if (this.chart) {
+        setTimeout(() => {
+          this.chart.resize();
+        }, 300);
+      }
+    },
+    bardata(val) {
+      if (val.area && val.area.length < this.pageSize) {
+        this.areaData = val.area;
+        for (let i = val.area.length; i <= this.pageSize; i++) {
+          this.areaData.push("");
+        }
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

+ 398 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/current-scatter-chart.json

@@ -0,0 +1,398 @@
+
+{
+	"color": [
+			"#1C99FF",
+			"#FF8700",
+			"#e6b600d9",
+			"#0098d9",
+			"#3D54BE",
+			"#005eaa",
+			"#cda819",
+			"#32a487"
+	],
+	"textStyle": {},
+	"title": {
+			"textStyle": {
+					"color": "#333333"
+			},
+			"subtextStyle": {
+					"color": "#aaaaaa"
+			}
+	},
+	"line": {
+			"itemStyle": {
+					"borderWidth": 1
+			},
+			"lineStyle": {
+					"width": 2
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"radar": {
+			"itemStyle": {
+					"borderWidth": 1
+			},
+			"lineStyle": {
+					"width": 2
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"bar": {
+			"itemStyle": {
+					"barBorderWidth": 0,
+					"barBorderColor": "#ccc"
+			}
+	},
+	"pie": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"scatter": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"boxplot": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"parallel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"sankey": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"funnel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"gauge": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"candlestick": {
+			"itemStyle": {
+					"color": "#c12e34",
+					"color0": "#2b821d",
+					"borderColor": "#c12e34",
+					"borderColor0": "#2b821d",
+					"borderWidth": 1
+			}
+	},
+	"graph": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			},
+			"lineStyle": {
+					"width": 1,
+					"color": "#aaaaaa"
+			},
+			"symbolSize": 4,
+			"symbol": "emptyCircle",
+			"smooth": false,
+			"color": [
+					"#c12e34",
+					"#e6b600",
+					"#0098d9",
+					"#50ec39",
+					"#005eaa",
+					"#339ca8",
+					"#cda819",
+					"#32a487"
+			],
+			"label": {
+					"color": "#eeeeee"
+			}
+	},
+	"map": {
+			"itemStyle": {
+					"areaColor": "#ddd",
+					"borderColor": "#eee",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#c12e34"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "#e6b600",
+							"borderColor": "#ddd",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#c12e34"
+					}
+			}
+	},
+	"geo": {
+			"itemStyle": {
+					"areaColor": "#ddd",
+					"borderColor": "#eee",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#c12e34"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "#e6b600",
+							"borderColor": "#ddd",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#c12e34"
+					}
+			}
+	},
+	"categoryAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#333"
+			},
+			"splitLine": {
+					"show": false,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"valueAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"logAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#333"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"timeAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisTick": {
+					"show": true,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#333"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#ccc"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.3)",
+									"rgba(200,200,200,0.3)"
+							]
+					}
+			}
+	},
+	"toolbox": {
+			"iconStyle": {
+					"borderColor": "#06467c"
+			},
+			"emphasis": {
+					"iconStyle": {
+							"borderColor": "#4187c2"
+					}
+			},
+			"textStyle": {
+				"color": "#838383"
+			}
+	},
+	"legend": {
+			"textStyle": {
+					"color": "#838383"
+			}
+	},
+	"tooltip": {
+			"axisPointer": {
+					"lineStyle": {
+							"color": "#cccccc",
+							"width": 1
+					},
+					"crossStyle": {
+							"color": "#cccccc",
+							"width": 1
+					}
+			}
+	},
+	"timeline": {
+			"lineStyle": {
+					"color": "#005eaa",
+					"width": 1
+			},
+			"itemStyle": {
+					"color": "#005eaa",
+					"borderWidth": 1
+			},
+			"controlStyle": {
+					"color": "#005eaa",
+					"borderColor": "#005eaa",
+					"borderWidth": 0.5
+			},
+			"checkpointStyle": {
+					"color": "#005eaa",
+					"borderColor": "#316bc2"
+			},
+			"label": {
+					"color": "#005eaa"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"color": "#005eaa"
+					},
+					"controlStyle": {
+							"color": "#005eaa",
+							"borderColor": "#005eaa",
+							"borderWidth": 0.5
+					},
+					"label": {
+							"color": "#005eaa"
+					}
+			}
+	},
+	"visualMap": {
+			"color": [
+					"#1790cf",
+					"#a2d4e6"
+			]
+	},
+	"dataZoom": {
+			"backgroundColor": "rgba(47,69,84,0)",
+			"dataBackgroundColor": "rgba(47,69,84,0.3)",
+			"fillerColor": "rgba(167,183,204,0.4)",
+			"handleColor": "#a7b7cc",
+			"handleSize": "100%",
+			"textStyle": {
+					"color": "#333333"
+			}
+	},
+	"markPoint": {
+			"label": {
+					"color": "#eeeeee"
+			},
+			"emphasis": {
+					"label": {
+							"color": "#eeeeee"
+					}
+			}
+	}
+}

+ 426 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/current-scatter-chart.vue

@@ -0,0 +1,426 @@
+<template>
+  <div class="chart" :id="id"></div>
+</template>
+
+<script>
+import util from "@tools/util";
+import partten from "@tools/partten";
+import * as echarts from "echarts";
+import chartTheme from "./current-scatter-chart.json";
+
+export default {
+  name: "currentScatterChart",
+  props: {
+    // 图表宽度
+    width: {
+      type: String,
+      default: "100%",
+    },
+    // 图表高度
+    height: {
+      type: String,
+      default: "350px",
+    },
+    // 图表主标题
+    chartTitle: {
+      type: String,
+      default: "自定义图表组件",
+    },
+    // X 轴配置项
+    xAxisData: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    // Y 轴配置项
+    yAxisData: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    dataSet: {
+      type: String,
+      default: "",
+    },
+    // 图表核心数据
+    seriesData: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    // 是否显示图表图例
+    showLegend: {
+      type: Boolean,
+      default: true,
+    },
+    // 是否默认采用笔刷模式
+    brushSelected: {
+      type: Boolean,
+      default: false,
+    },
+    theme: {
+      type: Boolean,
+      default: false,
+    },
+    echartsTheme: {
+      type: String,
+      default: "",
+    },
+    showToolbox: {
+      type: Boolean,
+      default: true,
+    },
+    tooltipTrigger: {
+      type: String,
+      default: "item",
+    },
+    brushIndex: {
+      type: Number,
+      defaylt: () => {
+        return 0;
+      },
+    },
+  },
+  data() {
+    return {
+      id: "",
+      chart: null,
+      color: [
+        "#05bb4c",
+        "#4b55ae",
+        "#fa8c16",
+        "#f8de5b",
+        "#1a93cf",
+        "#c531c7",
+        "#bd3338",
+      ],
+    };
+  },
+  computed: {
+    collapse() {
+      return this.$store.state.collapse;
+    },
+  },
+  watch: {
+    height() {
+      if (this.chart) {
+        this.chart.resize();
+      }
+    },
+    collapse(val) {
+      if (this.chart) {
+        setTimeout(() => {
+          this.chart.resize();
+        }, 300);
+      }
+    },
+  },
+  methods: {
+    resize() {},
+    initChart() {
+      const that = this;
+      echarts.registerTheme("chartTheme", chartTheme);
+      let myChart = echarts.init(document.getElementById(this.id), "dark");
+      that.chart = myChart;
+      //指定图表的配置项和数据
+      let legendData = [];
+      that.seriesData.forEach((ele) => {
+        legendData.push(ele.name);
+      });
+      const option = {
+        backgroundColor: "",
+        //标题
+        title: {
+          text: that.chartTitle,
+          // right: 460,
+          left: "center",
+          // left: 110,
+          // top: 4,
+          textStyle: {
+            fontSize: 16,
+            color:
+              that.echartsTheme === "dark" ? partten.getColor("white") : "#000",
+          },
+        },
+        // backgroundColor:
+        //   that.theme === "dark"
+        //     ? "rgba(0,0,0,0.4)"
+        //     : "rgba(255,255,255,0.5)",
+        //工具箱
+        color: [
+          "#3D54BE",
+          "rgb(255,0,0)",
+          "#a1a1a1",
+          "#0098d9",
+          "#FF8700",
+          "#005eaa",
+          "#cda819",
+          "#32a487",
+        ],
+        toolbox: {
+          show: that.showToolbox,
+          x: "right",
+          position: [10, 10],
+          // backgroundColor:'rgba(0,0,0,0.4)',
+          borderColor: that.theme
+            ? partten.getColor("gray")
+            : partten.getColor("white"),
+          textStyle: {
+            fontSize: util.vh(16),
+            color: that.theme
+              ? partten.getColor("gray")
+              : partten.getColor("white"),
+          },
+          iconStyle: {
+            borderColor: that.theme
+              ? partten.getColor("gray")
+              : partten.getColor("white"),
+          },
+          emphasis: {
+            iconStyle: {
+              borderColor: that.theme
+                ? partten.getColor("gray")
+                : partten.getColor("white"),
+            },
+          },
+        },
+        tooltip: {
+          trigger: that.tooltipTrigger,
+          axisPointer: {
+            type: "line",
+          },
+          backgroundColor: "rgba(0,0,0,0.4)",
+          borderColor: partten.getColor("white"),
+          textStyle: {
+            fontSize: util.vh(16),
+            color: "#fff",
+          },
+          //   formatter(params) {
+          //     console.log(123123, params);
+          //     let str = "";
+          //     params?.forEach((ele) => {
+          //       str += `${ele.seriesName}: ${
+          //         ele?.value?.[1] || ele.axisValue
+          //       }${that.getChartUnit(ele.seriesName)}\n`;
+          //     });
+          //     // if (params.value && params.value.x) {
+          //     //   str = `${params.seriesName}<br />风速:${params.value.x} m/s<br />功率:${params.value.y} kW`;
+          //     // } else {
+          //     //   str = `${params.name}`;
+          //     // }
+          //     return str;
+          //   },
+        },
+        dataZoom: [
+          {
+            type: "inside", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+          {
+            type: "slider", //图表下方的伸缩条
+            show: false, //是否显示
+            realtime: true, //拖动时,是否实时更新系列的视图
+            start: 0, //伸缩条开始位置(1-100),可以随时更改
+            end: 100, //伸缩条结束位置(1-100),可以随时更改
+          },
+        ],
+        textStyle: {
+          fontSize: util.vh(16),
+          color: that.echartsTheme === "dark" ? "#fff" : "#000",
+        },
+        //图例-每一条数据的名字
+        legend: {
+          show: that.showLegend,
+          //   data: ["拟合功率", "保证功率", "无用点", "有用点", "Cp值"],
+          data: legendData,
+          right: "center",
+          top: "25",
+          // icon: "circle",
+          itemWidth: 6,
+          inactiveColor:
+            that.echartsTheme === "dark" ? partten.getColor("white") : "#000",
+          textStyle: {
+            color:
+              that.echartsTheme === "dark" ? partten.getColor("white") : "#000",
+            fontSize: 14,
+          },
+        },
+        grid: {
+          top: 48,
+          left: 40,
+          right: 40,
+          bottom: 24,
+        },
+        //x轴
+        xAxis: [
+          {
+            name: "m/s",
+            nameTextStyle: {
+              color: "#838383",
+            },
+            type: "value",
+            boundaryGap: false,
+            data: that.xAxisData || [],
+            min: 0,
+            max: 25,
+            interval: 1,
+            axisLabel: {
+              formatter: "{value}",
+            },
+            splitLine: {
+              show: false,
+            },
+            textStyle: {
+              color:
+                that.echartsTheme === "dark"
+                  ? partten.getColor("gray")
+                  : "#000",
+            },
+          },
+        ],
+        //y轴没有显式设置,根据值自动生成y轴
+        yAxis: [
+          {
+            splitLine: {
+              show: false,
+            },
+            position: "left",
+            min: 0,
+            name: "kW",
+            nameTextStyle: {
+              color: "#838383",
+            },
+          },
+          {
+            splitLine: {
+              show: false,
+            },
+            position: "right",
+            min: 0,
+          },
+        ],
+        animation: true,
+        dataset: that.dataSet.length ? JSON.parse(that.dataSet) : [],
+        //数据-data是最终要显示的数据
+        series: that.seriesData,
+      };
+
+      if (that.brushSelected) {
+        option.brush = {
+          seriesIndex: [2, 3],
+          yAxisIndex: that.brushIndex,
+          transformable: true,
+          throttleType: "debounce",
+          throttleDelay: 1000,
+          removeOnClick: true,
+          brushType: "polygon",
+          brushMode: "multiple",
+          brushStyle: {
+            borderWidth: 1,
+            borderColor: "#ff2424",
+          },
+        };
+      }
+
+      that.resize = function () {
+        myChart.resize();
+      };
+
+      window.addEventListener("resize", that.resize);
+
+      myChart.setOption(option);
+      if (that.brushSelected) {
+        myChart.dispatchAction({
+          type: "takeGlobalCursor",
+          // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+          key: "brush",
+          brushOption: {
+            seriesIndex: [2, 3],
+            yAxisIndex: 0,
+            transformable: true,
+            throttleType: "debounce",
+            throttleDelay: 1000,
+            removeOnClick: true,
+            brushType: "polygon",
+            brushMode: "multiple",
+            brushStyle: {
+              borderWidth: 1,
+              color: "rgba(255,36,36,0.2)",
+              borderColor: "#ff2424",
+            },
+          },
+        });
+      }
+
+      myChart.off("brushSelected");
+      myChart.on("brushSelected", (params) => {
+        that.$emit("getSelected", params.batch || []);
+      });
+      myChart.off("click");
+      myChart.on("click", (params) => {
+        // console.log(params)
+        if (params.componentType === "markArea") {
+          myChart.dispatchAction({
+            type: "brush",
+            areas: [
+              {
+                xAxisIndex: 0,
+                brushType: "lineX",
+                coordRange: [params.data.coord[0][0], params.data.coord[1][0]],
+              },
+            ],
+          });
+        }
+      });
+    },
+
+    getChartUnit(seriesName) {
+      let unit = "";
+      if (/功率/.test(seriesName)) {
+        unit = "kW";
+      } else if (/风速/.test(seriesName)) {
+        unit = "m/s";
+      }
+      return ` ${unit}`;
+    },
+  },
+  created() {
+    this.id = "chart-" + util.newGUID();
+  },
+  mounted() {
+    // this.$nextTick(() => {
+    this.$el.style.width = this.width;
+    this.$el.style.height = this.height;
+    this.initChart();
+    if (this.chart) {
+      this.chart.resize();
+    }
+    // });
+  },
+  updated() {
+    // console.log('update')
+    let myChart = echarts.init(document.getElementById(this.id));
+    myChart.dispose();
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  unmounted() {
+    window.removeEventListener("resize", this.resize);
+  },
+};
+</script>
+
+<style lang="less">
+.chart {
+  width: 100%;
+  height: 100%;
+  display: inline-block;
+}
+</style>

File diff suppressed because it is too large
+ 70875 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/combineCom/data.json


File diff suppressed because it is too large
+ 25045 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/data.json


File diff suppressed because it is too large
+ 1 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/leaflet.canvas-markers.js


+ 531 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/leafletMap.vue

@@ -0,0 +1,531 @@
+<template>
+    <div class="mapCom">
+        <div id="map"></div>
+    </div>
+</template>
+<script>
+    // import httpRequest from "@/utils/request.js";
+    import {
+        CanvasLabel
+    } from "@panzhiyue/leaflet-canvaslabel";
+    import "./leaflet.canvas-markers.js";
+    export default {
+        props: {
+            ids: {
+                type: Array,
+                default: () => {
+                    return [];
+                },
+            },
+            windList: {
+                type: Array,
+                default: () => {
+                    return [];
+                },
+            },
+        },
+        data() {
+            return {
+                map: null,
+                DefaultIcon1: null,
+                layerGroup: [],
+                layers: [],
+                rightObj: {},
+                areaLayer: null,
+                tilsUrl: "./static/kMapTiles/{z}/{x}/{y}.jpg",
+                ciLayer: null,
+            };
+        },
+        watch: {
+            ids(val) {
+                this.funStationPos(val);
+                // this.funStationPosLabel(val)
+            },
+        },
+        mounted() {
+            this.initMap();
+        },
+        methods: {
+            initMap() {
+                //矢量文本标签渲染器
+                let canvasLabel = new L.CanvasLabel({
+                    collisionFlg: true,
+                    scale: 2,
+                });
+                this.map = L.map("map", {
+                    renderer: canvasLabel,
+                    // center: [40.02404009136253, 116.50641060224784], // 地图中心--北京
+                    // center: [38.44673272215545, 106.27624511718751], // 地图中心--银川
+                    // center: [108.953939, 34.266611], // 地图中心--陕西
+                    // center: [109.470962, 34.520632], // 地图中心--渭南
+                    zoom: 16, //缩放比列
+                    zoomControl: false, //禁用 + - 按钮
+                    doubleClickZoom: true, // 禁用双击放大
+                    attributionControl: false, // 移除右下角leaflet标识
+                    preferCanvas: true,
+                    contextmenu: true,
+                    contextmenuWidth: 140,
+                    contextmenuItems: [{
+                            text: "功率曲线拟合分析",
+                            callback: this.powerLine,
+                        },
+                        {
+                            text: "对风偏差分析",
+                            callback: this.windAny,
+                        },
+                        {
+                            text: "曲线偏差率分析",
+                            callback: this.qxAny,
+                        },
+                        {
+                            text: "温度与功率分析",
+                            callback: this.wdyglAny,
+                        },
+                        {
+                            text: "损失电量分析",
+                            callback: this.ssdlAny,
+                        },
+                        {
+                            text: "桨距角分析",
+                            callback: this.jjjAny,
+                        },
+                    ],
+                });
+                let name = L.tileLayer(
+                    "http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
+                ).addTo(this.map)
+
+                // let name = L.tileLayer(this.tilsUrl, {
+                //     minZoom: 1,
+                //     maxZoom: 16,
+                // }).addTo(this.map);
+
+                // this.setAreaLayer("db", true);
+                // this.setAreaLayer("jb", true);
+                this.setAreaLayer("nx", true);
+            },
+
+            async funStationPos(ids) {
+                let res = null;
+                // if (ids.length > 0) {
+                //     res = await httpRequest.get("/base/location", {
+                //         params: {
+                //             ids: this.ids.join(","),
+                //         },
+                //     });
+                // } else {
+                //     res = await httpRequest.get("/base/station", {
+                //         params: {},
+                //     });
+                // }
+                if (res.code === 200) {
+                    if (res.data && res.data.length) {
+                        this.layers = [];
+                        if (this.ciLayer !== null) {
+                            this.ciLayer.clearLayers();
+                            this.ciLayer = L.canvasIconLayer({}).addTo(this.map);
+                        } else {
+                            this.ciLayer = L.canvasIconLayer({}).addTo(this.map);
+                        }
+
+                        let iconUrl = require(`@/assets/images/indexCom/fengji.png`);
+
+                        for (let i = 0; i < res.data.length; i++) {
+                            let item = res.data[i];
+
+                            let marker = L.marker(
+                                    [Number(item.latitude), Number(item.longitude)], {
+                                        // title: item.name,
+                                        icon: L.divIcon({
+                                            // html: `<div style="position:relative;top:40px;left:5px">${item.aname}</div>`,
+                                            className: "iconSty",
+                                            iconUrl: iconUrl,
+                                            iconSize: [30, 39],
+                                            iconAnchor: [15, 12.5],
+                                        }),
+                                        data: item,
+                                    }
+                                )
+                                .bindTooltip(
+                                    `
+                                <div class="tip-box-top">
+                                    <div class="item">${item.aname}</div>
+                                    <div class="item">经度:${item.latitude}°</div>
+                                    <div class="item">纬度:${item.longitude}°</div>
+                                    <div class="item">海拔高度:${item.altitude}m</div>
+                                </div>`
+                                )
+                                .addTo(this.map);
+
+                            let latlng = L.latLng(
+                                Number(item.latitude),
+                                Number(item.longitude)
+                            );
+                            let c = L.circleMarker(latlng, {
+                                radius: 5,
+                                color: "transparent",
+                                labelStyle: {
+                                    text: item.aname,
+                                    scale: 1,
+                                    rotation: 0,
+                                    offsetY: 35,
+                                    fillStyle: "#000",
+                                    zIndex: i,
+                                },
+                                data: item,
+                            }).addTo(this.map);
+                            this.layers.push(c);
+
+                            this.ciLayer.addLayer(marker);
+                            this.layers.push(marker);
+
+                            let that = this;
+                            marker.on("mouseover", function onmouseover(e) {
+                                that.rightObj = item;
+                            });
+                        }
+                        let center = this.map.getCenter();
+                        this.map.panTo([center.lat, center.lng], {
+                            animate: true,
+                        });
+                        this.map.setView(this.layers[0].getLatLng(), 13);
+                    }
+                }
+            },
+
+            async funStationPosLabel(ids) {
+                if (this.layers.length > 0) {
+                    for (var i = 0; i < this.layers.length; i++) {
+                        this.map.removeLayer(this.layers[i]);
+                    }
+                    this.layers = [];
+                }
+                let res = null;
+                if (ids.length > 0) {
+                    res = await httpRequest.get("/base/location", {
+                        params: {
+                            ids: this.ids.join(","),
+                        },
+                    });
+                } else {
+                    res = await httpRequest.get("/base/station", {
+                        params: {},
+                    });
+                }
+                if (res.code === 200) {
+                    if (res.data && res.data.length) {
+                        this.layers = [];
+                        for (let i = 0; i < res.data.length; i++) {
+                            let item = res.data[i];
+
+                            let latlng = L.latLng(
+                                Number(item.latitude),
+                                Number(item.longitude)
+                            );
+                            let c = L.circleMarker(latlng, {
+                                    radius: 5,
+                                    color: "#12e799",
+                                    labelStyle: {
+                                        text: item.aname,
+                                        scale: 1,
+                                        rotation: 0,
+                                        offsetY: 15,
+                                        fillStyle: "#000",
+                                        zIndex: i,
+                                    },
+                                    data: item,
+                                })
+                                .bindTooltip(
+                                    `
+                                <div class="tip-box-top">
+                                    <div class="item">${item.aname}</div>
+                                    <div class="item">经度:${item.latitude}°</div>
+                                    <div class="item">纬度:${item.longitude}°</div>
+                                    <div class="item">海拔高度:${item.altitude}m</div>
+                                </div>`
+                                )
+                                .addTo(this.map);
+                            this.layers.push(c);
+
+                            let that = this;
+                            c.on("mouseover", function onmouseover(e) {
+                                console.log("map", item);
+                                that.rightObj = item;
+                            });
+                        }
+                        let center = this.map.getCenter();
+                        this.map.panTo([center.lat, center.lng], {
+                            animate: true,
+                        });
+                        this.map.setView(this.layers[0].getLatLng(), 13);
+                    }
+                }
+            },
+
+            setAreaLayer(jsonName, isBounds) {
+                const wfAllGeoJson = require(`@/assets/${jsonName}.json`);
+                this.areaLayer = L.geoJSON(wfAllGeoJson, {
+                    style: (feature) => {
+                        return {
+                            fillOpacity: 0.1,
+                            fillColor: "rgb(27, 242, 245)",
+                            weight: 2,
+                            color: "rgb(27, 242, 245)",
+                        };
+                    },
+                });
+                this.map.addLayer(this.areaLayer);
+                if (isBounds) {
+                    this.map.fitBounds(this.areaLayer.getBounds());
+                }
+            },
+
+            powerLine(e) {
+                if (!this.rightObj.latitude && !this.rightObj.longitude) {
+                    this.$message({
+                        message: "该坐标系下暂无功率曲线拟合",
+                        type: "error",
+                    });
+                } else {
+                    this.layers.forEach((item) => {
+                        if (item.options.data) {
+                            if (item.options.data.name.indexOf("风电场") === -1) {
+                                if (
+                                    item.options.data.latitude === this.rightObj.latitude &&
+                                    item.options.data.longitude === this.rightObj.longitude
+                                ) {
+                                    this.$emit("rightClick", {
+                                        menuIndex: 0,
+                                        current: this.rightObj,
+                                    });
+                                }
+                            } else {
+                                if (item.options.data.name === this.rightObj.name) {
+                                    this.$message({
+                                        message: "风场暂无功率曲线拟合功能",
+                                        type: "error",
+                                    });
+                                }
+                            }
+                        }
+                    });
+                }
+            },
+
+            windAny(e) {
+                if (!this.rightObj.latitude && !this.rightObj.longitude) {
+                    this.$message({
+                        message: "该坐标系下暂无对风偏差分析",
+                        type: "error",
+                    });
+                } else {
+                    this.layers.forEach((item) => {
+                        if (item.options.data) {
+                            if (item.options.data.name.indexOf("风电场") === -1) {
+                                if (
+                                    item.options.data.latitude === this.rightObj.latitude &&
+                                    item.options.data.longitude === this.rightObj.longitude
+                                ) {
+                                    this.$emit("rightClick", {
+                                        menuIndex: 1,
+                                        current: this.rightObj,
+                                    });
+                                }
+                            } else {
+                                if (item.options.data.name === this.rightObj.name) {
+                                    this.$message({
+                                        message: "风场暂无对风偏差分析功能",
+                                        type: "error",
+                                    });
+                                }
+                            }
+                        }
+                    });
+                }
+            },
+
+            qxAny(e) {
+                if (!this.rightObj.latitude && !this.rightObj.longitude) {
+                    this.$message({
+                        message: "该坐标系下暂无曲线偏差分析",
+                        type: "error",
+                    });
+                } else {
+                    this.layers.forEach((item) => {
+                        if (item.options.data) {
+                            if (item.options.data.name.indexOf("风电场") === -1) {
+                                if (
+                                    item.options.data.latitude === this.rightObj.latitude &&
+                                    item.options.data.longitude === this.rightObj.longitude
+                                ) {
+                                    this.$emit("rightClick", {
+                                        menuIndex: 2,
+                                        current: this.rightObj,
+                                    });
+                                }
+                            } else {
+                                if (item.options.data.name === this.rightObj.name) {
+                                    this.$message({
+                                        message: "风场暂无曲线偏差分析功能",
+                                        type: "error",
+                                    });
+                                }
+                            }
+                        }
+                    });
+                }
+            },
+
+            wdyglAny(e) {
+                if (!this.rightObj.latitude && !this.rightObj.longitude) {
+                    this.$message({
+                        message: "该坐标系下暂无温度与功率分析",
+                        type: "error",
+                    });
+                } else {
+                    this.layers.forEach((item) => {
+                        if (item.options.data) {
+                            if (item.options.data.name.indexOf("风电场") === -1) {
+                                if (
+                                    item.options.data.latitude === this.rightObj.latitude &&
+                                    item.options.data.longitude === this.rightObj.longitude
+                                ) {
+                                    this.$emit("rightClick", {
+                                        menuIndex: 3,
+                                        current: this.rightObj,
+                                    });
+                                }
+                            } else {
+                                if (item.options.data.name === this.rightObj.name) {
+                                    this.$message({
+                                        message: "风场暂无温度与功率分析功能",
+                                        type: "error",
+                                    });
+                                }
+                            }
+                        }
+                    });
+                }
+            },
+
+            ssdlAny(e) {
+                if (!this.rightObj.latitude && !this.rightObj.longitude) {
+                    this.$message({
+                        message: "该坐标系下暂无损失电量分析",
+                        type: "error",
+                    });
+                } else {
+                    this.layers.forEach((item) => {
+                        if (item.options.data) {
+                            if (item.options.data.name.indexOf("风电场") === -1) {
+                                if (
+                                    item.options.data.latitude === this.rightObj.latitude &&
+                                    item.options.data.longitude === this.rightObj.longitude
+                                ) {
+                                    this.$emit("rightClick", {
+                                        menuIndex: 4,
+                                        current: this.rightObj,
+                                    });
+                                }
+                            } else {
+                                if (item.options.data.name === this.rightObj.name) {
+                                    this.$message({
+                                        message: "风场暂无损失电量分析功能",
+                                        type: "error",
+                                    });
+                                }
+                            }
+                        }
+                    });
+                }
+            },
+
+            jjjAny(e) {
+                if (!this.rightObj.latitude && !this.rightObj.longitude) {
+                    this.$message({
+                        message: "该坐标系下暂无桨距角分析",
+                        type: "error",
+                    });
+                } else {
+                    this.layers.forEach((item) => {
+                        if (item.options.data) {
+                            if (item.options.data.name.indexOf("风电场") === -1) {
+                                if (
+                                    item.options.data.latitude === this.rightObj.latitude &&
+                                    item.options.data.longitude === this.rightObj.longitude
+                                ) {
+                                    this.$emit("rightClick", {
+                                        menuIndex: 5,
+                                        current: this.rightObj,
+                                    });
+                                }
+                            } else {
+                                if (item.options.data.name === this.rightObj.name) {
+                                    this.$message({
+                                        message: "风场暂无桨距角分析功能",
+                                        type: "error",
+                                    });
+                                }
+                            }
+                        }
+                    });
+                }
+            },
+        },
+    };
+</script>
+<style scoped lang="less">
+    .mapCom {
+        height: 100%;
+
+        .iconLabel {
+            width: 80px !important;
+        }
+
+        .iconSty {
+            .iconStyClass {
+                width: 50px;
+                height: 100px;
+                position: relative;
+                top: 40px;
+            }
+        }
+    }
+
+    #map {
+        width: 100%;
+        height: 100%;
+    }
+
+    .lmap-image {
+        width: 32px;
+        height: 32px;
+    }
+
+    .lmap-span {
+        display: inline-block;
+        margin-left: 5px;
+        padding: 5px;
+        font-weight: bold;
+        line-height: 20px;
+        font-size: 14px;
+        color: #fff;
+        white-space: nowrap;
+    }
+
+    .lmap-text {
+        display: inline-block;
+        margin-left: 5px;
+        padding: 5px;
+        font-weight: bold;
+        line-height: 20px;
+        font-size: 16px;
+        color: #fff;
+        width: 500px;
+        white-space: nowrap;
+        position: absolute;
+        text-align: center;
+        top: 25px;
+        left: -250px;
+    }
+</style>

+ 205 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/posChart.vue

@@ -0,0 +1,205 @@
+<script setup name="posChart">
+    import {
+        ref,
+        reactive,
+        shallowRef,
+        defineProps,
+        watch,
+        nextTick,
+        onActivated,
+        onMounted,
+        defineEmits
+    } from 'vue'
+    import AMapLoader from '@amap/amap-jsapi-loader';
+    import {
+        ElMessage
+    } from 'element-plus';
+    import httpRequest from '@/utils/request.js'
+    // import stationPosRes from './stationPos.json'
+    const emits = defineEmits(['rightClick', 'mapDone'])
+    const map = shallowRef(null);
+    const aMap = ref(null)
+    const container = ref()
+    const funMapSet = (callback = (flag) => {}) => {
+        AMapLoader.load({
+            key: "	540080009cfdae95b6b5a4f47af24f90", // 申请好的Web端开发者Key,首次调用 load 时必填
+            version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
+            plugins: [''], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
+        }).then((AMap) => {
+            aMap.value = AMap;
+            map.value = new AMap.Map(container.value, { //设置地图容器id
+                viewMode: "3D", //是否为3D地图模式
+                zoom: 9, //初始化地图级别
+                center: [106.065974, 37.428168], //初始化地图中心点位置
+                layers: [
+                    // 卫星
+                    new AMap.TileLayer.Satellite(),
+                    // 路网
+                    new AMap.TileLayer.RoadNet()
+                ]
+            });
+            callback(true)
+        }).catch(e => {
+            console.error(e);
+            callback(false)
+        })
+    }
+    const funStationPos = async () => {
+        const res = await httpRequest.get('/base/location', {
+            params: {
+                ids: props.ids.join(","),
+            },
+        })
+        if (res.code === 200) {
+            if (res.data && res.data.length) {
+                map.value.clearMap()
+                res.data.forEach(item => {
+                    const marker = new aMap.value.Marker({
+                        icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_r.png",
+                        // icon: "./static/run_Icon.gif",
+                        position: [Number(item.longitude), Number(item.latitude)],
+                        anchor: 'bottom-center'
+                    });
+                    // 设置label标签
+                    // label默认蓝框白底左上角显示,样式className为:amap-marker-label
+                    marker.setLabel({
+                        direction: 'right',
+                        offset: new aMap.value.Pixel(10, 0), //设置文本标注偏移量
+                        content: `${item.aname}`, //设置文本标注内容
+                    });
+                    map.value.add(marker)
+                    // marker.setTitle(item.name);
+
+                    //创建右键菜单
+                    const contextMenu = new aMap.value.ContextMenu();
+                    /**右键菜单可根据props中传参定义 */
+                    //右键1
+                    contextMenu.addItem("功率曲线拟合", (e) => {
+                        console.log('rightObj====>>>>', rightObj.value)
+                        // funCombineGet(rightObj.value)
+                        emits('rightClick', {
+                            menuIndex: 0,
+                            current: rightObj.value,
+                        })
+                    }, 0);
+
+                    //右键2
+                    contextMenu.addItem("对风偏差分析", () => {
+                        emits('rightClick', {
+                            menuIndex: 1,
+                            current: rightObj.value,
+                        })
+                    }, 1);
+
+                    // //右键2
+                    // contextMenu.addItem("温度与功率分析", () => {
+                    // 	emits('rightClick', {
+                    // 		menuIndex: 2,
+                    // 		current: rightObj.value
+                    // 	})
+                    // }, 2);
+                    map.value.add(marker)
+                    // marker.setTitle(item.name);
+                    // 设置label标签
+                    // label默认蓝框白底左上角显示,样式className为:amap-marker-label
+                    marker.setLabel({
+                        direction: 'right',
+                        offset: new aMap.value.Pixel(10, 0), //设置文本标注偏移量
+                        content: `${item.name}`, //设置文本标注内容
+                    });
+                    //绑定鼠标右击事件——弹出右键菜单
+                    marker.on('rightclick', function (e) {
+                        rightObj.value = item
+                        contextMenu.open(map.value, e.lnglat);
+                    });
+
+                })
+                map.value.setFitView()
+            }
+        }
+    }
+
+    const funStationPosvs = async () => {
+        const res = await httpRequest.get('/base/station', {
+            params: {},
+        })
+        if (res.code === 200) {
+            if (res.data && res.data.length) {
+                map.value.clearMap()
+                res.data.forEach(item => {
+                    const marker = new aMap.value.Marker({
+                        icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_r.png",
+                        // icon: "./static/run_Icon.gif",
+                        position: [Number(item.longitude), Number(item.latitude)],
+                        anchor: 'bottom-center'
+                    });
+                    // 设置label标签
+                    // label默认蓝框白底左上角显示,样式className为:amap-marker-label
+                    marker.setLabel({
+                        direction: 'right',
+                        offset: new aMap.value.Pixel(10, 0), //设置文本标注偏移量
+                        content: `${item.aname}`, //设置文本标注内容
+                    });
+                    map.value.add(marker)
+                    // marker.setTitle(item.name);
+
+                })
+                map.value.setFitView()
+            }
+        }
+    }
+
+    const props = defineProps({
+        ids: {
+            type: Array,
+            default: () => [],
+        },
+        windList: {
+            type: Array,
+            default: () => []
+        },
+        height: {
+            type: String,
+            default: '100%'
+        }
+    })
+    /** 右键后对象数据的接收 */
+    const rightObj = ref(null)
+    /**监听windList */
+    watch(() => props.ids, (val) => {
+        if (val.length > 0) {
+            funStationPos()
+        } else {
+            funStationPosvs()
+        }
+        // httpRequest
+        //     .get("/base/location", {
+        //         params: {
+        //             ids: value.join(","),
+        //         },
+        //     })
+        //     .then((res) => {
+        //         this.searchId = value || [];
+        //         this.wtList = res.data || [];
+        //         this.getWpList();
+        //     });
+    })
+    //created
+    onMounted(() => {
+        funMapSet(mapStatus => {
+            if (!mapStatus) {
+                ElMessage.error('地图未加载成功, 请刷新重试或检查网络!')
+                return false
+            }
+            funStationPos()
+            emits('mapDone', mapStatus)
+        })
+    })
+</script>
+<template>
+    <div :style="{height: props.height}">
+        <div class="h-full" ref="container" style="height: 100%">
+            <el-empty description="地图未加载成功, 请刷新重试或检查网络!"></el-empty>
+        </div>
+    </div>
+</template>

+ 399 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateAnalysis.json

@@ -0,0 +1,399 @@
+
+{
+	"color": [
+			"#626c91",
+			"#96dee8",
+			"#3fb1e3",
+			"#6be6c1",
+			"#a0a7e6",
+			"#c4ebad",
+			"rgb(126,254,123)",
+			"rgb(254,200,10)",
+			"rgb(224,103,2)",
+			"rgb(242,8,1)",
+			"rgb(127,0,1)"
+
+	],
+	"backgroundColor": "rgba(252,252,252,0)",
+	"textStyle": {},
+	"title": {
+			"textStyle": {
+					"color": "#000"
+			},
+			"subtextStyle": {
+					"color": "#000"
+			}
+	},
+	"line": {
+			"itemStyle": {
+					"borderWidth": "2"
+			},
+			"lineStyle": {
+					"width": "2"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": true
+	},
+	"radar": {
+			"itemStyle": {
+					"borderWidth": "2"
+			},
+			"lineStyle": {
+					"width": "2"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": false
+	},
+	"bar": {
+			"itemStyle": {
+					"barBorderWidth": 0,
+					"barBorderColor": "#ccc"
+			}
+	},
+	"pie": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"scatter": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"boxplot": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"parallel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"sankey": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"funnel": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"gauge": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			}
+	},
+	"candlestick": {
+			"itemStyle": {
+					"color": "#e6a0d2",
+					"color0": "transparent",
+					"borderColor": "#e6a0d2",
+					"borderColor0": "#3fb1e3",
+					"borderWidth": "2"
+			}
+	},
+	"graph": {
+			"itemStyle": {
+					"borderWidth": 0,
+					"borderColor": "#ccc"
+			},
+			"lineStyle": {
+					"width": "1",
+					"color": "#cccccc"
+			},
+			"symbolSize": "8",
+			"symbol": "emptyCircle",
+			"smooth": false,
+			"color": [
+					"#3fb1e3",
+					"#6be6c1",
+					"#626c91",
+					"#a0a7e6",
+					"#c4ebad",
+					"#96dee8"
+			],
+			"label": {
+					"color": "#ffffff"
+			}
+	},
+	"map": {
+			"itemStyle": {
+					"areaColor": "#eeeeee",
+					"borderColor": "#aaaaaa",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "rgba(63,177,227,0.25)",
+							"borderColor": "#3fb1e3",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#3fb1e3"
+					}
+			}
+	},
+	"geo": {
+			"itemStyle": {
+					"areaColor": "#eeeeee",
+					"borderColor": "#aaaaaa",
+					"borderWidth": 0.5
+			},
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"areaColor": "rgba(63,177,227,0.25)",
+							"borderColor": "#3fb1e3",
+							"borderWidth": 1
+					},
+					"label": {
+							"color": "#3fb1e3"
+					}
+			}
+	},
+	"categoryAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#838383"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"valueAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#838383"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#838383",
+					"fontSize": 10
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#838383"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"logAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#cccccc"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#999999"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#eeeeee"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"timeAxis": {
+			"axisLine": {
+					"show": true,
+					"lineStyle": {
+							"color": "#cccccc"
+					}
+			},
+			"axisTick": {
+					"show": false,
+					"lineStyle": {
+							"color": "#333"
+					}
+			},
+			"axisLabel": {
+					"show": true,
+					"color": "#999999"
+			},
+			"splitLine": {
+					"show": true,
+					"lineStyle": {
+							"color": [
+									"#eeeeee"
+							]
+					}
+			},
+			"splitArea": {
+					"show": false,
+					"areaStyle": {
+							"color": [
+									"rgba(250,250,250,0.05)",
+									"rgba(200,200,200,0.02)"
+							]
+					}
+			}
+	},
+	"toolbox": {
+			"iconStyle": {
+					"borderColor": "#999999"
+			},
+			"emphasis": {
+					"iconStyle": {
+							"borderColor": "#666666"
+					}
+			}
+	},
+	"legend": {
+			"textStyle": {
+					"color": "#999999"
+			}
+	},
+	"tooltip": {
+			"axisPointer": {
+					"lineStyle": {
+							"color": "#cccccc",
+							"width": 1
+					},
+					"crossStyle": {
+							"color": "#cccccc",
+							"width": 1
+					}
+			}
+	},
+	"timeline": {
+			"lineStyle": {
+					"color": "#626c91",
+					"width": 1
+			},
+			"itemStyle": {
+					"color": "#626c91",
+					"borderWidth": 1
+			},
+			"controlStyle": {
+					"color": "#626c91",
+					"borderColor": "#626c91",
+					"borderWidth": 0.5
+			},
+			"checkpointStyle": {
+					"color": "#3fb1e3",
+					"borderColor": "#3fb1e3"
+			},
+			"label": {
+					"color": "#626c91"
+			},
+			"emphasis": {
+					"itemStyle": {
+							"color": "#626c91"
+					},
+					"controlStyle": {
+							"color": "#626c91",
+							"borderColor": "#626c91",
+							"borderWidth": 0.5
+					},
+					"label": {
+							"color": "#626c91"
+					}
+			}
+	},
+	"visualMap": {
+			"color": [
+					"#2a99c9",
+					"#afe8ff"
+			]
+	},
+	"dataZoom": {
+			"backgroundColor": "rgba(255,255,255,0)",
+			"dataBackgroundColor": "rgba(222,222,222,1)",
+			"fillerColor": "rgba(114,230,212,0.25)",
+			"handleColor": "#cccccc",
+			"handleSize": "100%",
+			"textStyle": {
+					"color": "#999999"
+			}
+	},
+	"markPoint": {
+			"label": {
+					"color": "#ffffff"
+			},
+			"emphasis": {
+					"label": {
+							"color": "#ffffff"
+					}
+			}
+	}
+}

+ 200 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateCom/chart.vue

@@ -0,0 +1,200 @@
+<template>
+    <div :id="chartId" :style="{ height: props.height, width: props.width }"></div>
+</template>
+
+<script setup>
+    import util from "@tools/util";
+    import chartTheme from "../rateAnalysis.json";
+    import {
+        ref,
+        toRaw,
+        computed,
+        onMounted,
+        watch,
+        nextTick
+    } from "vue";
+    import {
+        useStore
+    } from "vuex";
+    import * as echarts from "echarts";
+    const chartId = "chart-" + util.newGUID(); //chartId
+    const chartIns = ref(null); //chart 实例
+    const props = defineProps({
+        xAxis: {
+            type: Object,
+            required: true,
+            default: () => ({}),
+        },
+        series: {
+            type: Array,
+            required: true,
+        },
+        height: {
+            type: String,
+            required: false,
+            default: "500px",
+        },
+        width: {
+            type: String,
+            required: false,
+            default: "500px",
+        },
+        title: {
+            type: String,
+            required: false,
+        },
+        subtext: {
+            type: String,
+            required: false,
+        },
+        // 是否为dialog中单表
+        isDiaAlone: {
+            type: Boolean,
+            default: false,
+        },
+        // 是否含雷达图
+        isRadar: {
+            type: Boolean,
+            default: false,
+        },
+        theme: {
+            type: Boolean,
+            default: false,
+        },
+        echartsTheme: {
+            type: String,
+            default: "",
+        },
+    });
+
+    /**定义option */
+    const option = computed({
+        get() {
+            let radar = null;
+            if (props.isRadar && props.xAxis.data.length) {
+                radar = {
+                    radius: "70%",
+                    center: ["60%", "50%"],
+                    indicator: props.xAxis.data.map((o) => {
+                        return {
+                            text: "",
+                            max: 1000,
+                        };
+                    }),
+                    splitArea: {
+                        show: false,
+                    },
+                    splitLine: {
+                        show: false,
+                    },
+                };
+            }
+            return {
+                backgroundColor: "",
+                title: {
+                    text: props.title || "",
+                    subtext: props.subtext || "",
+                    top: 10,
+                    left: props.isDiaAlone ? "22%" : "5%",
+                },
+                angleAxis: props.xAxis || {},
+                radiusAxis: {},
+                polar: {
+                    radius: "70%",
+                    center: props.subtext !== "风速风向玫瑰图" ? ["60%", "50%"] : ["50%", "50%"],
+                },
+                radar: radar,
+                tooltip: {
+                    formatter: (params) => {
+                        return params.componentSubType === "radar" ?
+                            `${params.marker}${params.seriesName}` :
+                            props.subtext !== "风速风向玫瑰图" ?
+                            `${params.marker}${params.seriesName}m<br/>${
+                params.value > 1 ? "频次:" + params.value : ""
+              }` :
+                            `${params.marker}${params.seriesName}<br/>${
+                "最大风速:" + params.value
+              }m/s`;
+                    },
+                    confine: true,
+                },
+                series: props.series || [],
+                legend: {
+                    show: true,
+                    orient: "vertical",
+                    left: props.isDiaAlone ? "22%" : "5%",
+                    itemWidth: 16,
+                    itemHeight: 10,
+                    textStyle: {
+                        fontSize: util.vh(10),
+                    },
+                    top: "middle",
+                    // data: ['0-2.5', '2.5-5', '5-7.5', '7.5-10', '10-12.5', '12.5-15', '15-17.5', '17.5-20',
+                    //     '20-22.5', '22.5-25', '25-inf'
+                    // ]
+                    data: ["0-3", "3-5", "5-10", "10-12", "12-25", "25-inf"],
+                },
+            };
+        },
+        set(val) {},
+    });
+    watch(
+        () => option,
+        (newVal, oldVal) => {
+            if (chartIns.value) {
+                const echartIns = toRaw(chartIns.value);
+                echartIns.setOption(newVal.value);
+            }
+        }, {
+            deep: true,
+        }
+    );
+
+    watch([() => props.width, () => props.height], (newVal, oldVal) => {
+        if (chartIns.value) {
+            const echartIns = toRaw(chartIns.value);
+            nextTick(() => echartIns.resize());
+        }
+    });
+    const store = useStore();
+    const collapse = computed({
+        get() {
+            return store.state.collapse;
+        },
+        set(val) {},
+    });
+    watch(collapse, (val) => {
+        if (chartIns.value) {
+            setTimeout(() => {
+                chartIns.value.resize();
+            }, 300);
+        }
+    });
+
+    onMounted(() => {
+        nextTick(() => {
+            init();
+        });
+    });
+
+    watch(
+        () => props.echartsTheme,
+        (newVal, oldVal) => init()
+    );
+
+    const init = () => {
+        echarts.registerTheme("chartTheme", chartTheme);
+        const echartIns = echarts.init(
+            document.getElementById(chartId),
+            props.echartsTheme
+        );
+        document.getElementById(chartId).removeAttribute("_echarts_instance_") ?
+            document.getElementById(chartId).removeAttribute("_echarts_instance_") :
+            "";
+        chartIns.value = echartIns;
+        echartIns.setOption(option.value);
+        window.addEventListener("resize", () => {
+            echartIns.resize();
+        });
+    };
+</script>

File diff suppressed because it is too large
+ 46416 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateCom/data.json


+ 234 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateCom/lineChart.vue

@@ -0,0 +1,234 @@
+<script setup>
+import util from "@tools/util";
+import chartTheme from "./../rateAnalysis.json";
+import { ref, toRaw, computed, onMounted, watch, nextTick } from "vue";
+import { useStore } from "vuex";
+import * as echarts from "echarts";
+const chartId = "chart-" + util.newGUID(); //chartId
+const chartIns = ref(null); //chart 实例
+const emits = defineEmits(["getSelected"]);
+const props = defineProps({
+  xAxis: {
+    type: Object,
+    required: true,
+    default: () => ({}),
+  },
+  yAxis: {
+    type: Array,
+    required: false,
+  },
+  series: {
+    type: Array,
+    required: true,
+  },
+  dataset: {
+    type: Array,
+    required: false,
+    default: () => [],
+  },
+  height: {
+    type: String,
+    required: false,
+    default: "500px",
+  },
+  width: {
+    type: String,
+    required: false,
+    default: "500px",
+  },
+  title: {
+    type: String,
+    required: false,
+  },
+  subtext: {
+    type: String,
+    required: false,
+  },
+  brush: {
+    type: Boolean,
+    required: false,
+    default: false,
+  },
+  theme: {
+    type: Boolean,
+    default: false,
+  },
+  echartsTheme: {
+    type: String,
+    default: "",
+  },
+});
+
+/**定义option */
+const option = computed({
+  get() {
+    console.log(props.subtext, props.series);
+    return {
+      backgroundColor: "",
+      color: [
+        "#FF8700",
+        "#0098d980",
+        "#626c91",
+        "#a0a7e6",
+        "#c4ebad",
+        "#96dee8",
+      ],
+      title: {
+        text: props.title || "",
+        subtext: props.subtext || "",
+        top: 6,
+        left: "5%",
+      },
+      xAxis: props.xAxis || {},
+      yAxis: props.yAxis || {},
+      brush: {
+        seriesIndex: [1],
+        yAxisIndex: 0,
+        transformable: true,
+        throttleType: "debounce",
+        throttleDelay: 1000,
+        removeOnClick: true,
+        brushType: props.brush ? "polygon" : false,
+        brushMode: "multiple",
+        brushStyle: {
+          borderWidth: 1,
+          borderColor: "#ff2424",
+        },
+      },
+      toolbox: {
+        show: props.brush,
+      },
+      tooltip: {
+        confine: true,
+        axisPointer: {
+          type: "cross",
+        },
+      },
+      dataset: props.dataset || [],
+      series: props.series || [],
+      legend: {
+        right: "120",
+        top: "5",
+        itemWidth: 6,
+      },
+      grid: {
+        top: 80,
+        left: 40,
+        right: 40,
+        bottom: 40,
+      },
+      dataZoom: [
+        {
+          type: "inside", //图表下方的伸缩条
+          show: false, //是否显示
+          realtime: true, //拖动时,是否实时更新系列的视图
+          start: 0, //伸缩条开始位置(1-100),可以随时更改
+          end: 100, //伸缩条结束位置(1-100),可以随时更改
+        },
+        {
+          type: "slider", //图表下方的伸缩条
+          show: false, //是否显示
+          realtime: true, //拖动时,是否实时更新系列的视图
+          start: 0, //伸缩条开始位置(1-100),可以随时更改
+          end: 100, //伸缩条结束位置(1-100),可以随时更改
+        },
+      ],
+    };
+  },
+  set(val) {},
+});
+watch(
+  () => option,
+  (newVal, oldVal) => {
+    if (chartIns.value) {
+      const echartIns = toRaw(chartIns.value);
+      echartIns.setOption(toRaw(newVal.value));
+    }
+  },
+  {
+    deep: true,
+  }
+);
+watch([() => props.width, () => props.height], (newVal, oldVal) => {
+  if (chartIns.value) {
+    const echartIns = toRaw(chartIns.value);
+    nextTick(() => echartIns.resize());
+  }
+});
+const store = useStore();
+const collapse = computed({
+  get() {
+    return store.state.collapse;
+  },
+  set(val) {},
+});
+watch(collapse, (val) => {
+  if (chartIns.value) {
+    setTimeout(() => {
+      chartIns.value.resize();
+    }, 300);
+  }
+});
+const funBrushChange = (flag) => {
+  const echartIns = toRaw(chartIns.value);
+  echartIns.dispatchAction({
+    type: "takeGlobalCursor",
+    // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
+    key: "brush",
+    brushOption: {
+      seriesIndex: [1],
+      yAxisIndex: 0,
+      transformable: true,
+      throttleType: "debounce",
+      throttleDelay: 1000,
+      removeOnClick: true,
+      brushType: flag ? "polygon" : false,
+      brushMode: "multiple",
+      brushStyle: {
+        borderWidth: 1,
+        color: "rgba(255,36,36,0.2)",
+        borderColor: "#ff2424",
+      },
+    },
+  });
+  echartIns.off("brushSelected");
+  echartIns.on("brushSelected", (params) => {
+    emits("getSelected", params.batch || []);
+  });
+};
+watch(
+  () => props.brush,
+  (newVal, oldVal) => funBrushChange(newVal)
+);
+
+onMounted(() => {
+  nextTick(() => {
+    init();
+  });
+});
+
+watch(
+  () => props.echartsTheme,
+  (newVal, oldVal) => init()
+);
+
+const init = () => {
+  echarts.registerTheme("chartTheme", chartTheme);
+  const echartIns = echarts.init(
+    document.getElementById(chartId),
+    props.echartsTheme
+  );
+  document.getElementById(chartId).removeAttribute("_echarts_instance_")
+    ? document.getElementById(chartId).removeAttribute("_echarts_instance_")
+    : "";
+  chartIns.value = echartIns;
+  echartIns.setOption(option.value);
+  funBrushChange(props.brush);
+  window.addEventListener("resize", () => {
+    echartIns.resize();
+  });
+};
+</script>
+<template>
+  <div :id="chartId" :style="{ height: '100%', width: props.width }"></div>
+</template>

+ 185 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/rateCom/scatterSingleChart.vue

@@ -0,0 +1,185 @@
+<script setup name="scatterSingleChart">
+    import util from "@tools/util";
+    import chartTheme from './../rateAnalysis.json'
+    import {
+        ref,
+        toRaw,
+        computed,
+        onMounted,
+        watch,
+        nextTick
+    } from 'vue';
+    import {
+        useStore
+    } from 'vuex'
+    import * as echarts from 'echarts'
+    const chartId = 'chart-' + util.newGUID(); //chartId
+    const chartIns = ref(null) //chart 实例
+    const props = defineProps({
+        xAxis: {
+            type: Array,
+            required: true,
+            default: () => ([])
+        },
+        yAxis: {
+            type: Array,
+            required: true,
+            default: () => ([])
+        },
+        series: {
+            type: Array,
+            required: false,
+            default: () => ([])
+        },
+        height: {
+            type: String,
+            required: false,
+            default: '500px'
+        },
+        title: {
+            type: String,
+            required: false,
+            default: ''
+        },
+        subtext: {
+            type: String,
+            required: false,
+            default: ''
+        },
+        width: {
+            type: String,
+            required: false,
+            default: '500px'
+        },
+        theme: {
+            type: Boolean,
+            default: false
+        },
+        echartsTheme: {
+            type: String,
+            default: ''
+        },
+    })
+
+    /**定义option */
+    const option = computed({
+        get() {
+            return {
+                backgroundColor: '',
+                tooltip: {
+                    position: 'top',
+                    formatter: function (params) {
+                        if (params.componentType === 'markLine') {
+                            return params.name
+                        } else {
+                            return (
+                                '偏航:' + params.value[0] +
+                                '度<br/ >风速:' +
+                                params.value[1] +
+                                'm/s'
+                            );
+                        }
+                    }
+                },
+                title: {
+                    text: props.title || '',
+                    subtext: props.subtext || '',
+                    top: 6,
+                    left: '5%',
+                },
+                grid: {
+                    top: 80,
+                    left: 40,
+                    right: 40,
+                    bottom: 40,
+                },
+                xAxis: props.xAxis || [],
+                //  {
+                // 	type: 'category',
+                // 	data: props.xAxis || [],
+                // 	boundaryGap: false,
+                // 	splitLine: {
+                // 		show: true
+                // 	},
+                // 	axisLine: {
+                // 		show: false
+                // 	}
+                // },
+                yAxis: props.yAxis || [],
+                // {
+                // 	type: 'category',
+                // 	data: props.yAxis,
+                // 	axisLine: {
+                // 		show: false
+                // 	}
+                // },
+                series: props.series || []
+                // [
+                // 	{
+                // 		name: 'Punch Card',
+                // 		type: 'scatter',
+                // 		symbolSize: function (val) {
+                // 			return val[2] * 2;
+                // 		},
+                // 		data: props.data,
+                // 		animationDelay: function (idx) {
+                // 			return idx * 5;
+                // 		}
+                // 	}
+                // ]
+            }
+        },
+        set(val) {}
+    })
+    watch(() => option, (newVal, oldVal) => {
+        if (chartIns.value) {
+            // console.log(newVal)
+            const echartIns = toRaw(chartIns.value)
+            echartIns.setOption(toRaw(newVal.value))
+        }
+    }, {
+        deep: true
+    })
+    watch([() => props.width, () => props.height], (newVal, oldVal) => {
+        if (chartIns.value) {
+            const echartIns = toRaw(chartIns.value)
+            nextTick(() => echartIns.resize())
+        }
+    })
+    const store = useStore()
+    const collapse = computed({
+        get() {
+            return store.state.collapse
+        },
+        set(val) {}
+    })
+    watch(collapse, (val) => {
+        if (chartIns.value) {
+            setTimeout(() => {
+                chartIns.value.resize()
+            }, 300)
+        }
+    })
+    onMounted(() => {
+        nextTick(() => {
+            init()
+        })
+    })
+
+    watch(() => props.echartsTheme, (newVal, oldVal) => init())
+
+    const init = () => {
+        echarts.registerTheme('chartTheme', chartTheme)
+        const echartIns = echarts.init(document.getElementById(chartId), props.echartsTheme)
+        document.getElementById(chartId).removeAttribute("_echarts_instance_") ? document.getElementById(chartId)
+            .removeAttribute("_echarts_instance_") : ''
+        chartIns.value = echartIns
+        echartIns.setOption(option.value)
+        window.addEventListener('resize', () => {
+            echartIns.resize()
+        })
+    }
+</script>
+<template>
+    <div :id="chartId" :style="{ height: '100%', width: props.width }"></div>
+</template>

File diff suppressed because it is too large
+ 1 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/stationPos.json


+ 52 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/components/table.vue

@@ -0,0 +1,52 @@
+<script setup name="table">
+import { computed, ref } from 'vue';
+
+const props = defineProps({
+  height: {
+    type: String,
+    default: '800px'
+  },
+  data: {
+    type: Array,
+    default: () => ([]),
+  },
+  column: {
+    type: Array,
+    default: () => ([]),
+  },
+  tableName: {
+    type: String,
+    default: '',
+  },
+  tableId: {
+    type: String,
+    default: '',
+  },
+  loading: {
+    type: Boolean,
+    default: false,
+  }
+})
+const emits = defineEmits(['export'])
+const funExport = () => {
+  emits('export')
+}
+const tableRef = ref('')
+const tableHeight =  computed(() => {
+  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 46 : 739
+})
+</script>
+<template>
+  <div ref="tableRef" class=""
+    :style="{ height: typeof props.height === 'string' ? props.height : props.height + 'px' }">
+    <div class="flex justify-between items-center pb-[10px]">
+      <h3>{{ props.tableName }}</h3>
+      <!-- <el-button size="small" type="primary" @click="funExport" :disabled="!props.tableId">数据导出</el-button> -->
+    </div>
+    <el-table stripe :data="props.data" size="small" v-loading="props.loading" :max-height="tableHeight"
+      :style="{ width: '100%' }">
+      <el-table-column align="center" show-overflow-tooltip v-for="item in props.column" :prop="item.prop"
+        :label="item.label" sortable resizable :min-width="item.width ? item.width : 80" />
+    </el-table>
+  </div>
+</template>

File diff suppressed because it is too large
+ 1843 - 0
src/views/economicsOperation/stationAnalyse/posAnalysis/index.vue


+ 360 - 0
src/views/economicsOperation/thematicAnalysis/windAnalysis/components/barLineChart.vue

@@ -0,0 +1,360 @@
+<template>
+    <div class="chart" :id="id"></div>
+</template>
+
+<script>
+    import util from "@/helper/util.js";
+    import partten from "@/helper/partten.js";
+    import * as echarts from "echarts";
+
+    export default {
+        name: "multiple-bar-chart",
+        componentName: "multiple-bar-chart",
+        props: {
+            width: {
+                type: String,
+                default: "100%",
+            },
+            height: {
+                type: String,
+                default: "800px",
+            },
+            // 传入数据
+            bardata: {
+                type: Object,
+                default: () => {
+                    return {
+                        area: [
+                            "风场1",
+                            "风场2",
+                            "风场3",
+                            "风场4",
+                            "风场5",
+                            "风场6",
+                            "风场7",
+                            "风场8",
+                            "风场9",
+                        ],
+                        legend: [
+                            "实际电量",
+                            "计划检修损失",
+                            "非计划检修损失",
+                            "限电损失",
+                            "受累损失",
+                            "性能损失",
+                            "理论发电量"
+                        ],
+                        data: [
+                            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+                            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+                            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+                            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+                            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+                            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+                            [1320, 1302, 901, 634, 1390, 1330, 1320, 1000, 500],
+                            [320, 302, 301, 334, 390, 330, 320, 100, 50],
+                        ],
+                    };
+                },
+            },
+            lineData: {
+                type: Array,
+                default: () => [200, 350, 400, 500, 600, 700, 800, 900, 1200],
+            },
+            lineName: {
+                type: String,
+                default: "损失电量",
+            },
+            // 单位
+            units: {
+                type: Array,
+                default: () => ["(万KWh)", "(风速)"],
+            },
+            // 显示 legend
+            showLegend: {
+                type: Boolean,
+                default: true,
+            },
+            // 颜色
+            color: {
+                type: Array,
+                default: () => ["#323E6F", "#e17e23", "#ba3237", "#c531c7", "#ffffff", "#EDEB2F"],
+            },
+            // 每页显示个数
+            pageSize: {
+                type: Number,
+                default: 20,
+            },
+        },
+        data() {
+            return {
+                id: "",
+                chart: null,
+                themeName: 'light',
+                areaData: [],
+            };
+        },
+        methods: {
+            initChart() {
+                let chart = echarts.init(this.$el);
+                this.chart = chart
+                let option = {
+                    color: this.color,
+                    grid: {
+                        left: 40,
+                        right: 40,
+                        bottom: 16,
+                        top: 16,
+                        containLabel: true,
+                    },
+                    legend: {
+                        show: this.showLegend,
+                        data: this.bardata.legend,
+                        right: 56,
+                        // icon: "ract",
+                        itemWidth: 8,
+                        itemHeight: 8,
+                        inactiveColor: this.themeName === "dark" ?
+                            partten.getColor("gray") : "#838383",
+                        textStyle: {
+                            color: this.themeName === "dark" ?
+                                partten.getColor("grayl") : "#838383",
+                            fontSize: 12,
+                        },
+                    },
+                    tooltip: {
+                        trigger: "axis",
+                        backgroundColor: true ?
+                            "rgba(255,255,255,0.9)" : "rgba(255,255,255,0.9)",
+                        borderColor: this.themeName === "dark" ?
+                            partten.getColor("gray") : "#838383",
+                        textStyle: {
+                            color: this.themeName === "dark" ? "#fff" : "#838383",
+                            fontSize: util.vh(16),
+                        },
+                    },
+                    dataZoom: [{
+                            type: "inside",
+                            start: 0,
+                            end: this.end,
+                            yAxisIndex: [0],
+                        },
+                        {
+                            start: 0,
+                            end: this.end,
+                            top: 20,
+                            bottom: 40,
+                            yAxisIndex: [0],
+                            backgroundColor: "transparent",
+                            // handleIcon: "path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z",
+                            handleStyle: {
+                                color: this.themeName === "dark" ?
+                                    partten.getColor("green") : partten.getColor("blue"),
+                            },
+                            moveHandleSize: 0,
+                            // dataBackground: {
+                            //   lineStyle: {
+                            //     color: partten.getColor("gray"),
+                            //   },
+                            //   areaStyle: {
+                            //     color: partten.getColor("gray"),
+                            //   },
+                            // },
+                            // selectedDataBackground: {
+                            //   lineStyle: {
+                            //     color: partten.getColor("yellow"),
+                            //   },
+                            //   areaStyle: {
+                            //     color: partten.getColor("yellow"),
+                            //   },
+                            // },
+                            fillerColor: "transparent",
+                            textStyle: {
+                                color: this.themeName === "dark" ?
+                                    partten.getColor("grayl") : "#838383",
+                            },
+                            borderColor: this.themeName === "dark" ?
+                                partten.getColor("gray") : "#838383",
+                            brushSelect: false,
+                        },
+                    ],
+                    yAxis: [{
+                        type: "category",
+                        axisLabel: {
+                            color: this.themeName === "dark" ?
+                                partten.getColor("gray") : "#838383",
+                        },
+                        inverse: true,
+                        // minInterval: 10,
+                        // maxInterval: 10,
+                        axisLine: {
+                            show: false,
+                        },
+                        axisTick: {
+                            show: false,
+                        },
+                        data: this.areaData,
+                    }, ],
+                    xAxis: [{
+                            type: "value",
+                            name: '万kWh',
+                            axisLabel: {
+                                color: this.themeName === "dark" ?
+                                    partten.getColor("gray") : "#838383",
+                                // formatter: "{value}万kWh",
+                            },
+                            axisLine: {
+                                type: "dashed",
+                                lineStyle: {
+                                    color: this.themeName === "dark" ?
+                                        partten.getColor("gray") : "#838383",
+                                },
+                                width: 5,
+                            },
+                            axisTick: {
+                                show: false,
+                            },
+                            splitLine: {
+                                lineStyle: {
+                                    type: "dashed",
+                                    dashOffset: 10,
+                                    color: this.themeName === "dark" ? "#5a6162" : "#838383" + 80,
+                                },
+                            },
+                        },
+                        {
+                            type: "value",
+                            name: "",
+                            axisLabel: {
+                                show: false,
+                                // formatter: "{value}万kWh",
+                                // color: partten.getColor("gray"),
+                            },
+                            axisLine: {
+                                show: false,
+                            },
+                            axisTick: {
+                                show: false,
+                            },
+                            splitLine: {
+                                show: false,
+                            },
+                        },
+                    ],
+                    series: [],
+                };
+
+                if (this.bardata && this.bardata.legend)
+                    // bar data
+                    for (var i = 0; i < this.bardata.legend.length; i++) {
+                        option.series.push({
+                            name: this.bardata.legend[i].name,
+                            type: "bar",
+                            stack: "总量",
+                            barWidth: 16,
+                            label: {
+                                show: false,
+                                position: "insideRight",
+                            },
+                            data: this.bardata.data[i],
+                        });
+                    }
+
+                // line data
+                if (this.lineData.length > 0) {
+                    option.series.push({
+                        name: "理论发电量",
+                        type: "line",
+                        data: this.lineData,
+                        smooth: false, //平滑展示
+                        xAxisIndex: 1,
+                        lineStyle: {
+                            color: this.themeName === "dark" ?
+                                partten.getColor("green") : partten.getColor("blue"),
+                        },
+                        itemStyle: {
+                            color: this.themeName === "dark" ?
+                                partten.getColor("green") : partten.getColor("blue"),
+                        },
+                    });
+                }
+                chart.setOption(option);
+                chart.resize()
+            },
+        },
+        created() {
+            this.id = "pie-chart-" + util.newGUID();
+            if (this.bardata.area && this.bardata.area.length < this.pageSize) {
+                this.areaData = this.bardata.area;
+                for (let i = this.bardata.area.length; i <= this.pageSize; i++) {
+                    this.areaData.push("");
+                }
+            }
+        },
+        mounted() {
+            this.$nextTick(() => {
+                this.$el.style.width = this.width;
+                this.$el.style.height = this.height;
+                this.initChart();
+            });
+        },
+        updated() {
+            this.$nextTick(() => {
+                this.initChart();
+            });
+        },
+        beforeUpdate() {
+            this.areaData = this.bardata.area;
+        },
+        beforeUpdate() {
+            this.areaData = this.bardata.area;
+        },
+        activated() {
+            this.$nextTick(() => {
+                this.$el.style.width = this.width;
+                this.$el.style.height = this.height;
+                this.initChart();
+            });
+        },
+        computed: {
+            collapse() {
+                return this.$store.state.collapse
+            },
+            legend() {
+                return this.bardata.legend;
+            },
+            end() {
+                var result = 20;
+                if (this.areaData) {
+                    result = parseInt((this.pageSize / this.areaData.length) * 100);
+                }
+                return result;
+            },
+        },
+        watch: {
+            collapse(val) {
+                if (this.chart) {
+                    setTimeout(() => {
+                        this.chart.resize()
+                    }, 300)
+                }
+            },
+            bardata(val) {
+                if (val.area && val.area.length < this.pageSize) {
+                    this.areaData = val.area;
+                    for (let i = val.area.length; i <= this.pageSize; i++) {
+                        this.areaData.push("");
+                    }
+                }
+            },
+        },
+    };
+</script>
+
+<style lang="less" scoped>
+    .chart {
+        width: 100%;
+        height: 100%;
+        display: inline-block;
+    }
+</style>

File diff suppressed because it is too large
+ 16502 - 0
src/views/economicsOperation/thematicAnalysis/windAnalysis/components/data.json


+ 119 - 0
src/views/economicsOperation/thematicAnalysis/windAnalysis/components/search.vue

@@ -0,0 +1,119 @@
+<script setup name="search">
+import { onMounted, reactive, ref } from 'vue'
+import request from '@/api/axios.js'
+import SubmitBtn from '@com/SubmitBtn.vue'
+
+const queryForm = reactive({
+	station: '',
+	lineIds: [],
+	wtIds: [],
+	type: '1',
+	st: Date.now() - 30 * 24 * 60 * 60 * 1000,
+	et: Date.now(),
+})
+/**场站 */
+const stationList = ref([])
+const funGetStation = async () => {
+	const res = await request.get("/base/station")
+	stationList.value = res.data
+}
+const funStationChange = (stationId) => {
+	if (stationId) {
+		funGetWind(stationId)
+	} else {
+		queryForm.wtIds = []
+		windList.value = []
+	}
+	funSubmit()
+}
+/**项目 */
+const windList = ref([])
+const funGetWind = async (stationId) => {
+	const res = await request.get("/base/project", {params: { stationId }})
+	windList.value = res.data
+	queryForm.wtIds = []
+}
+const funWindChange = (windArr) => {
+	if (windArr?.length) {
+		funGetLine(windArr)
+	} else {
+		queryForm.lineIds = []
+		lineList.value = []
+	}
+	funSubmit()
+}
+/**期次 */
+const lineList = ref([])
+const funGetLine = async (wtIds) => {
+	const res = await request.get("/base/line", {params: { projectId: wtIds.join() }})
+	lineList.value = res.data
+	queryForm.lineIds = []
+}
+/**导出 */
+const emits = defineEmits(['submit'])
+const funSubmit = async () => {
+	const query = {
+		station: queryForm.station,
+		line: queryForm.lineIds.join(),
+		project: queryForm.wtIds.join(),
+		type: '',
+		st: new Date(queryForm.st).formatDate('yyyy-MM-dd'),
+		et: new Date(queryForm.et).formatDate('yyyy-MM-dd'),
+	}
+	emits('submit', query)
+}
+const funType = (type) => {
+	queryForm.type = type
+	queryForm.station = ''
+	queryForm.lineIds = []
+	queryForm.wtIds = []
+	const query = {
+		station: queryForm.station,
+		line: queryForm.lineIds.join(),
+		project: queryForm.wtIds.join(),
+		type: queryForm.type,
+		st: new Date(queryForm.st).formatDate('yyyy-MM-dd'),
+		et: new Date(queryForm.et).formatDate('yyyy-MM-dd'),
+	}
+	emits('submit',query)
+}
+/**created */
+funGetStation()
+funType('1')
+</script>
+<template>
+	<div class="pl-[20px] flex items-center h-[80px] relative">
+		<div class="absolute top-[-7px] left-[20px] text-[#838383] text-[14px]">操作面板</div>
+		<el-form class="" :inline="true" :model="queryForm">
+			<el-form-item label="场站" class="!mb-0">
+				<el-select v-model="queryForm.station" class="w-[150px]" @change="funStationChange">
+					<el-option v-for="item in stationList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item label="期次" class="!mb-0">
+				<el-select multiple class="w-[150px]" clearable v-model="queryForm.wtIds" @change="funWindChange" collapse-tags>
+					<el-option v-for="item in windList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item label="线路" class="!mb-0">
+				<el-select multiple class="w-[150px]" clearable v-model="queryForm.lineIds" @change="funSubmit" collapse-tags>
+					<el-option v-for="item in lineList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item label="开始时间" class="!mb-0">
+				<el-date-picker type="date" class="!w-[150px]" v-model="queryForm.st" @change="funSubmit" ></el-date-picker>
+			</el-form-item>
+			<el-form-item label="结束时间" class="!mb-0">
+				<el-date-picker type="date" class="!w-[150px]" v-model="queryForm.et" @change="funSubmit" ></el-date-picker>
+			</el-form-item>
+			<el-form-item class="!mb-0">
+				<submit-btn v-prevdbclick:5000="funSubmit" desc="执行"></submit-btn>
+			</el-form-item>
+			<el-form-item class="!mb-0">
+				<submit-btn @click="funType('1')" :type="queryForm.type==='1'? 'success': 'default'" desc="风场"></submit-btn>
+				<submit-btn @click="funType('2')" :type="queryForm.type==='2'? 'success': 'default'" desc="期次"></submit-btn>
+				<submit-btn @click="funType('3')" :type="queryForm.type==='3'? 'success': 'default'" desc="集电线路"></submit-btn>
+			</el-form-item>
+		</el-form>
+	</div>
+</template>

+ 90 - 0
src/views/economicsOperation/thematicAnalysis/windAnalysis/components/table.vue

@@ -0,0 +1,90 @@
+<script setup name="table">
+import {outExportExcel} from '@/utils/exportExcel.js'
+import {ref, computed} from 'vue'
+const props = defineProps({
+  height: {
+    type: String,
+    default: '800px'
+  },
+  data: {
+    type: Array,
+    default: () => ([]),
+  },
+  column: {
+    type: Array,
+    default: () => ([]),
+  },
+  tableName: {
+    type: String,
+    default: '',
+  },
+  tableId: {
+    type: String,
+    default: '',
+  },
+  loading: {
+    type: Boolean,
+    default: false,
+  },
+  showSummary:{
+    type: Boolean,
+    default: false,
+  },
+  summaryMethod: {
+    type: Function,
+    default: () => () => {}
+  }
+})
+const emits = defineEmits(['export'])
+const funExport = () => {
+  const columns = props.column.map(o => {
+    return {
+      ...o,
+      property: o.prop
+    }
+  })
+  let summary = []
+  const summaryObj = {}
+  const tHeader = []
+  const tHeaderKeys = []
+  const tableData = []
+  if(props.showSummary && props.summaryMethod){
+    summary = props.summaryMethod({columns,data: props.data})
+  }
+  for(const key in props.column){
+    tHeader.push(props.column[key].label)
+    tHeaderKeys.push(props.column[key].prop)
+    if(props.showSummary && props.summaryMethod){
+      summaryObj[props.column[key].prop] = summary[key] 
+    }
+  }
+  const exportName = props.tableName
+  tableData.push(...props.data)
+  if(props.showSummary && props.summaryMethod){
+    tableData.push(summaryObj)
+  }
+  outExportExcel(tHeader,tHeaderKeys,tableData,exportName)
+}
+const tableRef = ref('')
+const tableHeight =  computed(() => {
+  return tableRef.value.offsetHeight? tableRef.value.offsetHeight - 46 : 739
+})
+</script>
+<template>
+  <div ref="tableRef" class="p-[10px] shadow rounded-[6px] shadow-blue-500"
+    :style="{ height: typeof props.height === 'string' ? props.height : props.height + 'px' }">
+    <div class="flex justify-between items-center pb-[10px]">
+      <h3>{{props.tableName}}</h3>
+      <el-button size="small" type="primary" @click="funExport" :disabled="!props.tableId">数据导出</el-button>
+    </div>
+    <el-table :data="props.data"
+      stripe
+      :show-summary="showSummary"
+      :summary-method="summaryMethod"
+      size="small" v-loading="props.loading"
+      :max-height="tableHeight"
+      :style="{ width: '100%'}">
+      <el-table-column align="center" show-overflow-tooltip v-for="item in props.column" :prop="item.prop" :label="item.label" sortable resizable :min-width="item.width? item.width : 80" />
+    </el-table>
+  </div>
+</template>

+ 642 - 0
src/views/economicsOperation/thematicAnalysis/windAnalysis/index.vue

@@ -0,0 +1,642 @@
+<template>
+    <div class="dataAnalysisWindAna" :class="!theme ? 'themeDark' : 'themeLight'">
+        <div class="dataAnalysisWindAnaMain">
+            <!-- <div class="main_top">
+                <p class="topPsty">损失电量分析</p>
+            </div> -->
+            <div class="main">
+                <div class="treeDataMain">
+                    <tree-cop ref="treeCopRef" :data="treeData" @checkChange="funTreeCheckChange" :show-checkbox="true"
+                        :height="treeHeight" @currentChange="funCurrentChange" @refresh="funGetTree"></tree-cop>
+                </div>
+                <div class="excelDataMain">
+                    <excel-cop :checkIds="excelCheckIds" :showCheckbox="excelCheckboxShow" :data="excelList"
+                        :theme="theme" :height="excelHeight" @excelChange="funExcelChange"
+                        @checkChange="funExcelCheckChange">
+                    </excel-cop>
+                </div>
+                <div class="tableDataMain">
+                    <div class="px-[10px] shadow rounded-[6px] shadow-blue-500">
+                        <el-tabs v-model="activeTab">
+                            <el-tab-pane label="图表展示" name="1"> </el-tab-pane>
+                            <el-tab-pane label="表格数据" name="2"> </el-tab-pane>
+                            <table-cop class="" v-if="activeTab === '2'" :data="tableData" :showSummary="true"
+                                :summaryMethod="funSummary" :column="tableColumn" :loading="tableLoading" :theme="theme"
+                                :height="tableHeight" :tableId="tableShowId" :tableName="tableName"></table-cop>
+                            <div v-show="activeTab === '1'" :style="{
+                  height:
+                    typeof tableHeight === 'string'
+                      ? tableHeight
+                      : tableHeight + 'px',
+                }" class="p-[10px]">
+                                <bar-line-chart-cop v-show="lineData.length" :height="tableHeight" :bardata="barData"
+                                    :lineData="lineData" :color="barColor" lineName="理论发电量"></bar-line-chart-cop>
+                                <el-empty v-show="!lineData.length" description="请选择条件"></el-empty>
+                            </div>
+                        </el-tabs>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script setup name="prepare">
+    import tableCop from "@com/generatingCapacityComponent/table.vue";
+    import treeCop from "@com/generatingCapacityComponent/tree.vue";
+    import excelCop from "@com/generatingCapacityComponent/excel.vue";
+    import barLineChartCop from "./components/barLineChart.vue";
+    import {
+        ElMessage
+    } from "element-plus";
+    import {
+        onMounted,
+        ref,
+        onActivated,
+        watch
+    } from "vue";
+    import {
+        useStore
+    } from "vuex";
+    // import httpRequest from "@/utils/request.js";
+    import jsonData from "./components/data.json";
+    /**配置参数 */
+    const treeHeight = ref(window.innerHeight - 0 + "px"); //tree高度
+    const excelHeight = ref(window.innerHeight - 0 + "px"); //excel高度
+    const tableHeight = ref(window.innerHeight - 20 + "px");
+    /**table 开始 */
+    const tableShowId = ref("");
+    const tableName = ref("损失电量分析");
+    const tableColumn = ref([]);
+    const tableLoading = ref(false);
+    const tableData = ref([]);
+    const funSummary = ({
+        columns,
+        data
+    }) => {
+        const sums = [];
+        columns.forEach((column, index) => {
+            if (index === 0) {
+                sums[index] = "合计";
+                return;
+            }
+            const values = data.map((item) => Number(item[column.property]));
+            if (!values.every((value) => Number.isNaN(value))) {
+                sums[index] = values.reduce((prev, curr) => {
+                    const value = Number(curr);
+                    if (!Number.isNaN(value)) {
+                        return Number((prev + curr).toFixed(2));
+                    } else {
+                        return Number(prev.toFixed(2));
+                    }
+                }, 0);
+            } else {
+                sums[index] = "--";
+            }
+            if (["speed", "fnlly"].includes(column.property)) {
+                if (!Number.isNaN(sums[index])) {
+                    sums[index] = Number((sums[index] / data.length).toFixed(2));
+                }
+            }
+        });
+
+        return sums;
+    };
+    const funSubmit = async () => {
+        if (!excelCheckIds.value.length) {
+            ElMessage.error("请勾选要展现的项");
+            return false;
+        }
+        tableLoading.value = true;
+        tableData.value = [];
+        tableShowId.value = "";
+        barData.value = {
+            area: [],
+            legend: [],
+            data: [],
+        };
+        lineData.value = [];
+        const res = await httpRequest.get("/fjjxb/five/loss/cal", {
+            params: {
+                ids: excelCheckIds.value.join(),
+            },
+        });
+        if (res.code !== 200 || !res.data.title) {
+            tableLoading.value = false;
+            return false;
+        }
+        ElMessage.success(res.msg);
+        tableColumn.value = res.data.title.map((o) => {
+            return {
+                prop: o.key,
+                label: o.des,
+                width: o.des === "时间" ? 100 : 80,
+            };
+        });
+        tableData.value = res.data.data;
+
+        const name = [],
+            data = [],
+            llfdl = [],
+            legend = [{
+                    name: "实际电量",
+                    icon: "rect",
+                },
+                {
+                    name: "计划检修损失",
+                    icon: "rect",
+                },
+                {
+                    name: "非计划检修损失",
+                    icon: "rect",
+                },
+                {
+                    name: "限电损失",
+                    icon: "rect",
+                },
+                {
+                    name: "受累损失",
+                    icon: "rect",
+                },
+                {
+                    name: "性能损失",
+                    icon: "rect",
+                },
+                {
+                    name: "理论发电量",
+                    icon: "circle",
+                },
+            ],
+            // legend = [
+            //     "实际电量",
+            //     "计划检修损失",
+            //     "非计划检修损失",
+            //     "限电损失",
+            //     "受累损失",
+            //     "性能损失",
+            //     "理论发电量"
+            // ],
+            data2 = []; //项目列表
+
+        // if (params.station) {
+        // 	let arr = [];
+        // 	let hj = res.data.data.pop();
+        // 	res.data.data.forEach((ele, index) => {
+        // 		arr[ele.id.split('_')[1] - 1] = ele
+        // 	})
+        // 	arr.push(hj);
+        // 	res.data.data = arr;
+        // }
+
+        res.data.data.forEach((item, index) => {
+            name.push(item.name);
+            data.push([item.sjfdl, item.jhjx, item.fjhjx, item.xd, item.sl, item.xn]);
+            llfdl.push(item.llfdl);
+            data2.push({
+                index: index + 1,
+                name: item.name,
+                llfdl: item.llfdl,
+                sjfdl: item.sjfdl,
+                speed: item.speed,
+                fjhjx: item.fjhjx,
+                jhjx: item.jhjx,
+                sl: item.sl,
+                xd: item.xd,
+                xn: item.xn,
+                fnlly: item.fnlly,
+                is_light: false,
+            });
+        });
+        if (data.length > 0) {
+            let arr1 = [];
+            const length = data[0].length;
+            for (var i = 0; i < length; i++) {
+                let arr2 = [];
+                data.forEach((ele) => {
+                    arr2.push(ele[i]);
+                });
+                arr1.push(arr2);
+            }
+            lineData.value = llfdl;
+            barData.value = {
+                area: name,
+                legend: legend,
+                data: arr1,
+            };
+        }
+
+        tableLoading.value = false;
+        tableShowId.value = "1";
+        activeTab.value = "1";
+    };
+    /**barlineChart 开始 */
+    const barData = ref({
+        area: [],
+        legend: [],
+        data: [],
+    });
+    const lineData = ref([]);
+    const barColor = [
+        "#4b55ae",
+        "#e17e23",
+        "#ba3237",
+        "#c531c7",
+        "rgb(63,177,227)",
+        "#05bb4c",
+    ];
+
+    /**tabs */
+    const activeTab = ref("1");
+    /**excel 开始 */
+    const excelCheckboxShow = ref(false);
+    const excelType = ref("");
+    const treeCopRef = ref(); //treeCop ref
+    const excelCheckIds = ref([]);
+    const excelList = ref([]);
+    const funExcelChange = async (obj) => {
+        //点击excel项时
+        return false;
+    };
+    const funExcelCheckChange = ({
+        checkArr,
+        data
+    }) => {
+        //bug
+        excelCheckIds.value = checkArr;
+        funSubmit();
+    };
+
+    /**prepare tree 开始 */
+    const treeData = ref([]);
+    const actTreeNode = ref(null); //当前激活的treeNode
+    const funRepeatMap = (arr) => {
+        return arr.map((o) => {
+            if (o.children) {
+                const findIndex = o.children.findIndex((p) => !!p.type);
+                if (findIndex !== -1) {
+                    o.childs = o.children;
+                    o.children = [];
+                    if (!actTreeNode.value) {
+                        //判断当且仅有process获取tree时 赋值
+                        actTreeNode.value = o;
+                    }
+                }
+            }
+            return {
+                ...o,
+                children: o.children ? funRepeatMap(o.children) : [],
+            };
+        });
+    };
+    const funGetTree = async () => {
+        actTreeNode.value = null;
+        const res = await httpRequest.get("/power/prepare/tree");
+        treeData.value = funRepeatMap(res.data);
+        excelList.value = [];
+        if (actTreeNode.value) {
+            funCurrentChange({
+                current: actTreeNode.value,
+                currentNode: null,
+            });
+            if (treeCopRef.value) {
+                treeCopRef.value.$refs.tree.setCheckedKeys([actTreeNode.value.id]);
+                excelCheckIds.value = actTreeNode.value.childs.map((o) => o.id);
+                funSubmit();
+            }
+        }
+    };
+    const funCurrentChange = ({
+        current,
+        currentNode
+    }) => {
+        excelCheckboxShow.value = true;
+        if (current.childs) {
+            excelList.value = current.childs.map((o) => {
+                return {
+                    id: o.id,
+                    interval: o.interval,
+                    path: o.path,
+                    prepareid: o.prepareid,
+                    station: o.station,
+                    time: o.time,
+                    type: o.type,
+                    windturbine: o.windturbine,
+                    name: o.path.substring(
+                        o.path.indexOf(o.station + "_") + (o.station + "_").length
+                    ),
+                };
+            });
+        } else {
+            excelList.value = [];
+        }
+    };
+    const funTreeCheckChange = ({
+        current,
+        checkedNodes,
+        checkedKeys,
+        halfCheckedNodes,
+        halfCheckedKeys,
+    }) => {
+        //tree change  -> excel change
+        funCurrentChange({
+            current,
+            currentNode: "",
+        });
+        const checkIds = [];
+        if (checkedNodes.checkedNodes.length) {
+            let checkArr = checkedNodes.checkedNodes;
+            checkArr.forEach((it) => {
+                if (it.childs && it.childs.length) {
+                    it.childs.forEach((iv) => {
+                        checkIds.push(iv.id);
+                    });
+                }
+            });
+        }
+        excelCheckIds.value = checkIds;
+        funSubmit();
+    };
+    /**created */
+    const theme = ref(null);
+    const echartsTheme = ref("");
+    const store = useStore();
+    watch(
+        () => store.state.theme,
+        (newVal, oldVal) => {
+            theme.value = newVal;
+            echartsTheme.value = !newVal ? "dark" : "";
+            funGetTree();
+        }, {
+            deep: true,
+        }
+    );
+    const initPageData = () => {
+        actTreeNode.value = null;
+        treeData.value = funRepeatMap(JSON.parse(JSON.stringify(jsonData.treeData)));
+        excelList.value = [];
+        if (actTreeNode.value) {
+            if (actTreeNode.value.childs) {
+                excelList.value = actTreeNode.value.childs.map((o) => {
+                    return {
+                        id: o.id,
+                        interval: o.interval,
+                        path: o.path,
+                        prepareid: o.prepareid,
+                        station: o.station,
+                        time: o.time,
+                        type: o.type,
+                        windturbine: o.windturbine,
+                        isCheck: false,
+                        name: o.path.substring(
+                            o.path.indexOf(o.station + "_") + (o.station + "_").length
+                        ),
+                    };
+                });
+            } else {
+                excelList.value = [];
+            }
+
+            if (treeCopRef.value) {
+                treeCopRef.value.$refs.tree.setCheckedKeys([actTreeNode.value.id]);
+                excelCheckIds.value = actTreeNode.value.childs.map((o) => o.id);
+
+                tableLoading.value = true;
+                tableData.value = [];
+                tableShowId.value = "";
+                barData.value = {
+                    area: [],
+                    legend: [],
+                    data: [],
+                };
+                lineData.value = [];
+                tableColumn.value = jsonData.tableData.title.map((o) => {
+                    return {
+                        prop: o.key,
+                        label: o.des,
+                        width: o.des === "时间" ? 100 : 80,
+                    };
+                });
+                tableData.value = jsonData.tableData.data;
+
+                const name = [],
+                    data = [],
+                    llfdl = [],
+                    legend = [{
+                            name: "实际电量",
+                            icon: "rect",
+                        },
+                        {
+                            name: "计划检修损失",
+                            icon: "rect",
+                        },
+                        {
+                            name: "非计划检修损失",
+                            icon: "rect",
+                        },
+                        {
+                            name: "限电损失",
+                            icon: "rect",
+                        },
+                        {
+                            name: "受累损失",
+                            icon: "rect",
+                        },
+                        {
+                            name: "性能损失",
+                            icon: "rect",
+                        },
+                        {
+                            name: "理论发电量",
+                            icon: "circle",
+                        },
+                    ],
+                    data2 = []; //项目列表
+
+                jsonData.tableData.data.forEach((item, index) => {
+                    name.push(item.name);
+                    data.push([
+                        item.sjfdl,
+                        item.jhjx,
+                        item.fjhjx,
+                        item.xd,
+                        item.sl,
+                        item.xn,
+                    ]);
+                    llfdl.push(item.llfdl);
+                    data2.push({
+                        index: index + 1,
+                        name: item.name,
+                        llfdl: item.llfdl,
+                        sjfdl: item.sjfdl,
+                        speed: item.speed,
+                        fjhjx: item.fjhjx,
+                        jhjx: item.jhjx,
+                        sl: item.sl,
+                        xd: item.xd,
+                        xn: item.xn,
+                        fnlly: item.fnlly,
+                        is_light: false,
+                    });
+                });
+                if (data.length > 0) {
+                    let arr1 = [];
+                    const length = data[0].length;
+                    for (var i = 0; i < length; i++) {
+                        let arr2 = [];
+                        data.forEach((ele) => {
+                            arr2.push(ele[i]);
+                        });
+                        arr1.push(arr2);
+                    }
+                    lineData.value = llfdl;
+                    barData.value = {
+                        area: name,
+                        legend: legend,
+                        data: arr1,
+                    };
+                }
+
+                tableLoading.value = false;
+                tableShowId.value = "1";
+                activeTab.value = "1";
+            }
+        }
+    };
+    /**mounted */
+    onMounted(() => {
+        initPageData();
+        //   funGetTree();
+        theme.value = store.state.theme;
+        echartsTheme.value = !theme.value ? "dark" : "";
+        tableHeight.value = window.innerHeight - 20 + "px";
+        excelHeight.value = window.innerHeight - 0 + "px";
+        treeHeight.value = window.innerHeight - 0 + "px";
+        window.addEventListener("resize", () => {
+            tableHeight.value = window.innerHeight - 20 + "px";
+            excelHeight.value = window.innerHeight - 0 + "px";
+            treeHeight.value = window.innerHeight - 0 + "px";
+        });
+    });
+    /**activated */
+    onActivated(() => {
+        // funGetTree()
+    });
+</script>
+<style lang="less" scoped>
+    .dataAnalysisWindAna {
+        height: 100%;
+
+        .dataAnalysisWindAnaMain {
+            height: 100%;
+
+            .main_top {
+                height: 40px;
+                display: flex;
+                align-items: center;
+
+                .topPsty {
+                    position: relative;
+                    top: 5px;
+                    padding: 7px 20px;
+                    font-size: 12px;
+                    font-weight: 600;
+                    margin-left: 10px;
+                    border-radius: 3px;
+                }
+            }
+
+            .main {
+                display: flex;
+                width: 100%;
+
+                .treeDataMain,
+                .excelDataMain,
+                .tableDataMain {
+                    border-radius: 10px;
+                }
+
+                .treeDataMain {
+                    margin-right: 10px;
+                    padding: 10px 0 10px 10px;
+                    width: calc(19% - 20px);
+                }
+
+                .excelDataMain {
+                    margin-right: 10px;
+                    padding: 10px 0 10px 10px;
+                    width: calc(15% - 20px);
+                }
+
+                .tableDataMain {
+                    padding: 10px;
+                    width: calc(66% - 20px);
+                    position: relative;
+
+                    .butten_com {
+                        position: absolute;
+                        right: 20px;
+                        z-index: 111111;
+                    }
+                }
+            }
+        }
+    }
+
+    .themeDark {
+        .dataAnalysisWindAnaMain {
+            .main_top {
+                .topPsty {
+                    color: #1c99ff;
+                    background: linear-gradient(to top, fade(#2169c3, 50%), fade(#2169c3, 0));
+                }
+            }
+
+            .main {
+                // background: linear-gradient(to left, fade(#2169c3, 50%), fade(#2169c3, 0));
+                background: rgba(33, 105, 195, .2);
+
+                .treeDataMain {
+                    background: transparent;
+                }
+
+                .excelDataMain {
+                    // background: #313233;
+                }
+
+                .tableDataMain {
+                    margin-top: 5px;
+                    // background: #212223;
+                }
+            }
+        }
+    }
+
+    .themeLight {
+        padding: 0;
+
+        .dataAnalysisWindAnaMain {
+            .main_top {
+                .topPsty {
+                    color: #2778ff;
+                    background: #ffffff;
+                }
+            }
+
+            .main {
+                background: #e6e8f2;
+
+                .treeDataMain {
+                    background: transparent;
+                }
+
+                .excelDataMain {
+                    background: #f4f6fb;
+                }
+
+                .tableDataMain {
+                    background: #fff;
+                    margin-top: 5px;
+                }
+            }
+        }
+    }
+</style>

+ 39 - 0
src/views/nxReport/czjbbb/index.vue

@@ -0,0 +1,39 @@
+<template>
+    <div style="height: 100%">
+        <iframe :src="url" width="100%" height="100%" frameborder="0" scrolling="auto"></iframe>
+    </div>
+</template>
+<script>
+    export default {
+        name: "czjbbb",
+        data() {
+            return {
+                url: "",
+            };
+        },
+        mounted() {
+            if (window.location.origin.indexOf('10.220.1.5') !== -1) {
+                this.url =
+                    "http://10.220.1.5:8001/rbi/ebibase/showreport.do?resid=EANA$2$2$1$72977a47b6154b299ebcc708634e63dc$e3b52de7efe7422bb0ddafa9967371dd&id=admin&pw=admin"
+            } else {
+                this.url =
+                    "http://123.60.219.66:8083/bi/ebibase/showreport.do?resid=EANA$2$2$1$041302f30436412d9ba78f161a6575f0$d0cec38cba1f43128d9aa5d348198c6e&id=admin&pw=admin"
+            }
+        },
+    };
+</script>
+<style lang="less" scope>
+    @titleGray: #9ca5a8;
+    @rowGray: #606769;
+    @darkBack: #536268;
+
+    .knowledge-2 {
+        .el-select {
+            width: 200px;
+        }
+
+        .el-input {
+            width: 200px;
+        }
+    }
+</style>

+ 11 - 2
src/views/nxReport/czzyb/index.vue

@@ -5,12 +5,21 @@
 </template>
 <script>
     export default {
-        name: "gkjlb",
+        name: "czzyb",
         data() {
             return {
-                url: "http://123.60.219.66:8083/bi/ebipro/easyolap.do?action=edit&resid=EANA$2$8$1$041302f30436412d9ba78f161a6575f0$f5c25912e8aa49d78e33f070bf944858&id=admin&pw=admin",
+                url: "",
             };
         },
+        mounted() {
+            if (window.location.origin.indexOf('10.220.1.5') !== -1) {
+                this.url =
+                    "http://10.220.1.5:8001/rbi/ebipro/easyolap.do?action=edit&resid=EANA$2$8$1$72977a47b6154b299ebcc708634e63dc$bb7ed0d54ad94d6fa1dead9bd0018ecb&id=admin&pw=admin"
+            } else {
+                this.url =
+                    "http://123.60.219.66:8083/bi/ebipro/easyolap.do?action=edit&resid=EANA$2$8$1$041302f30436412d9ba78f161a6575f0$f5c25912e8aa49d78e33f070bf944858&id=admin&pw=admin"
+            }
+        },
     };
 </script>
 <style lang="less" scope>

src/views/nxReport/pjfs/index.vue → src/views/nxReport/xmjbbb/index.vue