Explorar o código

Merge branch 'master' of http://git.xt.wenhq.top:8083/hs/zhny_ui

luogang hai 9 meses
pai
achega
b8ccca54c2

+ 11 - 1
ems-ui/package.json

@@ -39,16 +39,20 @@
   },
   "dependencies": {
     "@antv/x6": "^2.18.1",
+    "@logicflow/core": "^2.0.6",
+    "@logicflow/extension": "^2.0.10",
     "@riophae/vue-treeselect": "^0.4.0",
     "autofit.js": "^3.1.3",
     "axios": "0.24.0",
+    "bpmn-js": "^17.11.1",
     "clipboard": "2.0.8",
     "core-js": "^3.25.3",
     "dayjs": "^1.11.13",
+    "diagram-js": "^14.11.3",
     "echarts": "5.4.0",
     "echarts-gl": "^2.0.9",
     "element-resize-detector": "^1.2.4",
-    "element-ui": "2.15.14",
+    "element-ui": "^2.15.14",
     "file-saver": "2.0.5",
     "fuse.js": "6.4.3",
     "highlight.js": "9.18.5",
@@ -56,6 +60,7 @@
     "js-beautify": "1.13.0",
     "js-cookie": "3.0.1",
     "jsencrypt": "3.0.0-rc.1",
+    "jsplumb": "^2.15.6",
     "nprogress": "0.2.0",
     "quill": "1.3.7",
     "screenfull": "5.0.2",
@@ -64,10 +69,14 @@
     "vue": "2.6.12",
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
+    "vue-flowchart": "^0.1.1",
+    "vue-graph": "^0.9.3",
+    "vue-jsplumb": "^1.0.1",
     "vue-meta": "2.4.0",
     "vue-router": "3.4.9",
     "vue-seamless-scroll": "^1.1.23",
     "vue-select": "^3.20.3",
+    "vue-super-flow": "^1.4.0",
     "vuedraggable": "2.24.3",
     "vuex": "3.6.0"
   },
@@ -81,6 +90,7 @@
     "compression-webpack-plugin": "6.1.2",
     "connect": "3.6.6",
     "eslint": "7.15.0",
+    "eslint-loader": "^4.0.2",
     "eslint-plugin-vue": "7.2.0",
     "lint-staged": "10.5.3",
     "runjs": "4.4.2",

+ 63 - 0
ems-ui/src/api/mgr/OpEnergyStrategy.js

@@ -0,0 +1,63 @@
+import request from '@/utils/request'
+
+
+//获取能源策略参数
+export function getStrategyParam(code) {
+  return request({
+    url: '/ems/energyStrategy/param?strategyCode='+code,
+    method: 'get',
+  })
+}
+
+// 获取能源策略参数选项
+export function getStrategyParamOption(query) {
+  return request({
+    url: '/ems/energyStrategy/param/option',
+    method: 'get',
+    params: query
+  })
+}
+
+// 修改能源策略
+export function updateOpEnergyStrategy(data) {
+  return request({
+    url: '/ems/energyStrategy/param',
+    method: 'put',
+    data: data
+  })
+}
+
+//查询策略步骤
+export function getStrategyStep(code) {
+  return request({
+    url: '/ems/energyStrategy/step?strategyCode='+code,
+    method: 'get',
+  })
+}
+
+//新增策略步骤
+
+export function addStrategyStep(data) {
+  return request({
+    url: '/ems/energyStrategy/step',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改策略步骤
+export function updateStrategyStep(data) {
+  return request({
+    url: '/ems/energyStrategy/step',
+    method: 'put',
+    data: data
+  })
+}
+
+//删除策略步骤
+export function deleteStrategyStep(code) {
+  return request({
+    url: '/ems/energyStrategy/step?strategyCode='+code,
+    method: 'delete',
+  })
+}

+ 6 - 0
ems-ui/src/router/index.js

@@ -41,6 +41,7 @@ export const constantRoutes = [
       }
     ]
   },
+
   {
     path: '/login',
     component: () => import('@/views/login'),
@@ -51,6 +52,11 @@ export const constantRoutes = [
     component: () => import('@/views/register'),
     hidden: true
   },
+  // {
+  //   path: '/test',
+  //   component: () => import('@/views/mgr/test.vue'),
+  //   hidden: true
+  // },
   {
     path: '/404',
     component: () => import('@/views/error/404'),

+ 2 - 2
ems-ui/src/views/analysis/power/store.vue

@@ -109,8 +109,8 @@
           <span>{{ parseTime(scope.row.date, '{y}-{m}-{d}') }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="充电电量(kW-h)" align="center" prop="chargeElecQuantity" width="130" />
-      <el-table-column label="放电电量(kW-h)" align="center" prop="dischargeElecQuantity" width="130"/>
+      <el-table-column label="充电电量(kW.h)" align="center" prop="chargeElecQuantity" width="130" />
+      <el-table-column label="放电电量(kW.h)" align="center" prop="dischargeElecQuantity" width="130"/>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button

+ 2 - 2
ems-ui/src/views/mgr/powergrid.vue

@@ -195,7 +195,6 @@ export default {
         ]
       },
 
-
       elecQuantity: {
         series: [
           {
@@ -221,7 +220,6 @@ export default {
         series: [
           {
             type: 'pie',
-
             data: [],
             label: {
               show: true,
@@ -257,6 +255,8 @@ export default {
       //     }
       //   ]
       // },
+
+
       pvSupplyIndex: {
         unit: '  ',
         xAxis: {

+ 3 - 0
ems-ui/src/views/mgr/poweruse.vue

@@ -517,3 +517,6 @@ export default {
   // }
 }
 </style>
+
+
+}

+ 397 - 5
ems-ui/src/views/mgr/strategy.vue

@@ -76,7 +76,7 @@
           </el-table-column>
           <el-table-column label="状态" align="center" prop="strategyState" >
             <template slot-scope="scope">
-              <scope>{{ getStateName(scope.row.strategyState)}}</scope>
+              {{ getStateName(scope.row.strategyState)}}
             </template>
           </el-table-column>
           <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
@@ -84,18 +84,162 @@
               <el-button
                 size="mini"
                 type="text"
+                icon="el-icon-message"
+                @click="handleParameter(scope.row)"
+                v-hasPermi="['basecfg:energyStrategy:edit']"
+              >参数
+              </el-button>
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-info"
+                @click="handleStep(scope.row)"
+                v-hasPermi="['basecfg:energyStrategy:edit']"
+              >步骤
+              </el-button>
+              <el-button
+                size="mini"
+                type="text"
                 icon="el-icon-edit"
                 @click="handleUpdate(scope.row)"
                 v-hasPermi="['ems:energyStrategy:edit']"
               >修改
               </el-button>
-              <el-button size="mini" type="text" icon="el-icon-delete" class="deleteBtn" @click="handleDelete(scope.row)" v-hasPermi="['ems:energyStrategy:remove']">
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-delete"
+                class="deleteBtn"
+                @click="handleDelete(scope.row)"
+                v-hasPermi="['ems:energyStrategy:remove']">
                 删除</el-button>
-
             </template>
           </el-table-column>
+
+          <!-- 参数弹框 -->
+          <el-dialog title="策略参数维护" :visible.sync="openParameterDialog" width="50%" append-to-body>
+            <div>
+              <div class="container-block">
+                <SubTitle title="默认参数" />
+              </div>
+              <div v-for="param in defaultParams" :key="param.paramName">
+                <label class="param-label">{{ param.paramName }}</label>
+                <el-input v-if="param.paramValueFormat === 'text'" v-model="param.paramValue" placeholder="请输入" @change="handleParamChange"></el-input>
+                <el-select v-if="param.paramValueFormat === 'enum'" v-model="param.paramValue" placeholder="请选择" @change="handleParamChange">
+                  <el-option
+                    v-for="item in paramOptions"
+                    :key="item.key"
+                    :label="item.name"
+                    :value="item.key">
+                    <el-tooltip :content="item.desc" placement="top">
+                      <div>{{ item.name }}</div>
+                    </el-tooltip>
+                  </el-option>
+                </el-select>
+              </div>
+            </div>
+      <!--  模型参数输入框/下拉框 -->
+            <div class="container-block">
+              <SubTitle title="模式参数" />
+            </div>
+            <div v-if="selectedParamValue === 'maxPowerTrack'">
+              <!-- 当 selectedParamValue 为 'maxPowerTrack' 时,不显示任何模式参数 -->
+            </div>
+            <div v-if="selectedParamValue === 'inverterControl'">
+              <el-select v-model="selectedParamKey" placeholder="请选择">
+                <el-option
+                  v-for="item in modelParamOptions"
+                  :key="item.key"
+                  :label="item.name"
+                  :value="item.key">
+                  <el-tooltip :content="item.desc" placement="top">
+                    <div>{{ item.name }}</div>
+                  </el-tooltip>
+                </el-option>
+              </el-select>
+            </div>
+            <div v-if="selectedParamValue === 'powerAndVoltage'">
+              <!-- 当 selectedParamValue 为 'powerAndVoltage' 时,显示文本框 -->
+              <div v-for="item in defaultParamsOption" :key="item.paramName" class="param-container">
+                <label>{{ item.paramName }}</label>
+                <el-input v-if="item.paramValueFormat === 'text'" v-model="item.paramValue" class="param-containerInput"></el-input>
+              </div>
+            </div>
+            <div slot="footer" class="dialog-footer">
+              <el-button type="primary" @click="updateOpEnergyStrategy">确认</el-button>
+              <el-button @click="openParameterDialog = false">关闭</el-button>
+            </div>
+
+          </el-dialog>
         </el-table>
 
+        <!-- 步骤流程图弹框 -->
+        <el-dialog title="步骤流程图" :visible.sync="stepDialogVisible" width="80%" :style="{ height: '80vh' }">
+          <div style="display: flex;">
+            <div style="width: 50%;" >
+              <el-steps direction="vertical" :active="currentStepDetail.stepIndex">
+                <el-step
+                  v-for="(step, index) in strategyStepOption"
+                  :key="step.id"
+                  :title="step.stepName"
+                  :index="index + 1"
+                  @click.native="handleStepClick(step)">
+                </el-step>
+              </el-steps>
+                <el-button type="primary" icon="el-icon-plus" @click="addStep" style="position: absolute; left: 16px;  width: 30px; height: 30px; padding: 0; border-radius: 50%;"></el-button>
+            </div>
+            <div style="width: 50%; padding-left: 20px;">
+              <div v-if="currentStepDetail">
+                <el-form v-if="editMode" label-width="120px">
+                  <el-form-item label="步骤名称">
+                    <el-input v-model="currentStepDetail.stepName"></el-input>
+                  </el-form-item>
+                  <el-form-item label="策略代码">
+                    <el-input v-model="currentStepDetail.strategyCode"></el-input>
+                  </el-form-item>
+                  <el-form-item label="步骤代码">
+                    <el-input v-model="currentStepDetail.stepCode"></el-input>
+                  </el-form-item>
+                  <el-form-item label="步骤顺序">
+                    <el-input v-model="currentStepDetail.stepIndex"></el-input>
+                  </el-form-item>
+                  <el-form-item label="步骤处理">
+                    <el-input v-model="currentStepDetail.stepHandler"></el-input>
+                  </el-form-item>
+                  <el-form-item label="步骤参数">
+                    <el-input v-model="currentStepDetail.stepParam"></el-input>
+                  </el-form-item>
+                  <el-form-item label="目标设施">
+                    <el-input v-model="currentStepDetail.targetFacs"></el-input>
+                  </el-form-item>
+                  <el-form-item label="目标设备">
+                    <el-input v-model="currentStepDetail.targetDevice"></el-input>
+                  </el-form-item>
+                  <el-form-item>
+                    <el-button type="primary" @click="saveStep">保存</el-button>
+                    <el-button type="primary" @click="deleteStep">删除步骤</el-button>
+                    <el-button @click="cancelEdit">退出编辑</el-button>
+                  </el-form-item>
+                </el-form>
+                <div v-else>
+                  <h3>步骤详情</h3>
+                  <p><strong>步骤名称:</strong> {{ currentStepDetail.stepName }}</p>
+                  <p><strong>策略代码:</strong> {{ currentStepDetail.strategyCode }}</p>
+                  <p><strong>步骤代码:</strong> {{ currentStepDetail.stepCode }}</p>
+                  <p><strong>步骤顺序:</strong> {{ currentStepDetail.stepIndex }}</p>
+                  <p><strong>步骤处理:</strong> {{ currentStepDetail.stepHandler }}</p>
+                  <p><strong>步骤参数:</strong> {{ currentStepDetail.stepParam }}</p>
+                  <p><strong>目标设施:</strong> {{ currentStepDetail.targetFacs }}</p>
+                  <p><strong>目标设备:</strong> {{ currentStepDetail.targetDevice }}</p>
+                  <el-button type="primary" @click="editMode = true">编辑</el-button>
+                  <el-button  @click="stepDialogVisible = false">关闭</el-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-dialog>
+
+
         <pagination
           v-show="total>0"
           :total="total"
@@ -145,11 +289,22 @@ import { addEnergyStrategy, delEnergyStrategy, getEnergyStrategy, listEnergyStra
 import { areaTreeSelect } from '@/api/basecfg/area'
 import Treeselect from '@riophae/vue-treeselect'
 import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+import {
+  addStrategyStep,
+  deleteStrategyStep,
+  getStrategyParam,
+  getStrategyParamOption,
+  getStrategyStep,
+  updateOpEnergyStrategy, updateStrategyStep
+} from '@/api/mgr/OpEnergyStrategy'
+import { Tooltip } from 'element-ui';
+import SubTitle from "@/components/SubTitle/index.vue";
+import BaseChart from "@/components/BaseChart/index.vue";
 
 export default {
   name: 'EnergyStrategy',
   dicts: ['strategy_type', 'allow_modify', 'exec_mode'],
-  components: { Treeselect },
+  components: {BaseChart, SubTitle, Treeselect},
   data() {
     return {
       // 遮罩层
@@ -174,12 +329,39 @@ export default {
       // 区域名称
       areaName: undefined,
       areaOptions: [],
-      strategyType: 1,
+      strategyType: "1",
       showExecRule: false,
       defaultProps: {
         children: 'children',
         label: 'label'
       },
+
+      // 控制参数弹框的显示
+      openParameterDialog: false,
+      paramOptions: [], // 存储参数选项
+      selectedParamValue: '', // 存储选中的参数值
+      selectedParamKey:'',
+      defaultControlMode:'',
+      defaultParams: [], // 存储default下的参数
+      selectedParamDesc:'',
+      modelParamOptions: [], // 存储模型参数选项
+      modelParamValue: '', // 存储模型参数值
+      modeParams: [], // 存储模式参数的数据
+      currentStrategyCode:'',
+      defaultParamsOption:[],
+      paramKeys:'',//获取"controlMode": "reactivePower"、 "voltage":
+      paramValues:'',
+      savedParams: {}, // 用于存储用户保存的参数
+
+      stepDialogVisible:false,
+      strategyStepOption:[],
+      strategyStepName:'',
+      activeStep:'',
+      currentStepDetail:[],
+      editMode:true,
+      currentRow:null,
+      nextStepId: 1, // 初始ID值
+
       // 查询参数
       queryParams: {
         pageNum: 1,
@@ -242,6 +424,7 @@ export default {
     this.getAreaTree('Area')
     this.getList();
   },
+
   methods: {
     /** 查询能源策略列表 */
     getList() {
@@ -287,6 +470,7 @@ export default {
       this.ids = selection.map(item => item.id);
       this.single = selection.length !== 1;
       this.multiple = !selection.length;
+
     },
     /** 新增按钮操作 */
     handleAdd() {
@@ -296,6 +480,192 @@ export default {
       this.form.execMode = 99;
       this.form.strategyType = this.strategyType;
     },
+
+    /** 参数按钮操作 */
+    handleParameter(row) {
+      console.log("参数按钮操作!!!!!",row)
+      this.currentStrategyCode=row.strategyCode
+      this.openParameterDialog = true; // 打开弹框
+      this.getStrategyParam(row.strategyCode);
+      this.getStrategyParamOption(row.strategyType, 'default.controlMode');
+      console.log("打开参数弹框时的 selectedParamValue:", this.selectedParamValue);
+
+
+    },
+    /** 获取默认参数 */
+    getStrategyParam(strategyCode) {
+      getStrategyParam(strategyCode).then(response => {
+        const params = response.data.default.controlMode;
+        this.defaultParams = [
+          { paramName: params.paramName, paramValue: this.selectedParamValue, paramValueFormat: params.paramValueFormat },
+        ];
+      console.log(" 获取默认参数", this.defaultParams)
+      })
+    },
+
+
+    /** 获取参数选项 */
+    getStrategyParamOption(strategyType, paramKey) {
+      getStrategyParamOption({strategyType, paramKey}).then(response => {
+        // 更新控制模式下拉框的选项
+        this.paramOptions = response.data;
+      })
+    },
+    getStrategyParamOptions(strategyType, paramKey) {
+      getStrategyParamOption({strategyType, paramKey}).then(response => {
+        // 更新模式参数下拉框的选项
+        this.modelParamOptions = response.data;
+        console.log('更新下拉框的选项',this.modelParamOptions);
+
+      })
+    },
+
+    handleParamChange(value) {
+      this.selectedParamValue = value;
+      console.log("选中的参数值:", this.selectedParamValue);
+      switch (this.selectedParamValue) {
+        case 'maxPowerTrack':
+          // 无模式参数
+          this.modelParamOptions = [];
+          break;
+        case 'inverterControl':
+          getStrategyParam(this.currentStrategyCode).then(response => {
+            const inverterControlParams = response.data.inverterControl;
+            console.log("inverterControlParams",inverterControlParams)
+            this.paramKeys = Object.keys(inverterControlParams);
+            console.log("Param Keys:", this.paramKeys);
+          });
+          this.getStrategyParamOptions(1, 'inverterControl.controlMode');
+          break;
+        case 'powerAndVoltage':
+
+          // 直接展示文本框,不需要调用接口
+          getStrategyParam(this.currentStrategyCode).then(response => {
+            const powerAndVoltageParams = response.data.powerAndVoltage;
+            this.paramKeys = Object.keys(powerAndVoltageParams);
+            this.defaultParamsOption = Object.values(powerAndVoltageParams);
+            // 重置 powerAndVoltage 模式下的参数值
+            this.defaultParamsOption.forEach((item) => {
+              item.paramValue = ''; // 或者设置为某个初始值
+            });
+
+          });
+          break;
+        default:
+          console.error('未知的参数值');
+      }
+    },
+
+    updateOpEnergyStrategy() {
+      // 根据 selectedParamValue 确定参数结构
+      if (this.selectedParamValue === 'powerAndVoltage') {
+        this.paramKeys.forEach((key, index) => {
+          const requestBody = {
+            strategyCode: this.currentStrategyCode,
+            paramGroup: this.selectedParamValue,
+            paramKey: key,
+            paramValue: this.defaultParamsOption[index].paramValue,
+          };
+          console.log("requestBody",requestBody)
+          updateOpEnergyStrategy(requestBody).then(response => {
+            if (response || response.data || response.data.success) {
+              this.$message.success('参数修改成功');
+               this.openParameterDialog = false; // 关闭弹框
+            } else {
+              this.$message.error('参数修改失败');
+            }
+          });
+        });
+      }else if(this.selectedParamValue === 'inverterControl'){
+        this.paramKeys.forEach((key, index) => {
+          const requestBody = {
+            strategyCode: this.currentStrategyCode,
+            paramGroup: this.selectedParamValue,
+            paramKey: key,
+            paramValue: this.selectedParamKey,
+          };
+        console.log("requestBody",requestBody)
+        updateOpEnergyStrategy(requestBody).then(response => {
+          if (response || response.data || response.data.success) {
+            this.$message.success('参数修改成功');
+            this.openParameterDialog = false; // 关闭弹框
+          } else {
+            this.$message.error('参数修改失败');
+          }
+        });
+        });
+      }
+    },
+    /**步骤流程图弹框*/
+    handleStep(row){
+      this.stepDialogVisible=true;
+      this.editMode=false;
+      this.currentRow = row; // 保存当前行的数据
+      getStrategyStep(row.strategyCode).then(response => {
+        this.strategyStepOption=response.data
+        this.activeStep = 1;
+        // 默认展示第一个步骤的详情
+        this.currentStepDetail = this.strategyStepOption[0] || {};
+        this.editMode = false;
+      })
+    },
+    handleStepClick(step) {
+      this.currentStepDetail = step;
+      this.editMode = false;
+    },
+    addStep() {
+      const newStep = {
+        id:'',
+        stepName: '',
+        stepCode: '',
+        stepIndex: this.strategyStepOption.length + 1 || 1,
+        stepHandler: '',
+        stepParam: '',
+        targetFacs: '',
+        targetDevice: '',
+      };
+      // 将新步骤添加到策略步骤选项中
+      this.strategyStepOption.push(newStep);
+      // 更新当前步骤详情为新步骤
+      this.currentStepDetail = newStep;
+      this.editMode = true;
+    },
+
+    saveStep() {
+      // 克隆当前步骤详情,以避免直接修改原始数据
+      const stepDetailToSave = { ...this.currentStepDetail };
+      console.log("保存步骤信息:", stepDetailToSave);
+      if (stepDetailToSave.id != null && stepDetailToSave.id !== '') {
+        // 更新操作
+        updateStrategyStep(stepDetailToSave).then(response => {
+          this.$message.success('修改成功');
+          this.handleStep(this.currentRow);
+        }).catch(error => {
+          console.error('保存失败', error);
+        });
+      } else {
+        addStrategyStep(stepDetailToSave).then(response => {
+          this.$message.success('新增成功');
+          // 重新加载步骤信息
+          this.handleStep(this.currentRow);
+        }).catch(error => {
+          console.error('保存失败', error);
+        });
+      }
+    },
+
+    cancelEdit() {
+      this.editMode = false;
+    },
+    deleteStep() {
+      deleteStrategyStep(this.currentStepDetail.strategyCode).then(response => {
+        this.$message.success('删除成功');
+        this.handleStep(this.currentRow);
+        this.stepDialogVisible=false
+      }).catch(error => {
+        console.error('删除失败', error);
+      });
+    },
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
@@ -373,3 +743,25 @@ export default {
   },
 };
 </script>
+
+<style lang="css" scoped>
+
+.param-label {
+  display: inline-block;
+  margin-right: 10px;
+}
+.param-container {
+  display: flex;
+  align-items: center;
+  margin-bottom: 10px; /* 根据需要调整间距 */
+}
+.param-containerInput {
+  width: 40%;
+}
+
+.param-container label {
+  margin-right: 10px; /* 根据需要调整标签和输入框之间的间距 */
+  white-space: nowrap; /* 防止标签换行 */
+}
+
+</style>

+ 2 - 1
ems-ui/vue.config.js

@@ -35,7 +35,8 @@ module.exports = {
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
-        target: `http://172.192.13.80:9100/`,
+        target: 'http://172.192.13.80:9100/',
+        // target: 'http://127.0.0.1:9100/',
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API + '/ems']: process.env.EMS_REWRITE_URL,