From 48e498136c8784ee79a698da2c852ca3aa0549ab Mon Sep 17 00:00:00 2001
From: jinpengyong <jpy123456>
Date: Wed, 29 Dec 2021 15:10:41 +0800
Subject: [PATCH] 行业贡献率,区域贡献率

---
 screen-api/src/main/java/com/moral/api/service/HistoryMonthlyService.java          |    8 
 screen-api/src/main/java/com/moral/api/service/impl/ProfessionServiceImpl.java     |  214 +++------
 screen-api/src/main/java/com/moral/api/service/RegionService.java                  |   18 
 screen-api/src/main/java/com/moral/api/controller/ProfessionController.java        |   10 
 screen-api/src/main/java/com/moral/api/controller/RegionController.java            |   85 ++++
 screen-api/src/main/java/com/moral/api/service/impl/HistoryHourlyServiceImpl.java  |  131 ++++-
 screen-api/src/main/java/com/moral/api/service/impl/DeviceServiceImpl.java         |   31 +
 screen-api/src/main/java/com/moral/api/service/DeviceService.java                  |    6 
 screen-api/src/main/java/com/moral/api/service/HistoryDailyService.java            |    8 
 screen-api/src/main/java/com/moral/api/service/impl/HistoryDailyServiceImpl.java   |   65 ++
 screen-api/src/main/java/com/moral/api/service/HistoryHourlyService.java           |   24 
 screen-api/src/main/java/com/moral/api/service/impl/HistoryMonthlyServiceImpl.java |  143 ++++--
 screen-job/src/main/java/com/moral/api/service/impl/CityAqiServiceImpl.java        |    4 
 screen-api/src/main/java/com/moral/api/service/impl/RegionServiceImpl.java         |  498 +++++++++++++++++++++++
 14 files changed, 997 insertions(+), 248 deletions(-)

diff --git a/screen-api/src/main/java/com/moral/api/controller/ProfessionController.java b/screen-api/src/main/java/com/moral/api/controller/ProfessionController.java
index 455c8aa..d322e92 100644
--- a/screen-api/src/main/java/com/moral/api/controller/ProfessionController.java
+++ b/screen-api/src/main/java/com/moral/api/controller/ProfessionController.java
@@ -44,9 +44,13 @@
         return ResultMessage.ok(response);
     }
 
-    @ApiOperation(value = "���������������������������������������������", notes = "���������������������������������������������")
+    @ApiOperation(value = "������������������������������������������������", notes = "������������������������������������������������")
     @GetMapping("getSensorByProfessions")
-    public ResultMessage getProfessions(HttpServletRequest request) {
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "organizationId", value = "������id", required = true, paramType = "query", dataType = "Integer"),
+            @ApiImplicitParam(name = "professions", value = "������key���������������������", required = true, paramType = "query", dataType = "String")
+    })
+    public ResultMessage getSensorByProfessions(HttpServletRequest request) {
         Map<String, Object> params = WebUtils.getParametersStartingWith(request, null);
         if (ObjectUtils.isEmpty(params.get("organizationId")) || ObjectUtils.isEmpty(params.get("professions"))) {
             return ResultMessage.fail(ResponseCodeEnum.PARAMETERS_IS_MISSING.getCode(),
@@ -68,7 +72,7 @@
     public ResultMessage professionContribution(HttpServletRequest request) {
         Map<String, Object> params = WebUtils.getParametersStartingWith(request, null);
         if (ObjectUtils.isEmpty(params.get("organizationId"))
-                ||ObjectUtils.isEmpty(params.get("professions"))
+                || ObjectUtils.isEmpty(params.get("professions"))
                 || ObjectUtils.isEmpty(params.get("type"))
                 || ObjectUtils.isEmpty(params.get("time"))
                 || ObjectUtils.isEmpty(params.get("sensorCode"))) {
diff --git a/screen-api/src/main/java/com/moral/api/controller/RegionController.java b/screen-api/src/main/java/com/moral/api/controller/RegionController.java
new file mode 100644
index 0000000..a88db8f
--- /dev/null
+++ b/screen-api/src/main/java/com/moral/api/controller/RegionController.java
@@ -0,0 +1,85 @@
+package com.moral.api.controller;
+
+import groovy.util.logging.Slf4j;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.moral.api.service.RegionService;
+import com.moral.constant.ResponseCodeEnum;
+import com.moral.constant.ResultMessage;
+import com.moral.util.WebUtils;
+
+@Slf4j
+@Api(tags = "���������������������")
+@CrossOrigin(origins = "*", maxAge = 3600)
+@RequestMapping("region")
+@RestController
+public class RegionController {
+
+    @Autowired
+    private RegionService regionService;
+
+    @ApiOperation(value = "������������id������������������������", notes = "������������id������������������������")
+    @GetMapping("getRegionsByOrganizationId")
+    public ResultMessage getRegionsByOrganizationId(Integer organizationId) {
+        if (ObjectUtils.isEmpty(organizationId)) {
+            return ResultMessage.fail(ResponseCodeEnum.PARAMETERS_IS_MISSING.getCode(),
+                    ResponseCodeEnum.PARAMETERS_IS_MISSING.getMsg());
+        }
+        Set<Map<String, Object>> response = regionService.getRegionsByOrganizationId(organizationId);
+        return ResultMessage.ok(response);
+    }
+
+    @ApiOperation(value = "������������������������������������������������������", notes = "������������������������������������������������������")
+    @GetMapping("getSensorByRegionCodes")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "organizationId", value = "������id", required = true, paramType = "query", dataType = "Integer"),
+            @ApiImplicitParam(name = "regionCodes", value = "������������������������������������", required = true, paramType = "query", dataType = "String")
+    })
+    public ResultMessage getSensorByProfessions(HttpServletRequest request) {
+        Map<String, Object> params = WebUtils.getParametersStartingWith(request, null);
+        if (ObjectUtils.isEmpty(params.get("organizationId")) || ObjectUtils.isEmpty(params.get("regionCodes"))) {
+            return ResultMessage.fail(ResponseCodeEnum.PARAMETERS_IS_MISSING.getCode(),
+                    ResponseCodeEnum.PARAMETERS_IS_MISSING.getMsg());
+        }
+        Set<Map<String, Object>> response = regionService.getSensorByRegionCodesAndOrganizationId(params);
+        return ResultMessage.ok(response);
+    }
+
+    @ApiOperation(value = "���������������", notes = "���������������")
+    @GetMapping("regionContribution")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "organizationId", value = "������id", required = true, paramType = "query", dataType = "Integer"),
+            @ApiImplicitParam(name = "regionCodes", value = "���������������������������������", required = true, paramType = "query", dataType = "String"),
+            @ApiImplicitParam(name = "type", value = "���������������2021-12������������2021-12-24���", required = true, paramType = "query", dataType = "String"),
+            @ApiImplicitParam(name = "time", value = "������", required = true, paramType = "query", dataType = "String"),
+            @ApiImplicitParam(name = "sensorCode", value = "���������code", required = true, paramType = "query", dataType = "String")
+    })
+    public ResultMessage regionContribution(HttpServletRequest request) {
+        Map<String, Object> params = WebUtils.getParametersStartingWith(request, null);
+        if (ObjectUtils.isEmpty(params.get("organizationId"))
+                || ObjectUtils.isEmpty(params.get("regionCodes"))
+                || ObjectUtils.isEmpty(params.get("type"))
+                || ObjectUtils.isEmpty(params.get("time"))
+                || ObjectUtils.isEmpty(params.get("sensorCode"))) {
+            return ResultMessage.fail(ResponseCodeEnum.PARAMETERS_IS_MISSING.getCode(),
+                    ResponseCodeEnum.PARAMETERS_IS_MISSING.getMsg());
+        }
+        List<Map<String, Object>> response = regionService.regionContribution(params);
+        return ResultMessage.ok(response);
+    }
+}
diff --git a/screen-api/src/main/java/com/moral/api/service/DeviceService.java b/screen-api/src/main/java/com/moral/api/service/DeviceService.java
index 0fe13b7..76de203 100644
--- a/screen-api/src/main/java/com/moral/api/service/DeviceService.java
+++ b/screen-api/src/main/java/com/moral/api/service/DeviceService.java
@@ -31,4 +31,10 @@
     //���������������������������������������
     List<Map<String, Object>> getDevicesByOrganizationId(Integer orgId);
 
+    //���������������������������mac������
+    List<String> getMacsByOrganizationId(Integer organizationId);
+
+    //������������������,���������������������������mac������
+    List getMacsByOrgIdAndRegionCode(Integer organizationId,Integer regionCode);
+
 }
diff --git a/screen-api/src/main/java/com/moral/api/service/HistoryDailyService.java b/screen-api/src/main/java/com/moral/api/service/HistoryDailyService.java
index ad3d9e9..9985bbd 100644
--- a/screen-api/src/main/java/com/moral/api/service/HistoryDailyService.java
+++ b/screen-api/src/main/java/com/moral/api/service/HistoryDailyService.java
@@ -72,4 +72,12 @@
      * */
     List<HistoryDaily> getValueByMacs(List<String> macs, String time);
 
+    /**
+     * @description ���������������������
+     * @param list ������
+     * @param sensorCode ������code
+     * @param type ���������������������������������max���������������min���������������sum���������������avg���
+     * */
+    Double calculatedValue(List<HistoryDaily> list, String sensorCode, String type);
+
 }
diff --git a/screen-api/src/main/java/com/moral/api/service/HistoryHourlyService.java b/screen-api/src/main/java/com/moral/api/service/HistoryHourlyService.java
index 3b7e654..1317a23 100644
--- a/screen-api/src/main/java/com/moral/api/service/HistoryHourlyService.java
+++ b/screen-api/src/main/java/com/moral/api/service/HistoryHourlyService.java
@@ -56,13 +56,13 @@
     List<Map<String, Object>> getThermodynamicDiagramDataByOrgIdSensorCodeTimeslot(Map<String, Object> map);
 
     /**
-     *@Description: ���������������������������������
-     *@Param: [map]
-     *@return: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
-     *@Author: lizijie
-     *@Date: 2021/12/28 10:04
+     * @Description: ���������������������������������
+     * @Param: [map]
+     * @return: java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
+     * @Author: lizijie
+     * @Date: 2021/12/28 10:04
      **/
-    List<Map<String, Object>> getHourCompleteDataByMacSensorCodeDate(Map<String,Object> map);
+    List<Map<String, Object>> getHourCompleteDataByMacSensorCodeDate(Map<String, Object> map);
 
     /**
      * @Description: ������mac������������������������
@@ -74,10 +74,18 @@
     List<HistoryHourly> getValueByMacAndTime(String mac, Date startDate, Date endDate);
 
     /**
-     * @description: ���������������������������������������
      * @param macs List<String>
      * @param time String ������2021-12-23
-     * */
+     * @description: ���������������������������������������
+     */
     List<HistoryHourly> getValueByMacs(List<String> macs, String time);
 
+    /**
+     * @param list       ������
+     * @param sensorCode ������code
+     * @param type       ���������������������������������max���������������min���������������sum���������������avg���
+     * @description ���������������������
+     */
+    Double calculatedValue(List<HistoryHourly> list, String sensorCode, String type, Double lower, Double upper);
+
 }
diff --git a/screen-api/src/main/java/com/moral/api/service/HistoryMonthlyService.java b/screen-api/src/main/java/com/moral/api/service/HistoryMonthlyService.java
index dba3ab6..be479d6 100644
--- a/screen-api/src/main/java/com/moral/api/service/HistoryMonthlyService.java
+++ b/screen-api/src/main/java/com/moral/api/service/HistoryMonthlyService.java
@@ -59,4 +59,12 @@
      * @param time String ������2021
      * */
     List<HistoryMonthly> getValueByMacs(List<String> macs, String time);
+
+    /**
+     * @description ���������������������
+     * @param list ������
+     * @param sensorCode ������code
+     * @param type ���������������������������������max���������������min���������������sum���������������avg���
+     * */
+    Double calculatedValue(List<HistoryMonthly> list, String sensorCode, String type);
 }
diff --git a/screen-api/src/main/java/com/moral/api/service/RegionService.java b/screen-api/src/main/java/com/moral/api/service/RegionService.java
new file mode 100644
index 0000000..cb82fcb
--- /dev/null
+++ b/screen-api/src/main/java/com/moral/api/service/RegionService.java
@@ -0,0 +1,18 @@
+package com.moral.api.service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public interface RegionService {
+
+    //������������id������������������������������������������������������
+    Set<Map<String, Object>> getRegionsByOrganizationId(Integer organizationId);
+
+    //������������������������������������������������������
+    Set<Map<String, Object>> getSensorByRegionCodesAndOrganizationId(Map<String, Object> params);
+
+    //���������������
+    List<Map<String, Object>> regionContribution(Map<String, Object> params);
+
+}
diff --git a/screen-api/src/main/java/com/moral/api/service/impl/DeviceServiceImpl.java b/screen-api/src/main/java/com/moral/api/service/impl/DeviceServiceImpl.java
index 3541861..b289309 100644
--- a/screen-api/src/main/java/com/moral/api/service/impl/DeviceServiceImpl.java
+++ b/screen-api/src/main/java/com/moral/api/service/impl/DeviceServiceImpl.java
@@ -22,7 +22,6 @@
 
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -166,11 +165,33 @@
     @Override
     public List<Map<String, Object>> getDevicesByOrganizationId(Integer orgId) {
         //������������������mac
-        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
-        queryWrapper.select("mac").eq("organization_id", orgId).eq("is_delete", Constants.NOT_DELETE);
-        List<Device> devices = deviceMapper.selectList(queryWrapper);
+        List macs = getMacsByOrganizationId(orgId);
         //���redis������������������������
-        return devices.stream().map(device -> (Map<String, Object>) redisTemplate.opsForHash().get(RedisConstants.DEVICE, device.getMac())).collect(Collectors.toList());
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (Object mac : macs) {
+            Map<String, Object> map = (Map<String, Object>) redisTemplate.opsForHash().get(RedisConstants.DEVICE, mac.toString());
+            result.add(map);
+        }
+        return result;
+    }
+
+    @Override
+    public List getMacsByOrganizationId(Integer organizationId) {
+        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("mac")
+                .eq("organization_id", organizationId)
+                .eq("is_delete", Constants.NOT_DELETE);
+        return deviceMapper.selectObjs(queryWrapper);
+    }
+
+    @Override
+    public List getMacsByOrgIdAndRegionCode(Integer organizationId,Integer regionCode) {
+        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("mac")
+                .eq("organization_id", organizationId)
+                .eq("is_delete", Constants.NOT_DELETE)
+                .eq("town_code", regionCode);
+        return deviceMapper.selectObjs(queryWrapper);
     }
 
     private Device getDeviceByMacFromDB(String mac) {
diff --git a/screen-api/src/main/java/com/moral/api/service/impl/HistoryDailyServiceImpl.java b/screen-api/src/main/java/com/moral/api/service/impl/HistoryDailyServiceImpl.java
index d6fe2f6..c976a62 100644
--- a/screen-api/src/main/java/com/moral/api/service/impl/HistoryDailyServiceImpl.java
+++ b/screen-api/src/main/java/com/moral/api/service/impl/HistoryDailyServiceImpl.java
@@ -1,7 +1,27 @@
 package com.moral.api.service.impl;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.OptionalDouble;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.DoubleStream;
+import java.util.stream.Stream;
+
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.moral.api.entity.Device;
 import com.moral.api.entity.GeoCoordinate;
 import com.moral.api.entity.HistoryDaily;
@@ -9,21 +29,11 @@
 import com.moral.api.mapper.DeviceMapper;
 import com.moral.api.mapper.HistoryDailyMapper;
 import com.moral.api.service.HistoryDailyService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.moral.api.service.OrganizationService;
 import com.moral.api.utils.GetCenterPointFromListOfCoordinates;
 import com.moral.constant.Constants;
 import com.moral.util.DateUtils;
 import com.moral.util.PollutantUtils;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.ObjectUtils;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -337,5 +347,40 @@
         return historyDailyMapper.selectList(queryWrapper);
     }
 
+    @Override
+    public Double calculatedValue(List<HistoryDaily> list, String sensorCode, String type) {
+        Supplier<Stream<HistoryDaily>> supplier = list::stream;
+        DoubleStream doubleStream = supplier.get()
+                .flatMapToDouble(v -> {
+                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
+                    Object sensorValue = dataValue.get(sensorCode);
+                    if (ObjectUtils.isEmpty(sensorValue)) {
+                        return null;
+                    }
+                    double aDouble = Double.parseDouble(sensorValue.toString());
+                    return DoubleStream.of(aDouble);
+                });
+        Double result = null;
+        OptionalDouble optionalDouble = null;
+        if ("sum".equals(type)) {
+            result = doubleStream.sum();
+        } else {
+            if ("min".equals(type)) {
+                optionalDouble = doubleStream.average();
+
+            } else if ("max".equals(type)) {
+                optionalDouble = doubleStream.min();
+
+            } else if ("avg".equals(type)) {
+                optionalDouble = doubleStream.max();
+            }
+
+            if (optionalDouble.isPresent()) {
+                result = optionalDouble.getAsDouble();
+            }
+        }
+        return result;
+    }
+
 
 }
diff --git a/screen-api/src/main/java/com/moral/api/service/impl/HistoryHourlyServiceImpl.java b/screen-api/src/main/java/com/moral/api/service/impl/HistoryHourlyServiceImpl.java
index 21062af..6715169 100644
--- a/screen-api/src/main/java/com/moral/api/service/impl/HistoryHourlyServiceImpl.java
+++ b/screen-api/src/main/java/com/moral/api/service/impl/HistoryHourlyServiceImpl.java
@@ -1,13 +1,36 @@
 package com.moral.api.service.impl;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.OptionalDouble;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.DoubleStream;
+import java.util.stream.Stream;
+
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.moral.api.config.mybatis.MybatisPlusConfig;
-import com.moral.api.entity.*;
+import com.moral.api.entity.Device;
+import com.moral.api.entity.GeoCoordinate;
+import com.moral.api.entity.HistoryHourly;
+import com.moral.api.entity.Organization;
 import com.moral.api.mapper.DeviceMapper;
 import com.moral.api.mapper.HistoryHourlyMapper;
 import com.moral.api.service.HistoryHourlyService;
 import com.moral.api.service.OrganizationService;
+import com.moral.api.service.SensorService;
 import com.moral.api.utils.GetCenterPointFromListOfCoordinates;
 import com.moral.constant.Constants;
 import com.moral.constant.SeparateTableType;
@@ -16,16 +39,6 @@
 import com.moral.util.DateUtils;
 import com.moral.util.MybatisPLUSUtils;
 import com.moral.util.PollutantUtils;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.ObjectUtils;
-
-import java.sql.Array;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -533,26 +546,26 @@
         String mac = map.get("mac").toString();
         String sensorCode = map.get("sensor_code").toString();
         String date = map.get("date").toString();
-        String dateTime = date.replace("-","");
-        String timeUnits = dateTime.substring(0,6)+"_complete";
-        Map<String,Object> params = new HashMap<>();
-        params.put("timeUnits",timeUnits);
-        params.put("mac",mac);
+        String dateTime = date.replace("-", "");
+        String timeUnits = dateTime.substring(0, 6) + "_complete";
+        Map<String, Object> params = new HashMap<>();
+        params.put("timeUnits", timeUnits);
+        params.put("mac", mac);
         List resultList = new ArrayList();
         for (int i = 0; i < 24; i++) {
-            Map<String,Object> oneHourDateMap = new HashMap<>();
+            Map<String, Object> oneHourDateMap = new HashMap<>();
             String j;
-            if (i<10){
-                j = " 0"+i+":00:00";
-            }else {
-                j = " "+i+":00:00";
+            if (i < 10) {
+                j = " 0" + i + ":00:00";
+            } else {
+                j = " " + i + ":00:00";
             }
-            String time = date+j;
-            params.put("time",time);
-            String resultTime = time.substring(0,13);
-            if (ObjectUtils.isEmpty(historyHourlyMapper.selectHourlyData(params))){
-                oneHourDateMap.put("time",resultTime);
-                oneHourDateMap.put("values",new ArrayList<>());
+            String time = date + j;
+            params.put("time", time);
+            String resultTime = time.substring(0, 13);
+            if (ObjectUtils.isEmpty(historyHourlyMapper.selectHourlyData(params))) {
+                oneHourDateMap.put("time", resultTime);
+                oneHourDateMap.put("values", new ArrayList<>());
                 resultList.add(oneHourDateMap);
                 continue;
             }
@@ -560,11 +573,11 @@
             oneHourlyData = historyHourlyMapper.selectHourlyData(params);
             JSONObject js = JSONObject.parseObject(oneHourlyData);
             String sensorDate = js.get(sensorCode).toString();
-            sensorDate = sensorDate.replace("[","");
-            sensorDate = sensorDate.replace("]","");
+            sensorDate = sensorDate.replace("[", "");
+            sensorDate = sensorDate.replace("]", "");
             String[] split = sensorDate.split(",");
-            oneHourDateMap.put("time",resultTime);
-            oneHourDateMap.put("values",split);
+            oneHourDateMap.put("time", resultTime);
+            oneHourDateMap.put("values", split);
             resultList.add(oneHourDateMap);
         }
         return resultList;
@@ -598,6 +611,62 @@
         return multiTableQuery(queryWrapper, tableNames);
     }
 
+    @Override
+    public Double calculatedValue(List<HistoryHourly> list, String sensorCode, String type, Double lower, Double upper) {
+        Supplier<Stream<HistoryHourly>> supplier = list::stream;
+        DoubleStream doubleStream = supplier.get()
+                .flatMapToDouble(v -> {
+                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
+                    Object sensorValue = dataValue.get(sensorCode);
+
+                    if (ObjectUtils.isEmpty(sensorValue)) {
+                        return null;
+                    }
+
+                    //���������������������
+                    Object flag = dataValue.get(sensorCode + "-" + Constants.MARKER_BIT_KEY);
+                    if (!Constants.MARKER_BIT_TRUE.equals(flag)) {
+                        return null;
+                    }
+
+                    double aDouble = Double.parseDouble(sensorValue.toString());
+
+                    //������������������������������
+                    if (!ObjectUtils.isEmpty(lower)) {
+                        if (aDouble < lower) {
+                            return null;
+                        }
+                    }
+                    if (!ObjectUtils.isEmpty(upper)) {
+                        if (aDouble > upper) {
+                            return null;
+                        }
+                    }
+
+                    return DoubleStream.of(aDouble);
+                });
+        Double result = null;
+        OptionalDouble optionalDouble = null;
+        if ("sum".equals(type)) {
+            result = doubleStream.sum();
+        } else {
+            if ("min".equals(type)) {
+                optionalDouble = doubleStream.average();
+
+            } else if ("max".equals(type)) {
+                optionalDouble = doubleStream.min();
+
+            } else if ("avg".equals(type)) {
+                optionalDouble = doubleStream.max();
+            }
+
+            if (optionalDouble.isPresent()) {
+                result = optionalDouble.getAsDouble();
+            }
+        }
+        return result;
+    }
+
     /**
      * @Description: ������������������������������������������������wrapper���������������
      * @Param: [wrapper, tableNames]
diff --git a/screen-api/src/main/java/com/moral/api/service/impl/HistoryMonthlyServiceImpl.java b/screen-api/src/main/java/com/moral/api/service/impl/HistoryMonthlyServiceImpl.java
index 946fd43..613a00c 100644
--- a/screen-api/src/main/java/com/moral/api/service/impl/HistoryMonthlyServiceImpl.java
+++ b/screen-api/src/main/java/com/moral/api/service/impl/HistoryMonthlyServiceImpl.java
@@ -11,6 +11,7 @@
 import com.moral.api.utils.GetCenterPointFromListOfCoordinates;
 import com.moral.constant.Constants;
 import com.moral.util.PollutantUtils;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ObjectUtils;
@@ -18,7 +19,10 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
+import java.util.stream.DoubleStream;
+import java.util.stream.Stream;
 
 /**
  * <p>
@@ -43,10 +47,10 @@
     @Override
     public HistoryMonthly getHistoryMonthlyByMacAndDate(String mac, Date date) {
         QueryWrapper<HistoryMonthly> wrapper = new QueryWrapper<>();
-        wrapper.eq("mac",mac);
-        wrapper.eq("time",date);
+        wrapper.eq("mac", mac);
+        wrapper.eq("time", date);
         List<HistoryMonthly> historyMonthlies = historyMonthlyMapper.selectList(wrapper);
-        if(ObjectUtils.isEmpty(historyMonthlies))
+        if (ObjectUtils.isEmpty(historyMonthlies))
             return null;
         return historyMonthlies.get(0);
     }
@@ -54,12 +58,12 @@
     @Override
     public Map<String, HistoryMonthly> getHistoryMonthlyByMacsAndDate(List<String> mac, Date date) {
         QueryWrapper<HistoryMonthly> wrapper = new QueryWrapper<>();
-        wrapper.in("mac",mac);
-        wrapper.eq("time",date);
+        wrapper.in("mac", mac);
+        wrapper.eq("time", date);
         List<HistoryMonthly> historyMonthlies = historyMonthlyMapper.selectList(wrapper);
-        Map<String,HistoryMonthly> map = new HashMap<>();
+        Map<String, HistoryMonthly> map = new HashMap<>();
         for (HistoryMonthly historyMonthly : historyMonthlies) {
-            map.put(historyMonthly.getMac(),historyMonthly);
+            map.put(historyMonthly.getMac(), historyMonthly);
         }
         return map;
     }
@@ -74,8 +78,8 @@
         //������������
         //���������������
         List<Organization> allChildrenOrganization = organizationService.getChildrenOrganizationsById(orgId);
-        if (!ObjectUtils.isEmpty(allChildrenOrganization) || allChildrenOrganization.size() < 1){
-            for (Organization organization:allChildrenOrganization) {
+        if (!ObjectUtils.isEmpty(allChildrenOrganization) || allChildrenOrganization.size() < 1) {
+            for (Organization organization : allChildrenOrganization) {
                 allOrgId.add(organization.getId());
             }
         }
@@ -84,38 +88,38 @@
         //������������list���������������mac
         List<String> deviceMacList = new ArrayList<>();
         //������������map���Mac������key���device������value
-        Map<String,Device> deviceMap = new HashMap<>();
+        Map<String, Device> deviceMap = new HashMap<>();
         List<Double> longitudeList = new ArrayList<>();
         List<Double> latitudeList = new ArrayList<>();
-        for (Integer orgIdWithoutDuplicates:allOrgIdWithoutDuplicates) {
+        for (Integer orgIdWithoutDuplicates : allOrgIdWithoutDuplicates) {
             //������id������������������
             QueryWrapper<Device> wrapper_device = new QueryWrapper<>();
-            wrapper_device.eq("is_delete",Constants.NOT_DELETE).eq("organization_id",orgIdWithoutDuplicates);
+            wrapper_device.eq("is_delete", Constants.NOT_DELETE).eq("organization_id", orgIdWithoutDuplicates);
             List<Device> devices = new ArrayList<>();
             devices = deviceMapper.selectList(wrapper_device);
-            if (devices.size()>0){
-                for (Device device:devices) {
+            if (devices.size() > 0) {
+                for (Device device : devices) {
                     String mac = device.getMac();
                     deviceMacList.add(mac);
-                    deviceMap.put(mac,device);
+                    deviceMap.put(mac, device);
                     double longitude = device.getLongitude();
                     double latitude = device.getLatitude();
                     longitudeList.add(longitude);
                     latitudeList.add(latitude);
                 }
-            }else {
+            } else {
                 continue;
             }
         }
         //������������
-        String time = parameters.get("time").toString().substring(0,7)+"-01 00:00:00";
-        resultMap.put("time",time);
+        String time = parameters.get("time").toString().substring(0, 7) + "-01 00:00:00";
+        resultMap.put("time", time);
         QueryWrapper<HistoryMonthly> historyMonthlyQueryWrapper = new QueryWrapper<>();
-        historyMonthlyQueryWrapper.eq("time",time);
+        historyMonthlyQueryWrapper.eq("time", time);
         historyMonthlyQueryWrapper.in("mac", deviceMacList);
         List<HistoryMonthly> historyDailies = historyMonthlyMapper.selectList(historyMonthlyQueryWrapper);
         List<Object> list = new ArrayList<>();
-        for (HistoryMonthly historyDailyData:historyDailies) {
+        for (HistoryMonthly historyDailyData : historyDailies) {
             List<Object> list1 = new ArrayList<>();
             String mac = historyDailyData.getMac();
             Device device = deviceMap.get(mac);
@@ -129,17 +133,17 @@
             list1.add(level);
             list.add(list1);
         }
-        resultMap.put("list",list);
-        double latitudeMin = Collections.min(latitudeList)-0.0018;
-        double latitudeMax = Collections.max(latitudeList)+0.0018;
-        double longitudeMin = Collections.min(longitudeList)-0.2/(111*Math.cos(latitudeMin));
-        double longitudeMax = Collections.max(longitudeList)+0.2/(111*Math.cos(latitudeMin));
+        resultMap.put("list", list);
+        double latitudeMin = Collections.min(latitudeList) - 0.0018;
+        double latitudeMax = Collections.max(latitudeList) + 0.0018;
+        double longitudeMin = Collections.min(longitudeList) - 0.2 / (111 * Math.cos(latitudeMin));
+        double longitudeMax = Collections.max(longitudeList) + 0.2 / (111 * Math.cos(latitudeMin));
         List<Double> bound = new ArrayList<>();
         bound.add(longitudeMin);
         bound.add(latitudeMin);
         bound.add(longitudeMax);
         bound.add(latitudeMax);
-        resultMap.put("bound",bound);
+        resultMap.put("bound", bound);
         List<List> bound1 = new ArrayList<>();
         List<Double> left_up = new ArrayList<>();
         left_up.add(latitudeMax);
@@ -158,7 +162,7 @@
         bound1.add(right_down);
         bound1.add(left_down);
         List<GeoCoordinate> geoCoordinates = new ArrayList<>();
-        for (List bo:bound1) {
+        for (List bo : bound1) {
             GeoCoordinate g = new GeoCoordinate();
             g.setLatitude(Double.parseDouble(bo.get(0).toString()));
             g.setLongitude(Double.parseDouble(bo.get(1).toString()));
@@ -168,7 +172,7 @@
         List centerPoint = new ArrayList();
         centerPoint.add(centerPoint400.getLongitude());
         centerPoint.add(centerPoint400.getLatitude());
-        resultMap.put("centerPoint",centerPoint);
+        resultMap.put("centerPoint", centerPoint);
         return resultMap;
     }
 
@@ -181,8 +185,8 @@
         //������������
         //���������������
         List<Organization> allChildrenOrganization = organizationService.getChildrenOrganizationsById(orgId);
-        if (!ObjectUtils.isEmpty(allChildrenOrganization) || allChildrenOrganization.size() < 1){
-            for (Organization organization:allChildrenOrganization) {
+        if (!ObjectUtils.isEmpty(allChildrenOrganization) || allChildrenOrganization.size() < 1) {
+            for (Organization organization : allChildrenOrganization) {
                 allOrgId.add(organization.getId());
             }
         }
@@ -191,33 +195,33 @@
         //������������list���������������mac
         List<String> deviceMacList = new ArrayList<>();
         //������������map���Mac������key���device������value
-        Map<String,Device> deviceMap = new HashMap<>();
+        Map<String, Device> deviceMap = new HashMap<>();
         List<Double> longitudeList = new ArrayList<>();
         List<Double> latitudeList = new ArrayList<>();
-        for (Integer orgIdWithoutDuplicates:allOrgIdWithoutDuplicates) {
+        for (Integer orgIdWithoutDuplicates : allOrgIdWithoutDuplicates) {
             //������id������������������
             QueryWrapper<Device> wrapper_device = new QueryWrapper<>();
-            wrapper_device.eq("is_delete",Constants.NOT_DELETE).eq("organization_id",orgIdWithoutDuplicates);
+            wrapper_device.eq("is_delete", Constants.NOT_DELETE).eq("organization_id", orgIdWithoutDuplicates);
             List<Device> devices = new ArrayList<>();
             devices = deviceMapper.selectList(wrapper_device);
-            if (devices.size()>0){
-                for (Device device:devices) {
+            if (devices.size() > 0) {
+                for (Device device : devices) {
                     String mac = device.getMac();
                     deviceMacList.add(mac);
-                    deviceMap.put(mac,device);
+                    deviceMap.put(mac, device);
                     double longitude = device.getLongitude();
                     double latitude = device.getLatitude();
                     longitudeList.add(longitude);
                     latitudeList.add(latitude);
                 }
-            }else {
+            } else {
                 continue;
             }
         }
-        double latitudeMin = Collections.min(latitudeList)-0.0018;
-        double latitudeMax = Collections.max(latitudeList)+0.0018;
-        double longitudeMin = Collections.min(longitudeList)-0.2/(111*Math.cos(latitudeMin));
-        double longitudeMax = Collections.max(longitudeList)+0.2/(111*Math.cos(latitudeMin));
+        double latitudeMin = Collections.min(latitudeList) - 0.0018;
+        double latitudeMax = Collections.max(latitudeList) + 0.0018;
+        double longitudeMin = Collections.min(longitudeList) - 0.2 / (111 * Math.cos(latitudeMin));
+        double longitudeMax = Collections.max(longitudeList) + 0.2 / (111 * Math.cos(latitudeMin));
         List<Double> bound = new ArrayList<>();
         bound.add(longitudeMin);
         bound.add(latitudeMin);
@@ -241,7 +245,7 @@
         bound1.add(right_down);
         bound1.add(left_down);
         List<GeoCoordinate> geoCoordinates = new ArrayList<>();
-        for (List bo:bound1) {
+        for (List bo : bound1) {
             GeoCoordinate g = new GeoCoordinate();
             g.setLatitude(Double.parseDouble(bo.get(0).toString()));
             g.setLongitude(Double.parseDouble(bo.get(1).toString()));
@@ -253,16 +257,16 @@
         centerPoint.add(centerPoint400.getLatitude());
         List<Map<String, Object>> resultList = new ArrayList<>();
         //������������
-        String endTime = parameters.get("endTime").toString().substring(0,7)+"-01 00:00:00";
+        String endTime = parameters.get("endTime").toString().substring(0, 7) + "-01 00:00:00";
         //������������
         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
         int months = Integer.parseInt(parameters.get("months").toString());
         Date newEndTime = new Date();
-        for (int i=months;i>=0;i--){
+        for (int i = months; i >= 0; i--) {
             Map<String, Object> resultMap = new HashMap<>();
             //������������������������������
-            resultMap.put("centerPoint",centerPoint);
-            resultMap.put("bound",bound);
+            resultMap.put("centerPoint", centerPoint);
+            resultMap.put("bound", bound);
             Calendar calendar = Calendar.getInstance();
             try {
                 newEndTime = df.parse(endTime);
@@ -270,16 +274,16 @@
                 e.printStackTrace();
             }
             calendar.setTime(newEndTime);
-            calendar.set(Calendar.MONTH,calendar.get(Calendar.MONDAY)-i);
-            String time = df.format(calendar.getTime())+"-01 00:00:00";
+            calendar.set(Calendar.MONTH, calendar.get(Calendar.MONDAY) - i);
+            String time = df.format(calendar.getTime()) + "-01 00:00:00";
             //������������
-            resultMap.put("time",time);
+            resultMap.put("time", time);
             QueryWrapper<HistoryMonthly> historyMonthlyQueryWrapper = new QueryWrapper<>();
-            historyMonthlyQueryWrapper.eq("time",time);
+            historyMonthlyQueryWrapper.eq("time", time);
             historyMonthlyQueryWrapper.in("mac", deviceMacList);
             List<HistoryMonthly> historyDailies = historyMonthlyMapper.selectList(historyMonthlyQueryWrapper);
             List<Object> list = new ArrayList<>();
-            for (HistoryMonthly historyMonthlyData:historyDailies) {
+            for (HistoryMonthly historyMonthlyData : historyDailies) {
                 List<Object> list1 = new ArrayList<>();
                 String mac = historyMonthlyData.getMac();
                 Device device = deviceMap.get(mac);
@@ -293,7 +297,7 @@
                 list1.add(level);
                 list.add(list1);
             }
-            resultMap.put("list",list);
+            resultMap.put("list", list);
             resultList.add(resultMap);
         }
         return resultList;
@@ -307,4 +311,39 @@
                 .in("mac", macs);
         return historyMonthlyMapper.selectList(queryWrapper);
     }
+
+    @Override
+    public Double calculatedValue(List<HistoryMonthly> list, String sensorCode, String type) {
+        Supplier<Stream<HistoryMonthly>> supplier = list::stream;
+        DoubleStream doubleStream = supplier.get()
+                .flatMapToDouble(v -> {
+                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
+                    Object sensorValue = dataValue.get(sensorCode);
+                    if (ObjectUtils.isEmpty(sensorValue)) {
+                        return null;
+                    }
+                    double aDouble = Double.parseDouble(sensorValue.toString());
+                    return DoubleStream.of(aDouble);
+                });
+        Double result = null;
+        OptionalDouble optionalDouble = null;
+        if ("sum".equals(type)) {
+            result = doubleStream.sum();
+        } else {
+            if ("min".equals(type)) {
+                optionalDouble = doubleStream.average();
+
+            } else if ("max".equals(type)) {
+                optionalDouble = doubleStream.min();
+
+            } else if ("avg".equals(type)) {
+                optionalDouble = doubleStream.max();
+            }
+
+            if (optionalDouble.isPresent()) {
+                result = optionalDouble.getAsDouble();
+            }
+        }
+        return result;
+    }
 }
diff --git a/screen-api/src/main/java/com/moral/api/service/impl/ProfessionServiceImpl.java b/screen-api/src/main/java/com/moral/api/service/impl/ProfessionServiceImpl.java
index 104c9f0..a52a729 100644
--- a/screen-api/src/main/java/com/moral/api/service/impl/ProfessionServiceImpl.java
+++ b/screen-api/src/main/java/com/moral/api/service/impl/ProfessionServiceImpl.java
@@ -13,12 +13,8 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.OptionalDouble;
 import java.util.Set;
-import java.util.function.Supplier;
 import java.util.stream.Collectors;
-import java.util.stream.DoubleStream;
-import java.util.stream.Stream;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -31,6 +27,7 @@
 import com.moral.api.entity.HistoryMonthly;
 import com.moral.api.entity.Organization;
 import com.moral.api.entity.Sensor;
+import com.moral.api.entity.SysDictData;
 import com.moral.api.service.CityAqiDailyService;
 import com.moral.api.service.CityAqiMonthlyService;
 import com.moral.api.service.CityAqiService;
@@ -41,6 +38,7 @@
 import com.moral.api.service.OrganizationService;
 import com.moral.api.service.ProfessionService;
 
+import com.moral.api.service.SensorService;
 import com.moral.constant.Constants;
 import com.moral.constant.RedisConstants;
 
@@ -84,6 +82,9 @@
 
     @Autowired
     private OrganizationService organizationService;
+
+    @Autowired
+    private SensorService sensorService;
 
     private static Map<String, String> senorMap = new HashMap<>();
 
@@ -183,7 +184,7 @@
         Integer locationLevelCode = organizationService.getOne(organizationQueryWrapper).getLocationLevelCode();
 
         //���������������������������
-        List allMacs = getMacsByOrgId(orgId);
+        List<String> allMacs = deviceService.getMacsByOrganizationId(orgId);
 
         List<String> timeLag = DateUtils.getTimeLag(time);
 
@@ -217,15 +218,7 @@
             Double allDeviceSum = null;
             List<HistoryMonthly> historyMonthlyList = allDeviceDataMap.get(yearMonth);
             if (!ObjectUtils.isEmpty(historyMonthlyList)) {
-                allDeviceSum = historyMonthlyList.stream().flatMapToDouble(v -> {
-                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
-                    Object o = dataValue.get(sensorCode);
-                    if (o == null) {
-                        return null;
-                    }
-                    double aDouble = Double.parseDouble(o.toString());
-                    return DoubleStream.of(aDouble);
-                }).sum();
+                allDeviceSum = historyMonthlyService.calculatedValue(historyMonthlyList, sensorCode, "sum");
             }
             resultMap.put("allDeviceSum", allDeviceSum);
 
@@ -234,9 +227,10 @@
             Double cityValue = null;
             if (cityAqiMap.get(yearMonth) != null) {
                 Map<String, Object> dataValue = JSONObject.parseObject(cityAqiMap.get(yearMonth).toString(), Map.class);
-                Object o = dataValue.get(sensorCode);
-                if (o != null) {
-                    cityValue = (Double) o;
+                //������������aqi������������������������
+                String sensorName = senorMap.get(sensorCode);
+                if (sensorName != null) {
+                    cityValue = (Double) dataValue.get(sensorName);
                 }
             }
             resultMap.put("cityValue", cityValue);
@@ -244,6 +238,18 @@
         }
 
         for (String profession : professions) {
+            //������������������
+            String professionName = null;
+            Map<String, Object> dictData = (Map<String, Object>) redisTemplate.opsForValue().get(RedisConstants.DICT_DATA_KEY);
+            List<SysDictData> professionInfo = (List<SysDictData>) dictData.get("profession");
+            for (SysDictData sysDictData : professionInfo) {
+                if (sysDictData.getDataKey().equals(profession)) {
+                    professionName = sysDictData.getDataValue();
+                    break;
+                }
+            }
+
+
             //���������������������
             List<Device> professionDevices = getDevicesOfProfessions(orgId, Collections.singletonList(profession));
             List<String> professionMacs = professionDevices.stream().map(Device::getMac).collect(Collectors.toList());
@@ -264,9 +270,10 @@
                 String contributionRate = null;
                 Double professionAvg = null;
                 if (!ObjectUtils.isEmpty(historyMonthlyList)) {
-                    Supplier<Stream<HistoryMonthly>> streamSupplier = historyMonthlyList::stream;
-                    professionAvg = calculatedValueOfYear(streamSupplier, sensorCode, "avg");
-                    Double professionSum = calculatedValueOfYear(streamSupplier, sensorCode, "sum");
+                    //���������������������
+                    professionAvg = historyMonthlyService.calculatedValue(historyMonthlyList, sensorCode, "avg");
+                    //������������������������
+                    Double professionSum = historyMonthlyService.calculatedValue(historyMonthlyList, sensorCode, "sum");
                     //���������������������
                     NumberFormat numberFormat = NumberFormat.getInstance();
                     numberFormat.setMaximumFractionDigits(2);
@@ -277,7 +284,7 @@
                 Map<String, Object> professionMap = new HashMap<>();
                 professionMap.put("contributionRate", contributionRate);
                 professionMap.put("value", professionAvg == null ? null : AmendUtils.sciCal(professionAvg, 0));
-                map.put(profession, professionMap);
+                map.put(professionName, professionMap);
             }
         }
         result.forEach(map -> map.remove("allDeviceSum"));
@@ -295,7 +302,7 @@
         Integer locationLevelCode = organizationService.getOne(organizationQueryWrapper).getLocationLevelCode();
 
         //���������������������������
-        List allMacs = getMacsByOrgId(orgId);
+        List<String> allMacs = deviceService.getMacsByOrganizationId(orgId);
 
         //������������
         List<String> timeLag = DateUtils.getTimeLag(time);
@@ -330,15 +337,7 @@
             Double allDeviceSum = null;
             List<HistoryDaily> historyDailyList = allDeviceDataMap.get(yearMonthDay);
             if (!ObjectUtils.isEmpty(historyDailyList)) {
-                allDeviceSum = historyDailyList.stream().flatMapToDouble(v -> {
-                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
-                    Object o = dataValue.get(sensorCode);
-                    if (o == null) {
-                        return null;
-                    }
-                    double aDouble = Double.parseDouble(o.toString());
-                    return DoubleStream.of(aDouble);
-                }).sum();
+                allDeviceSum = historyDailyService.calculatedValue(historyDailyList, sensorCode, "sum");
             }
             resultMap.put("allDeviceSum", allDeviceSum);
 
@@ -347,9 +346,10 @@
             Double cityValue = null;
             if (cityAqiMap.get(yearMonthDay) != null) {
                 Map<String, Object> dataValue = JSONObject.parseObject(cityAqiMap.get(yearMonthDay).toString(), Map.class);
-                Object o = dataValue.get(sensorCode);
-                if (o != null) {
-                    cityValue = (Double) o;
+                //������������aqi������������������������
+                String sensorName = senorMap.get(sensorCode);
+                if (sensorName != null) {
+                    cityValue = (Double) dataValue.get(sensorName);
                 }
             }
             resultMap.put("cityValue", cityValue);
@@ -357,6 +357,16 @@
         }
 
         for (String profession : professions) {
+            String professionName = null;
+            Map<String, Object> dictData = (Map<String, Object>) redisTemplate.opsForValue().get(RedisConstants.DICT_DATA_KEY);
+            List<SysDictData> professionInfo = (List<SysDictData>) dictData.get("profession");
+            for (SysDictData sysDictData : professionInfo) {
+                if (sysDictData.getDataKey().equals(profession)) {
+                    professionName = sysDictData.getDataValue();
+                    break;
+                }
+            }
+
             //���������������������
             List<Device> professionDevices = getDevicesOfProfessions(orgId, Collections.singletonList(profession));
             List<String> professionMacs = professionDevices.stream().map(Device::getMac).collect(Collectors.toList());
@@ -377,9 +387,10 @@
                 String contributionRate = null;
                 Double professionAvg = null;
                 if (!ObjectUtils.isEmpty(historyDailyList)) {
-                    Supplier<Stream<HistoryDaily>> streamSupplier = historyDailyList::stream;
-                    professionAvg = calculatedValueOfMonth(streamSupplier, sensorCode, "avg");
-                    Double professionSum = calculatedValueOfMonth(streamSupplier, sensorCode, "sum");
+                    //���������������������
+                    professionAvg = historyDailyService.calculatedValue(historyDailyList, sensorCode, "avg");
+                    //������������������������
+                    Double professionSum = historyDailyService.calculatedValue(historyDailyList, sensorCode, "sum");
                     //���������������������
                     NumberFormat numberFormat = NumberFormat.getInstance();
                     numberFormat.setMaximumFractionDigits(2);
@@ -390,7 +401,7 @@
                 Map<String, Object> professionMap = new HashMap<>();
                 professionMap.put("contributionRate", contributionRate);
                 professionMap.put("value", professionAvg == null ? null : AmendUtils.sciCal(professionAvg, 0));
-                map.put(profession, professionMap);
+                map.put(professionName, professionMap);
             }
         }
         result.forEach(map -> map.remove("allDeviceSum"));
@@ -406,8 +417,15 @@
                 .eq("id", orgId);
         Integer locationLevelCode = organizationService.getOne(organizationQueryWrapper).getLocationLevelCode();
 
+        //���������������������
+        QueryWrapper<Sensor> sensorQueryWrapper = new QueryWrapper<>();
+        sensorQueryWrapper.select("lower", "upper").eq("code", sensorCode);
+        Sensor sensor = sensorService.getOne(sensorQueryWrapper);
+        Double sensorLower = sensor.getLower();
+        Double sensorUpper = sensor.getUpper();
+
         //���������������������������
-        List allMacs = getMacsByOrgId(orgId);
+        List<String> allMacs = deviceService.getMacsByOrganizationId(orgId);
 
         //���������������
         List<String> timeLag = DateUtils.getTimeLag(time);
@@ -443,15 +461,7 @@
             Double allDeviceSum = null;
             List<HistoryHourly> historyHourlyList = allDeviceDataMap.get(yearMonthDayHour);
             if (!ObjectUtils.isEmpty(historyHourlyList)) {
-                allDeviceSum = historyHourlyList.stream().flatMapToDouble(v -> {
-                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
-                    Object o = dataValue.get(sensorCode);
-                    if (o == null) {
-                        return null;
-                    }
-                    double aDouble = Double.parseDouble(o.toString());
-                    return DoubleStream.of(aDouble);
-                }).sum();
+                allDeviceSum = historyHourlyService.calculatedValue(historyHourlyList, sensorCode, "sum", sensorLower, sensorUpper);
             }
             resultMap.put("allDeviceSum", allDeviceSum);
 
@@ -460,9 +470,10 @@
             Double cityValue = null;
             if (cityAqiMap.get(yearMonthDayHour) != null) {
                 Map<String, Object> dataValue = JSONObject.parseObject(cityAqiMap.get(yearMonthDayHour).toString(), Map.class);
-                Object o = dataValue.get(sensorCode);
-                if (o != null) {
-                    cityValue = (Double) o;
+                //������������aqi������������������������
+                String sensorName = senorMap.get(sensorCode);
+                if (sensorName != null) {
+                    cityValue = (Double) dataValue.get(sensorName);
                 }
             }
             resultMap.put("cityValue", cityValue);
@@ -470,6 +481,16 @@
         }
 
         for (String profession : professions) {
+            String professionName = null;
+            Map<String, Object> dictData = (Map<String, Object>) redisTemplate.opsForValue().get(RedisConstants.DICT_DATA_KEY);
+            List<SysDictData> professionInfo = (List<SysDictData>) dictData.get("profession");
+            for (SysDictData sysDictData : professionInfo) {
+                if (sysDictData.getDataKey().equals(profession)) {
+                    professionName = sysDictData.getDataValue();
+                    break;
+                }
+            }
+
             //���������������������
             List<Device> professionDevices = getDevicesOfProfessions(orgId, Collections.singletonList(profession));
             List<String> professionMacs = professionDevices.stream().map(Device::getMac).collect(Collectors.toList());
@@ -490,9 +511,10 @@
                 String contributionRate = null;
                 Double professionAvg = null;
                 if (!ObjectUtils.isEmpty(historyHourlyList)) {
-                    Supplier<Stream<HistoryHourly>> streamSupplier = historyHourlyList::stream;
-                    professionAvg = calculatedValueOfDay(streamSupplier, sensorCode, "avg");
-                    Double professionSum = calculatedValueOfDay(streamSupplier, sensorCode, "sum");
+                    //���������������������
+                    professionAvg = historyHourlyService.calculatedValue(historyHourlyList, sensorCode, "avg", sensorLower, sensorUpper);
+                    //������������������������
+                    Double professionSum = historyHourlyService.calculatedValue(historyHourlyList, sensorCode, "sum", sensorLower, sensorUpper);
                     //���������������������
                     NumberFormat numberFormat = NumberFormat.getInstance();
                     numberFormat.setMaximumFractionDigits(2);
@@ -503,92 +525,10 @@
                 Map<String, Object> professionMap = new HashMap<>();
                 professionMap.put("contributionRate", contributionRate);
                 professionMap.put("value", professionAvg == null ? null : AmendUtils.sciCal(professionAvg, 0));
-                map.put(profession, professionMap);
+                map.put(professionName, professionMap);
             }
         }
         result.forEach(map -> map.remove("allDeviceSum"));
-        return result;
-    }
-
-    //������������id������������macs
-    private List getMacsByOrgId(Integer orgId) {
-        //���������������������������
-        QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
-        deviceQueryWrapper.select("mac")
-                .eq("organization_id", orgId)
-                .eq("is_delete", Constants.NOT_DELETE);
-        return deviceService.listObjs(deviceQueryWrapper);
-    }
-
-    //������������������������������
-    private Double calculatedValueOfDay(Supplier<Stream<HistoryHourly>> supplier, String sensorCode, String type) {
-        DoubleStream doubleStream = supplier.get()
-                .flatMapToDouble(v -> {
-                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
-                    Object sensorValue = dataValue.get(sensorCode);
-                    if (ObjectUtils.isEmpty(sensorValue)) {
-                        return null;
-                    }
-                    double aDouble = Double.parseDouble(sensorValue.toString());
-                    return DoubleStream.of(aDouble);
-                });
-        Double result = null;
-        if ("avg".equals(type)) {
-            OptionalDouble optionalDouble = doubleStream.average();
-            if (optionalDouble.isPresent()) {
-                result = optionalDouble.getAsDouble();
-            }
-        } else if ("sum".equals(type)) {
-            result = doubleStream.sum();
-        }
-        return result;
-    }
-
-    //������������������������������
-    private Double calculatedValueOfMonth(Supplier<Stream<HistoryDaily>> supplier, String sensorCode, String type) {
-        DoubleStream doubleStream = supplier.get()
-                .flatMapToDouble(v -> {
-                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
-                    Object sensorValue = dataValue.get(sensorCode);
-                    if (ObjectUtils.isEmpty(sensorValue)) {
-                        return null;
-                    }
-                    double aDouble = Double.parseDouble(sensorValue.toString());
-                    return DoubleStream.of(aDouble);
-                });
-        Double result = null;
-        if ("avg".equals(type)) {
-            OptionalDouble optionalDouble = doubleStream.average();
-            if (optionalDouble.isPresent()) {
-                result = optionalDouble.getAsDouble();
-            }
-        } else if ("sum".equals(type)) {
-            result = doubleStream.sum();
-        }
-        return result;
-    }
-
-    //������������������������������
-    private Double calculatedValueOfYear(Supplier<Stream<HistoryMonthly>> supplier, String sensorCode, String type) {
-        DoubleStream doubleStream = supplier.get()
-                .flatMapToDouble(v -> {
-                    Map<String, Object> dataValue = JSONObject.parseObject(v.getValue(), Map.class);
-                    Object sensorValue = dataValue.get(sensorCode);
-                    if (ObjectUtils.isEmpty(sensorValue)) {
-                        return null;
-                    }
-                    double aDouble = Double.parseDouble(sensorValue.toString());
-                    return DoubleStream.of(aDouble);
-                });
-        Double result = null;
-        if ("avg".equals(type)) {
-            OptionalDouble optionalDouble = doubleStream.average();
-            if (optionalDouble.isPresent()) {
-                result = optionalDouble.getAsDouble();
-            }
-        } else if ("sum".equals(type)) {
-            result = doubleStream.sum();
-        }
         return result;
     }
 }
diff --git a/screen-api/src/main/java/com/moral/api/service/impl/RegionServiceImpl.java b/screen-api/src/main/java/com/moral/api/service/impl/RegionServiceImpl.java
new file mode 100644
index 0000000..834b1d3
--- /dev/null
+++ b/screen-api/src/main/java/com/moral/api/service/impl/RegionServiceImpl.java
@@ -0,0 +1,498 @@
+package com.moral.api.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.moral.api.entity.CityAqi;
+import com.moral.api.entity.CityAqiDaily;
+import com.moral.api.entity.CityAqiMonthly;
+import com.moral.api.entity.Device;
+import com.moral.api.entity.HistoryDaily;
+import com.moral.api.entity.HistoryHourly;
+import com.moral.api.entity.HistoryMonthly;
+import com.moral.api.entity.Organization;
+import com.moral.api.entity.Sensor;
+import com.moral.api.entity.SysArea;
+import com.moral.api.service.CityAqiDailyService;
+import com.moral.api.service.CityAqiMonthlyService;
+import com.moral.api.service.CityAqiService;
+import com.moral.api.service.DeviceService;
+import com.moral.api.service.HistoryDailyService;
+import com.moral.api.service.HistoryHourlyService;
+import com.moral.api.service.HistoryMonthlyService;
+import com.moral.api.service.OrganizationService;
+import com.moral.api.service.RegionService;
+import com.moral.api.service.SensorService;
+import com.moral.api.service.SysAreaService;
+import com.moral.constant.Constants;
+import com.moral.constant.RedisConstants;
+import com.moral.util.AmendUtils;
+import com.moral.util.DateUtils;
+
+@Service
+public class RegionServiceImpl implements RegionService {
+
+    @Autowired
+    private DeviceService deviceService;
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    @Autowired
+    private OrganizationService organizationService;
+
+    @Autowired
+    private CityAqiMonthlyService cityAqiMonthlyService;
+
+    @Autowired
+    private CityAqiDailyService cityAqiDailyService;
+
+    @Autowired
+    private CityAqiService cityAqiService;
+
+    @Autowired
+    private HistoryMonthlyService historyMonthlyService;
+
+    @Autowired
+    private HistoryDailyService historyDailyService;
+
+    @Autowired
+    private HistoryHourlyService historyHourlyService;
+
+    @Autowired
+    private SysAreaService sysAreaService;
+
+    @Autowired
+    private SensorService sensorService;
+
+    private static Map<String, String> senorMap = new HashMap<>();
+
+    static {
+        senorMap.put(Constants.SENSOR_CODE_PM25, "PM2_5");
+        senorMap.put(Constants.SENSOR_CODE_PM10, "PM10");
+        senorMap.put(Constants.SENSOR_CODE_SO2, "SO2");
+        senorMap.put(Constants.SENSOR_CODE_NO2, "NO2");
+        senorMap.put(Constants.SENSOR_CODE_CO, "CO");
+        senorMap.put(Constants.SENSOR_CODE_O3, "O3");
+    }
+
+    @Override
+    public Set<Map<String, Object>> getRegionsByOrganizationId(Integer organizationId) {
+        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("mac")
+                .eq("organization_id", organizationId)
+                .eq("is_delete", Constants.NOT_DELETE);
+        List<Object> macs = deviceService.listObjs(queryWrapper);
+
+        List<Map<String, Object>> devices = new ArrayList<>();
+        //���redis������������
+        Map<String, Object> entries = redisTemplate.opsForHash().entries(RedisConstants.DEVICE);
+        entries.forEach((key, value) -> {
+            if (macs.contains(key)) {
+                devices.add((Map<String, Object>) value);
+            }
+        });
+        return devices.stream()
+                .map(device -> (Map<String, Object>) device.get("town"))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Set<Map<String, Object>> getSensorByRegionCodesAndOrganizationId(Map<String, Object> params) {
+        Set<Map<String, Object>> result = new HashSet<>();
+        Integer orgId = Integer.parseInt(params.get("organizationId").toString());
+        List<String> regionCodes = Arrays.asList(params.get("regionCodes").toString().split(","));
+        //������������������macs
+        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
+        queryWrapper.select("mac")
+                .eq("organization_id", orgId)
+                .eq("is_delete", Constants.NOT_DELETE)
+                .in("town_code", regionCodes);
+        List<Object> macs = deviceService.listObjs(queryWrapper);
+
+        //������������mac���������������������������
+        for (Object mac : macs) {
+            Device device = (Device) redisTemplate.opsForHash().get(RedisConstants.DEVICE_INFO, mac.toString());
+            List<Sensor> sensors = device.getVersion().getSensors();
+            sensors.forEach(sensor -> {
+                Map<String, Object> sensorMap = new HashMap<>();
+                sensorMap.put("sensorCode", sensor.getCode());
+                sensorMap.put("sensorName", sensor.getName());
+                result.add(sensorMap);
+            });
+        }
+        return result;
+    }
+
+    @Override
+    public List<Map<String, Object>> regionContribution(Map<String, Object> params) {
+        int orgId = Integer.parseInt(params.get("organizationId").toString());
+        List<String> regionCodes = Arrays.asList(params.get("regionCodes").toString().split(","));
+        String type = params.get("type").toString();
+        String time = params.get("time").toString();
+        String sensorCode = params.get("sensorCode").toString();
+        List<Map<String, Object>> result = new ArrayList<>();
+        switch (type) {
+            case "year":
+                result = regionContributionOfYear(orgId, regionCodes, time, sensorCode);
+                break;
+            case "month":
+                result = regionContributionOfMonth(orgId, regionCodes, time, sensorCode);
+                break;
+            case "day":
+                result = regionContributionOfDay(orgId, regionCodes, time, sensorCode);
+                break;
+            default:
+                break;
+        }
+        return result;
+    }
+
+    //���������������
+    private List<Map<String, Object>> regionContributionOfYear(Integer orgId, List<String> regionCodes, String time, String sensorCode) {
+        List<Map<String, Object>> result = new ArrayList<>();
+
+        //������������������������������
+        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
+        organizationQueryWrapper.select("location_level_code")
+                .eq("id", orgId);
+        Integer locationLevelCode = organizationService.getOne(organizationQueryWrapper).getLocationLevelCode();
+
+        //���������������������������
+        List<String> allMacs = deviceService.getMacsByOrganizationId(orgId);
+
+        List<String> timeLag = DateUtils.getTimeLag(time);
+
+        //���������������������������
+        QueryWrapper<CityAqiMonthly> cityAqiMonthlyQueryWrapper = new QueryWrapper<>();
+        cityAqiMonthlyQueryWrapper.select("time", "value")
+                .eq("city_code", locationLevelCode)
+                .likeRight("time", time);
+        List<Map<String, Object>> cityAqis = cityAqiMonthlyService.listMaps(cityAqiMonthlyQueryWrapper);
+        Map<String, Object> cityAqiMap = new HashMap<>();
+        if (!ObjectUtils.isEmpty(cityAqis)) {
+            for (Map<String, Object> cityAqi : cityAqis) {
+                cityAqiMap.put(cityAqi.get("time").toString().substring(0, 7), cityAqi.get("value"));
+            }
+        }
+
+
+        //���������������������������������
+        List<HistoryMonthly> allDeviceData = historyMonthlyService.getValueByMacs(allMacs, time);
+        //���time������
+        Map<String, List<HistoryMonthly>> allDeviceDataMap = allDeviceData.stream()
+                .collect(Collectors.groupingBy(o -> DateUtils.dateToDateString(o.getTime()).substring(0, 7)));
+
+
+        for (String yearMonth : timeLag) {
+            Map<String, Object> resultMap = new HashMap<>();
+            resultMap.put("time", yearMonth);
+
+
+            //������������������������������
+            Double allDeviceSum = null;
+            List<HistoryMonthly> historyMonthlyList = allDeviceDataMap.get(yearMonth);
+            if (!ObjectUtils.isEmpty(historyMonthlyList)) {
+                allDeviceSum = historyMonthlyService.calculatedValue(historyMonthlyList, sensorCode, "sum");
+            }
+            resultMap.put("allDeviceSum", allDeviceSum);
+
+
+            //���������
+            Double cityValue = null;
+            if (cityAqiMap.get(yearMonth) != null) {
+                Map<String, Object> dataValue = JSONObject.parseObject(cityAqiMap.get(yearMonth).toString(), Map.class);
+                //������������aqi������������������������
+                String sensorName = senorMap.get(sensorCode);
+                if (sensorName != null) {
+                    cityValue = (Double) dataValue.get(sensorName);
+                }
+            }
+            resultMap.put("cityValue", cityValue);
+            result.add(resultMap);
+        }
+
+        for (String regionCode : regionCodes) {
+            QueryWrapper<SysArea> queryWrapper = new QueryWrapper<>();
+            queryWrapper.select("area_name").eq("area_code", Integer.parseInt(regionCode));
+            String regionName = sysAreaService.getOne(queryWrapper).getAreaName();
+
+            //���������������������������������
+            List<String> regionMacs = deviceService.getMacsByOrgIdAndRegionCode(orgId, Integer.parseInt(regionCode));
+
+            //������������������������������������������
+            List<HistoryMonthly> regionDeviceData = historyMonthlyService.getValueByMacs(regionMacs, time);
+            //���time������
+            Map<String, List<HistoryMonthly>> regionDataMap = regionDeviceData.stream()
+                    .collect(Collectors.groupingBy(o -> DateUtils.dateToDateString(o.getTime()).substring(0, 7)));
+
+
+            for (Map<String, Object> map : result) {
+                Object allDeviceSum = map.get("allDeviceSum");
+                String resultTime = map.get("time").toString();
+                List<HistoryMonthly> historyMonthlyList = regionDataMap.get(resultTime);
+                //���������
+                String contributionRate = null;
+                Double regionAvg = null;
+                if (!ObjectUtils.isEmpty(historyMonthlyList)) {
+                    regionAvg = historyMonthlyService.calculatedValue(historyMonthlyList, sensorCode, "avg");
+                    Double regionSum = historyMonthlyService.calculatedValue(historyMonthlyList, sensorCode, "sum");
+                    //���������������������
+                    NumberFormat numberFormat = NumberFormat.getInstance();
+                    numberFormat.setMaximumFractionDigits(2);
+                    if (allDeviceSum != null) {
+                        contributionRate = numberFormat.format(regionSum / ((Double) allDeviceSum) * 100) + "%";
+                        System.out.println(regionSum + "===" + allDeviceSum);
+                    }
+                }
+                Map<String, Object> professionMap = new HashMap<>();
+                professionMap.put("contributionRate", contributionRate);
+                professionMap.put("value", regionAvg == null ? null : AmendUtils.sciCal(regionAvg, 0));
+                map.put(regionName, professionMap);
+            }
+        }
+        result.forEach(map -> map.remove("allDeviceSum"));
+        return result;
+    }
+
+    //���������������
+    private List<Map<String, Object>> regionContributionOfMonth(Integer orgId, List<String> regionCodes, String time, String sensorCode) {
+        List<Map<String, Object>> result = new ArrayList<>();
+
+        //������������������������������
+        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
+        organizationQueryWrapper.select("location_level_code")
+                .eq("id", orgId);
+        Integer locationLevelCode = organizationService.getOne(organizationQueryWrapper).getLocationLevelCode();
+
+        //���������������������������
+        List<String> allMacs = deviceService.getMacsByOrganizationId(orgId);
+
+        //������������
+        List<String> timeLag = DateUtils.getTimeLag(time);
+
+
+        //���������������������������
+        QueryWrapper<CityAqiDaily> cityAqiDailyQueryWrapper = new QueryWrapper<>();
+        cityAqiDailyQueryWrapper.select("time", "value")
+                .eq("city_code", locationLevelCode)
+                .likeRight("time", time);
+        List<Map<String, Object>> cityAqis = cityAqiDailyService.listMaps(cityAqiDailyQueryWrapper);
+        Map<String, Object> cityAqiMap = new HashMap<>();
+        if (!ObjectUtils.isEmpty(cityAqis)) {
+            for (Map<String, Object> cityAqi : cityAqis) {
+                cityAqiMap.put(cityAqi.get("time").toString().substring(0, 10), cityAqi.get("value"));
+            }
+        }
+
+
+        //���������������������������������
+        List<HistoryDaily> allDeviceData = historyDailyService.getValueByMacs(allMacs, time);
+        //���time������
+        Map<String, List<HistoryDaily>> allDeviceDataMap = allDeviceData.stream()
+                .collect(Collectors.groupingBy(o -> DateUtils.dateToDateString(o.getTime()).substring(0, 10)));
+
+
+        for (String yearMonthDay : timeLag) {
+            Map<String, Object> resultMap = new HashMap<>();
+            resultMap.put("time", yearMonthDay);
+
+            //������������������������������
+            Double allDeviceSum = null;
+            List<HistoryDaily> historyDailyList = allDeviceDataMap.get(yearMonthDay);
+            if (!ObjectUtils.isEmpty(historyDailyList)) {
+                allDeviceSum = historyDailyService.calculatedValue(historyDailyList, sensorCode, "sum");
+            }
+            resultMap.put("allDeviceSum", allDeviceSum);
+
+
+            //���������
+            Double cityValue = null;
+            if (cityAqiMap.get(yearMonthDay) != null) {
+                Map<String, Object> dataValue = JSONObject.parseObject(cityAqiMap.get(yearMonthDay).toString(), Map.class);
+                //������������aqi������������������������
+                String sensorName = senorMap.get(sensorCode);
+                if (sensorName != null) {
+                    cityValue = (Double) dataValue.get(sensorName);
+                }
+            }
+            resultMap.put("cityValue", cityValue);
+            result.add(resultMap);
+        }
+
+        for (String regionCode : regionCodes) {
+            QueryWrapper<SysArea> queryWrapper = new QueryWrapper<>();
+            queryWrapper.select("area_name").eq("area_code", Integer.parseInt(regionCode));
+            String regionName = sysAreaService.getOne(queryWrapper).getAreaName();
+
+            //���������������������������������
+            List<String> regionMacs = deviceService.getMacsByOrgIdAndRegionCode(orgId, Integer.parseInt(regionCode));
+
+
+            //������������������������������������
+            List<HistoryDaily> professionDeviceData = historyDailyService.getValueByMacs(regionMacs, time);
+            //���time������
+            Map<String, List<HistoryDaily>> professionDataMap = professionDeviceData.stream()
+                    .collect(Collectors.groupingBy(o -> DateUtils.dateToDateString(o.getTime()).substring(0, 10)));
+
+
+            for (Map<String, Object> map : result) {
+                Object allDeviceSum = map.get("allDeviceSum");
+                String resultTime = map.get("time").toString();
+                List<HistoryDaily> historyDailyList = professionDataMap.get(resultTime);
+                //���������
+                String contributionRate = null;
+                Double regionAvg = null;
+                if (!ObjectUtils.isEmpty(historyDailyList)) {
+                    //���������������������
+                    regionAvg = historyDailyService.calculatedValue(historyDailyList, sensorCode, "avg");
+                    //������������������������
+                    Double regionSum = historyDailyService.calculatedValue(historyDailyList, sensorCode, "sum");
+                    //���������������������
+                    NumberFormat numberFormat = NumberFormat.getInstance();
+                    numberFormat.setMaximumFractionDigits(2);
+                    if (allDeviceSum != null) {
+                        contributionRate = numberFormat.format(regionSum / ((Double) allDeviceSum) * 100) + "%";
+                    }
+                }
+                Map<String, Object> professionMap = new HashMap<>();
+                professionMap.put("contributionRate", contributionRate);
+                professionMap.put("value", regionAvg == null ? null : AmendUtils.sciCal(regionAvg, 0));
+                map.put(regionName, professionMap);
+            }
+        }
+        result.forEach(map -> map.remove("allDeviceSum"));
+        return result;
+    }
+
+    private List<Map<String, Object>> regionContributionOfDay(Integer orgId, List<String> regionCodes, String time, String sensorCode) {
+        List<Map<String, Object>> result = new ArrayList<>();
+
+        //������������������������������
+        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
+        organizationQueryWrapper.select("location_level_code")
+                .eq("id", orgId);
+        Integer locationLevelCode = organizationService.getOne(organizationQueryWrapper).getLocationLevelCode();
+
+        //���������������������
+        QueryWrapper<Sensor> sensorQueryWrapper = new QueryWrapper<>();
+        sensorQueryWrapper.select("lower", "upper").eq("code", sensorCode);
+        Sensor sensor = sensorService.getOne(sensorQueryWrapper);
+        Double sensorLower = sensor.getLower();
+        Double sensorUpper = sensor.getUpper();
+
+        //���������������������������
+        List<String> allMacs = deviceService.getMacsByOrganizationId(orgId);
+
+        //���������������
+        List<String> timeLag = DateUtils.getTimeLag(time);
+
+
+        //������������������������������
+        QueryWrapper<CityAqi> cityAqiQueryWrapper = new QueryWrapper<>();
+        cityAqiQueryWrapper.select("time", "value")
+                .eq("city_code", locationLevelCode)
+                .likeRight("time", time);
+        List<Map<String, Object>> cityAqis = cityAqiService.listMaps(cityAqiQueryWrapper);
+        Map<String, Object> cityAqiMap = new HashMap<>();
+        if (!ObjectUtils.isEmpty(cityAqis)) {
+            for (Map<String, Object> cityAqi : cityAqis) {
+                cityAqiMap.put(cityAqi.get("time").toString().substring(0, 13), cityAqi.get("value"));
+            }
+        }
+
+
+        //������������������������������������
+        List<HistoryHourly> allDeviceData = historyHourlyService.getValueByMacs(allMacs, time);
+        //���time������
+        Map<String, List<HistoryHourly>> allDeviceDataMap = allDeviceData.stream()
+                .collect(Collectors.groupingBy(o -> DateUtils.dateToDateString(o.getTime()).substring(0, 13)));
+
+
+        for (String yearMonthDayHour : timeLag) {
+            Map<String, Object> resultMap = new HashMap<>();
+            resultMap.put("time", yearMonthDayHour);
+
+
+            //������������������������������
+            Double allDeviceSum = null;
+            List<HistoryHourly> historyHourlyList = allDeviceDataMap.get(yearMonthDayHour);
+            if (!ObjectUtils.isEmpty(historyHourlyList)) {
+                allDeviceSum = historyHourlyService.calculatedValue(historyHourlyList, sensorCode, "sum", sensorLower, sensorUpper);
+            }
+            resultMap.put("allDeviceSum", allDeviceSum);
+
+
+            //���������
+            Double cityValue = null;
+            if (cityAqiMap.get(yearMonthDayHour) != null) {
+                Map<String, Object> dataValue = JSONObject.parseObject(cityAqiMap.get(yearMonthDayHour).toString(), Map.class);
+                //������������aqi������������������������
+                String sensorName = senorMap.get(sensorCode);
+                if (sensorName != null) {
+                    cityValue = Double.parseDouble(dataValue.get(sensorName).toString());
+                }
+            }
+            resultMap.put("cityValue", cityValue);
+            result.add(resultMap);
+        }
+
+        for (String regionCode : regionCodes) {
+            QueryWrapper<SysArea> queryWrapper = new QueryWrapper<>();
+            queryWrapper.select("area_name").eq("area_code", Integer.parseInt(regionCode));
+            String regionName = sysAreaService.getOne(queryWrapper).getAreaName();
+
+            //���������������������������������
+            List<String> regionMacs = deviceService.getMacsByOrgIdAndRegionCode(orgId, Integer.parseInt(regionCode));
+
+
+            //���������������������������������������
+            List<HistoryHourly> professionDeviceData = historyHourlyService.getValueByMacs(regionMacs, time);
+            //���time������
+            Map<String, List<HistoryHourly>> professionDataMap = professionDeviceData.stream()
+                    .collect(Collectors.groupingBy(o -> DateUtils.dateToDateString(o.getTime()).substring(0, 13)));
+
+
+            for (Map<String, Object> map : result) {
+                Object allDeviceSum = map.get("allDeviceSum");
+                String resultTime = map.get("time").toString();
+                List<HistoryHourly> historyHourlyList = professionDataMap.get(resultTime);
+                //���������
+                String contributionRate = null;
+                Double regionAvg = null;
+                if (!ObjectUtils.isEmpty(historyHourlyList)) {
+                    //���������������������
+                    regionAvg = historyHourlyService.calculatedValue(historyHourlyList, sensorCode, "avg", sensorLower, sensorUpper);
+                    //������������������������
+                    Double regionSum = historyHourlyService.calculatedValue(historyHourlyList, sensorCode, "sum", sensorLower, sensorUpper);
+                    //���������������������
+                    NumberFormat numberFormat = NumberFormat.getInstance();
+                    numberFormat.setMaximumFractionDigits(2);
+                    if (allDeviceSum != null) {
+                        contributionRate = numberFormat.format(regionSum / ((Double) allDeviceSum) * 100) + "%";
+                    }
+                }
+                Map<String, Object> professionMap = new HashMap<>();
+                professionMap.put("contributionRate", contributionRate);
+                professionMap.put("value", regionAvg == null ? null : AmendUtils.sciCal(regionAvg, 0));
+                map.put(regionName, professionMap);
+            }
+        }
+        result.forEach(map -> map.remove("allDeviceSum"));
+        return result;
+    }
+}
diff --git a/screen-job/src/main/java/com/moral/api/service/impl/CityAqiServiceImpl.java b/screen-job/src/main/java/com/moral/api/service/impl/CityAqiServiceImpl.java
index 9cfadbd..2e88c31 100644
--- a/screen-job/src/main/java/com/moral/api/service/impl/CityAqiServiceImpl.java
+++ b/screen-job/src/main/java/com/moral/api/service/impl/CityAqiServiceImpl.java
@@ -61,7 +61,7 @@
         //������������������time������������������
         Date dataTime = DateUtils.addHours(time, -1);
         Date start = null;
-        if (DateUtils.getHour(time) >= 8) {
+        if (DateUtils.getHour(time) >= 8 || DateUtils.getHour(time) == 0) {
             start = DateUtils.addHours(time, -8);
         }
 
@@ -112,7 +112,7 @@
                 params.put("value", JSONObject.toJSONString(aqi));
                 cityAqis.add(params);
                 if (cityAqis.size() >= 6) {
-                    OptionalDouble average = cityAqis.parallelStream().flatMapToDouble(v -> {
+                    OptionalDouble average = cityAqis.stream().flatMapToDouble(v -> {
                         Map<String, Object> dataValue = JSONObject.parseObject((String) v.get("value"), Map.class);
                         double o3 = Double.parseDouble(dataValue.get("O3").toString());
                         return DoubleStream.of(o3);

--
Gitblit v1.8.0