luogang 11 сар өмнө
parent
commit
1017d8b983

+ 136 - 128
ems-ui/src/utils/index.js

@@ -1,19 +1,41 @@
 import { UUID } from 'uuidjs';
 import { parseTime } from './ruoyi';
-
+export function dateFormat(date, format = 'yyyy-MM-dd HH:mm:ss') {
+  const o = {
+    'M+': date.getMonth() + 1, // 月份
+    'd+': date.getDate(), // 日
+    'h+': date.getHours() % 12 === 0 ? 12 : date.getHours() % 12, // 小时
+    'H+': date.getHours(), // 小时
+    'm+': date.getMinutes(), // 分
+    's+': date.getSeconds(), // 秒
+    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
+    S: date.getMilliseconds(), // 毫秒
+    a: date.getHours() < 12 ? '上午' : '下午', // 上午/下午
+    A: date.getHours() < 12 ? 'AM' : 'PM' // AM/PM
+  };
+  if (/(y+)/.test(format)) {
+    format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
+  }
+  for (let k in o) {
+    if (new RegExp('(' + k + ')').test(format)) {
+      format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
+    }
+  }
+  return format;
+}
 /**
  * 表格时间格式化
  */
 export function formatDate(cellValue) {
-  if (cellValue == null || cellValue == "") return "";
-  var date = new Date(cellValue)
-  var year = date.getFullYear()
-  var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
-  var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
-  var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
-  var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
-  var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
-  return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
+  if (cellValue == null || cellValue == '') return '';
+  var date = new Date(cellValue);
+  var year = date.getFullYear();
+  var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
+  var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
+  var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
+  var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
+  var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
+  return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
 }
 
 /**
@@ -23,39 +45,29 @@ export function formatDate(cellValue) {
  */
 export function formatTime(time, option) {
   if (('' + time).length === 10) {
-    time = parseInt(time) * 1000
+    time = parseInt(time) * 1000;
   } else {
-    time = +time
+    time = +time;
   }
-  const d = new Date(time)
-  const now = Date.now()
+  const d = new Date(time);
+  const now = Date.now();
 
-  const diff = (now - d) / 1000
+  const diff = (now - d) / 1000;
 
   if (diff < 30) {
-    return '刚刚'
+    return '刚刚';
   } else if (diff < 3600) {
     // less 1 hour
-    return Math.ceil(diff / 60) + '分钟前'
+    return Math.ceil(diff / 60) + '分钟前';
   } else if (diff < 3600 * 24) {
-    return Math.ceil(diff / 3600) + '小时前'
+    return Math.ceil(diff / 3600) + '小时前';
   } else if (diff < 3600 * 24 * 2) {
-    return '1天前'
+    return '1天前';
   }
   if (option) {
-    return parseTime(time, option)
+    return parseTime(time, option);
   } else {
-    return (
-      d.getMonth() +
-      1 +
-      '月' +
-      d.getDate() +
-      '日' +
-      d.getHours() +
-      '时' +
-      d.getMinutes() +
-      '分'
-    )
+    return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分';
   }
 }
 
@@ -64,18 +76,18 @@ export function formatTime(time, option) {
  * @returns {Object}
  */
 export function getQueryObject(url) {
-  url = url == null ? window.location.href : url
-  const search = url.substring(url.lastIndexOf('?') + 1)
-  const obj = {}
-  const reg = /([^?&=]+)=([^?&=]*)/g
+  url = url == null ? window.location.href : url;
+  const search = url.substring(url.lastIndexOf('?') + 1);
+  const obj = {};
+  const reg = /([^?&=]+)=([^?&=]*)/g;
   search.replace(reg, (rs, $1, $2) => {
-    const name = decodeURIComponent($1)
-    let val = decodeURIComponent($2)
-    val = String(val)
-    obj[name] = val
-    return rs
-  })
-  return obj
+    const name = decodeURIComponent($1);
+    let val = decodeURIComponent($2);
+    val = String(val);
+    obj[name] = val;
+    return rs;
+  });
+  return obj;
 }
 
 /**
@@ -84,14 +96,14 @@ export function getQueryObject(url) {
  */
 export function byteLength(str) {
   // returns the byte length of an utf8 string
-  let s = str.length
+  let s = str.length;
   for (var i = str.length - 1; i >= 0; i--) {
-    const code = str.charCodeAt(i)
-    if (code > 0x7f && code <= 0x7ff) s++
-    else if (code > 0x7ff && code <= 0xffff) s += 2
-    if (code >= 0xDC00 && code <= 0xDFFF) i--
+    const code = str.charCodeAt(i);
+    if (code > 0x7f && code <= 0x7ff) s++;
+    else if (code > 0x7ff && code <= 0xffff) s += 2;
+    if (code >= 0xdc00 && code <= 0xdfff) i--;
   }
-  return s
+  return s;
 }
 
 /**
@@ -99,13 +111,13 @@ export function byteLength(str) {
  * @returns {Array}
  */
 export function cleanArray(actual) {
-  const newArray = []
+  const newArray = [];
   for (let i = 0; i < actual.length; i++) {
     if (actual[i]) {
-      newArray.push(actual[i])
+      newArray.push(actual[i]);
     }
   }
-  return newArray
+  return newArray;
 }
 
 /**
@@ -113,13 +125,13 @@ export function cleanArray(actual) {
  * @returns {Array}
  */
 export function param(json) {
-  if (!json) return ''
+  if (!json) return '';
   return cleanArray(
     Object.keys(json).map(key => {
-      if (json[key] === undefined) return ''
-      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
+      if (json[key] === undefined) return '';
+      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
     })
-  ).join('&')
+  ).join('&');
 }
 
 /**
@@ -127,21 +139,21 @@ export function param(json) {
  * @returns {Object}
  */
 export function param2Obj(url) {
-  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
   if (!search) {
-    return {}
+    return {};
   }
-  const obj = {}
-  const searchArr = search.split('&')
+  const obj = {};
+  const searchArr = search.split('&');
   searchArr.forEach(v => {
-    const index = v.indexOf('=')
+    const index = v.indexOf('=');
     if (index !== -1) {
-      const name = v.substring(0, index)
-      const val = v.substring(index + 1, v.length)
-      obj[name] = val
+      const name = v.substring(0, index);
+      const val = v.substring(index + 1, v.length);
+      obj[name] = val;
     }
-  })
-  return obj
+  });
+  return obj;
 }
 
 /**
@@ -149,9 +161,9 @@ export function param2Obj(url) {
  * @returns {string}
  */
 export function html2Text(val) {
-  const div = document.createElement('div')
-  div.innerHTML = val
-  return div.textContent || div.innerText
+  const div = document.createElement('div');
+  div.innerHTML = val;
+  return div.textContent || div.innerText;
 }
 
 /**
@@ -162,20 +174,20 @@ export function html2Text(val) {
  */
 export function objectMerge(target, source) {
   if (typeof target !== 'object') {
-    target = {}
+    target = {};
   }
   if (Array.isArray(source)) {
-    return source.slice()
+    return source.slice();
   }
   Object.keys(source).forEach(property => {
-    const sourceProperty = source[property]
+    const sourceProperty = source[property];
     if (typeof sourceProperty === 'object') {
-      target[property] = objectMerge(target[property], sourceProperty)
+      target[property] = objectMerge(target[property], sourceProperty);
     } else {
-      target[property] = sourceProperty
+      target[property] = sourceProperty;
     }
-  })
-  return target
+  });
+  return target;
 }
 
 /**
@@ -184,18 +196,16 @@ export function objectMerge(target, source) {
  */
 export function toggleClass(element, className) {
   if (!element || !className) {
-    return
+    return;
   }
-  let classString = element.className
-  const nameIndex = classString.indexOf(className)
+  let classString = element.className;
+  const nameIndex = classString.indexOf(className);
   if (nameIndex === -1) {
-    classString += '' + className
+    classString += '' + className;
   } else {
-    classString =
-      classString.substr(0, nameIndex) +
-      classString.substr(nameIndex + className.length)
+    classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
   }
-  element.className = classString
+  element.className = classString;
 }
 
 /**
@@ -204,9 +214,9 @@ export function toggleClass(element, className) {
  */
 export function getTime(type) {
   if (type === 'start') {
-    return new Date().getTime() - 3600 * 1000 * 24 * 90
+    return new Date().getTime() - 3600 * 1000 * 24 * 90;
   } else {
-    return new Date(new Date().toDateString())
+    return new Date(new Date().toDateString());
   }
 }
 
@@ -217,38 +227,38 @@ export function getTime(type) {
  * @return {*}
  */
 export function debounce(func, wait, immediate) {
-  let timeout, args, context, timestamp, result
+  let timeout, args, context, timestamp, result;
 
-  const later = function() {
+  const later = function () {
     // 据上一次触发时间间隔
-    const last = +new Date() - timestamp
+    const last = +new Date() - timestamp;
 
     // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
     if (last < wait && last > 0) {
-      timeout = setTimeout(later, wait - last)
+      timeout = setTimeout(later, wait - last);
     } else {
-      timeout = null
+      timeout = null;
       // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
       if (!immediate) {
-        result = func.apply(context, args)
-        if (!timeout) context = args = null
+        result = func.apply(context, args);
+        if (!timeout) context = args = null;
       }
     }
-  }
+  };
 
-  return function(...args) {
-    context = this
-    timestamp = +new Date()
-    const callNow = immediate && !timeout
+  return function (...args) {
+    context = this;
+    timestamp = +new Date();
+    const callNow = immediate && !timeout;
     // 如果延时不存在,重新设定延时
-    if (!timeout) timeout = setTimeout(later, wait)
+    if (!timeout) timeout = setTimeout(later, wait);
     if (callNow) {
-      result = func.apply(context, args)
-      context = args = null
+      result = func.apply(context, args);
+      context = args = null;
     }
 
-    return result
-  }
+    return result;
+  };
 }
 
 /**
@@ -260,17 +270,17 @@ export function debounce(func, wait, immediate) {
  */
 export function deepClone(source) {
   if (!source && typeof source !== 'object') {
-    throw new Error('error arguments', 'deepClone')
+    throw new Error('error arguments', 'deepClone');
   }
-  const targetObj = source.constructor === Array ? [] : {}
+  const targetObj = source.constructor === Array ? [] : {};
   Object.keys(source).forEach(keys => {
     if (source[keys] && typeof source[keys] === 'object') {
-      targetObj[keys] = deepClone(source[keys])
+      targetObj[keys] = deepClone(source[keys]);
     } else {
-      targetObj[keys] = source[keys]
+      targetObj[keys] = source[keys];
     }
-  })
-  return targetObj
+  });
+  return targetObj;
 }
 
 /**
@@ -278,16 +288,16 @@ export function deepClone(source) {
  * @returns {Array}
  */
 export function uniqueArr(arr) {
-  return Array.from(new Set(arr))
+  return Array.from(new Set(arr));
 }
 
 /**
  * @returns {string}
  */
 export function createUniqueString() {
-  const timestamp = +new Date() + ''
-  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
-  return (+(randomNum + timestamp)).toString(32)
+  const timestamp = +new Date() + '';
+  const randomNum = parseInt((1 + Math.random()) * 65536) + '';
+  return (+(randomNum + timestamp)).toString(32);
 }
 
 /**
@@ -297,7 +307,7 @@ export function createUniqueString() {
  * @returns {boolean}
  */
 export function hasClass(ele, cls) {
-  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
+  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
 }
 
 /**
@@ -306,7 +316,7 @@ export function hasClass(ele, cls) {
  * @param {string} cls
  */
 export function addClass(ele, cls) {
-  if (!hasClass(ele, cls)) ele.className += ' ' + cls
+  if (!hasClass(ele, cls)) ele.className += ' ' + cls;
 }
 
 /**
@@ -316,23 +326,21 @@ export function addClass(ele, cls) {
  */
 export function removeClass(ele, cls) {
   if (hasClass(ele, cls)) {
-    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
-    ele.className = ele.className.replace(reg, ' ')
+    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
+    ele.className = ele.className.replace(reg, ' ');
   }
 }
 
 export function makeMap(str, expectsLowerCase) {
-  const map = Object.create(null)
-  const list = str.split(',')
+  const map = Object.create(null);
+  const list = str.split(',');
   for (let i = 0; i < list.length; i++) {
-    map[list[i]] = true
+    map[list[i]] = true;
   }
-  return expectsLowerCase
-    ? val => map[val.toLowerCase()]
-    : val => map[val]
+  return expectsLowerCase ? val => map[val.toLowerCase()] : val => map[val];
 }
 
-export const exportDefault = 'export default '
+export const exportDefault = 'export default ';
 
 export const beautifierConf = {
   html: {
@@ -373,20 +381,20 @@ export const beautifierConf = {
     e4x: true,
     indent_empty_lines: true
   }
-}
+};
 
 // 首字母大小
 export function titleCase(str) {
-  return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
+  return str.replace(/( |^)[a-z]/g, L => L.toUpperCase());
 }
 
 // 下划转驼峰
 export function camelCase(str) {
-  return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
+  return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase());
 }
 
 export function isNumberStr(str) {
-  return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
+  return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str);
 }
 
 export const uuid = () => {
@@ -398,6 +406,6 @@ export const uuid = () => {
  * @param obj
  * @returns {any}
  */
-export const copyObj = (obj) => {
+export const copyObj = obj => {
   return JSON.parse(JSON.stringify(obj));
 };

+ 160 - 207
ems-ui/src/views/basecfg/meterdevc/index.vue

@@ -3,43 +3,23 @@
     <el-row :gutter="20">
       <el-col :span="4" :xs="24">
         <div class="head-container">
-          <el-input
-            v-model="areaName"
-            placeholder="请输入区块名称"
-            clearable
-            size="small"
-            prefix-icon="el-icon-search"
-            style="margin-bottom: 20px"
-          />
+          <el-input v-model="areaName" placeholder="请输入区块名称" clearable size="small" prefix-icon="el-icon-search"
+            style="margin-bottom: 20px" />
         </div>
         <div class="head-container">
-          <el-tree
-            :data="areaOptions"
-            :props="defaultProps"
-            :expand-on-click-node="false"
-            :filter-node-method="filterNode"
-            ref="tree"
-            node-key="id"
-            default-expand-all
-            highlight-current
-            @node-click="handleNodeClick"
-          />
+          <el-tree :data="areaOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree"
+            node-key="id" default-expand-all highlight-current @node-click="handleNodeClick" />
         </div>
       </el-col>
       <el-col :span="20" :xs="24">
         <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
           <el-form-item label="计量类别" prop="meterCls">
-            <el-select v-model="queryParams.meterCls" >
+            <el-select v-model="queryParams.meterCls">
               <el-option v-for="item in emsClsOptions" :label="item.name" :value="item.code" :key="item.code" />
             </el-select>
           </el-form-item>
           <el-form-item label="设备代码" prop="deviceCode">
-            <el-input
-              v-model="queryParams.deviceCode"
-              placeholder="请输入设备代码"
-              clearable
-              @keyup.enter.native="handleQuery"
-            />
+            <el-input v-model="queryParams.deviceCode" placeholder="请输入设备代码" clearable @keyup.enter.native="handleQuery" />
           </el-form-item>
           <el-form-item>
             <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -49,36 +29,16 @@
 
         <el-row :gutter="10" class="mb8">
           <el-col :span="1.5">
-            <el-button
-              type="primary"
-              plain
-              icon="el-icon-plus"
-              size="mini"
-              @click="handleAdd"
-              v-hasPermi="['ems:device:add']"
-            >新增</el-button>
+            <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['ems:device:add']">新增
+            </el-button>
           </el-col>
           <el-col :span="1.5">
-            <el-button
-              type="success"
-              plain
-              icon="el-icon-edit"
-              size="mini"
-              :disabled="single"
-              @click="handleUpdate"
-              v-hasPermi="['ems:device:edit']"
-            >修改</el-button>
+            <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
+              v-hasPermi="['ems:device:edit']">修改</el-button>
           </el-col>
           <el-col :span="1.5">
-            <el-button
-              type="danger"
-              plain
-              icon="el-icon-delete"
-              size="mini"
-              :disabled="multiple"
-              @click="handleDelete"
-              v-hasPermi="['ems:device:remove']"
-            >删除</el-button>
+            <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
+              v-hasPermi="['ems:device:remove']">删除</el-button>
           </el-col>
           <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
         </el-row>
@@ -90,49 +50,39 @@
               <span>{{ "(" + getObjTypeName(scope.row.objType) + ")"+ scope.row.objName }}</span>
             </template>
           </el-table-column>
+          <el-table-column label="计量标签" align="center" prop="objTag" >
+            <template slot-scope="scope">
+              {{formatDict(scope.row.objTag,'objTagOptions')}}
+            </template>
+          </el-table-column>
           <el-table-column label="设备代码" align="center" prop="deviceCode" />
           <el-table-column label="计量类别" align="center" prop="meterCls">
             <template slot-scope="scope">
               <span>{{ getMeterClsName(scope.row.meterCls) }}</span>
             </template>
           </el-table-column>
-          <el-table-column label="采集方式" align="center" prop="colMode" >
+          <el-table-column label="采集方式" align="center" prop="colMode">
             <template slot-scope="scope">
               <span>{{ getColModeName(scope.row.colMode) }}</span>
             </template>
           </el-table-column>
-          <el-table-column label="采集周期" align="center" prop="colCycle" >
+          <el-table-column label="采集周期" align="center" prop="colCycle">
             <template slot-scope="scope">
               <span>{{ getColCycleName(scope.row.colCycle) }}</span>
             </template>
           </el-table-column>
           <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
             <template slot-scope="scope">
-              <el-button
-                size="mini"
-                type="text"
-                icon="el-icon-edit"
-                @click="handleUpdate(scope.row)"
-                v-hasPermi="['ems:device:edit']"
-              >修改</el-button>
-              <el-button
-                size="mini"
-                type="text"
-                icon="el-icon-delete"
-                @click="handleDelete(scope.row)"
-                v-hasPermi="['ems:device:remove']"
-              >删除</el-button>
+              <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['ems:device:edit']">修改
+              </el-button>
+              <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['ems:device:remove']">
+                删除</el-button>
             </template>
           </el-table-column>
         </el-table>
 
-        <pagination
-          v-show="total>0"
-          :total="total"
-          :page.sync="queryParams.pageNum"
-          :limit.sync="queryParams.pageSize"
-          @pagination="getList"
-        />
+        <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
+          @pagination="getList" />
 
         <!-- 添加或修改计量设备对话框 -->
         <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
@@ -143,7 +93,7 @@
               </el-select>
             </el-form-item>
             <el-form-item label="计量类别" prop="meterCls">
-              <el-select v-model="form.meterCls" >
+              <el-select v-model="form.meterCls">
                 <el-option v-for="item in emsClsOptions" :label="item.name" :value="item.code" :key="item.code" />
               </el-select>
             </el-form-item>
@@ -156,21 +106,21 @@
               </el-select>
             </el-form-item>
             <el-form-item label="计量对象" prop="objCode">
-              <treeselect v-model="objCode" :options="objCodeOptions" :show-count="true" placeholder="请选择计量对象" ref="treeObjCodeOptions"/>
+              <treeselect v-model="objCode" :options="objCodeOptions" :show-count="true" placeholder="请选择计量对象" ref="treeObjCodeOptions" />
             </el-form-item>
             <el-form-item label="计量标签" prop="objTag">
               <el-radio-group v-model="form.objTag" size="medium">
-                <el-radio v-for="(item, index) in objTagOptions" :key="index" :label="item.code"
-                          :disabled="item.disabled">{{item.name}}</el-radio>
+                <el-radio v-for="(item, index) in objTagOptions" :key="index" :label="item.code" :disabled="item.disabled">{{item.name}}
+                </el-radio>
               </el-radio-group>
             </el-form-item>
             <el-form-item label="采集方式" prop="colMode">
-              <el-select v-model="form.colMode" >
+              <el-select v-model="form.colMode">
                 <el-option v-for="item in colModeOptions" :label="item.name" :value="item.code" :key="item.code" />
               </el-select>
             </el-form-item>
             <el-form-item label="采集周期" prop="colCycle" v-if="form.colMode === 0">
-              <el-select v-model="form.colCycle" >
+              <el-select v-model="form.colCycle">
                 <el-option v-for="item in colCycleOptions" :label="item.name" :value="item.code" :key="item.code" />
               </el-select>
             </el-form-item>
@@ -192,15 +142,15 @@
 </template>
 
 <script>
-import { listDevice, getDevice, delDevice, addDevice, updateDevice } from "@/api/device/meterDevice";
-import { devTreeByFacs } from "@/api/device/device";
+import { listDevice, getDevice, delDevice, addDevice, updateDevice } from '@/api/device/meterDevice'
+import { devTreeByFacs } from '@/api/device/device'
 import { areaTreeSelect, areaTreeSelectByCode } from '@/api/basecfg/area'
-import { listBuildingByArea } from "@/api/basecfg/building";
-import Treeselect from "@riophae/vue-treeselect";
-import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import { listBuildingByArea } from '@/api/basecfg/building'
+import Treeselect from '@riophae/vue-treeselect'
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 
 export default {
-  name: "Device",
+  name: 'Device',
   components: { Treeselect },
   data() {
     return {
@@ -219,7 +169,7 @@ export default {
       // 计量设备表格数据
       deviceList: [],
       // 弹出层标题
-      title: "",
+      title: '',
       // 是否显示弹出层
       open: false,
       // 区域名称
@@ -230,33 +180,33 @@ export default {
       selectObjCode: null,
       objCode: null,
       defaultProps: {
-        children: "children",
-        label: "label"
+        children: 'children',
+        label: 'label'
       },
       // 能源分类树
       emsClsOptions: [
-        {"code": 45, "name": "电表"},
-        {"code": 70, "name": "水表"}
+        { code: 45, name: '电表' },
+        { code: 70, name: '水表' }
       ],
       objTypeOptions: [
-        {"code": 1, "name": "区块"},
-        {"code": 2, "name": "设备"}
+        { code: 1, name: '区块' },
+        { code: 2, name: '设备' }
       ],
       objTagOptions: [
-        {"code": 0, "name": "公摊表"},
-        {"code": 1, "name": "个户表"}
+        { code: 0, name: '公摊表' },
+        { code: 1, name: '个户表' }
       ],
       colCycleOptions: [
-        {"code": 0, "name": "实时"},
-        {"code": 1, "name": "分钟"},
-        {"code": 2, "name": "小时"},
-        {"code": 3, "name": "天"},
-        {"code": 4, "name": "月"},
-        {"code": 5, "name": "双月"},
+        { code: 0, name: '实时' },
+        { code: 1, name: '分钟' },
+        { code: 2, name: '小时' },
+        { code: 3, name: '天' },
+        { code: 4, name: '月' },
+        { code: 5, name: '双月' }
       ],
       colModeOptions: [
-        {"code": 0, "name": "自动抄表"},
-        {"code": 1, "name": "手动抄表"}
+        { code: 0, name: '自动抄表' },
+        { code: 1, name: '手动抄表' }
       ],
       // 查询参数
       queryParams: {
@@ -279,71 +229,63 @@ export default {
       form: {},
       // 表单校验
       rules: {
-        areaCode: [
-          { required: true, message: "选择服务区", trigger: "blur" }
-        ],
-        deviceCode: [
-          { required: true, message: "设备代码不能为空", trigger: "blur" }
-        ],
-        meterCls: [
-          { required: true, message: "计量类别不能为空", trigger: "blur" }
-        ],
-        objType: [
-          { required: true, message: "计量对象类型 1-区块 2-设备不能为空", trigger: "change" }
-        ],
-        objCode: [
-          { required: true, message: "计量对象编码不能为空", trigger: "blur" }
-        ]
+        areaCode: [{ required: true, message: '选择服务区', trigger: 'blur' }],
+        deviceCode: [{ required: true, message: '设备代码不能为空', trigger: 'blur' }],
+        meterCls: [{ required: true, message: '计量类别不能为空', trigger: 'blur' }],
+        objType: [{ required: true, message: '计量对象类型 1-区块 2-设备不能为空', trigger: 'change' }],
+        objCode: [{ required: true, message: '计量对象编码不能为空', trigger: 'blur' }]
       }
-    };
+    }
   },
-  watch:{
+  watch: {
     objCode: {
       handler(id) {
-        const option = this.$refs.treeObjCodeOptions.getNode(id);
-        this.objCode = option.id;
-        this.form.objCode = option.id;
+        if (id) {
+          const option = this.$refs.treeObjCodeOptions.getNode(id)
+          this.objCode = option.id
+          this.form.objCode = option.id
 
-        if (1 === this.form.objType) {
-          if ('Area'  === option.raw.tier) {
-            this.form.objSubType = 1;
-          } else if ('Building'  === option.raw.tier) {
-            this.form.objSubType = 2;
-          } else if ('Zoning'  === option.raw.tier) {
-            this.form.objSubType = 3;
-          }
-        } else if (2 === this.form.objType) {
-          if ('Facs'  === option.raw.tier) {
-            this.form.objSubType = 1;
-          } else if ('Device'  === option.raw.tier) {
-            this.form.objSubType = 2;
+          if (this.form.objType === 1) {
+            if (option.raw.tier === 'Area') {
+              this.form.objSubType = 1
+            } else if (option.raw.tier === 'Building') {
+              this.form.objSubType = 2
+            } else if (option.raw.tier === 'Zoning') {
+              this.form.objSubType = 3
+            }
+          } else if (this.form.objType === 2) {
+            if (option.raw.tier === 'Facs') {
+              this.form.objSubType = 1
+            } else if (option.raw.tier === 'Device') {
+              this.form.objSubType = 2
+            }
           }
         }
       }
     },
     // 根据名称筛选区域树
     areaName(val) {
-      this.$refs.tree.filter(val);
+      this.$refs.tree.filter(val)
     }
   },
   created() {
-    this.getAreaTree('Area');
-    this.getList();
+    this.getAreaTree('Area')
+    this.getList()
   },
   methods: {
     /** 查询计量设备列表 */
     getList() {
-      this.loading = true;
+      this.loading = true
       listDevice(this.queryParams).then(response => {
-        this.deviceList = response.rows;
-        this.total = response.total;
-        this.loading = false;
-      });
+        this.deviceList = response.rows
+        this.total = response.total
+        this.loading = false
+      })
     },
     // 取消按钮
     cancel() {
-      this.open = false;
-      this.reset();
+      this.open = false
+      this.reset()
     },
     // 表单重置
     reset() {
@@ -357,102 +299,114 @@ export default {
         colCycle: null,
         colMode: null,
         specDesc: null
-      };
-      this.objCode = null;
-      this.resetForm("form");
+      }
+      this.objCode = null
+      this.resetForm('form')
     },
     /** 搜索按钮操作 */
     handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
+      this.queryParams.pageNum = 1
+      this.getList()
     },
     /** 重置按钮操作 */
     resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
+      this.resetForm('queryForm')
+      this.handleQuery()
     },
     // 多选框选中数据
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
+      this.single = selection.length !== 1
       this.multiple = !selection.length
     },
     /** 新增按钮操作 */
     handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加计量设备";
+      this.reset()
+      this.open = true
+      this.title = '添加计量设备'
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
-      this.reset();
+      this.reset()
       const id = row.id || this.ids
       getDevice(id).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "修改计量设备";
-      });
+        this.form = response.data
+        this.open = true
+        this.title = '修改计量设备'
+      })
 
-      this.objCode = row.objCode;
+      this.objCode = row.objCode
       if (row.objType === 1) {
         areaTreeSelectByCode('Area', row.areaCode).then(response => {
-          this.objCodeOptions = response.data;
-        });
+          this.objCodeOptions = response.data
+        })
       } else if (row.objType === 2) {
-        devTreeByFacs(row.areaCode).then(response =>{
-          this.objCodeOptions = response.data;
+        devTreeByFacs(row.areaCode).then(response => {
+          this.objCodeOptions = response.data
         })
       }
     },
     handleAreaSelect(areaCode) {
       listBuildingByArea(areaCode).then(response => {
-        this.buildingOptions = response.data;
+        this.buildingOptions = response.data
       })
     },
     /** 提交按钮 */
     submitForm() {
-      this.$refs["form"].validate(valid => {
+      this.$refs['form'].validate(valid => {
         if (valid) {
           if (this.form.id != null) {
             updateDevice(this.form).then(response => {
-              this.$modal.msgSuccess("修改成功");
-              this.open = false;
-              this.getList();
-            });
+              this.$modal.msgSuccess('修改成功')
+              this.open = false
+              this.getList()
+            })
           } else {
             addDevice(this.form).then(response => {
-              this.$modal.msgSuccess("新增成功");
-              this.open = false;
-              this.getList();
-            });
+              this.$modal.msgSuccess('新增成功')
+              this.open = false
+              this.getList()
+            })
           }
         }
-      });
+      })
     },
     /** 删除按钮操作 */
     handleDelete(row) {
-      const ids = row.id || this.ids;
-      this.$modal.confirm('是否确认删除计量设备编号为"' + ids + '"的数据项?').then(function() {
-        return delDevice(ids);
-      }).then(() => {
-        this.getList();
-        this.$modal.msgSuccess("删除成功");
-      }).catch(() => {});
+      const ids = row.id || this.ids
+      this.$modal
+        .confirm('是否确认删除计量设备编号为"' + ids + '"的数据项?')
+        .then(function() {
+          return delDevice(ids)
+        })
+        .then(() => {
+          this.getList()
+          this.$modal.msgSuccess('删除成功')
+        })
+        .catch(() => {})
+    },
+    formatDict(val, options, key = 'code', text = 'name') {
+      let name = ''
+      this[options].forEach(item => {
+        if (val === item[key]) {
+          name = item[text]
+        }
+      })
+      return name
     },
-
     getMeterClsName(meterCls) {
       const clsMap = {
         45: '电表',
         70: '水表'
-      };
-      return clsMap[meterCls] || '未知';
+      }
+      return clsMap[meterCls] || '未知'
     },
     getObjTypeName(objType) {
       const typeMap = {
         1: '区块',
         2: '设备'
-      };
-      return typeMap[objType] || '未知';
+      }
+      return typeMap[objType] || '未知'
     },
     getColCycleName(colCycle) {
       const cycleMap = {
@@ -462,44 +416,43 @@ export default {
         3: '天',
         4: '月',
         5: '双月'
-      };
-      return cycleMap[colCycle] || '';
+      }
+      return cycleMap[colCycle] || ''
     },
     getColModeName(colMode) {
       const modeMap = {
         0: '自动抄表',
         1: '手动抄表'
-      };
-      return modeMap[colMode] || '未知';
+      }
+      return modeMap[colMode] || '未知'
     },
     /** 查询区域树结构 */
     getAreaTree(tier) {
       areaTreeSelect(tier).then(response => {
-        this.areaOptions = response.data;
-      });
+        this.areaOptions = response.data
+      })
     },
     // 筛选节点
     filterNode(value, data) {
-      if (!value) return true;
-      return data.label.indexOf(value) !== -1;
+      if (!value) return true
+      return data.label.indexOf(value) !== -1
     },
     // 节点单击事件
     handleNodeClick(data) {
-      this.queryParams.areaCode = data.id;
-      this.handleQuery();
+      this.queryParams.areaCode = data.id
+      this.handleQuery()
     },
     changeObjOptions(objType) {
       if (objType === 1) {
         areaTreeSelectByCode('Area', this.form.areaCode).then(response => {
-          this.objCodeOptions = response.data;
-
-        });
+          this.objCodeOptions = response.data
+        })
       } else if (objType === 2) {
-        devTreeByFacs(this.form.areaCode).then(response =>{
-          this.objCodeOptions = response.data;
+        devTreeByFacs(this.form.areaCode).then(response => {
+          this.objCodeOptions = response.data
         })
       }
     }
   }
-};
+}
 </script>

+ 176 - 173
ems-ui/src/views/devmgr/meterRead/index.vue

@@ -3,106 +3,93 @@
     <el-row :gutter="20">
       <el-col :span="4" :xs="24">
         <div class="head-container">
-          <el-input
-            v-model="areaName"
-            placeholder="请输入服务区名称"
-            clearable
-            size="small"
-            prefix-icon="el-icon-search"
-            style="margin-bottom: 20px"
-          />
+          <el-input v-model="areaName" placeholder="请输入服务区名称" clearable size="small" prefix-icon="el-icon-search"
+            style="margin-bottom: 20px" />
         </div>
         <div class="head-container">
-          <el-tree
-            :data="areaOptions"
-            :props="defaultProps"
-            :expand-on-click-node="false"
-            :filter-node-method="filterNode"
-            ref="tree"
-            node-key="id"
-            default-expand-all
-            highlight-current
-            @node-click="handleNodeClick"
-          />
+          <el-tree :data="areaOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree"
+            node-key="id" default-expand-all highlight-current @node-click="handleNodeClick" />
         </div>
       </el-col>
       <el-col :span="20" :xs="24">
-        <el-tabs v-model="activeTab"  @tab-change="handleTabChange">
+        <el-tabs v-model="activeTab" @tab-click="handleTabChange">
           <el-tab-pane label="电表抄报" name="first">
-            <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-              <el-form-item label="计量类别" prop="meterCls">
-                <el-select v-model="queryParams.meterCls" >
-                  <el-option v-for="item in emsClsOptions" :label="item.name" :value="item.code" :key="item.code" />
-                </el-select>
-              </el-form-item>
-              <el-form-item label="设备代码" prop="deviceCode">
-                <el-input
-                  v-model="queryParams.deviceCode"
-                  placeholder="请输入设备代码"
-                  clearable
-                  @keyup.enter.native="handleQuery"
-                />
-              </el-form-item>
-              <el-form-item>
-                <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
-                <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
-              </el-form-item>
-            </el-form>
-
-            <el-table v-loading="loading" :data="deviceList" >
-              <el-table-column label="计量对象" align="left" prop="objName" width="300px">
-                <template slot-scope="scope">
-                  <span>{{ "(" + getObjTypeName(scope.row.objType) + ")"+ scope.row.objName }}</span>
-                </template>
-              </el-table-column>
-              <el-table-column label="设备代码" align="center" prop="deviceCode" />
-
-              <el-table-column label="抄表周期" align="center" prop="colCycle" >
-                <template slot-scope="scope">
-                  <span>{{ getColCycleName(scope.row.colCycle) }}</span>
-                </template>
-              </el-table-column>
-              <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-                <template slot-scope="scope">
-                  <el-button
-                    size="mini"
-                    type="text"
-                    @click="handleViewRec(scope.row)"
-                    v-hasPermi="['ems:device:edit']"
-                  >填报</el-button>
-                  <el-button
-                    size="mini"
-                    type="text"
-                    @click="handleViewRec(scope.row)"
-                    v-hasPermi="['ems:device:remove']"
-                  >查看</el-button>
-                </template>
-              </el-table-column>
-            </el-table>
-
-            <pagination
-              v-show="total>0"
-              :total="total"
-              :page.sync="queryParams.pageNum"
-              :limit.sync="queryParams.pageSize"
-              @pagination="getList"
-            />
           </el-tab-pane>
           <el-tab-pane label="水表抄报" name="second">
-
           </el-tab-pane>
         </el-tabs>
+        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
+          <el-form-item label="设备代码" prop="deviceCode">
+            <el-input v-model="queryParams.deviceCode" placeholder="请输入设备代码" clearable @keyup.enter.native="handleQuery" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+        <el-table v-loading="loading" :data="deviceList">
+          <el-table-column label="计量对象" align="left" prop="objName" width="300px">
+            <!-- <template slot-scope="scope">
+                  <span>{{ "(" + getObjTypeName(scope.row.objType) + ")"+ scope.row.objName }}</span>
+                </template> -->
+          </el-table-column>
+          <el-table-column label="设备代码" align="center" prop="deviceCode" />
+          <el-table-column label="抄表周期" align="center" prop="colCycle">
+            <template slot-scope="scope">
+              <span>{{ getColCycleName(scope.row.colCycle) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+            <template slot-scope="scope">
+              <el-button size="mini" type="text" @click="handleRecord(scope.row)">填报</el-button>
+              <el-button size="mini" type="text" @click="handleViewRec(scope.row)">查看</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
+          @pagination="getList" />
+        <el-dialog :title="fillTitle" :visible.sync="fillFormOpen" width="500px" append-to-body>
+          <el-form ref="fillForm" :model="fillForm" label-width="150px">
+            <el-form-item label="抄表月份">
+              <el-input readonly :value="fillForm.currentMonth" />
+            </el-form-item>
+            <el-form-item label="上次抄表日期">
+              <el-input readonly :value="fillForm.lastTime" />
+            </el-form-item>
+            <el-form-item label="上次抄表示数">
+              <el-input readonly :value="fillForm.lastReading" />
+            </el-form-item>
+            <el-form-item required :rules="[{required:true,message:'请选择本次抄表时间'}]" label="本次抄表时间" prop="meterTime">
+              <el-date-picker style="width:100%" value-format="yyyy-MM-dd" v-model="fillForm.meterTime" type="date" placeholder="选择日期">
+              </el-date-picker>
+            </el-form-item>
+            <el-form-item required :rules="[{required:true,message:'请输入当前抄表示数'}]" label="本次抄表示数" prop="meterReading">
+              <el-input v-model="fillForm.meterReading" oninput="value=value.replace(/[^\d]/g,'')" placeholder="请输入本次抄表示数" />
+            </el-form-item>
+            <el-form-item label="倍率" prop="magnification">
+              <el-input readonly v-model="fillForm.magnification" />
+            </el-form-item>
+            <el-form-item label="增量">
+              <el-input readonly :value="increase" />
+            </el-form-item>
 
+          </el-form>
+          <div slot="footer" class="dialog-footer">
+            <el-button type="primary" @click="submitFillForm">确 定</el-button>
+            <el-button @click="fillCancel">取 消</el-button>
+          </div>
+        </el-dialog>
         <!-- 历史抄表记录 -->
         <el-dialog :title="title" :visible.sync="recListOpen" width="1200px" append-to-body>
-          <el-form ref="recListForm" :model="recListForm" :rules="rules" label-width="80px">
+          <el-form ref="recListForm" :model="recListForm" label-width="80px">
             <el-form-item label="抄表历史" prop="recList">
-              <el-table  v-loading="loading" :data="recListForm.recList" max-height="280px">
-                <el-table-column label="设备代码" align="center" prop="deviceCode"/>
+              <el-table v-loading="loading" :data="recListForm.recList" max-height="280px">
+                <el-table-column label="设备代码" align="center" prop="deviceCode" />
                 <el-table-column label="年份" align="center" prop="year" />
                 <el-table-column label="月份" align="center" prop="meterMonth" />
-                <el-table-column label="抄表日期" align="center" prop="meterTime"/>
-                <el-table-column label="抄表示数" align="center" prop="meterReading"/>
+                <el-table-column label="抄表日期" align="center" prop="meterTime" />
+                <el-table-column label="抄表示数" align="center" prop="meterReading" />
                 <el-table-column label="用量" align="center" prop="increase" />
               </el-table>
             </el-form-item>
@@ -117,65 +104,41 @@
 </template>
 
 <script>
-import { listDevice, getDevice, delDevice, addDevice, updateDevice } from "@/api/device/meterDevice";
-import { listMeterReadingByParam, getLastRecord, addMeterReading, updateMeterReading, delMeterReading } from "@/api/device/meterRead"
+import { listDevice, getDevice } from '@/api/device/meterDevice'
+import { listMeterReadingByParam, getLastRecord, addMeterReading, updateMeterReading, delMeterReading } from '@/api/device/meterRead'
 import { areaTreeSelect } from '@/api/basecfg/area'
-import Treeselect from "@riophae/vue-treeselect";
-import "@riophae/vue-treeselect/dist/vue-treeselect.css";
-
-
+import Treeselect from '@riophae/vue-treeselect'
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+import { dateFormat } from '@/utils/index.js'
 export default {
-  name: "Device",
+  name: 'Device',
   components: { Treeselect },
   data() {
     return {
       activeTab: 'first',
       // 遮罩层
       loading: true,
-      // 选中数组
-      ids: [],
-      // 非单个禁用
-      single: true,
-      // 非多个禁用
-      multiple: true,
-      // 显示搜索条件
-      showSearch: true,
       // 总条数
       total: 0,
       // 计量设备表格数据
       deviceList: [],
       // 弹出层标题
-      title: "",
+      title: '',
       // 记录表单开启
       recListOpen: false,
       // 填报表单开启
       fillFormOpen: false,
       // 区域名称
       areaName: undefined,
-      objCodeOptions: [],
       areaOptions: [],
-      buildingOptions: [],
-      selectObjCode: null,
-      objCode: null,
       defaultProps: {
-        children: "children",
-        label: "label"
+        children: 'children',
+        label: 'label'
       },
-      colCycleOptions: [
-        {"code": 0, "name": "实时"},
-        {"code": 1, "name": "分钟"},
-        {"code": 2, "name": "小时"},
-        {"code": 3, "name": "天"},
-        {"code": 4, "name": "月"}
-      ],
-      colModeOptions: [
-        {"code": 0, "name": "自动抄表"},
-        {"code": 1, "name": "手动抄表"}
-      ],
       // 能源分类树
       emsClsOptions: [
-        {"code": 45, "name": "电表"},
-        {"code": 70, "name": "水表"}
+        { code: 45, name: '电表' },
+        { code: 70, name: '水表' }
       ],
       // 查询参数
       queryParams: {
@@ -189,69 +152,74 @@ export default {
       recListForm: {
         recList: []
       },
-      sbForm: {},
-      // 表单校验
-      rules: {
-        areaCode: [
-          { required: true, message: "选择服务区", trigger: "blur" }
-        ],
-        deviceCode: [
-          { required: true, message: "设备代码不能为空", trigger: "blur" }
-        ],
-        meterCls: [
-          { required: true, message: "计量类别不能为空", trigger: "blur" }
-        ],
-        objType: [
-          { required: true, message: "计量对象类型 1-区块 2-设备不能为空", trigger: "change" }
-        ],
-        objCode: [
-          { required: true, message: "计量对象编码不能为空", trigger: "blur" }
-        ]
+      fillTitle: '',
+      fillForm: {
+        currentMonth: '',
+        deviceCode: '',
+        areaCode: '',
+        year: '',
+        meterMonth: '',
+        lastTime: '',
+        lastReading: '',
+        meterTime: '',
+        meterReading: '',
+        increase: '',
+        magnification: 1
+      }
+    }
+  },
+  computed: {
+    increase() {
+      const { meterReading, magnification, lastReading } = this.fillForm
+      if (meterReading && magnification) {
+        return (meterReading - (lastReading || 0)) * magnification
       }
-    };
+      return ''
+    }
   },
   created() {
-    this.getAreaTree('Area');
-    this.getList();
+    this.getAreaTree('Area')
+    this.getList()
   },
+
   methods: {
     /** 查询计量设备列表 */
     getList() {
-      this.loading = true;
+      this.loading = true
       listDevice(this.queryParams).then(response => {
-        this.deviceList = response.rows;
-        this.total = response.total;
-        this.loading = false;
-      });
+        this.deviceList = response.rows
+        this.total = response.total
+        this.loading = false
+      })
     },
 
     /** 搜索按钮操作 */
     handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
+      this.queryParams.pageNum = 1
+      this.getList()
     },
     /** 重置按钮操作 */
     resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
+      this.resetForm('queryForm')
+      this.handleQuery()
     },
-    handleTabChange(newTabName) {
-      console.log('当前激活的Tab:', newTabName);
+    handleTabChange() {
       // 根据newTabName给someParam赋值
-      if (newTabName === 'first') {
+      if (this.activeTab === 'first') {
         // 电表抄表
-        this.queryParams.meterCls = '45';
-      } else if (newTabName === 'second') {
+        this.queryParams.meterCls = '45'
+      } else if (this.activeTab === 'second') {
         // 水表抄表
-        this.queryParams.meterCls = '70';
+        this.queryParams.meterCls = '70'
       }
+      this.handleQuery()
     },
     getObjTypeName(objType) {
       const typeMap = {
         1: '区块',
         2: '设备'
-      };
-      return typeMap[objType] || '未知';
+      }
+      return typeMap[objType] || '未知'
     },
     getColCycleName(colCycle) {
       const cycleMap = {
@@ -260,39 +228,74 @@ export default {
         2: '小时',
         3: '天',
         4: '月'
-      };
-      return cycleMap[colCycle] || '';
+      }
+      return cycleMap[colCycle] || ''
     },
     /** 查询区域树结构 */
     getAreaTree(tier) {
       areaTreeSelect(tier).then(response => {
-        this.areaOptions = response.data;
-      });
+        this.areaOptions = response.data
+      })
     },
     // 筛选节点
     filterNode(value, data) {
-      if (!value) return true;
-      return data.label.indexOf(value) !== -1;
+      if (!value) return true
+      return data.label.indexOf(value) !== -1
     },
     // 节点单击事件
     handleNodeClick(data) {
-      this.queryParams.areaCode = data.id;
-      this.handleQuery();
+      this.queryParams.areaCode = data.id
+      this.handleQuery()
     },
     handleViewRec(row) {
       const queryMeterReading = {
-        "areaCode": row.areaCode,
-        "deviceCode": row.deviceCode,
-      };
-
+        areaCode: row.areaCode,
+        deviceCode: row.deviceCode
+      }
+      this.title = row.objName
       listMeterReadingByParam(queryMeterReading).then(response => {
-        this.recListOpen = true;
-        this.recListForm.recList = response.data;
+        this.recListOpen = true
+        this.recListForm.recList = response.data
+      })
+    },
+    async handleRecord(row) {
+      this.fillForm = this.$options.data().fillForm
+      this.resetForm('fillForm')
+      this.fillTitle = row.objName
+      this.fillFormOpen = true
+      const nowDay = new Date()
+      this.fillForm.year = nowDay.getFullYear()
+      this.fillForm.meterMonth = dateFormat(nowDay, 'yyyyMM')
+      this.fillForm.currentMonth = dateFormat(nowDay, 'yyyy年MM月')
+      this.fillForm.deviceCode = row.deviceCode
+      this.fillForm.areaCode = row.areaCode
+      // 获取上次填报记录
+      await getLastRecord(row.areaCode, row.deviceCode).then(({ data }) => {
+        if (data) {
+          this.fillForm.lastTime = data.meterTime
+          this.fillForm.lastReading = data.meterReading
+        }
       })
+      // 获取设备倍率
+      getDevice(row.id).then(response => {
+        this.fillForm.magnification = response.data.magnification || 1
+      })
+    },
+    submitFillForm() {
+      this.$refs['fillForm'].validate(valid => {
+        if (valid) {
+          this.fillForm.increase = this.increase
+          addMeterReading(this.fillForm)
+        }
+      })
+      this.fillFormOpen = false
+    },
+    fillCancel() {
+      this.fillFormOpen = false
     },
     closeRecList() {
-      this.recListOpen = false;
+      this.recListOpen = false
     }
   }
-};
+}
 </script>

+ 225 - 0
ems-ui/src/views/warn/strategy.vue

@@ -0,0 +1,225 @@
+<template>
+  <div class="dashboard-container">
+    <p>选择节点</p>
+    <div class="antvBox">
+      <div class="menu-list">
+        <div v-for="item in moduleList" :key="item.id" draggable="true" @dragend="handleDragEnd($event, item)">
+          <img :src="item.image" alt="" />
+          <p>{{ item.name }}</p>
+        </div>
+      </div>
+      <div class="canvas-card">
+        <div id="container" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { Graph } from '@antv/x6'
+export default {
+  name: 'antvX6',
+  data() {
+    return {
+      moduleList: [
+        {
+          id: 1,
+          name: '节点1',
+          image: require('@/assets/images/profile.jpg')
+        },
+        {
+          id: 8,
+          name: '节点2',
+          image: require('@/assets/images/profile.jpg')
+        },
+        {
+          id: 2,
+          name: '节点3',
+          image: require('@/assets/images/profile.jpg')
+        },
+        {
+          id: 3,
+          name: '节点4',
+          image: require('@/assets/images/profile.jpg')
+        }
+      ],
+      graph: null
+    }
+  },
+  mounted() {
+    this.initGraph()
+  },
+  methods: {
+    initGraph() {
+      const container = document.getElementById('container')
+      this.graph = new Graph({
+        container: container, // 画布容器
+        width: container.offsetWidth, // 画布宽
+        height: container.offsetHeight, // 画布高
+        background: false, // 背景(透明)
+        snapline: true, // 对齐线
+        // 配置连线规则
+        connecting: {
+          snap: true, // 自动吸附
+          allowBlank: false, // 是否允许连接到画布空白位置的点
+          allowMulti: true, // 是否允许在相同的起始节点和终止之间创建多条边
+          allowLoop: true, // 是否允许创建循环连线,即边的起始节点和终止节点为同一节点
+          highlight: true, // 拖动边时,是否高亮显示所有可用的节点
+          highlighting: {
+            magnetAdsorbed: {
+              name: 'stroke',
+              args: {
+                attrs: {
+                  fill: '#5F95FF',
+                  stroke: '#5F95FF'
+                }
+              }
+            }
+          },
+          router: {
+            // 对路径添加额外的点
+            name: 'orth'
+          },
+          connector: {
+            // 边渲染到画布后的样式
+            name: 'rounded',
+            args: {
+              radius: 8
+            }
+          }
+        },
+        panning: {
+          enabled: false
+        },
+        mousewheel: {
+          enabled: true, // 支持滚动放大缩小
+          zoomAtMousePosition: true,
+          modifiers: 'ctrl',
+          minScale: 0.5,
+          maxScale: 3
+        },
+        grid: {
+          type: 'dot',
+          size: 20, // 网格大小 10px
+          visible: true, // 渲染网格背景
+          args: {
+            color: '#a0a0a0', // 网格线/点颜色
+            thickness: 2 // 网格线宽度/网格点大小
+          }
+        }
+      })
+    },
+    // 拖动后松开鼠标触发事件
+    handleDragEnd(e, item) {
+      console.log(e, item) // 可以获取到最后拖动后松开鼠标时的坐标和拖动的节点相关信息
+      this.addHandleNode(e.pageX - 500, e.pageY - 200, new Date().getTime(), item.image, item.name)
+    },
+    // 添加节点到画布
+    addHandleNode(x, y, id, image, name) {
+      this.graph.addNode({
+        id: id,
+        shape: 'image', // 指定使用何种图形,默认值为 'rect'
+        x: x,
+        y: y,
+        width: 60,
+        height: 60,
+        imageUrl: image,
+        attrs: {
+          body: {
+            stroke: '#ffa940',
+            fill: '#ffd591'
+          },
+          label: {
+            textWrap: {
+              width: 90,
+              text: name
+            },
+            fill: 'black',
+            fontSize: 12,
+            refX: 0.5,
+            refY: '100%',
+            refY2: 4,
+            textAnchor: 'middle',
+            textVerticalAnchor: 'top'
+          }
+        },
+        ports: {
+          groups: {
+            group1: {
+              position: [30, 30]
+            }
+          },
+          items: [
+            {
+              group: 'group1',
+              id: 'port1',
+              attrs: {
+                circle: {
+                  r: 6,
+                  magnet: true,
+                  stroke: '#ffffff',
+                  strokeWidth: 2,
+                  fill: '#5F95FF'
+                }
+              }
+            }
+          ]
+        },
+        zIndex: 10
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.dashboard-container {
+  .antvBox {
+    display: flex;
+    width: 100%;
+    height: 100%;
+    color: black;
+    padding-top: 20px;
+    .menu-list {
+      height: 100%;
+      width: 300px;
+      padding: 0 10px;
+      box-sizing: border-box;
+      display: flex;
+      justify-content: space-between;
+      align-content: flex-start;
+      flex-wrap: wrap;
+      > div {
+        margin-bottom: 10px;
+        border-radius: 5px;
+        padding: 0 10px;
+        box-sizing: border-box;
+        cursor: pointer;
+        color: black;
+        width: 105px;
+        display: flex;
+        flex-wrap: wrap;
+
+        justify-content: center;
+        img {
+          height: 50px;
+          width: 50px;
+        }
+        P {
+          width: 90px;
+          text-align: center;
+        }
+      }
+    }
+    .canvas-card {
+      width: 1700px;
+      height: 750px;
+      box-sizing: border-box;
+      > div {
+        width: 1400px;
+        height: 750px;
+        border: 2px dashed #2149ce;
+      }
+    }
+  }
+}
+</style>