浏览代码

+ 大屏源接口对接

chen.cheng 1 月之前
父节点
当前提交
26f0e75aba

+ 25 - 17
ems-ui-application/src/store/modules/userState.js

@@ -1,22 +1,30 @@
 export const userState = {
-  namespaced: true,
-  state: {
-    selectedServiceArea: '',
-    areaType:''
-  },
-
-  mutations: {
-    setSelectedArea: (state, area) => {
-      state.selectedServiceArea = area;
+    namespaced: true,
+    state: {
+        selectedServiceArea: '',
+        areaType: '',
+        regionFactor: 1,
+        elec2CFactor: 1
     },
-    setAreaType: (state, type) => {
-      state.areaType = type;
-    }
-  },
 
-  getters: {
-    getSelectedArea(state) {
-      return state.selectedServiceArea;
+    mutations: {
+        setSelectedArea: (state, area) => {
+            state.selectedServiceArea = area;
+        },
+        setAreaType: (state, type) => {
+            state.areaType = type;
+        },
+        setRegionFactor: (state, regionFactor) => {
+            state.regionFactor = regionFactor;
+        },
+        setElec2CFactor: (state, elec2CFactor) => {
+            state.elec2CFactor = elec2CFactor;
+        }
     },
-  }
+
+    getters: {
+        getSelectedArea(state) {
+            return state.selectedServiceArea;
+        },
+    }
 }

+ 2 - 0
ems-ui-cloud/.env.74

@@ -10,5 +10,7 @@ VUE_APP_BASE_API = '/dev-api'
 # 网关路由
 EMS_REWRITE_URL = '74/ems'
 
+VUE_APP_REGION_CODE = 'CN'
+
 # 路由懒加载
 VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 46 - 0
ems-ui-cloud/src/api/screen/index.js

@@ -0,0 +1,46 @@
+import request from '@/utils/request';
+
+// 查询光伏并网计量光伏并网计量-日数据列表
+export function pgSupplyTotalPv(query) {
+  return request({
+    url: '/ems/pg/supply/hour/total/pv',
+    method: 'get',
+    params: query,
+  });
+}
+
+
+export function pgSupplyDayTotalPv(query) {
+  return request({
+    url: '/ems/pg/supply/hour/day/pv',
+    method: 'get',
+    params: query,
+  });
+}
+
+
+export function pgSupplyHourTotalPv(query) {
+  return request({
+    url: '/ems/pg/supply/hour/hour/pv',
+    method: 'get',
+    params: query,
+  });
+}
+
+
+export function ecoDateRange(query) {
+  return request({
+    url: '/ems/EmsEcoD/date/range',
+    method: 'get',
+    params: query,
+  });
+}
+
+
+export function predictionProdDateRange(query) {
+  return request({
+    url: '/ems/predictionProd/date/range',
+    method: 'get',
+    params: query,
+  });
+}

+ 9 - 1
ems-ui-cloud/src/store/modules/userState.js

@@ -2,7 +2,9 @@ export const userState = {
   namespaced: true,
   state: {
     selectedServiceArea: '',
-    areaType:''
+    areaType: '',
+    regionFactor: 1,
+    elec2CFactor: 1
   },
 
   mutations: {
@@ -11,6 +13,12 @@ export const userState = {
     },
     setAreaType: (state, type) => {
       state.areaType = type;
+    },
+    setRegionFactor: (state, regionFactor) => {
+      state.regionFactor = regionFactor;
+    },
+    setElec2CFactor: (state, elec2CFactor) => {
+      state.elec2CFactor = elec2CFactor;
     }
   },
 

+ 99 - 96
ems-ui-cloud/src/utils/DateTool.js

@@ -3,101 +3,104 @@ import dayjs from 'dayjs';
 const isSameOrBefore = require('dayjs/plugin/isSameOrBefore');
 dayjs.extend(isSameOrBefore);
 export const DateTool = {
-  DateFormat: {
-    YYYY: 'YYYY',
-    YYYY_MM: 'YYYY-MM',
-    YYYY_MM_DD: 'YYYY-MM-DD',
-    YYYY_MM_DD_HH_mm: 'YYYY-MM-DD HH:mm',
-    YYYY_MM_DD_HH_mm_ss: 'YYYY-MM-DD HH:mm:ss',
-    YYYY_MM_DD_HH_mm_ss_SSS: 'YYYY-MM-DD HH:mm:ss.SSS',
-    YYYYMMDD: 'YYYYMMDD',
-    YYYYMMDDHHmmss: 'YYYYMMDDHHmmss',
-    YYYY_MM_DD_00_00_00: 'YYYY-MM-DD 00:00:00',
-    YYYY_MM_DD_23_59_59: 'YYYY-MM-DD 23:59:59',
-    MM_DD: 'MM-DD',
-  },
-  /**
-   * 获取当天时间刻度
-   * @param timeSplit 单位分钟
-   */
-  getTime: function (timeSplit = 5) {
-    const now = dayjs();
-    let zero = dayjs().startOf('date').add(1, 'hour');
-    const result = [];
-    while (zero.isSameOrBefore(now)) {
-      result.push(zero.format('HH:mm'));
-      zero = zero.add(timeSplit, 'minute');
-    }
-    return result;
-  },
-  now: (format = DateTool.DateFormat.YYYY_MM_DD) => {
-    return dayjs().format(format);
-  },
-  /**
-   * 获取一段时间的日期
-   * @param start 开始时间
-   * @param end 结束时间
-   * @param format
-   */
-  getDayOfRange: function (start, end, format = this.DateFormat.YYYY_MM_DD) {
-    const dates = [];
-    let current = dayjs(start);
-    while (current.isSameOrBefore(end)) {
-      dates.push(current.format(format));
-      current = current.add(1, 'day');
-    }
-    return dates;
-  },
+    DateFormat: {
+        YYYY: 'YYYY',
+        YYYY_MM: 'YYYY-MM',
+        YYYY_MM_DD: 'YYYY-MM-DD',
+        YYYY_MM_DD_HH_mm: 'YYYY-MM-DD HH:mm',
+        YYYY_MM_DD_HH_mm_ss: 'YYYY-MM-DD HH:mm:ss',
+        YYYY_MM_DD_HH_mm_ss_SSS: 'YYYY-MM-DD HH:mm:ss.SSS',
+        YYYYMMDD: 'YYYYMMDD',
+        YYYYMMDDHHmmss: 'YYYYMMDDHHmmss',
+        YYYY_MM_DD_00_00_00: 'YYYY-MM-DD 00:00:00',
+        YYYY_MM_DD_23_59_59: 'YYYY-MM-DD 23:59:59',
+        MM_DD: 'MM-DD',
+    },
+    /**
+     * 获取当天时间刻度
+     * @param timeSplit 单位分钟
+     */
+    getTime: function (timeSplit = 5) {
+        const now = dayjs();
+        let zero = dayjs().startOf('date').add(1, 'hour');
+        const result = [];
+        while (zero.isSameOrBefore(now)) {
+            result.push(zero.format('HH:mm'));
+            zero = zero.add(timeSplit, 'minute');
+        }
+        return result;
+    },
+    now: (format = DateTool.DateFormat.YYYY_MM_DD) => {
+        return dayjs().format(format);
+    },
+    /**
+     * 获取一段时间的日期
+     * @param start 开始时间
+     * @param end 结束时间
+     * @param format
+     */
+    getDayOfRange: function (start, end, format = this.DateFormat.YYYY_MM_DD) {
+        const dates = [];
+        let current = dayjs(start);
+        while (current.isSameOrBefore(end)) {
+            dates.push(current.format(format));
+            current = current.add(1, 'day');
+        }
+        return dates;
+    },
 
-  getMonthOfRange: function (start, end, format = this.DateFormat.YYYY_MM) {
-    const dates = [];
-    let current = dayjs(start);
-    while (current.isSameOrBefore(end)) {
-      dates.push(current.format(format));
-      current = current.add(1, 'month');
-    }
-    return dates;
-  },
-  get24Time: function (timeSplit = 5) {
-    const now = dayjs();
-    let zero = dayjs().subtract(1, 'day').startOf('hour').add(1, 'hour');
-    const result = [];
-    while (zero.isSameOrBefore(now)) {
-      result.push(zero.format('MM-DD HH:mm'));
-      zero = zero.add(timeSplit, 'minute');
-    }
-    return result;
-  },
-  getMonthsOfYearAgo: () => {
-    const month = [];
-    const currentDate = dayjs();
-    const oneYearAgo = currentDate.subtract(1, 'year');
-    let currentMonth = oneYearAgo.startOf('month');
-    while (currentMonth.isBefore(currentDate.endOf('month'))) {
-      month.push(currentMonth.format(DateTool.DateFormat.YYYY_MM));
-      currentMonth = currentMonth.add(1, 'month').startOf('month');
-    }
-    return month;
-  },
-  timeIndex: (date = dayjs()) => {
-    return date.format('HH');
-  },
-  lastDay: (format = DateTool.DateFormat.YYYY_MM_DD) => {
-    return dayjs().subtract(1, 'day').format(format);
-  },
-  lastMonth: (format = DateTool.DateFormat.YYYY_MM) => {
-    return dayjs().subtract(1, 'month').format(format);
-  },
-  lastYear: (format = DateTool.DateFormat.YYYY) => {
-    return dayjs().subtract(1, 'year').format(format);
-  },
-  lastYearMonthStart: () => {
-    return dayjs().subtract(1, 'year').format(`${DateTool.DateFormat.YYYY_MM}-01`);
-  },
-  thisYear: (format = DateTool.DateFormat.YYYY) => {
-    return dayjs().format(format);
-  },
-  thisMonth: (format = DateTool.DateFormat.YYYY_MM) => {
-    return dayjs().format(format);
-  },
+    getMonthOfRange: function (start, end, format = this.DateFormat.YYYY_MM) {
+        const dates = [];
+        let current = dayjs(start);
+        while (current.isSameOrBefore(end)) {
+            dates.push(current.format(format));
+            current = current.add(1, 'month');
+        }
+        return dates;
+    },
+    get24Time: function (timeSplit = 5) {
+        const now = dayjs();
+        let zero = dayjs().subtract(1, 'day').startOf('hour').add(1, 'hour');
+        const result = [];
+        while (zero.isSameOrBefore(now)) {
+            result.push(zero.format('MM-DD HH:mm'));
+            zero = zero.add(timeSplit, 'minute');
+        }
+        return result;
+    },
+    getMonthsOfYearAgo: () => {
+        const month = [];
+        const currentDate = dayjs();
+        const oneYearAgo = currentDate.subtract(1, 'year');
+        let currentMonth = oneYearAgo.startOf('month');
+        while (currentMonth.isBefore(currentDate.endOf('month'))) {
+            month.push(currentMonth.format(DateTool.DateFormat.YYYY_MM));
+            currentMonth = currentMonth.add(1, 'month').startOf('month');
+        }
+        return month;
+    },
+    timeIndex: (date = dayjs()) => {
+        return date.format('HH');
+    },
+    lastDay: (format = DateTool.DateFormat.YYYY_MM_DD) => {
+        return dayjs().subtract(1, 'day').format(format);
+    },
+    lastMonth: (format = DateTool.DateFormat.YYYY_MM) => {
+        return dayjs().subtract(1, 'month').format(format);
+    },
+    thisMonthLastDay: (format = DateTool.DateFormat.YYYY_MM_DD) => {
+        return dayjs().endOf('month').format(format);
+    },
+    lastYear: (format = DateTool.DateFormat.YYYY) => {
+        return dayjs().subtract(1, 'year').format(format);
+    },
+    lastYearMonthStart: () => {
+        return dayjs().subtract(1, 'year').format(`${DateTool.DateFormat.YYYY_MM}-01`);
+    },
+    thisYear: (format = DateTool.DateFormat.YYYY) => {
+        return dayjs().format(format);
+    },
+    thisMonth: (format = DateTool.DateFormat.YYYY_MM) => {
+        return dayjs().format(format);
+    },
 };

+ 264 - 255
ems-ui-cloud/src/utils/index.js

@@ -1,27 +1,28 @@
-import { UUID } from 'uuidjs';
-import { parseTime } from './ruoyi';
+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));
+    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;
+    return format;
 }
 
 /**
@@ -29,23 +30,24 @@ export function dateFormat(date, format = 'yyyy-MM-dd HH:mm:ss') {
  * @param {*} n
  */
 export const getDayAgoDate = (n = 0) => {
-  let curDate = new Date();
-  let newDate = new Date(curDate - 1000 * 60 * 60 * 24 * n);
-  return newDate
+    let curDate = new Date();
+    let newDate = new Date(curDate - 1000 * 60 * 60 * 24 * n);
+    return newDate
 }
+
 /**
  * 表格时间格式化
  */
 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;
 }
 
 /**
@@ -54,31 +56,31 @@ export function formatDate(cellValue) {
  * @returns {string}
  */
 export function formatTime(time, option) {
-  if (('' + time).length === 10) {
-    time = parseInt(time) * 1000;
-  } else {
-    time = +time;
-  }
-  const d = new Date(time);
-  const now = Date.now();
-
-  const diff = (now - d) / 1000;
-
-  if (diff < 30) {
-    return '刚刚';
-  } else if (diff < 3600) {
-    // less 1 hour
-    return Math.ceil(diff / 60) + '分钟前';
-  } else if (diff < 3600 * 24) {
-    return Math.ceil(diff / 3600) + '小时前';
-  } else if (diff < 3600 * 24 * 2) {
-    return '1天前';
-  }
-  if (option) {
-    return parseTime(time, option);
-  } else {
-    return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分';
-  }
+    if (('' + time).length === 10) {
+        time = parseInt(time) * 1000;
+    } else {
+        time = +time;
+    }
+    const d = new Date(time);
+    const now = Date.now();
+
+    const diff = (now - d) / 1000;
+
+    if (diff < 30) {
+        return '刚刚';
+    } else if (diff < 3600) {
+        // less 1 hour
+        return Math.ceil(diff / 60) + '分钟前';
+    } else if (diff < 3600 * 24) {
+        return Math.ceil(diff / 3600) + '小时前';
+    } else if (diff < 3600 * 24 * 2) {
+        return '1天前';
+    }
+    if (option) {
+        return parseTime(time, option);
+    } else {
+        return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分';
+    }
 }
 
 /**
@@ -86,18 +88,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;
-  search.replace(reg, (rs, $1, $2) => {
-    const name = decodeURIComponent($1);
-    let val = decodeURIComponent($2);
-    val = String(val);
-    obj[name] = val;
-    return rs;
-  });
-  return obj;
+    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;
 }
 
 /**
@@ -105,15 +107,15 @@ export function getQueryObject(url) {
  * @returns {number} output value
  */
 export function byteLength(str) {
-  // returns the byte length of an utf8 string
-  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--;
-  }
-  return s;
+    // returns the byte length of an utf8 string
+    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--;
+    }
+    return s;
 }
 
 /**
@@ -121,13 +123,13 @@ export function byteLength(str) {
  * @returns {Array}
  */
 export function cleanArray(actual) {
-  const newArray = [];
-  for (let i = 0; i < actual.length; i++) {
-    if (actual[i]) {
-      newArray.push(actual[i]);
+    const newArray = [];
+    for (let i = 0; i < actual.length; i++) {
+        if (actual[i]) {
+            newArray.push(actual[i]);
+        }
     }
-  }
-  return newArray;
+    return newArray;
 }
 
 /**
@@ -135,13 +137,13 @@ export function cleanArray(actual) {
  * @returns {Array}
  */
 export function param(json) {
-  if (!json) return '';
-  return cleanArray(
-    Object.keys(json).map(key => {
-      if (json[key] === undefined) return '';
-      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
-    })
-  ).join('&');
+    if (!json) return '';
+    return cleanArray(
+        Object.keys(json).map(key => {
+            if (json[key] === undefined) return '';
+            return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
+        })
+    ).join('&');
 }
 
 /**
@@ -149,21 +151,21 @@ export function param(json) {
  * @returns {Object}
  */
 export function param2Obj(url) {
-  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
-  if (!search) {
-    return {};
-  }
-  const obj = {};
-  const searchArr = search.split('&');
-  searchArr.forEach(v => {
-    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 search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ');
+    if (!search) {
+        return {};
     }
-  });
-  return obj;
+    const obj = {};
+    const searchArr = search.split('&');
+    searchArr.forEach(v => {
+        const index = v.indexOf('=');
+        if (index !== -1) {
+            const name = v.substring(0, index);
+            const val = v.substring(index + 1, v.length);
+            obj[name] = val;
+        }
+    });
+    return obj;
 }
 
 /**
@@ -171,9 +173,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;
 }
 
 /**
@@ -183,21 +185,21 @@ export function html2Text(val) {
  * @returns {Object}
  */
 export function objectMerge(target, source) {
-  if (typeof target !== 'object') {
-    target = {};
-  }
-  if (Array.isArray(source)) {
-    return source.slice();
-  }
-  Object.keys(source).forEach(property => {
-    const sourceProperty = source[property];
-    if (typeof sourceProperty === 'object') {
-      target[property] = objectMerge(target[property], sourceProperty);
-    } else {
-      target[property] = sourceProperty;
+    if (typeof target !== 'object') {
+        target = {};
     }
-  });
-  return target;
+    if (Array.isArray(source)) {
+        return source.slice();
+    }
+    Object.keys(source).forEach(property => {
+        const sourceProperty = source[property];
+        if (typeof sourceProperty === 'object') {
+            target[property] = objectMerge(target[property], sourceProperty);
+        } else {
+            target[property] = sourceProperty;
+        }
+    });
+    return target;
 }
 
 /**
@@ -205,17 +207,17 @@ export function objectMerge(target, source) {
  * @param {string} className
  */
 export function toggleClass(element, className) {
-  if (!element || !className) {
-    return;
-  }
-  let classString = element.className;
-  const nameIndex = classString.indexOf(className);
-  if (nameIndex === -1) {
-    classString += '' + className;
-  } else {
-    classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
-  }
-  element.className = classString;
+    if (!element || !className) {
+        return;
+    }
+    let classString = element.className;
+    const nameIndex = classString.indexOf(className);
+    if (nameIndex === -1) {
+        classString += '' + className;
+    } else {
+        classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
+    }
+    element.className = classString;
 }
 
 /**
@@ -223,11 +225,11 @@ export function toggleClass(element, className) {
  * @returns {Date}
  */
 export function getTime(type) {
-  if (type === 'start') {
-    return new Date().getTime() - 3600 * 1000 * 24 * 90;
-  } else {
-    return new Date(new Date().toDateString());
-  }
+    if (type === 'start') {
+        return new Date().getTime() - 3600 * 1000 * 24 * 90;
+    } else {
+        return new Date(new Date().toDateString());
+    }
 }
 
 /**
@@ -237,38 +239,38 @@ export function getTime(type) {
  * @return {*}
  */
 export function debounce(func, wait, immediate) {
-  let timeout, args, context, timestamp, result;
-
-  const later = function () {
-    // 据上一次触发时间间隔
-    const last = +new Date() - timestamp;
-
-    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
-    if (last < wait && last > 0) {
-      timeout = setTimeout(later, wait - last);
-    } else {
-      timeout = null;
-      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
-      if (!immediate) {
-        result = func.apply(context, args);
-        if (!timeout) context = args = null;
-      }
-    }
-  };
-
-  return function (...args) {
-    context = this;
-    timestamp = +new Date();
-    const callNow = immediate && !timeout;
-    // 如果延时不存在,重新设定延时
-    if (!timeout) timeout = setTimeout(later, wait);
-    if (callNow) {
-      result = func.apply(context, args);
-      context = args = null;
-    }
-
-    return result;
-  };
+    let timeout, args, context, timestamp, result;
+
+    const later = function () {
+        // 据上一次触发时间间隔
+        const last = +new Date() - timestamp;
+
+        // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
+        if (last < wait && last > 0) {
+            timeout = setTimeout(later, wait - last);
+        } else {
+            timeout = null;
+            // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
+            if (!immediate) {
+                result = func.apply(context, args);
+                if (!timeout) context = args = null;
+            }
+        }
+    };
+
+    return function (...args) {
+        context = this;
+        timestamp = +new Date();
+        const callNow = immediate && !timeout;
+        // 如果延时不存在,重新设定延时
+        if (!timeout) timeout = setTimeout(later, wait);
+        if (callNow) {
+            result = func.apply(context, args);
+            context = args = null;
+        }
+
+        return result;
+    };
 }
 
 /**
@@ -279,18 +281,18 @@ export function debounce(func, wait, immediate) {
  * @returns {Object}
  */
 export function deepClone(source) {
-  if (!source && typeof source !== 'object') {
-    throw new Error('error arguments', 'deepClone');
-  }
-  const targetObj = source.constructor === Array ? [] : {};
-  Object.keys(source).forEach(keys => {
-    if (source[keys] && typeof source[keys] === 'object') {
-      targetObj[keys] = deepClone(source[keys]);
-    } else {
-      targetObj[keys] = source[keys];
+    if (!source && typeof source !== 'object') {
+        throw new Error('error arguments', 'deepClone');
     }
-  });
-  return targetObj;
+    const targetObj = source.constructor === Array ? [] : {};
+    Object.keys(source).forEach(keys => {
+        if (source[keys] && typeof source[keys] === 'object') {
+            targetObj[keys] = deepClone(source[keys]);
+        } else {
+            targetObj[keys] = source[keys];
+        }
+    });
+    return targetObj;
 }
 
 /**
@@ -298,16 +300,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);
 }
 
 /**
@@ -317,7 +319,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|$)'));
 }
 
 /**
@@ -326,7 +328,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;
 }
 
 /**
@@ -335,95 +337,95 @@ export function addClass(ele, cls) {
  * @param {string} cls
  */
 export function removeClass(ele, cls) {
-  if (hasClass(ele, cls)) {
-    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
-    ele.className = ele.className.replace(reg, ' ');
-  }
+    if (hasClass(ele, cls)) {
+        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(',');
-  for (let i = 0; i < list.length; i++) {
-    map[list[i]] = true;
-  }
-  return expectsLowerCase ? val => map[val.toLowerCase()] : val => map[val];
+    const map = Object.create(null);
+    const list = str.split(',');
+    for (let i = 0; i < list.length; i++) {
+        map[list[i]] = true;
+    }
+    return expectsLowerCase ? val => map[val.toLowerCase()] : val => map[val];
 }
 
 export const exportDefault = 'export default ';
 
 export const beautifierConf = {
-  html: {
-    indent_size: '2',
-    indent_char: ' ',
-    max_preserve_newlines: '-1',
-    preserve_newlines: false,
-    keep_array_indentation: false,
-    break_chained_methods: false,
-    indent_scripts: 'separate',
-    brace_style: 'end-expand',
-    space_before_conditional: true,
-    unescape_strings: false,
-    jslint_happy: false,
-    end_with_newline: true,
-    wrap_line_length: '110',
-    indent_inner_html: true,
-    comma_first: false,
-    e4x: true,
-    indent_empty_lines: true
-  },
-  js: {
-    indent_size: '2',
-    indent_char: ' ',
-    max_preserve_newlines: '-1',
-    preserve_newlines: false,
-    keep_array_indentation: false,
-    break_chained_methods: false,
-    indent_scripts: 'normal',
-    brace_style: 'end-expand',
-    space_before_conditional: true,
-    unescape_strings: false,
-    jslint_happy: true,
-    end_with_newline: true,
-    wrap_line_length: '110',
-    indent_inner_html: true,
-    comma_first: false,
-    e4x: true,
-    indent_empty_lines: true
-  }
+    html: {
+        indent_size: '2',
+        indent_char: ' ',
+        max_preserve_newlines: '-1',
+        preserve_newlines: false,
+        keep_array_indentation: false,
+        break_chained_methods: false,
+        indent_scripts: 'separate',
+        brace_style: 'end-expand',
+        space_before_conditional: true,
+        unescape_strings: false,
+        jslint_happy: false,
+        end_with_newline: true,
+        wrap_line_length: '110',
+        indent_inner_html: true,
+        comma_first: false,
+        e4x: true,
+        indent_empty_lines: true
+    },
+    js: {
+        indent_size: '2',
+        indent_char: ' ',
+        max_preserve_newlines: '-1',
+        preserve_newlines: false,
+        keep_array_indentation: false,
+        break_chained_methods: false,
+        indent_scripts: 'normal',
+        brace_style: 'end-expand',
+        space_before_conditional: true,
+        unescape_strings: false,
+        jslint_happy: true,
+        end_with_newline: true,
+        wrap_line_length: '110',
+        indent_inner_html: true,
+        comma_first: false,
+        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 = () => {
-  return UUID.generate();
+    return UUID.generate();
 };
 
-export const  numToStr=(num, fixed = 2) =>{
-  const million = 10000; // 一万
-  const billion = 100000000; // 一亿
-  let unit = "";
-  let result = Number(num);
-  if (num >= billion) {
-    unit = "亿";
-    result = num / billion;
-  } else if (num >= million) {
-    unit = "万";
-    result = num / million;
-  }
-  return result.toFixed(fixed) + unit;
+export const numToStr = (num, fixed = 2) => {
+    const million = 10000; // 一万
+    const billion = 100000000; // 一亿
+    let unit = "";
+    let result = Number(num);
+    if (num >= billion) {
+        unit = "亿";
+        result = num / billion;
+    } else if (num >= million) {
+        unit = "万";
+        result = num / million;
+    }
+    return result.toFixed(fixed) + unit;
 }
 
 /**
@@ -432,6 +434,13 @@ export const  numToStr=(num, fixed = 2) =>{
  * @returns {any}
  */
 export const copyObj = obj => {
-  return JSON.parse(JSON.stringify(obj));
+    return JSON.parse(JSON.stringify(obj));
 };
 
+
+export const array2Map = (arr = [], key = 'date') => {
+    return arr.reduce((acc, cur) => {
+        acc[cur[key]] = cur;
+        return acc;
+    }, {});
+};

+ 36 - 17
ems-ui-cloud/src/views/largeScreen/center.vue

@@ -1,38 +1,55 @@
 <template>
-  <div class="center" id="model">
-    <CusTabs :tabs="areaTabs" :active.sync="areaType" @tab-click="areaTabClick" />
+  <div style="width: 100%;height: 100%">
+    <CusTabs :tabs="areaTabs" :active.sync="areaType" @tab-click="areaTabClick"/>
+    <div class="center" id="model">
+
+    </div>
   </div>
+
 </template>
 <script>
 import CusTabs from './components/CusTabs.vue';
 import {mapMutations} from 'vuex';
 import renderModel from './three/renderModel'
+
+const areaEnums = {
+  all: {name: '全部', value: ''},
+  '1': {name: '北区', value: '321283124S3001'},
+  '2': {name: '南区', value: '321283124S3002'}
+};
 export default {
   name: 'Center',
-  data () {
+  data() {
     return {
-      areaType: '',
-      areaTabs: [{name: '全部', value: ''}, {name: '北区', value: '1'}, {name: '南区', value: '2'}],
+      areaType: 'all',
+      areaTabs: [
+        {name: '全部', value: 'all'},
+        {name: '北区', value: '1'},
+        {
+          name: '南区',
+          value: '2'
+        }
+      ],
       modelApi: null,
     };
   },
   components: {
     CusTabs
   },
-  mounted () {
+  mounted() {
     this.initThree();
   },
   methods: {
     ...mapMutations('userState', ['setAreaType']),
-    areaTabClick () {
-      this.setAreaType(this.areaType)
+    areaTabClick() {
+      this.setAreaType(areaEnums[this.areaType].value)
       if (this.areaType === '2') {
         const target = {
           position: {x: -68.07200022928386, y: -573.3788080485533, z: 358.4490004266269}, // 相机目标位置
           targetContent: {x: -68.07200022928386, y: -58.61085804855406, z: -48.804124573372285}, // 控制器目标焦点
           time: 1000 // 动画时间
         };
-        this.modelApi.flyTo(target,1.2)
+        this.modelApi.flyTo(target, 1.2)
       } else if (this.areaType === '1') {
         const target = {
           position: {x: 2.9287885309866817, y: -403.9781890137868, z: 376.33849737114133}, // 相机目标位置
@@ -49,7 +66,7 @@ export default {
         this.modelApi.flyTo(target)
       }
     },
-    initThree () {
+    initThree() {
       setTimeout(() => {
         this.modelApi = new renderModel('#model')
         this.modelApi.init()
@@ -60,6 +77,12 @@ export default {
 }
 </script>
 <style lang='scss' scoped>
+.tabs {
+  position: absolute;
+  top: 90px;
+  left: 403px;
+  z-index: 50;
+}
 .center {
   // background: url("~@/assets/images/center.jpg") no-repeat;
   // background-size:cover ;
@@ -68,13 +91,9 @@ export default {
   // margin: auto auto 0;
   height: 100%;
   position: relative;
+  z-index: 1;
+
 
-  .tabs {
-    position: absolute;
-    top: 90px;
-    left: 403px;
-    z-index: 45;
-  }
 
   ::v-deep .tag3d {
     // color: #fff;
@@ -103,7 +122,7 @@ export default {
       gap: 2px;
       padding: 0 3px;
 
-      >div {
+      > div {
         background-color: #0F4565;
         white-space: nowrap;
         margin-right: 4px;

+ 37 - 16
ems-ui-cloud/src/views/largeScreen/index.vue

@@ -1,25 +1,25 @@
 <template>
   <div class="large-screen" id="largeScreen">
     <div class="header">
-      <span class="header-name">{{sysTitle}}</span>
+      <span class="header-name">{{ sysTitle }}</span>
     </div>
     <div class="left-sidebar-container">
       <div class="top-info-area">
         <div class="info-block">
           <img src="@/assets/images/home/tianqi.svg" alt="">
-          <span>{{weather.text}}</span>
-          <span>{{weather.temperature}}</span>
+          <span>{{ weather.text }}</span>
+          <span>{{ weather.temperature }}</span>
         </div>
       </div>
       <router-view class="sidebar-router-view" name="left"></router-view>
     </div>
-    <router-view class="center"></router-view>
+    <router-view></router-view>
     <div class="right-sidebar-container">
       <div class="top-info-area">
         <div class="info-block ">
           <span class="date-info">
-            <span>{{nowDay.currentTime}}</span>
-            <span>{{nowDay.week}}</span>
+            <span>{{ nowDay.currentTime }}</span>
+            <span>{{ nowDay.week }}</span>
           </span>
         </div>
       </div>
@@ -36,11 +36,15 @@ import autofit from 'autofit.js'
 import Footer from './footer.vue';
 import {dateFormat} from '@/utils/index.js'
 import axios from 'axios';
+import {listFactor} from "@/api/basecfg/cacfg";
+import {mapMutations} from 'vuex';
+import {listDisStaCoal} from "@/api/basecfg/disStaCoal";
+
 export default {
   name: 'LargeScreen',
-  data () {
+  data() {
     return {
-      sysTitle:'',
+      sysTitle: '',
       nowDay: {
         currentTime: '',
         week: '',
@@ -48,7 +52,7 @@ export default {
       timer: null,
       weather: {
         text: '',
-        temperature:''
+        temperature: ''
       }
     };
   },
@@ -56,7 +60,22 @@ export default {
     Footer
   },
   computed: {},
-  mounted () {
+  async created() {
+    const {rows: regionFactor} = await listFactor({
+      regionCode: process.env.VUE_APP_REGION_CODE,
+    })
+    if (regionFactor && regionFactor.length > 0) {
+      this.setRegionFactor(regionFactor[0].factorValue)
+    }
+
+    const {rows: energyFactor} = await listDisStaCoal({
+      energyCode: '45',
+    })
+    if (regionFactor && regionFactor.length > 0) {
+      this.setElec2CFactor(energyFactor[0].coefficientValue)
+    }
+  },
+  mounted() {
     autofit.init({
       designHeight: 1080,
       designWidth: 1920,
@@ -72,18 +91,19 @@ export default {
       this.sysTitle = response.msg;
     });
   },
-  beforeDestroy () {
+  beforeDestroy() {
     clearInterval(this.timer)
-    this.timer=null
+    this.timer = null
   },
   methods: {
-    getDate () {
+    ...mapMutations('userState', ["setRegionFactor", "setElec2CFactor"]),
+    async getDate() {
       let nowTime = new Date();
       this.nowDay.week = "星期" + "日一二三四五六".charAt(nowTime.getDay());
-      this.nowDay.currentTime =dateFormat(nowTime,'yyyy-MM-dd HH:mm:ss')
+      this.nowDay.currentTime = dateFormat(nowTime, 'yyyy-MM-dd HH:mm:ss')
     },
-    getWeather () {
-      axios.get('https://api.seniverse.com/v3/weather/now.json?key=SoZVeNXSD1AlWok1V&location=nanjing&language=zh-Hans&unit=c').then(({data: { results}}) => {
+    getWeather() {
+      axios.get('https://api.seniverse.com/v3/weather/now.json?key=SoZVeNXSD1AlWok1V&location=nanjing&language=zh-Hans&unit=c').then(({data: {results}}) => {
         if (results && results.length) {
           this.weather.text = results[0].now.text
           this.weather.temperature = `${results[0].now.temperature}°C`
@@ -244,5 +264,6 @@ export default {
   background-image: url('~@/assets/images/layout/footer.png');
   background-position: center;
   background-repeat: no-repeat;
+  z-index: 50;
 }
 </style>

+ 186 - 67
ems-ui-cloud/src/views/largeScreen/source/left.vue

@@ -3,7 +3,7 @@
     <CusModule title="光伏发电量">
       <div class="elec-top-bar">
         <span class="elec-content">
-          今日发电量<span class="elec-value">{{todayEnergy}}</span><span class="unit"> kW·h</span>
+          今日发电量<span class="elec-value">{{ todayEnergy }}</span><span class="unit"> kW·h</span>
         </span>
       </div>
       <div class="elec-items-container">
@@ -18,36 +18,57 @@
         </div>
       </div>
     </CusModule>
-    <CusModule class="module-top" title="光伏发电指标">
-      <div class="elec-index">
-        <div class="panel-content" v-for="item, index in elecIndexList" :key="index">
-          <div class="image-container">
-            <img :src="require(`@/assets/images/source/elec${index + 1}.svg`)" alt="">
-          </div>
-          <div class="whitespace-pre">
-            <span class="value">{{ item.value }}</span>
-            <span class="unit">{{ item.unit }}</span>
-            <div class="label">{{ item.name }}</div>
-          </div>
-        </div>
-      </div>
+    <CusModule class="module-top" title="光伏发电实时指标">
+      <BaseChart height="250px" width="100%" :option="realtimeLineOptions"/>
     </CusModule>
     <CusModule class="module-top" title="历史发电量">
-      <BaseChart height="350px" width="100%" :option="lineOptions" />
+      <BaseChart height="350px" width="100%" :option="lineOptions"/>
     </CusModule>
   </div>
 </template>
 <script>
 import CusModule from '../components/CusModule.vue';
 import BaseChart from '@/components/BaseChart/index.vue'
-import {dateFormat} from '@/utils';
+import {copyObj, numToStr} from '@/utils';
 import {mapState} from 'vuex';
 import * as echarts from 'echarts'
+import {pgSupplyDayTotalPv, pgSupplyHourTotalPv, pgSupplyTotalPv} from "@/api/screen";
+import {DateTool} from "@/utils/DateTool";
+
+const option = {
+  legend: {
+    show: false,
+  },
+  tooltip: {
+    trigger: "axis",
+  },
+  grid: {
+    left: '5%',
+    right: '6%',
+    top: '15%',
+    bottom: '5%',
+    containLabel: true
+  },
+  yAxis: {
+    name: "kW·h",
+    splitLine: {
+      show: true,
+      lineStyle: {
+        color: '#334E5E'
+      }
+    },
+    axisLabel: {
+      interval: 0,
+      color: '#c1cadf',
+      fontSize: '10',
+    }
+  },
+}
 export default {
   name: 'SourceLeft',
-  data () {
+  data() {
     return {
-      todayEnergy:'321',
+      todayEnergy: '321',
       elecList: [
         {
           name: "本月发电量",
@@ -90,7 +111,8 @@ export default {
           unit: "",
         },
       ],
-      lineData:[]
+      lineData: [],
+      realtimeLineData: []
     };
   },
   components: {
@@ -99,28 +121,69 @@ export default {
   },
   computed: {
     ...mapState('userState', ['areaType']),
-    lineOptions () {
+    lineOptions() {
+      const copyOptions = copyObj(option);
       return {
-        legend: {
-          show: false,
-        },
-        tooltip: {
-          trigger: "axis",
-        },
-        yAxis: {
-          name: "kW·h",
+        ...copyOptions,
+        xAxis: {
           splitLine: {
-            show: true,
-            lineStyle: {
-              color: '#334E5E'
-            }
+            show: false,
+          },
+          axisLabel: {
+            color: '#c1cadf',
+            fontSize: '10',
           },
+          data: this.lineData.map(item => item.xData),
         },
+        series: [
+          {
+            type: 'line',
+            name: "发电量",
+            smooth: true,
+            lineStyle: {
+              normal: {
+                color: "#80DBE1", // 线条颜色
+              },
+            },
+            itemStyle: {
+              color: "#80DBE1",
+              borderColor: "#fff",
+              borderWidth: 3
+            },
+            areaStyle: { //区域填充样式
+              normal: {
+                //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
+                  offset: 0,
+                  color: "rgba(81, 139, 152,0.8)"
+                },
+                  {
+                    offset: 1,
+                    color: "rgba(81, 139, 152, 0)"
+                  }
+                ], false),
+                shadowColor: 'rgba(81, 139, 152, 0.5)', //阴影颜色
+                shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
+              }
+            },
+            data: this.lineData.map(item => item.yData),
+          },
+        ],
+      }
+    },
+    realtimeLineOptions() {
+      const copyOptions = copyObj(option);
+      return {
+        ...copyOptions,
         xAxis: {
           splitLine: {
             show: false,
           },
-          data: this.lineData.map(item=>item.xData),
+          axisLabel: {
+            color: '#c1cadf',
+            fontSize: '10',
+          },
+          data: this.realtimeLineData.map(item => item.xData),
         },
         series: [
           {
@@ -144,57 +207,113 @@ export default {
                   offset: 0,
                   color: "rgba(81, 139, 152,0.8)"
                 },
-                {
-                  offset: 1,
-                  color: "rgba(81, 139, 152, 0)"
-                }
+                  {
+                    offset: 1,
+                    color: "rgba(81, 139, 152, 0)"
+                  }
                 ], false),
                 shadowColor: 'rgba(81, 139, 152, 0.5)', //阴影颜色
                 shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
               }
             },
-            data: this.lineData.map(item=>item.yData),
+            data: this.realtimeLineData.map(item => item.yData),
           },
         ],
       }
     }
   },
   watch: {
-    areaType () {
-      this.getElecData()
-      this.lineData = this.getDatesOfLastTenDays()
+    areaType() {
+      this.qryPageDatas()
     }
   },
-  mounted () {
-    this.lineData = this.getDatesOfLastTenDays()
-    this.getElecData()
+  mounted() {
+    this.qryPageDatas()
   },
   methods: {
-    getDatesOfLastTenDays () {
-      var dates = [];
-      var today = new Date();
-      for (var i = 0; i < 10; i++) {
-        var pastDate = new Date(today);
-        pastDate.setDate(today.getDate() - i); // 减去i天
-        var formattedDate = dateFormat(pastDate, 'MM-dd');
-        dates.push(formattedDate);
+    qryPageDatas() {
+      this.getPgSupply()
+      this.getPgPvRealTimeSupply()
+      this.getHisPgPvSupply()
+    },
+    async getPgSupply() {
+      const {data: pgPvSupplyTotalPv} = await pgSupplyTotalPv({
+        areaCode: this.areaType
+      })
+      if (!pgPvSupplyTotalPv) {
+        return
       }
-      return dates.reverse().map(item => ({
-        xData: item,
-        yData: parseFloat(((Math.random() * 100 + 100)).toFixed(1))
-      }));
+      const {
+        thisDay,
+        thisMonth,
+        thisYear,
+        total
+      } = pgPvSupplyTotalPv
+      const [monthPv, yearPv, totalPv] = this.elecList
+      this.todayEnergy = numToStr(thisDay.genElecQuantity)
+      monthPv.value = numToStr(thisMonth.genElecQuantity)
+      yearPv.value = numToStr(thisYear.genElecQuantity)
+      totalPv.value = numToStr(total.genElecQuantity)
+    },
+    async getPgPvRealTimeSupply() {
+      const {data: pgPvRealtimeSupply} = await pgSupplyHourTotalPv({
+        areaCode: this.areaType,
+        date: DateTool.now(DateTool.DateFormat.YYYY_MM_DD)
+      })
+      if (!pgPvRealtimeSupply) {
+        return
+      }
+      const timeIndex = DateTool.getTime(60);
+      const timeIndexMap = {}
+      pgPvRealtimeSupply.forEach(item => {
+        timeIndexMap[item.timeIndex] = item
+      })
+      const lineData = []
+      timeIndex.forEach((item, index) => {
+        if (timeIndexMap[index + 1]) {
+          lineData.push({
+            xData: item,
+            yData: timeIndexMap[index + 1].genElecQuantity
+          })
+        } else {
+          lineData.push({
+            xData: item,
+            yData: 0
+          })
+        }
+      })
+      this.realtimeLineData = lineData
+    },
+    async getHisPgPvSupply() {
+      const {data: pgPvHisSupply} = await pgSupplyDayTotalPv({
+        areaCode: this.areaType,
+        date: DateTool.now(DateTool.DateFormat.YYYY_MM)
+      })
+      if (!pgPvHisSupply) {
+        return
+      }
+
+      const dateTips = DateTool.getDayOfRange(DateTool.now(`${DateTool.DateFormat.YYYY_MM}-01`), DateTool.now());
+      const dateIndexMap = {}
+      pgPvHisSupply.forEach(item => {
+        dateIndexMap[item.date] = item
+      })
+      const lineData = []
+      dateTips.forEach((item, index) => {
+        if (dateIndexMap[item]) {
+          lineData.push({
+            xData: item,
+            yData: dateIndexMap[item].genElecQuantity
+          })
+        } else {
+          lineData.push({
+            xData: item,
+            yData: 0
+          })
+        }
+      })
+      this.lineData = lineData
     },
-    getElecData () {
-      this.todayEnergy = Math.floor(Math.random() * 100 + 300)
-      this.elecList = this.elecList.map((item,index) => ({
-        ...item,
-        value:Math.floor(Math.random() * 100 + 900*(index+1))
-      }))
-      this.elecIndexList = this.elecIndexList.map(item => ({
-        ...item,
-        value:parseFloat(Math.random() * 100).toFixed(1)
-      }))
-    }
 
   }
 }

+ 58 - 49
ems-ui-cloud/src/views/largeScreen/source/right.vue

@@ -17,21 +17,17 @@
     <CusModule class="module-top" title="节能减排(今年)">
       <div class="energy">
         <div class="energy-item">
-          <div class="energy-item-value">{{reduce.coal}}</div>
+          <div class="energy-item-value">{{ reduce.coal }}</div>
           <div class="energy-item-name">标煤当量(吨)</div>
         </div>
         <div class="energy-item">
-          <div class="energy-item-value">{{reduce.co2}}</div>
+          <div class="energy-item-value">{{ reduce.co2 }}</div>
           <div class="energy-item-name">CO2当量(吨)</div>
         </div>
-        <div class="energy-item">
-          <div class="energy-item-value">{{reduce.tree}}</div>
-          <div class="energy-item-name">植树当量(棵)</div>
-        </div>
       </div>
     </CusModule>
     <CusModule class="module-top" title="发电趋势预测">
-      <BaseChart height="350px" width="100%" :option="lineOptions" />
+      <BaseChart height="350px" width="100%" :option="lineOptions"/>
     </CusModule>
   </div>
 </template>
@@ -39,18 +35,21 @@
 import CusModule from '../components/CusModule.vue';
 import BaseChart from '@/components/BaseChart/index.vue'
 import vueSeamlessScroll from 'vue-seamless-scroll'
-import {dateFormat} from '@/utils';
+import {array2Map} from '@/utils';
 import * as echarts from 'echarts'
 import {mapState} from 'vuex';
+import {DateTool} from "@/utils/DateTool";
+import {ecoDateRange, predictionProdDateRange} from "@/api/screen";
+
 export default {
   name: 'SourceRight',
-  data () {
+  data() {
     return {
       lineData: [],
       reduce: {
         coal: '',
         co2: '',
-        tree:''
+        tree: ''
       },
       classOption: {
         step: 0.3, // 数值越大速度滚动越快
@@ -103,8 +102,8 @@ export default {
     vueSeamlessScroll
   },
   computed: {
-    ...mapState('userState', ['areaType']),
-    lineOptions () {
+    ...mapState('userState', ['areaType', 'regionFactor', 'elec2CFactor']),
+    lineOptions() {
       return {
         legend: {
           show: false,
@@ -125,7 +124,7 @@ export default {
           splitLine: {
             show: false,
           },
-          data: this.lineData.map(item=>item.xData),
+          data: this.lineData.map(item => item.xData),
         },
         series: [
           {
@@ -149,51 +148,60 @@ export default {
                   offset: 0,
                   color: "rgba(81, 139, 152,0.8)"
                 },
-                {
-                  offset: 1,
-                  color: "rgba(81, 139, 152, 0)"
-                }
+                  {
+                    offset: 1,
+                    color: "rgba(81, 139, 152, 0)"
+                  }
                 ], false),
                 shadowColor: 'rgba(81, 139, 152, 0.5)', //阴影颜色
                 shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。
               }
             },
-            data: this.lineData.map(item=>item.yData),
+            data: this.lineData.map(item => item.yData),
           },
         ],
       }
     }
   },
   watch: {
-    areaType () {
-      this.lineData = this.getDatesOfLastTenDays()
-      this.getReduceData()
+    areaType() {
+      this.getDatas()
     }
   },
-  mounted () {
-    this.lineData = this.getDatesOfLastTenDays()
-    this.getReduceData()
+  mounted() {
+    this.getDatas()
   },
   methods: {
-    getDatesOfLastTenDays () {
-      var dates = [];
-      var today = new Date();
-      for (var i = 1; i < 11; i++) {
-        var pastDate = new Date(today);
-        pastDate.setDate(today.getDate() + i); // 减去i天
-        var formattedDate = dateFormat(pastDate, 'MM-dd');
-        dates.push(formattedDate);
-      }
-      return dates.map(item => ({
+    getDatas() {
+      this.getEcoDateRange()
+      this.getDatesOfLastTenDays()
+    },
+    async getDatesOfLastTenDays() {
+      const {data} = await predictionProdDateRange({
+        areaCode: this.areaType,
+        startRecTime: DateTool.now(DateTool.DateFormat.YYYY_MM)
+      })
+
+      const dates = DateTool.getDayOfRange(DateTool.now(`${DateTool.DateFormat.YYYY_MM}-01`), DateTool.thisMonthLastDay());
+      const mapIndex = array2Map(data, "date");
+      this.lineData = dates.map(item => ({
         xData: item,
-        yData: parseFloat(((Math.random() * 100 + 100)).toFixed(1))
-      }));
+        yData: mapIndex[item] ? mapIndex[item].elecProdQuantity : 0
+      }))
+    },
+
+    async getEcoDateRange() {
+      const {data: ecoDateRangeData} = await ecoDateRange({
+        areaCode: this.areaType,
+        date: DateTool.now(DateTool.DateFormat.YYYY)
+      })
+      if (!ecoDateRangeData) {
+        return
+      }
+      const {elecEcoQuantity} = ecoDateRangeData;
+      this.reduce.coal = (elecEcoQuantity * this.elec2CFactor / 1000).toFixed(2)
+      this.reduce.co2 = (elecEcoQuantity * this.regionFactor / 1000).toFixed(2)
     },
-    getReduceData () {
-      this.reduce.coal =parseFloat(((Math.random() * 100 + 500)).toFixed(1))
-      this.reduce.co2 =parseFloat(((Math.random() * 100 + 600)).toFixed(1))
-      this.reduce.tree =Math.floor(Math.random() * 100 + 1000)
-    }
   }
 }
 </script>
@@ -205,7 +213,7 @@ export default {
 
   .energy-item {
     position: relative;
-    flex: 1;
+    flex: 0.5;
     flex-shrink: 0;
     height: 169px;
     background: url('~@/assets/images/net/r1-item_bg.png') no-repeat;
@@ -215,7 +223,7 @@ export default {
       position: absolute;
       width: 100%;
       text-align: center;
-      bottom: 100px;
+      bottom: 70px;
       font-size: 14px;
       font-weight: bold;
     }
@@ -229,6 +237,7 @@ export default {
     }
   }
 }
+
 .seamless-header {
   margin-top: 20px;
   display: flex;
@@ -239,12 +248,12 @@ export default {
   background: #1B4A64;
   font-size: 16px;
 
-  >div:first-of-type,
-  >div:last-of-type {
+  > div:first-of-type,
+  > div:last-of-type {
     flex-basis: 35%;
   }
 
-  >div {
+  > div {
     text-align: center;
   }
 }
@@ -263,12 +272,12 @@ export default {
       background: #000;
     }
 
-    >div:first-of-type,
-    >div:last-of-type {
+    > div:first-of-type,
+    > div:last-of-type {
       flex-basis: 38%;
     }
 
-    >div {
+    > div {
       text-align: center;
       font-size: 13px;
     }