liuxiaolong
2019-11-02 bcffe049acc4d80b21d923f5c002496c280d5668
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
package com.cloud.count.service.serviceImpl;
 
import com.cloud.count.dao.CountDao;
import com.cloud.count.model.Config;
import com.cloud.count.model.People;
import com.cloud.count.service.CountService;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
@Service
public class CountServiceImpl implements CountService{
    /**
     * 进校人数比较基准值
     */
    public static volatile int baseEnters = 0;
    /**
     * 出校人数比较基准值
     */
    public static volatile int baseExits = 0;
    /**
     * 当前报文记录的累积进校人数
     */
    public static volatile int totalEnters = 0;
    /**
     * 当前报文记录的累积出校人数
     */
    public static volatile int totalExits = 0;
    /**
     * 统计设备可统计的最大数量
     */
    private static final int MAXCOUNT = 65535;
    /**
     * 统计设备单词可统计的最大数量
     */
    private static final int MAXCOUNTONCE = 100;
    /**
     * 计算的进入中间变量
     */
    private static volatile int tmpEnter = 0;
    private static volatile int tmpExit = 0;
    /**
     * 实时计算时作为计算的进校人数基准值
     */
    public static volatile int realtimeBaseEnters = 0;
    /**
     * 实时计算时作为计算的出校人数基准值
     */
    public static volatile int realtimebBaseExits = 0;
    /**
     * 误差数字(统计设备在放学时间重启,则进入人数小于出校人数,导致会出现负数的可能)
     */
    public static  volatile  int errorCount = 0;
 
    private static String[] time={"00","01","02","03","04","05",
            "06","07","08","09","10","11",
            "12","13","14","15","16","17",
            "18","19","20","21","22","23",
    };
    private static String[] time2={"00","05","10","15","20","25",
            "30","35","40","45","50","55"};
    public static volatile  int countType = 0;
 
    private static Map<Integer,Integer> dayAllMap = new HashMap<>();
    private static Map<Integer,Integer> dayOutMap = new HashMap<>();
    private static Map<Integer,Integer> dayInMap = new HashMap<>();
 
    public static int addEnter(int count) {
        int inCre = 0;
        if(tmpEnter <= count){
            inCre = count - tmpEnter;
        } else {
            if(tmpEnter >= (MAXCOUNT-MAXCOUNTONCE) && count <= MAXCOUNT) {
                inCre = count + MAXCOUNT - tmpEnter;
            }
        }
        tmpEnter = count;
        return inCre;
    }
 
    public static int addExit(int count) {
        int inCre = 0;
        if(tmpExit <= count){
            inCre = count - tmpExit;
        } else {
            if(tmpExit >= (MAXCOUNT-MAXCOUNTONCE) && count <= MAXCOUNT) {
                inCre = count + MAXCOUNT - tmpExit;
            }
        }
        tmpExit = count;
        return inCre;
    }
 
    /**
     * 统计参数初始化,用于统计设备重启情况(发送的第一条报文)
     */
    public static void initCountArgs(People people){
        baseEnters = 0;
        baseExits = 0;
        totalEnters = people.getEnters();
        totalExits = people.getExits();
        realtimeBaseEnters = 0;
        realtimebBaseExits = 0;
    }
 
    @Autowired
    private CountDao dao;
    /**
     * 查询页面所需数据,包括
     * 1.时间段内的进校人数 进校人数= 实际进校人数+校正值
     * 2.时间段内的出校人数
     * 3.校内人数 校内人数=进校人数-出校人数+初始值
     * 4.此时的进校人数
     * 5.此时的出校人数
     * 6.按小时统计 校内人数
     *
     * @return
     */
    @Override
    public Map<String, Object> getData() throws ParseException {
        Map<String,Object> map = new HashMap<>(16);
        // 获取一些初始值
        Config config = dao.getConfig();
        if(config==null) {
            config = new Config();
            config.setCor(1);
            config.setPassword("123456");
            config.setCountStartTime("06:00");
            config.setInit(1);
            config.setInitialPeople(60);
            config.setInitialTime("00:00");
        }
        // 初始人数值
        int initialPeople = (config.getInit()==1)?config.getInitialPeople():0;
        // 校正人数值
        int correctionPeople =(config.getCor()==1)?config.getCorrectionPeople():0;
        // 初始时间
        String initialTime = (config.getInit()==1)?config.getInitialTime():config.getCountStartTime();
 
        long now =(long)System.currentTimeMillis()/1000;
        // 今天的字符表示 "2018-12-20 "(有一个空格)
        String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date())+" ";
        // 默认开始计算时间
        long set = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(today+config.getCountStartTime()).getTime()/1000;
        // 获取设定初始值的初始时间
        long start = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(today+initialTime).getTime()/1000;
 
        if (now>start-1 && now<start+11){//表示从设置的初始化时间开始重新计数
           baseEnters = totalEnters;
           baseExits = totalExits;
 
           dayAllMap = new HashMap<>();
           dayInMap = new HashMap<>();
           dayOutMap = new HashMap<>();
       }
 
        // 从开始计算时间到现在的进校数
        //进校人数 = 当前报文totalEnters - 基准进校人数 + 校正值
        int inPeople = totalEnters - baseEnters + correctionPeople + initialPeople;
 
        int outPeople = totalExits - baseExits;
 
        // 校内总人数 = 进校人数 - 出校人数 + 校内初始化人数 + 误差数量
        int allPeople = inPeople - outPeople;
 
        // 现在离开始统计的时间的小时数 7个多小时 按7个小时算
        //int hour = (int)(Math.abs(now-set)+3599)/3600;
        int minute = (int)(Math.abs(now-set)+1799)/1800;
        int[] people = new int[minute];
        String[] time_set = new String[minute];
        // 开始统计时间 分开 如06:40
        String[] times = config.getCountStartTime().split(":");
        // 初始设置时间分开
        String[] times2 = initialTime.split(":");//初始化时间06:00
        // 设置时间图表的项
        int charat = Integer.parseInt(times[0]);//统计开始时间06:00
        int mm =Integer.parseInt(times2[0])-charat;//分钟是00
        // 设置时间图表的项,比如图表的开始统计时间为06:40,则time_set就是[06:40,07:40,08:40,09:40,10:40,11:40,12:40,]
        for(int i=0;i<minute;i++){
            //time_set[i]=time[charat]+":"+times[1];
           // charat = (charat+1)%24;
            time_set[i]=  new SimpleDateFormat("HH:mm").format( new Date((set+1800L*i)*1000L) );
           // System.out.println(time_set[i]);
        }
        // 设置 数据表的项
        // 初始时间小时减去 图表开始时间小时  如果为负数,依次统计不受影响,如果为正数,比如说从6:30开始统计,现在是10:00,要求在7:00 把数据初始化
        // 但是只会统计7:30,则7:30统计的数据默认为初始人数,并且以后的从7:30开始统计
        long hourset = set;
        for(int i=0;i<minute;i++){
            if( (mm == i) && (countType==0) ){
                people[i]=initialPeople;
                set = hourset; //这行代码很重要,表示重新统计
            }else {
 
               // people[i] = dao.countInPeople(set-60,hourset+3599)- dao.countOutPeople(set-60,hourset+3599)+initialPeople+correctionPeople;
                //每次都实时计算,会重复计算历史数据
//                people[i] = getDataValue(map,countType,set-60,hourset+1799,initialPeople,correctionPeople);
                //采用缓存的方式,算过的就不再计算了
                if(countType == 1){
                    if(dayInMap.containsKey(i) && minute >1 && (i != minute-1)){
                        people[i] = dayInMap.get(i);
                    }else{
                        people[i] = getDataValue(map,countType,set-60,hourset+1799,initialPeople,correctionPeople);
                        dayInMap.put(i, people[i]);
                    }
                } else if(countType == 0) {
                    if(dayAllMap.containsKey(i) && minute >1 && (i != minute-1)){
                        people[i] = dayAllMap.get(i);
                    }else{
                        people[i] = getDataValue(map,countType,set-60,hourset+1799,initialPeople,correctionPeople);
                        dayAllMap.put(i, people[i]);
                    }
                } else {
                    if(dayOutMap.containsKey(i) && minute >1 && (i != minute-1)){
                        people[i] = dayOutMap.get(i);
                    }else{
                        people[i] = getDataValue(map,countType,set-60,hourset+1799,initialPeople,correctionPeople);
                        dayOutMap.put(i, people[i]);
                    }
                }
 
 
            }
            hourset +=1800;
        }
 
        map.put("dat_in",inPeople);
        map.put("dat_out",outPeople);
        map.put("dat_no",allPeople);
        map.put("dat_all",people);
        map.put("time_set",time_set);
        return map;
    }
 
    /**
     *  1代表算进  -1代表算出  0代表算总和
     * @param i
     * @return
     */
   private int getDataValue( Map<String, Object> map,int i,long start,long end,int initialPeople,int correctionPeople){
       String todayStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        switch (i){
            case 1:
                map.put("countType","进校人数");
                Integer countInPeople = dao.countInPeople(start, end, todayStr);
                countInPeople=countInPeople==null||countInPeople < 0? 0 : countInPeople;
                return countInPeople+correctionPeople;
            case -1:
                map.put("countType","出校人数");
                Integer countOutPeople = dao.countOutPeople(start, end, todayStr);
                return countOutPeople==null||countOutPeople < 0? 0 : countOutPeople;
            case 0:
                map.put("countType","校内人数");
                Integer in = dao.countInPeople(start, end, todayStr);
                Integer out = dao.countOutPeople(start, end, todayStr);
                in = in==null||in<0?0:in;
                out = out==null||out<0?0:out;
                return in-out+initialPeople+correctionPeople;
            default:
                map.put("countType","人数");
                return 0;
        }
 
 }
    /**
     * 统计开始时间到现在的进出入情况
     *
     * @param startdate
     * @return
     */
    @Override
    public Map<String, Object> getNowData(Date startdate) {
        Map<String,Object> map = new HashMap<>(16);
        int inPeopleNow = totalEnters - realtimeBaseEnters;
        int outPeopleNow = totalExits - realtimebBaseExits;
        map.put("inNow",inPeopleNow);
        map.put("outNow",outPeopleNow);
        return map;
    }
 
    @Override
    public void savePeople(People people) {
        dao.savePeople(people);
    }
 
    @Override
    public void updateConfigInfo(Config config) {
        Config old = getConfig();
        config.setPassword(old.getPassword());
        dao.updateConfig(config);
    }
    @Override
    public Config getConfig(){
       return dao.getConfig();
    }
 
    @Override
    public void countType(int countType) {
        CountServiceImpl.countType=countType;
    }
 
    @Override
    public void setOld() {
        baseEnters = totalEnters;
        baseExits = totalExits;
    }
 
    @Override
    public void updateConfigPassword(String password) {
        Config config = getConfig();
        config.setPassword(password);
        dao.updateConfig(config);
    }
 
    @Override
    public void updateConfig(Config config) {
        dao.updateConfig(config);
    }
}