Selaa lähdekoodia

Merge branch 'master' of http://10.1.235.20:3000/asiainfo/ebc

 Conflicts:
	security-protection-service/src/main/java/com/ai/bss/security/protection/service/impl/AiIdenLogManageServiceImpl.java
wangchao 4 vuotta sitten
vanhempi
commit
2e7f84cbf8
22 muutettua tiedostoa jossa 1205 lisäystä ja 495 poistoa
  1. 1 1
      ebc-middle-platform/src/assets/locals/zh-CN.json
  2. 15 3
      ebc-middle-platform/src/components/loginer.vue
  3. 26 4
      monitor-manage-service/src/main/java/com/ai/bss/monitorManage/model/AiIdenLogDto.java
  4. 404 266
      monitor-manage-service/src/main/java/com/ai/bss/monitorManage/service/impl/KafkaProcessImpl.java
  5. 15 12
      monitor-manage-service/src/main/resources/application.properties
  6. 7 0
      security-protection-platform/src/api/access/index.js
  7. 4 0
      security-protection-platform/src/api/dashboard/index.js
  8. 8 1
      security-protection-platform/src/api/usermana/index.js
  9. 3 9
      security-protection-platform/src/components/VideoPlayer/index.vue
  10. 96 32
      security-protection-platform/src/modules/access/index.vue
  11. 4 3
      security-protection-platform/src/modules/aialarm/index.vue
  12. 64 13
      security-protection-platform/src/modules/dashboard/index.vue
  13. 223 40
      security-protection-platform/src/modules/usermana/components/modal/addUser.vue
  14. 1 2
      security-protection-platform/src/modules/usermana/index.vue
  15. 154 81
      security-protection-platform/src/modules/videoSurveillance/index.vue
  16. 1 1
      security-protection-service/src/main/java/com/ai/bss/security/protection/controller/EmployeeManagementController.java
  17. 16 1
      security-protection-service/src/main/java/com/ai/bss/security/protection/controller/InAndOutRecordController.java
  18. 2 2
      security-protection-service/src/main/java/com/ai/bss/security/protection/controller/ResourceToolManageController.java
  19. 122 12
      security-protection-service/src/main/java/com/ai/bss/security/protection/service/impl/AiIdenLogManageServiceImpl.java
  20. 8 0
      security-protection-service/src/main/java/com/ai/bss/security/protection/service/interfaces/AiIdenLogManageService.java
  21. 1 1
      security-protection-service/src/main/java/com/ai/bss/security/protection/service/interfaces/ResourceToolManageService.java
  22. 30 11
      security-protection-service/src/main/java/com/ai/bss/security/protection/service/task/AiResultRecordKafkaTask.java

+ 1 - 1
ebc-middle-platform/src/assets/locals/zh-CN.json

@ -81,7 +81,7 @@
81 81
      "hello": "您好",
82 82
      "welcome": "欢迎登录",
83 83
      "system": "系统",
84
      "demo": "系统名称",
84
      "demo": "人员定位与搜救",
85 85
      "username": "用户名",
86 86
      "account": "账户名",
87 87
      "password": "密码",

+ 15 - 3
ebc-middle-platform/src/components/loginer.vue

@ -158,11 +158,23 @@ export default {
158 158
            this.$test
159 159
              .post(services.login.FIND_MENUS, {userCode: data.RESULT.CODE})
160 160
              .then((data) => {
161
162
                localStorage.setItem('menus',  JSON.stringify(data))
161
                var map = new Map()
162
                data.RESULT.forEach(e => {
163
                  if (e.ROOT_MENU){
164
                    map.set(e.ROOT_MENU[0].NAME,e.ROOT_MENU[0].ID)
165
                  }
166
                  map.set(e.NAME,e.ID)
167
                  if (e.menu_list) {
168
                    e.menu_list.forEach( m => {
169
                      map.set(m.NAME,m.ID)
170
                    })
171
                  }
172
                })
173
                debugger
174
                localStorage.setItem('menus',  JSON.stringify(map))
163 175
                store.dispatch(`permission/${GENERATE_ROUTES}`, roles)
176
                this.$router.push({ name: this.homeName })
164 177
              })
165
            this.$router.push({ name: this.homeName })
166 178
          }).catch((e) => {
167 179
            this.loging = false
168 180
            this.$Message.danger(e)

+ 26 - 4
monitor-manage-service/src/main/java/com/ai/bss/monitorManage/model/AiIdenLogDto.java

@ -2,9 +2,6 @@ package com.ai.bss.monitorManage.model;
2 2
3 3
import lombok.Data;
4 4
5
import java.util.ArrayList;
6
import java.util.List;
7
8 5
@Data
9 6
public class AiIdenLogDto {
10 7
    private static final long serialVersionUID = -1L;
@ -12,18 +9,37 @@ public class AiIdenLogDto {
12 9
     * AI任务标识
13 10
     */
14 11
    private Long aiTaskId;
12
    
13
    /**
14
     * 监控场景归属的组织编码
15
     */
16
    private String organizationId;
17
    
15 18
    /**
16 19
     * AI匹配模型
17 20
     */
18 21
    private String aiIdenModel;
22
    
23
    /**
24
     * 工作工具标识
25
     */
26
    private String resourceToolId;
27
    
19 28
    /**
20 29
     * 工作工具编号
21 30
     */
22 31
    private String resourceToolCode;
32
    
33
    /**
34
     * '工作工具名称
35
     */
36
    private String resourceToolName;
37
    
23 38
    /**
24 39
     * 任务执行时间
25 40
     */
26 41
    private String taskExecuteTime;
42
    
27 43
    /**
28 44
     * 识别结果类型:AI执行结果、考勤和违规记录
29 45
     */
@ -31,7 +47,8 @@ public class AiIdenLogDto {
31 47
    /**
32 48
     * 识别结果详情
33 49
     */
34
    private List<IdenResultDto> idenResult;
50
    //private List<IdenResultDto> idenResult;
51
    private String idenResult;
35 52
    /**
36 53
     * 识别图片抓拍时间
37 54
     */
@ -50,4 +67,9 @@ public class AiIdenLogDto {
50 67
     */
51 68
    private String topic;
52 69
70
    
71
    /**
72
     * 关联员工号
73
     */
74
    private String relateEmployeeRoleId;
53 75
}

+ 404 - 266
monitor-manage-service/src/main/java/com/ai/bss/monitorManage/service/impl/KafkaProcessImpl.java

@ -1,5 +1,22 @@
1 1
package com.ai.bss.monitorManage.service.impl;
2 2
3
import java.io.File;
4
import java.util.ArrayList;
5
import java.util.HashMap;
6
import java.util.List;
7
import java.util.Map;
8
9
import org.apache.commons.lang.StringUtils;
10
import org.apache.logging.log4j.util.Strings;
11
import org.springframework.beans.factory.annotation.Autowired;
12
import org.springframework.beans.factory.annotation.Value;
13
import org.springframework.kafka.core.KafkaTemplate;
14
import org.springframework.scheduling.annotation.Async;
15
import org.springframework.stereotype.Service;
16
import org.springframework.util.CollectionUtils;
17
import org.springframework.web.multipart.MultipartFile;
18
import org.springframework.web.multipart.commons.CommonsMultipartFile;
19
3 20
import com.ai.bss.components.common.util.ImageBase64Converter;
4 21
import com.ai.bss.components.ebcai.service.EbcAiService;
5 22
import com.ai.bss.monitorManage.constant.MonitorManageConsts;
@ -10,295 +27,416 @@ import com.ai.bss.monitorManage.service.interfaces.FileManageService;
10 27
import com.ai.bss.monitorManage.service.interfaces.KafkaProcess;
11 28
import com.ai.bss.monitorManage.utils.DateUtils;
12 29
import com.ai.bss.monitorManage.utils.FileUtils;
30
import com.ai.bss.monitorManage.utils.HttpServiceUtil;
13 31
import com.ai.bss.monitorManage.utils.KafkaProducerConfig;
14 32
import com.ai.bss.monitorManage.utils.SecurityProtectionMinioConfig;
33
import com.alibaba.fastjson.JSON;
15 34
import com.alibaba.fastjson.JSONArray;
16 35
import com.alibaba.fastjson.JSONObject;
17
import lombok.extern.slf4j.Slf4j;
18
import org.apache.logging.log4j.util.Strings;
19
import org.springframework.beans.factory.annotation.Autowired;
20
import org.springframework.beans.factory.annotation.Value;
21
import org.springframework.kafka.core.KafkaTemplate;
22
import org.springframework.scheduling.annotation.Async;
23
import org.springframework.stereotype.Service;
24
import org.springframework.web.multipart.MultipartFile;
25
import org.springframework.web.multipart.commons.CommonsMultipartFile;
26
27
import java.io.File;
28
import java.util.*;
29 36
37
import lombok.extern.slf4j.Slf4j;
30 38
31 39
@Slf4j
32 40
@Service
33 41
public class KafkaProcessImpl implements KafkaProcess {
34 42
//    EBC设备tcp连接服务地址
35
    private static final String HOST = "47.105.130.83";
36
    private static final int PORT = 8042;
43
	private static final String HOST = "47.105.130.83";
44
	private static final int PORT = 8042;
37 45
38 46
//    private static String kafkaServers = "47.105.160.21:9090";
39
    private static String kafkaServers = "10.19.90.34:9090";
40
41
    @Value("${kafka.producer.servers}")
42
    private static String servers;
47
	private static String kafkaServers = "10.19.90.34:9090";
43 48
49
	@Value("${kafka.producer.servers}")
50
	private static String servers;
44 51
45
    @Value("${camera.filePath}")
46
    private String baseFilePath;
52
	@Value("${camera.filePath}")
53
	private String baseFilePath;
47 54
48
    @Value("${kafka.topic.aitask}")
49
    private String topicAiTask;
55
	@Value("${kafka.topic.aitask}")
56
	private String topicAiTask;
50 57
51
    @Value("${kafka.topic.aivideo}")
52
    private String topicAiVideo;
58
	@Value("${kafka.topic.aivideo}")
59
	private String topicAiVideo;
53 60
54
    @Autowired
55
    private EbcAiService ebcAiService;
61
	@Value("${ebc.protection.resource-url}")
62
	private String protectionResourceUrl;
56 63
57
    @Autowired
58
    private SecurityProtectionMinioConfig minioConfig;
64
	@Autowired
65
	private EbcAiService ebcAiService;
59 66
67
	@Autowired
68
	private SecurityProtectionMinioConfig minioConfig;
60 69
61
    @Autowired
62
    private FileManageService fileManageService;
70
	@Autowired
71
	private FileManageService fileManageService;
63 72
64
    @Async
65
    @Override
66
    public void processKafka(String topic,List<String> msgList){
73
	@Async
74
	@Override
75
	public void processKafka(String topic, List<String> msgList) {
67 76
//        List<DataPoint> dataPointList =  parseDataPoint(mockScenarioDataList,topic0,topic1);
68
        try {
69
            for (String msg : msgList) {
70
                sendKafkaDataPoint(topic,msg);
71
            }
72
        }catch (Exception e){
73
            e.printStackTrace();
74
        }
75
    }
76
77
    @Async
78
    @Override
79
    public void processKafka(String topic,String msg){
80
        try {
81
            sendKafkaDataPoint(topic,msg);
82
        }catch (Exception e){
83
            e.printStackTrace();
84
        }
85
    }
86
87
88
    @Async
89
    @Override
90
    public void processImageFile(String fileKey,String filePath) throws Exception {
91
        Thread.sleep(3000);
92
        String deviceCode = "";
93
        String fileType = "";
94
        String fileName = "";
95
        String dateTime = "";
96
        String[] keyArr;
97
        MultipartFile multipartFile = null;
98
        Map<String, String> minioFileMap = null;
99
        AiIdenLogDto aiIdenLogDto = null;
100
        String time = "";
101
        String bucketName =  "";
102
        keyArr = fileKey.split("~!@");
103
        deviceCode = keyArr[0];
104
        fileType = keyArr[1];
105
106
        aiIdenLogDto = new AiIdenLogDto();
107
        fileName = filePath.substring(filePath.lastIndexOf(MonitorManageConsts.getSystemSeparator())+1,filePath.length());
108
        if(fileType.equals(MonitorManageConsts.FILE_TYPE_IMG)){
109
            bucketName = minioConfig.getBucketAiImage();
110
            time = fileName.substring(3,17);
111
            dateTime = DateUtils.formatDate(DateUtils.convertDate(time,DateUtils.PURE_DATETIMEHHMM_PATTERN),DateUtils.NORM_DATETIME_PATTERN);
112
            aiIdenLogDto.setTaskExecuteTime(DateUtils.getSysDateTime());
113
            aiIdenLogDto.setIdenPictureSnapDate(dateTime);
114
        }
115
        //文件上传到 minio文件服务器
116
        multipartFile = new CommonsMultipartFile(FileUtils.createFileItem(new File(filePath),fileName));
117
118
        log.info("保存图片文件");
119
        minioFileMap = fileManageService.uploadFile(multipartFile,bucketName,deviceCode,null);
120
121
        if(fileType.equals(MonitorManageConsts.FILE_TYPE_IMG)){
122
            aiIdenLogDto.setIdenVideoUrl("");
123
            aiIdenLogDto.setIdenPictureUrl(minioFileMap.get("fileId"));
124
            aiIdenLogDto.setResourceToolCode(deviceCode);
125
            //安全帽识别
126
            aiIdenLogDto.setTopic(topicAiTask);//AI识别TOPICs
127
128
            //人体识别
129
            boolean isHuman = aiworkHumanDetect(filePath);
130
            //AI头盔检查
131
            if(isHuman){
132
                aiIdenLogDto = aiHelmetDetect(aiIdenLogDto,filePath);
133
            }
134
        }
135
136
        log.info("-------等待任务--------");
137
    }
138
139
    @Async
140
    @Override
141
    public void processVideoFile(String fileKey,String filePath) throws Exception {
142
        Thread.sleep(70000);
143
        String deviceCode = "";
144
        String fileType = "";
145
        String fileName = "";
146
        String dateTime = "";
147
        String[] keyArr;
148
        MultipartFile multipartFile = null;
149
        Map<String, String> minioFileMap = null;
150
        MonitorVideoLogDto monitorVideoLogDto = null;
151
        String time = "";
152
        String bucketName =  "";
153
            keyArr = fileKey.split("~!@");
154
            deviceCode = keyArr[0];
155
            fileType = keyArr[1];
156
157
                monitorVideoLogDto = new MonitorVideoLogDto();
158
                fileName = filePath.substring(filePath.lastIndexOf(MonitorManageConsts.getSystemSeparator())+1,filePath.length());
159
                if(fileType.equals(MonitorManageConsts.FILE_TYPE_VIDEO)){
160
                    bucketName = minioConfig.getBucketAiVideo();
161
                    time = fileName.substring(5,19);
162
                    dateTime = DateUtils.formatDate(DateUtils.convertDate(time,DateUtils.PURE_DATETIME_PATTERN),DateUtils.NORM_DATETIME_HHMM_PATTERN);
163
                    monitorVideoLogDto.setBeginTime(dateTime + ":00");
164
                    monitorVideoLogDto.setEndTime(dateTime + ":59");
165
166
                }
167
                //文件上传到 minio文件服务器
168
                multipartFile = new CommonsMultipartFile(FileUtils.createFileItem(new File(filePath),fileName));
169
170
                log.info("保存文件");
171
                minioFileMap = fileManageService.uploadFile(multipartFile,bucketName,deviceCode,null);
172
173
                if(fileType.equals(MonitorManageConsts.FILE_TYPE_VIDEO)){
174
                    monitorVideoLogDto.setTopic(topicAiVideo);//视频历史记录TOPIC
175
                    monitorVideoLogDto.setVideoUrl(minioFileMap.get("fileId"));
176
                    monitorVideoLogDto.setResourceToolCode(deviceCode);
177
                    processKafka(monitorVideoLogDto.getTopic(), JSONObject.toJSONString(monitorVideoLogDto));
178
                }
179
        log.info("-------等待任务--------");
180
    }
181
182
    public static void main(String[] args) throws Exception {
183
        String filePath = MonitorManageConsts.getSystemSeparator() + "home"+MonitorManageConsts.getSystemSeparator()+"puaiuc"+MonitorManageConsts.getSystemSeparator()+"data"+MonitorManageConsts.getSystemSeparator()
184
                +"DAHUA"+MonitorManageConsts.getSystemSeparator()+"5A02296PAKA885B"+MonitorManageConsts.getSystemSeparator()+"videos"+MonitorManageConsts.getSystemSeparator()+"video20201219151941.mp4";
185
       String  fileName = filePath.substring(filePath.lastIndexOf(MonitorManageConsts.getSystemSeparator())+1,filePath.length());
186
        String time = fileName.substring(5,19);
187
        String dateTime = DateUtils.formatDate(DateUtils.convertDate(time,DateUtils.PURE_DATETIME_PATTERN),DateUtils.NORM_DATETIME_HHMM_PATTERN);
188
        System.out.println(dateTime);
189
    }
190
191
192
193
    private Map<String, KafkaTemplate> kafkaTemplateMap = new HashMap<>();
194
195
196
    private boolean sendKafkaDataPoint(String topic,String msgStr){
197
        KafkaTemplate kafkaTemplate = kafkaTemplateMap.get(kafkaServers);
198
        if(kafkaTemplate == null){
199
            //new 实例
200
            KafkaProducerConfig kafkaProducerConfig = new KafkaProducerConfig(kafkaServers);
201
            kafkaTemplate = kafkaProducerConfig.kafkaTemplate();
202
            kafkaTemplateMap.put(kafkaServers,kafkaTemplate);
203
        }
204
205
        try {
206
            Object result = kafkaTemplate.send(topic, msgStr).get();
207
            System.out.println("发送kafka消息:topic="+topic + "msg: "+msgStr);
208
        } catch (Exception e) {
209
            log.error(e.getMessage());
210
            return false;
211
        }
212
213
        return true;
214
    }
215
216
217
    /**
218
     * AI头盔检查
219
     * @param aiIdenLogDto
220
     * @return
221
     */
222
    private AiIdenLogDto aiHelmetDetect(AiIdenLogDto aiIdenLogDto,String aifilePath){
223
        try {
224
            log.info("开始AI处理...");
225
            //安全帽识别
226
            String aiResponseData = ebcAiService.helmetDetect(ImageBase64Converter.convertFileToBase64(aifilePath), Strings.EMPTY, Strings.EMPTY);
77
		try {
78
			for (String msg : msgList) {
79
				sendKafkaDataPoint(topic, msg);
80
			}
81
		} catch (Exception e) {
82
			e.printStackTrace();
83
		}
84
	}
85
86
	@Async
87
	@Override
88
	public void processKafka(String topic, String msg) {
89
		try {
90
			sendKafkaDataPoint(topic, msg);
91
		} catch (Exception e) {
92
			e.printStackTrace();
93
		}
94
	}
95
96
	@Async
97
	@Override
98
	public void processImageFile(String fileKey, String filePath) throws Exception {
99
		Thread.sleep(3000);
100
		String deviceCode = "";
101
		String fileType = "";
102
		String fileName = "";
103
		String dateTime = "";
104
		String[] keyArr;
105
		MultipartFile multipartFile = null;
106
		Map<String, String> minioFileMap = null;
107
		AiIdenLogDto aiIdenLogDto = null;
108
		String time = "";
109
		String bucketName = "";
110
		keyArr = fileKey.split("~!@");
111
		deviceCode = keyArr[0];
112
		fileType = keyArr[1];
113
114
		aiIdenLogDto = new AiIdenLogDto();
115
		fileName = filePath.substring(filePath.lastIndexOf(MonitorManageConsts.getSystemSeparator()) + 1,
116
				filePath.length());
117
		if (fileType.equals(MonitorManageConsts.FILE_TYPE_IMG)) {
118
			bucketName = minioConfig.getBucketAiImage();
119
			time = fileName.substring(3, 17);
120
			//dateTime = DateUtils.formatDate(DateUtils.convertDate(time, DateUtils.PURE_DATETIMEHHMM_PATTERN),
121
			//		DateUtils.NORM_DATETIME_PATTERN);
122
			// aiIdenLogDto.setTaskExecuteTime(DateUtils.getSysDateTime());
123
			dateTime = DateUtils.formatDate(DateUtils.convertDate(time, DateUtils.PURE_DATETIME_PATTERN),
124
					DateUtils.NORM_DATETIME_PATTERN);
125
			aiIdenLogDto.setTaskExecuteTime(StringUtils.isEmpty(dateTime) ? DateUtils.getSysDateTime() : dateTime);
126
			aiIdenLogDto.setIdenPictureSnapDate(dateTime);
127
		}
128
		// 文件上传到 minio文件服务器
129
		multipartFile = new CommonsMultipartFile(FileUtils.createFileItem(new File(filePath), fileName));
130
131
		log.info("保存图片文件");
132
		minioFileMap = fileManageService.uploadFile(multipartFile, bucketName, deviceCode, null);
133
134
		if (fileType.equals(MonitorManageConsts.FILE_TYPE_IMG)) {
135
			aiIdenLogDto.setIdenVideoUrl("");
136
			aiIdenLogDto.setIdenPictureUrl(minioFileMap.get("fileId"));
137
			aiIdenLogDto.setResourceToolCode(deviceCode);
138
139
			// 根据监控任务执行AI识别
140
			List<Map> resourceToolInfoList = getResourceToolAllInfo(deviceCode);
141
142
			for (Map resourceToolInfoMap : resourceToolInfoList) {
143
				if (resourceToolInfoMap.get("aiTaskId") != null && aiworkHumanDetect(filePath)) {
144
					String aiIdenModel = resourceToolInfoMap.get("aiIdenModel") == null ? ""
145
							: resourceToolInfoMap.get("aiIdenModel").toString();
146
147
					aiIdenLogDto.setAiTaskId(Long.valueOf(resourceToolInfoMap.get("aiTaskId").toString()));
148
					aiIdenLogDto.setAiIdenModel(aiIdenModel);
149
					aiIdenLogDto.setOrganizationId(resourceToolInfoMap.get("orgId") == null ? ""
150
							: resourceToolInfoMap.get("orgId").toString());
151
					aiIdenLogDto.setResourceToolId(resourceToolInfoMap.get("resourceToolId") == null ? ""
152
							: resourceToolInfoMap.get("resourceToolId").toString());
153
					aiIdenLogDto.setResourceToolName(resourceToolInfoMap.get("resourceToolName") == null ? ""
154
							: resourceToolInfoMap.get("resourceToolName").toString());
155
					aiIdenLogDto.setTopic(topicAiTask);
156
157
					if (MonitorManageConsts.AI_MODEL_FACE.equals(aiIdenModel)) {
158
						aiIdenLogDto = faceAiRecog(aiIdenLogDto, filePath);
159
160
					} else if (MonitorManageConsts.AI_MODEL_CLOTHING_CODE.equals(aiIdenModel)) {
161
						aiIdenLogDto = aiHelmetDetect(aiIdenLogDto, filePath);
162
163
					}
164
					/*else if (MonitorManageConsts.AI_MODEL_STRANGER.equals(aiIdenModel)) {
165
						
166
					} else {
167
						
168
					}*/
169
				}
170
			}
171
172
			/*// 安全帽识别
173
			aiIdenLogDto.setTopic(topicAiTask);// AI识别TOPICs
174
			
175
			// 人体识别
176
			boolean isHuman = aiworkHumanDetect(filePath);
177
			// AI头盔检查
178
			if (isHuman) {
179
				aiIdenLogDto = aiHelmetDetect(aiIdenLogDto, filePath);
180
			}*/
181
		}
182
183
		log.info("-------等待任务--------");
184
	}
185
186
	@Async
187
	@Override
188
	public void processVideoFile(String fileKey, String filePath) throws Exception {
189
		Thread.sleep(70000);
190
		String deviceCode = "";
191
		String fileType = "";
192
		String fileName = "";
193
		String dateTime = "";
194
		String[] keyArr;
195
		MultipartFile multipartFile = null;
196
		Map<String, String> minioFileMap = null;
197
		MonitorVideoLogDto monitorVideoLogDto = null;
198
		String time = "";
199
		String bucketName = "";
200
		keyArr = fileKey.split("~!@");
201
		deviceCode = keyArr[0];
202
		fileType = keyArr[1];
203
204
		monitorVideoLogDto = new MonitorVideoLogDto();
205
		fileName = filePath.substring(filePath.lastIndexOf(MonitorManageConsts.getSystemSeparator()) + 1,
206
				filePath.length());
207
		if (fileType.equals(MonitorManageConsts.FILE_TYPE_VIDEO)) {
208
			bucketName = minioConfig.getBucketAiVideo();
209
			time = fileName.substring(5, 19);
210
			dateTime = DateUtils.formatDate(DateUtils.convertDate(time, DateUtils.PURE_DATETIME_PATTERN),
211
					DateUtils.NORM_DATETIME_HHMM_PATTERN);
212
			monitorVideoLogDto.setBeginTime(dateTime + ":00");
213
			monitorVideoLogDto.setEndTime(dateTime + ":59");
214
215
		}
216
		// 文件上传到 minio文件服务器
217
		multipartFile = new CommonsMultipartFile(FileUtils.createFileItem(new File(filePath), fileName));
218
219
		log.info("保存文件");
220
		minioFileMap = fileManageService.uploadFile(multipartFile, bucketName, deviceCode, null);
221
222
		if (fileType.equals(MonitorManageConsts.FILE_TYPE_VIDEO)) {
223
			monitorVideoLogDto.setTopic(topicAiVideo);// 视频历史记录TOPIC
224
			monitorVideoLogDto.setVideoUrl(minioFileMap.get("fileId"));
225
			monitorVideoLogDto.setResourceToolCode(deviceCode);
226
			processKafka(monitorVideoLogDto.getTopic(), JSONObject.toJSONString(monitorVideoLogDto));
227
		}
228
		log.info("-------等待任务--------");
229
	}
230
231
	public static void main(String[] args) throws Exception {
232
		String filePath = MonitorManageConsts.getSystemSeparator() + "home" + MonitorManageConsts.getSystemSeparator()
233
				+ "puaiuc" + MonitorManageConsts.getSystemSeparator() + "data"
234
				+ MonitorManageConsts.getSystemSeparator() + "DAHUA" + MonitorManageConsts.getSystemSeparator()
235
				+ "5A02296PAKA885B" + MonitorManageConsts.getSystemSeparator() + "videos"
236
				+ MonitorManageConsts.getSystemSeparator() + "video20201219151941.mp4";
237
		String fileName = filePath.substring(filePath.lastIndexOf(MonitorManageConsts.getSystemSeparator()) + 1,
238
				filePath.length());
239
		String time = fileName.substring(5, 19);
240
		String dateTime = DateUtils.formatDate(DateUtils.convertDate(time, DateUtils.PURE_DATETIME_PATTERN),
241
				DateUtils.NORM_DATETIME_HHMM_PATTERN);
242
		System.out.println(dateTime);
243
	}
244
245
	private Map<String, KafkaTemplate> kafkaTemplateMap = new HashMap<>();
246
247
	private boolean sendKafkaDataPoint(String topic, String msgStr) {
248
		KafkaTemplate kafkaTemplate = kafkaTemplateMap.get(kafkaServers);
249
		if (kafkaTemplate == null) {
250
			// new 实例
251
			KafkaProducerConfig kafkaProducerConfig = new KafkaProducerConfig(kafkaServers);
252
			kafkaTemplate = kafkaProducerConfig.kafkaTemplate();
253
			kafkaTemplateMap.put(kafkaServers, kafkaTemplate);
254
		}
255
256
		try {
257
			Object result = kafkaTemplate.send(topic, msgStr).get();
258
			System.out.println("发送kafka消息:topic=" + topic + "msg: " + msgStr);
259
		} catch (Exception e) {
260
			log.error(e.getMessage());
261
			return false;
262
		}
263
264
		return true;
265
	}
266
267
	/**
268
	 * AI头盔检查
269
	 * @param aiIdenLogDto
270
	 * @return
271
	 */
272
	private AiIdenLogDto aiHelmetDetect(AiIdenLogDto aiIdenLogDto, String aifilePath) {
273
		try {
274
			log.info("开始AI处理...");
275
			// 安全帽识别
276
			String aiResponseData = ebcAiService.helmetDetect(ImageBase64Converter.convertFileToBase64(aifilePath),
277
					Strings.EMPTY, Strings.EMPTY);
227 278
//			String aiResponseData = ebcAiService.helmetDetect(ImageBase64Converter.convertInputStreamToBase64(multipartFile.getInputStream()), Strings.EMPTY, Strings.EMPTY);
228
            JSONObject jsonObject = JSONObject.parseObject(aiResponseData);// JSONUtil.formatJsonStr(aiResponseData);
229
            System.out.println("AI 识别结果: "+jsonObject);
230
            IdenResultDto idenResultDto = null;
231
            List<IdenResultDto> idenResultDtoList = null;
232
            if(jsonObject.getString("Status").equals("Ok")){
233
                idenResultDtoList = new ArrayList<>();
234
                JSONArray jsonoArray = JSONArray.parseArray(jsonObject.getString("Result"));
235
                if(jsonoArray.size()>0){
236
                    for(int i=0;i<jsonoArray.size();i++){
237
                        JSONObject resultObj = JSONObject.parseObject(jsonoArray.get(i).toString());
238
                        String aiClassName = resultObj.getString("class");
239
                        //										safety_hat表示安全帽;ordinart_hat表示普通帽子;chef_hat表示厨师帽;none表示未戴帽子
240
                        if(aiClassName.equals("none")){
241
                            idenResultDto =new IdenResultDto();
242
                            idenResultDto.setAlarmEmployeeRoleId(MonitorManageConsts.alarmEmployeeRoleId);
243
                            idenResultDto.setAlarmType(MonitorManageConsts.AI_ALARM_TYPE_WEA);
244
                            idenResultDto.setAlarmMemo("未戴帽子");
245
                            aiIdenLogDto.setIdenResultType(MonitorManageConsts.AI_IDENTIFY_RESULT_ALARM);
246
                            idenResultDtoList.add(idenResultDto);
247
                            aiIdenLogDto.setIdenResult(idenResultDtoList);
248
                            aiIdenLogDto.setAiIdenModel(MonitorManageConsts.AI_MODEL_CLOTHING_CODE);
249
                        }else{
250
                            //						if(aiClassName.equals("safety_hat")){
251
                            idenResultDto =new IdenResultDto();
252
                            idenResultDto.setAlarmEmployeeRoleId(MonitorManageConsts.alarmEmployeeRoleId);
253
                            idenResultDto.setAlarmType(aiClassName);
254
                            idenResultDto.setAlarmMemo(aiClassName);
255
                            idenResultDtoList.add(idenResultDto);
256
                            aiIdenLogDto.setIdenResult(idenResultDtoList);
257
                            aiIdenLogDto.setIdenResultType(MonitorManageConsts.AI_IDENTIFY_RESULT);
258
                            aiIdenLogDto.setAiIdenModel(MonitorManageConsts.AI_MODEL_CLOTHING_CODE);
259
                        }
260
                    }
261
                    log.info("识别成功,推送KAFKA消息");
262
                    processKafka(aiIdenLogDto.getTopic(), JSONObject.toJSONString(aiIdenLogDto));
263
                }else{
264
                    log.info("没有识别到人,不推送KAFKA消息");
265
                }
266
            }
267
            //AI模型
279
			JSONObject jsonObject = JSONObject.parseObject(aiResponseData);// JSONUtil.formatJsonStr(aiResponseData);
280
			System.out.println("AI 识别结果: " + jsonObject);
281
			IdenResultDto idenResultDto = null;
282
			List<IdenResultDto> idenResultDtoList = null;
283
			if (jsonObject.getString("Status").equals("Ok")) {
284
				idenResultDtoList = new ArrayList<>();
285
				JSONArray jsonoArray = JSONArray.parseArray(jsonObject.getString("Result"));
286
				if (jsonoArray.size() > 0) {
287
					for (int i = 0; i < jsonoArray.size(); i++) {
288
						JSONObject resultObj = JSONObject.parseObject(jsonoArray.get(i).toString());
289
						String aiClassName = resultObj.getString("class");
290
						// safety_hat表示安全帽;ordinart_hat表示普通帽子;chef_hat表示厨师帽;none表示未戴帽子
291
						if (aiClassName.equals("none")) {
292
							idenResultDto = new IdenResultDto();
293
							idenResultDto.setAlarmEmployeeRoleId(MonitorManageConsts.alarmEmployeeRoleId);
294
							idenResultDto.setAlarmType(MonitorManageConsts.AI_ALARM_TYPE_WEA);
295
							idenResultDto.setAlarmMemo("未戴帽子");
296
							aiIdenLogDto.setIdenResultType(MonitorManageConsts.AI_IDENTIFY_RESULT_ALARM);
297
							idenResultDtoList.add(idenResultDto);
298
							// aiIdenLogDto.setIdenResult(idenResultDtoList);
299
							aiIdenLogDto.setIdenResult(JSON.toJSONString(idenResultDtoList));
300
							// aiIdenLogDto.setAiIdenModel(MonitorManageConsts.AI_MODEL_CLOTHING_CODE);
301
							aiIdenLogDto.setRelateEmployeeRoleId(MonitorManageConsts.alarmEmployeeRoleId);
302
						} else {
303
							// if(aiClassName.equals("safety_hat")){
304
							idenResultDto = new IdenResultDto();
305
							idenResultDto.setAlarmEmployeeRoleId(MonitorManageConsts.alarmEmployeeRoleId);
306
							idenResultDto.setAlarmType(aiClassName);
307
							idenResultDto.setAlarmMemo(aiClassName);
308
							idenResultDtoList.add(idenResultDto);
309
							// aiIdenLogDto.setIdenResult(idenResultDtoList);
310
							aiIdenLogDto.setIdenResult(JSON.toJSONString(idenResultDtoList));
311
							aiIdenLogDto.setIdenResultType(MonitorManageConsts.AI_IDENTIFY_RESULT);
312
							// aiIdenLogDto.setAiIdenModel(MonitorManageConsts.AI_MODEL_CLOTHING_CODE);
313
							aiIdenLogDto.setRelateEmployeeRoleId(MonitorManageConsts.alarmEmployeeRoleId);
314
						}
315
					}
316
					log.info("识别成功,推送KAFKA消息");
317
					processKafka(aiIdenLogDto.getTopic(), JSONObject.toJSONString(aiIdenLogDto));
318
				} else {
319
					log.info("没有识别到人,不推送KAFKA消息");
320
				}
321
			}
322
			// AI模型
268 323
//			aiIdenLogDto.setAiIdenModel(MonitorManageConsts.AI_MODEL_CLOTHING_CODE);
269
        }catch (Exception e){
270
            log.error("AI处理异常");
271
        }
272
        return aiIdenLogDto;
273
    }
274
275
    /**
276
     * AI人体识别
277
     * @param aifilePath
278
     * @return
279
     */
280
    private boolean aiworkHumanDetect(String aifilePath){
281
        boolean isHuman = false;
282
        try {
283
            //安全帽识别
284
            String aiResponseData = ebcAiService.workClothesDetect(ImageBase64Converter.convertFileToBase64(aifilePath),  true,true,0.9f);
285
286
            JSONObject jsonObject = JSONObject.parseObject(aiResponseData);// JSONUtil.formatJsonStr(aiResponseData);
287
            if(jsonObject.getString("Status").equals("Ok")){
288
                JSONArray jsonoArray = JSONArray.parseArray(jsonObject.getString("Result"));
289
                for(int i=0;i<jsonoArray.size();i++){
290
                    JSONObject resultObj = JSONObject.parseObject(jsonoArray.get(i).toString());
291
                    String aiClassName = resultObj.getString("lable");
292
//										safety_hat表示安全帽;ordinart_hat表示普通帽子;chef_hat表示厨师帽;none表示未戴帽子
293
                    if(aiClassName.equals("person")){
294
                        isHuman = true;
295
                    }
296
                }
297
            }
298
        }catch (Exception e){
299
            log.error("AI处理异常");
300
        }
301
        return isHuman;
302
    }
324
		} catch (Exception e) {
325
			log.error("AI处理异常");
326
		}
327
		return aiIdenLogDto;
328
	}
329
330
	/**
331
	 * AI人体识别(照片中是否有人)
332
	 * @param aifilePath
333
	 * @return
334
	 */
335
	private boolean aiworkHumanDetect(String aifilePath) {
336
		boolean isHuman = false;
337
		try {
338
			/*// 安全帽识别
339
			String aiResponseData = ebcAiService.workClothesDetect(ImageBase64Converter.convertFileToBase64(aifilePath),
340
					true, true, 0.9f);
341
			
342
			JSONObject jsonObject = JSONObject.parseObject(aiResponseData);// JSONUtil.formatJsonStr(aiResponseData);
343
			if (jsonObject.getString("Status").equals("Ok")) {
344
				JSONArray jsonoArray = JSONArray.parseArray(jsonObject.getString("Result"));
345
				for (int i = 0; i < jsonoArray.size(); i++) {
346
					JSONObject resultObj = JSONObject.parseObject(jsonoArray.get(i).toString());
347
					String aiClassName = resultObj.getString("lable");
348
			//										safety_hat表示安全帽;ordinart_hat表示普通帽子;chef_hat表示厨师帽;none表示未戴帽子
349
					if (aiClassName.equals("person")) {
350
						isHuman = true;
351
					}
352
				}
353
			}*/
354
355
			log.info("开始AI人数识别处理...");
356
			String aiResponseData = ebcAiService.headDetect(ImageBase64Converter.convertFileToBase64(aifilePath), true,
357
					0.9f);
358
359
			JSONObject jsonObject = JSONObject.parseObject(aiResponseData);
360
			JSONArray jsonArray = jsonObject.getJSONArray("Result");
361
			if (!CollectionUtils.isEmpty(jsonArray)) {
362
				isHuman = true;
363
				log.info("AI人数识别结果:有" + jsonArray.size() + "人");
364
			} else {
365
				log.info("AI人数识别结果:没有人");
366
			}
367
368
		} catch (Exception e) {
369
			log.error("AI处理异常");
370
		}
371
		return isHuman;
372
	}
373
374
	/**
375
	 * 人脸识别
376
	 * @param aiIdenLogDto
377
	 * @param aifilePath
378
	 * @return
379
	 */
380
	private AiIdenLogDto faceAiRecog(AiIdenLogDto aiIdenLogDto, String aifilePath) {
381
		try {
382
			log.info("开始AI人脸识别处理...");
383
			// 人脸识别
384
			String aiResponseData = ebcAiService.faceAiRecog(ImageBase64Converter.convertFileToBase64(aifilePath));
385
386
			JSONObject jsonObject = JSONObject.parseObject(aiResponseData);
387
			System.out.println("AI人脸识别结果: " + aiResponseData);
388
389
			if ("1".equals(jsonObject.getString("errorcode")) && "success".equals(jsonObject.getString("message"))) {
390
				JSONObject resultJsonObject = JSONObject.parseObject(jsonObject.getString("result"));
391
392
				if (resultJsonObject.getIntValue("is_match") == 0) {
393
					aiIdenLogDto.setIdenResult(jsonObject.getString("result"));
394
					aiIdenLogDto.setIdenResultType(MonitorManageConsts.AI_IDENTIFY_RESULT);
395
396
				} else {
397
					aiIdenLogDto.setIdenResult(jsonObject.getString("result"));
398
					aiIdenLogDto.setRelateEmployeeRoleId(resultJsonObject.getString("user_id"));
399
					aiIdenLogDto.setIdenResultType(MonitorManageConsts.AI_IDENTIFY_RESULT_ATTENDANCE);
400
401
				}
402
403
				log.info("识别成功,推送KAFKA消息");
404
				processKafka(aiIdenLogDto.getTopic(), JSONObject.toJSONString(aiIdenLogDto));
405
			} else {
406
				log.info("没有识别到人,不推送KAFKA消息");
407
				return aiIdenLogDto;
408
			}
409
		} catch (Exception e) {
410
			log.error("AI处理异常");
411
		}
412
		return aiIdenLogDto;
413
	}
414
415
	/**
416
	 * 根据设备code获取监控任务详情
417
	 * @param deviceCode
418
	 * @return
419
	 */
420
	private List<Map> getResourceToolAllInfo(String deviceCode) {
421
		List<Map> resourceToolInfoList = new ArrayList<Map>();
422
		try {
423
			String url = protectionResourceUrl + "?resourceToolCode=" + deviceCode;
424
			log.info("getResourceToolAllInfo method params: resourceToolCode=" + deviceCode + ", url=" + url);
425
426
			String resultJson = HttpServiceUtil.sendRequest(url);
427
			JSONObject resultData = JSON.parseObject(resultJson);
428
			if (StringUtils.isEmpty(resultData.getString("data"))) {
429
				log.info("getResourceToolAllInfo method returns an empty result");
430
				return resourceToolInfoList;
431
			}
432
433
			resourceToolInfoList = JSON.parseArray(resultData.getString("data"), Map.class);
434
			log.info("getResourceToolAllInfo method return result: " + resultData.getString("data"));
435
		} catch (Exception e) {
436
			log.error("getResourceToolAllInfo is error");
437
		}
438
439
		return resourceToolInfoList;
440
	}
303 441
304 442
}

+ 15 - 12
monitor-manage-service/src/main/resources/application.properties

@ -27,8 +27,8 @@ spring.main.allow-bean-definition-overriding=true
27 27
#kafka
28 28
#kafka.bootstrap-servers=47.105.160.21:9090
29 29
kafka.bootstrap-servers=10.19.90.34:9090
30
kafka.topic.deviceLocation=Topic_IoT_DeviceLocation_111
31
kafka.topic.alarm=Topic_IoT_IndividualAlarm_111
30
#kafka.topic.deviceLocation=Topic_IoT_DeviceLocation_111
31
#kafka.topic.alarm=Topic_IoT_IndividualAlarm_111
32 32
#kafka.topic.deviceLocation=DeviceLocationA
33 33
#kafka.topic.alarm=IndividualAlarmA
34 34
kafka.producer.batch-size=16785
@ -69,23 +69,26 @@ logging.level.com.ai=debug
69 69
logging.level.org.springframework.data=debug
70 70
71 71
72
#camera.filePath=/home/puaiuc/data/DAHUA
73
camera.filePath=E:\\data\\DAHUA
74
75
#AIÖ´Ðнá¹û
76
kafka.topic.aitask=topicTaskTest
77
#kafka.topic.aitask=topic_ai_task
78
#AIÊÓÆµ
79
kafka.topic.aivideo=topicVideoTest
80
#kafka.topic.aivideo=topic_ai_video
81
72
camera.filePath=/home/puaiuc/data/DAHUA
73
#camera.filePath=E:\\data\\DAHUA
82 74
75
#AI\u05b4\ufffd\u043d\ufffd\ufffd
76
#kafka.topic.aitask=topicTaskTest
77
kafka.topic.aitask=topic_ai_task
78
#AI\ufffd\ufffd\u01b5
79
#kafka.topic.aivideo=topicVideoTest
80
kafka.topic.aivideo=topic_ai_video
83 81
84 82
83
#AI\u5931\u8d25\u8bf7\u6c42\u5730\u5740
85 84
ebc.ai.head-det-url=http://10.1.251.211:7001/todo/api/v1.4/control/online/IMAGE/HEAD/PREDICT
86 85
ebc.ai.helmet-det-url=http://10.1.251.211:7003/todo/api/v1.4/control/online/IMAGE/HELMET/PREDICT
87 86
ebc.ai.smokingdet-url=http://10.1.251.213:5125/smokingdet
88 87
ebc.ai.instrument-det-url=http://10.1.251.213:19100/predict
89 88
ebc.ai.work-clothes-det-url=http://10.1.251.211:7003/todo/api/v1.4/control/online/IMAGE/HUMAN/PREDICT
90 89
90
ebc.ai.face-recog-service-url=http://10.21.10.28:9018/api/face/recog
91
92
93
#AI\u4efb\u52a1\u8bf7\u6c42\u5730\u5740
91 94
ebc.protection.resource-url=http://10.19.90.34:8018/sp/resourceTool/getResourceToolAllInfo

+ 7 - 0
security-protection-platform/src/api/access/index.js

@ -8,6 +8,13 @@ const api = {
8 8

9 9
  getaccesstype () {
10 10
    return $http.get('/access/getaccesstype')
11
  },
12
  getOneInAndOutRecord (params) {
13
    return $default.get('/sp/inAndOutRecord/queryOneInAndOutRecord', params)
14
  },
15
  // 获取公司
16
  getcompanyTypesList () {
17
    return $default.get('sp/employeeManagement/queryCompanyList')
11 18
  }
12 19

13 20
}

+ 4 - 0
security-protection-platform/src/api/dashboard/index.js

@ -20,6 +20,10 @@ const api = {
20 20
    return $default.get('/sp/homePage/queryAlarmAnalysisTopList', {}).then(resp => {
21 21
      return resp.data
22 22
    })
23
  },
24
  // 进出识别
25
  queryHomeLastInAndOutRecord (data) {
26
    return $default.get('/sp/inAndOutRecord/queryHomeLastInAndOutRecord?monitorSceneId=3', data)
23 27
  }
24 28
  // 直播流
25 29
  // queryMonitorSceneTerminalRel () {

+ 8 - 1
security-protection-platform/src/api/usermana/index.js

@ -50,7 +50,14 @@ const api = {
50 50
      return $default.delete(`/sp/employeeManagement/deleteEmployee?employeeId=${data.employeeId}`).catch((err) => { return err })
51 51
    }
52 52
  },
53
53
  // 新增用户
54
  creteEmployee(params) {
55
    return $default.post('/sp/employeeManagement/createEmployee', params)
56
  },
57
  // 获取职务列表
58
  getJobPositionList() {
59
    return $default.post('/sp/employeeManagement/queryJobPositionList')
60
  },
54 61
  // 获取单个用户信息
55 62
  getOneEmployee (params) {
56 63
    return $default.get('/sp/employeeManagement/queryOneEmployee', params)

+ 3 - 9
security-protection-platform/src/components/VideoPlayer/index.vue

@ -19,19 +19,13 @@ const defaultPlayerOptions = {
19 19
  // liveui: true,
20 20
  controlBar: {
21 21
    children: [
22
      { name: 'playToggle' }, // 播放按钮
23
      { name: 'currentTimeDisplay' }, // 当前已播放时间
24
      { name: 'progressControl' }, // 播放进度条
25
      { name: 'durationDisplay' }, // 总时间
22
      {name: 'currentTimeDisplay'}, // 当前已播放时间
23
      {name: 'durationDisplay'}, // 时间
26 24
      { // 倍数播放
27 25
        name: 'playbackRateMenuButton',
28 26
        playbackRates: [0.5, 1, 1.5, 2, 2.5]
29 27
      },
30
      {
31
        name: 'volumePanel', // 音量控制
32
        inline: true // 不使用水平方式
33
      },
34
      { name: 'FullscreenToggle' } // 全屏
28
      {name: 'FullscreenToggle'} // 全屏
35 29
    ]
36 30
  }
37 31
}

+ 96 - 32
security-protection-platform/src/modules/access/index.vue

@ -1,15 +1,16 @@
1
<template>
1
s<template>
2 2
  <div class="access">
3 3

4 4
    <div class="access_header">
5

5 6
      <div>
6 7
        <span class="title">开始时间 : </span>
7
        <t-date-picker :confirm="false" v-model="searchdata.beginTime" placeholder="请选择开始时间" style="width:200px;height:32px"></t-date-picker>
8
        <t-date-picker :confirm="false" v-model="searchdata.beginDay" placeholder="请选择开始时间" style="width:200px;height:32px"></t-date-picker>
8 9
      </div>
9 10

10 11
      <div>
11 12
        <span class="title">结束时间 : </span>
12
        <t-date-picker :confirm="false" v-model="searchdata.endTime" placeholder="请选择结束时间" style="width:200px;height:32px"></t-date-picker>
13
        <t-date-picker :confirm="false" v-model="searchdata.endDay" placeholder="请选择结束时间" style="width:200px;height:32px"></t-date-picker>
13 14
      </div>
14 15

15 16
      <!-- <div>
@ -21,7 +22,7 @@
21 22
      </div> -->
22 23
      <div class="alarm_people">
23 24
        <span class="title">员工 : </span>
24
        <t-input v-model="searchdata.relateEmployeeNameAsLike" placeholder="员工姓名、编号关键字" style="width: 200px"></t-input>
25
        <t-input v-model="searchdata.nameAsLike" placeholder="员工姓名" style="width: 200px"></t-input>
25 26
      </div>
26 27

27 28
    </div>
@ -42,17 +43,17 @@
42 43

43 44
    <t-table :data="data" line @selection-change="handleSelectionChange">
44 45
      <t-table-column type="selection" width="34px"></t-table-column>
45
      <t-table-column label="姓名" prop="relateEmployeeRoleName" width="60px">
46
      <t-table-column label="姓名" prop="employeeName" width="60px">
46 47
      </t-table-column>
47 48
      <t-table-column label="员工编号" prop="employeeCode" width="80px">
48 49
      </t-table-column>
49
      <t-table-column label="公司" prop="organizationName" width="94px">
50
      <t-table-column label="公司" prop="companyname" width="94px">
50 51
      </t-table-column>
51
      <t-table-column label="部门" prop="orgName" width="94px">
52
      <t-table-column label="部门" prop="organizationName" width="94px">
52 53
      </t-table-column>
53 54
      <t-table-column label="职务" prop="employeePositionZh" width="80px">
54 55
      </t-table-column>
55
      <t-table-column l="相似度" prop="similarity" width="75px">
56
      <t-table-column prop="simi" l="相似度" width="75px">
56 57
      </t-table-column>
57 58
      <t-table-column label="进出时间" prop="taskExecuteTime" width="160px">
58 59
      </t-table-column>
@ -60,7 +61,7 @@
60 61
      </t-table-column>
61 62
      <t-table-column label="终端名称" prop="resourceToolName" width="97px">
62 63
      </t-table-column>
63
      <t-table-column label="终端编号" prop="resourceToolCode" width="72px">
64
      <t-table-column label="终端编号" prop="resourceToolCode" width="90px">
64 65
      </t-table-column>
65 66
      <t-table-column label="操作" width="80px">
66 67
        <template slot-scope="scope">
@ -71,7 +72,7 @@
71 72
    </t-table>
72 73

73 74
    <!-- 分页 -->
74
    <t-pager :total="total" :current="page" show-elevator class="pager" @on-change="onChange"></t-pager>
75
    <t-pager :total="total" :current="page" :page-size="limit" show-elevator class="pager" @on-change="onChange"></t-pager>
75 76

76 77
    <!-- 模态框 -->
77 78
    <t-modal :visibled.sync="detail_modal" title="识别详情" width="840px" height="538px">
@ -81,36 +82,42 @@
81 82
          <div class="detail_item1">
82 83
            <div>抓拍图片</div>
83 84
            <div>
84
              <img :src="rowdata.idenVideoUrl" alt="" srcset="" style="width:100%;height:100%">
85
              <img :src="rowdata.pictureInfo.fileUrl" alt="" srcset="" style="width:100%;height:100%">
85 86
            </div>
86 87
          </div>
87 88
          <div class="detail_item2">
88 89
            <div>识别结果</div>
89 90
            <div>
90 91
              <div>
91
                <img :src="rowdata.idenPictureUrl" alt="" srcset="" style="width:120px;height:160px;border-radius: 5px; ">
92
                <!-- 修改-->
93
                <img src="" alt="" srcset="" style="width:120px;height:160px;border-radius: 5px; ">
92 94
                <div class="bottomimg">抓拍图片</div>
93 95
              </div>
94 96
              <div>
97
                <!-- 修改-->
95 98
                <img src="http://img95.699pic.com/photo/50028/0321.jpg_wh300.jpg" alt="" srcset="">
96 99
              </div>
97 100
              <div>
98
                <img :src="rowdata.headerUrl" alt="" srcset="" style="width:100%;height:160px; border-radius: 5px;">
101
                <img :src="rowdata.alarmInfo.headerImage" alt="" srcset="" style="width:100%;height:160px; border-radius: 5px;">
99 102
                <div class="bottomimg">人脸底库</div>
100 103
              </div>
101 104
            </div>
102 105
            <div class="describe">
103 106
              <div>
104
                <t-icon icon="user-outline"></t-icon> {{ rowdata.relateEmployeeRoleName }}({{ rowdata.code }})
107
                <t-icon icon="user-outline"></t-icon>
108
                {{ rowdata.alarmInfo.employeeName }}({{ rowdata.alarmInfo.employeeCode }})
105 109
              </div>
106 110
              <div>
107
                <t-icon icon="map-marker"></t-icon> {{ rowdata.terminalPosition }}
111
                <t-icon icon="map-marker"></t-icon>
112
                {{ rowdata.alarmInfo.terminalPosition || '--' }}
108 113
              </div>
109 114
              <div>
110
                <t-icon icon="clock-outline"></t-icon> {{ rowdata.taskExecuteTime }}
115
                <t-icon icon="clock-outline"></t-icon>
116
                {{ rowdata.alarmInfo.taskExecuteTime }}
111 117
              </div>
112 118
              <div>
113
                <t-icon icon="team-outline"></t-icon> 相似度:{{ rowdata.similarity }}
119
                <t-icon icon="team-outline"></t-icon> 相似度:
120
                {{ rowdata.alarmInfo.simi }}
114 121
              </div>
115 122
            </div>
116 123
          </div>
@ -126,9 +133,9 @@
126 133

127 134
<script>
128 135
import accessapi from '@/api/access'
129
import formatDateTime from '@/utils/formatDateTime.js'
130 136

131 137
export default {
138

132 139
  data () {
133 140
    return {
134 141
      // 进出类型
@ -140,14 +147,19 @@ export default {
140 147
      // 模态框显示
141 148
      detail_modal: false,
142 149
      // 当前行数据
143
      rowdata: {},
150
      rowdata: {
151
        alarmInfo: {},
152
        pictureInfo: {}
153
      },
154
      // 公司列表
155
      companyTypesList: [],
144 156

145 157
      // 查询的参数
146 158
      searchdata: {
147 159

148
        relateEmployeeNameAsLike: '',
149
        beginTime: '',
150
        endTime: ''
160
        nameAsLike: '',
161
        beginDay: '',
162
        endDay: ''
151 163
      },
152 164
      // 一页的数据
153 165
      data: [
@ -162,18 +174,42 @@ export default {
162 174

163 175
  mounted () {
164 176
    // this.gettype()
165
    this.search()
177
    this.getcompanyTypesList()
178
    // this.search()
166 179
  },
167 180
  methods: {
168 181
    // 表格中的选择数据
169 182
    handleSelectionChange (val) {
170 183
      this.selectdata = val
171 184
    },
185
    // 获取公司
186
    async getcompanyTypesList () {
187
      var res = await accessapi.getcompanyTypesList()
188
      // console.log('公司信息是', res)
189
      if (res.status === 200) {
190
        this.companyTypesList = res.data.data
191
        this.search()
192
      } else {
193
        this.$Message.danger('获取数据失败')
194
      }
195
    },
172 196
    // 点击详情
173
    handleClick (scope) {
174
      this.detail_modal = true
175
      this.rowdata = scope.row
176
      console.log(this.rowdata)
197
    async handleClick (scope) {
198
      // this.rowdata = scope.row
199
      // console.log(this.rowdata)
200
      // console.log('id是', scope.row.aiIdenLogId)
201
      var res = await accessapi.getOneInAndOutRecord({ params: { aiIdenLogId: scope.row.aiIdenLogId } })
202

203
      if (res.data.success) {
204
        this.detail_modal = true
205
        // this.rowdata = res.data.data
206
        this.rowdata.pictureInfo = res.data.data.pictureInfo
207
        this.rowdata.alarmInfo = res.data.data.alarmInfo
208
        // console.log(res.data.data)
209
        // console.log('详情数据是', this.rowdata)
210
      } else {
211
        this.$Message.danger('获取数据失败')
212
      }
177 213
    },
178 214
    // 分页
179 215
    onChange (val) {
@ -199,7 +235,7 @@ export default {
199 235
    // 查询数据
200 236
    async search () {
201 237
      // 检验数据
202
      var flag = this.startreend(this.searchdata.beginTime, this.searchdata.endTime)
238
      var flag = this.startreend(this.searchdata.beginDay, this.searchdata.endDay)
203 239
      if (flag) {
204 240
        // console.log(this.page)
205 241
        // console.log(this.searchdata)
@ -211,17 +247,45 @@ export default {
211 247
        var res = await accessapi.getaccesslist({ params: params })
212 248
        // console.log(res)
213 249
        if (res.status === 200) {
214
          console.log(res)
250
          // console.log(res)
215 251
          this.data = res.data.data.data
216
          this.data = this.data.map((item) => { item.taskExecuteTime = formatDateTime(item.taskExecuteTime); return item })
217
          console.log(this.data)
218
          this.total = Math.ceil(res.data.data.total / res.data.data.size) * 5
252
          this.data = this.data.map((item) => {
253
            // 处理进出时间
254
            // item.taskExecuteTime = formatDateTime(item.taskExecuteTime)
255
            // 处理相似度
256
            // item.simi = this.percentagedata(item.simi)
257
            // console.log('公司的数据是', this.companyTypesList)
258
            // console.log('公司id', item)
259
            // console.log('公司名字是', this.companyTypesList.filter((item1) => { return item1.id === 10000 }))
260
            item.companyinfo = this.companyTypesList.filter((item1) => { return item1.id === item.companyId })
261
            if (item.companyinfo.length > 0) {
262
              item.companyname = item.companyinfo[0].name
263
            } else {
264
              item.companyname = ''
265
            }
266

267
            return item
268
          })
269

270
          // this.total = Math.ceil(res.data.data.total / res.data.data.size) * 5
271
          // console.log(this.total)
272
          this.total = res.data.data.total
273
          // console.log('数据是', this.data)
219 274
        }
220 275
      } else {
221 276
        this.$Message.danger('开始时间不能在结束时间的后面')
222 277
      }
223 278
    },
224 279

280
    percentagedata (point) {
281
      if (point === 0) {
282
        return 0
283
      }
284
      var str = Number(point * 100).toFixed(1)
285
      str += '%'
286
      return str
287
    },
288

225 289
    // 重置数据
226 290
    reset () {
227 291
      for (var index in this.searchdata) {

+ 4 - 3
security-protection-platform/src/modules/aialarm/index.vue

@ -82,7 +82,7 @@
82 82
    </t-table>
83 83

84 84
    <!-- 分页 -->
85
    <t-pager :total="total" :current="page" show-elevator class="pager" @on-change="onChange"></t-pager>
85
    <t-pager :total="total" :current="page" :page-size="limit" show-elevator class="pager" @on-change="onChange"></t-pager>
86 86

87 87
    <!-- 模态框-->
88 88
    <t-modal :visibled.sync="details_modal" :title="clickdetail==0?'报警详情':'报警处理'" width="732px">
@ -390,8 +390,9 @@ export default {
390 390
          this.data = res.data.data.data
391 391
          this.data = this.data.map((item) => { item.aiIdenTime = formatDateTime(item.aiIdenTime); return item })
392 392
          console.log(this.data)
393

394
          this.total = Math.ceil(res.data.data.total / res.data.data.size) * 5
393
          console.log('数据是', res)
394
          // this.total = Math.ceil(res.data.data.total / res.data.data.size) * 5
395
          this.total = res.data.data.total
395 396
        } else {
396 397
          this.$Message.danger('数据获取失败')
397 398
        }

+ 64 - 13
security-protection-platform/src/modules/dashboard/index.vue

@ -70,17 +70,16 @@
70 70
          <span class="title-span">人员进出识别</span>
71 71
        </div>
72 72
        <div v-for="(item,index) in distinguishData" :style="`background-image: url(${border})`" class="distinguish">
73
          <div class="distinguish-title"> {{ item.name }} </div>
73
          <div class="distinguish-title"> {{ item.monitorSceneName }} </div>
74 74
          <div class="distinguish-row">
75 75
            <div class="similarity">
76
              <p style="opacity: 1;font-size: 12px">70%</p>
76
              <p class="p">{{ item.simi }}</p>
77 77
            </div>
78
            <img src="@/assets/images/indexT1.png" class="distinguish-col">
79
            <img src="@/assets/images/indexT1.png" class="distinguish-col">
78
            <img :src="item.newImg" alt="" class="distinguish-col">
79
            <img :src="item.headerImage" class="distinguish-col">
80 80
            <div style="width: 40%;margin-top: 4%;height: 79%;">
81
              <div class="distinguish-col-row">王小明(00220)</div>
82
              <div class="distinguish-col-row">已佩戴口罩</div>
83
              <div class="distinguish-col-row">2021.01.05 12:11:00</div>
81
              <div class="distinguish-col-row">{{ item.employeeName }}({{ item.employeeCode }})</div>
82
              <div class="distinguish-col-row">{{ item.taskExecuteTime }}</div>
84 83
            </div>
85 84
          </div>
86 85
        </div>
@ -92,6 +91,7 @@
92 91
93 92
<script>
94 93
import imgBg from '@/assets/images/indexTop.png'
94
import avatar from '@/assets/images/avatar.png'
95 95
import titleImgBg from '@/assets/images/indexTitle.png'
96 96
import polygon from '@/assets/images/polygon.png'
97 97
import border from '@/assets/images/border.png'
@ -159,7 +159,7 @@ export default {
159 159
        sources: [{
160 160
          withCredentials: false,
161 161
          type: 'application/x-mpegURL', // 这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
162
          src: 'http://10.19.90.34:1080/live/1.m3u8' // url地址
162
          src: 'http://10.19.90.34:1080/live/01.m3u8' // url地址
163 163
        }],
164 164
        flash: { hls: { withCredentials: false } },
165 165
        html5: { hls: { withCredentials: false } },
@ -174,6 +174,7 @@ export default {
174 174
      videoOptionsList: [],
175 175
      imgBg: imgBg,
176 176
      titleImgBg: titleImgBg,
177
      avatar: avatar,
177 178
      polygon: polygon,
178 179
      border: border,
179 180
      attendanceData: [],
@ -182,10 +183,7 @@ export default {
182 183
      alarmDataY: [],
183 184
      topData: [],
184 185
      topData1: [],
185
      distinguishData: [{name: '1风场', url: '@/assets/images/indexT1.png', url2: '@/assets/images/indexT1.png'},
186
        {name: '2风场', url: '@/assets/images/indexT1.png', url2: '@/assets/images/indexT1.png'},
187
        {name: '3风场', url: '@/assets/images/indexT1.png', url2: '@/assets/images/indexT1.png'},
188
        {name: '2风场', url: '@/assets/images/indexT1.png', url2: '@/assets/images/indexT1.png'}]
186
      distinguishData: []
189 187
    }
190 188
  },
191 189
  computed: {
@ -195,9 +193,13 @@ export default {
195 193
    setInterval(() => { // 当前时间
196 194
      this.nowDate = new Date()
197 195
    }, 1000)
196
    this.initRecognition()
198 197
    this.initAttendance()
199 198
    this.initAlarm()
200 199
    this.init24Top()
200
    setInterval(() => { // 识别记录
201
      this.initRecognition()
202
    }, 10000)
201 203
  },
202 204
  methods: {
203 205
    initVideo() {
@ -292,6 +294,46 @@ export default {
292 294
        }
293 295
      })
294 296
    },
297
    initRecognition() {
298
      dasapi.queryHomeLastInAndOutRecord({monitorSceneId: 3}).then(res => {
299
        var data = res.data.data
300
        if (data.length > 4){
301
          data = data.slice(0,4)
302
        }
303
        data.forEach(e => {
304
          e.simi = e.simi.split('.')[0] + '%'
305
          e.newImg = e.idenPictureUrl
306
          var loadTimer;
307
          var imgObject = new Image();
308
          imgObject.setAttribute('crossOrigin', 'anonymous');
309
          imgObject.src = e.idenPictureUrl;
310
          imgObject.onLoad = onImgLoaded();
311
          function onImgLoaded() {
312
            if (loadTimer != null) clearTimeout(loadTimer);
313
            if (!imgObject.complete) {
314
              loadTimer = setTimeout(function() {
315
                onImgLoaded();
316
              }, 3);
317
            } else {
318
              e.newImg = getImagePortion(imgObject, e.face_box[2] - e.face_box[0], e.face_box[3] - e.face_box[1], e.face_box[0], e.face_box[1]);
319
            }
320
          }
321
          function getImagePortion(imgObj, newWidth, newHeight, startX, startY){
322
            var tnCanvas = document.createElement('canvas');
323
            var tnCanvasContext = tnCanvas.getContext('2d');
324
            tnCanvas.width = newWidth; tnCanvas.height = newHeight;
325
            var bufferCanvas = document.createElement('canvas');
326
            var bufferContext = bufferCanvas.getContext('2d');
327
            bufferCanvas.width = imgObj.width;
328
            bufferCanvas.height = imgObj.height;
329
            bufferContext.drawImage(imgObj, 0, 0);
330
            tnCanvasContext.drawImage(bufferCanvas, startX,startY,newWidth, newHeight,0,0,newWidth,newHeight);
331
            return tnCanvas.toDataURL();
332
          }
333
        })
334
        this.distinguishData = data
335
      })
336
    },
295 337
    initAttendanceData() {
296 338
      var dom = document.getElementById('doughnut')
297 339
      var myChart = echarts.init(dom)
@ -602,6 +644,14 @@ export default {
602 644
            opacity: 0.5;
603 645
            border-radius: 50%;
604 646
            padding-top: 1%;
647
            filter:alpha(opacity=50); /*支持IE */
648
            -moz-opacity:0.5; /*支持FF */
649
            //opacity:0.5;
650
            .p{
651
              position:relative;
652
              color: #00d8f3;
653
              font-size: 10px
654
            }
605 655
          }
606 656
          .distinguish-col{
607 657
            width: 27%;
@ -610,7 +660,8 @@ export default {
610 660
          }
611 661
          .distinguish-col-row{
612 662
            padding-left: 5%;
613
            height: 30%;
663
            padding-top: 5%;
664
            height: 40%;
614 665
            width: 130%;
615 666
            color: white;
616 667
            font-size: 14px;

+ 223 - 40
security-protection-platform/src/modules/usermana/components/modal/addUser.vue

@ -1,9 +1,9 @@
1 1
<template>
2
  <t-modal :visibled.sync="visibled" :mask-closable="false">
2
  <t-modal :visibled.sync="isVisibled" :mask-closable="false">
3 3
    <template slot="header">
4 4
      <div class="device-modal-title">{{ isEdit?'用户编辑':'新增用户' }}</div>
5 5
    </template>
6
    <t-form :model="addUserModal" :rules="addUserModalRules" label-position="right">
6
    <t-form ref="addUserModal" :model="addUserModal" :rules="addUserModalRules" label-position="right">
7 7
      <t-form-item label="姓名:" prop="name">
8 8
        <t-input v-model="addUserModal.name" placeholder="请输入姓名"></t-input>
9 9
      </t-form-item>
@ -16,11 +16,11 @@
16 16
        </t-select>
17 17
      </t-form-item>
18 18
      <t-form-item v-if="addUserModal.apartments!==''" label="部门:" prop="organizeCode">
19
        <t-select-tree v-model="addUserModal.organizeCode" :node-data="departmentTypesList" width="200px" node-key="id"></t-select-tree>
19
        <t-select-tree v-model="addUserModal.organizeCode" :node-data="departmentTypesList" node-key="id"></t-select-tree>
20 20
      </t-form-item>
21 21
      <t-form-item label="职务:" prop="mainJobPosition">
22 22
        <t-select v-model="addUserModal.mainJobPosition" placeholder="请选择职务" clearable>
23
          <t-option v-for="(item,index) in dataList" :value="item.value" :key="index">{{ item.name }}</t-option>
23
          <t-option v-for="(item,index) in jobPoisitonList" :value="item.code" :key="index">{{ item.value }}</t-option>
24 24
        </t-select>
25 25
      </t-form-item>
26 26
      <t-form-item label="年龄:" prop="birthday">
@ -30,18 +30,37 @@
30 30
        <t-input v-model="addUserModal.mainWirelessCall" placeholder="请输入11位手机号"></t-input>
31 31
      </t-form-item>
32 32
      <t-form-item label="人脸图片:" prop="facePicture">
33
        <t-input v-model="addUserModal.facePicture" placeholder="请输入手机号"></t-input>
33
        <t-upload
34
          ref="uploader"
35
          :show-uploaded="true"
36
          :allowed-ext="['jpg','jpeg','png']"
37
          :max-size="2048"
38
          :before-upload="$_onUploadBeforeUpload"
39
          :data="{picture:'11d'}"
40
          multiple
41
          style="width:120px;height:160px;background-color:#FFFFFF;"
42
          type="drag"
43
          action="http://10.19.90.34:8018/sp/employeeManagement/uploadEmployeePicture"
44
          class="demo-upload-list"
45
        >
46
          <div class="picture-upload">
47
            <t-icon class="upload-icon" icon="plus-outline"></t-icon>
48
            <span style="color:rgba(0, 0, 0, 0.45)">上传照片</span>
49
          </div>
50
        </t-upload>
51
        <span style="color:rgba(0, 0, 0, 0.45);font-size:12px">照片格式:jpg、png或bmp文件,且不超过2M</span>
34 52
      </t-form-item>
35 53
    </t-form>
36 54
    <template slot="footer">
37 55
      <t-button @click="resetModalData">取消</t-button>
38 56
      <t-button v-if="isEdit" :loading="loadingSubmit" color="primary" @click="submitModalData">修改</t-button>
39
      <t-button v-else :loading="loadingSubmit" color="primary" @click="submitModalData">提交</t-button>
57
      <t-button v-else color="primary" @click="submitModalData">提交</t-button>
40 58
    </template>
41 59
  </t-modal>
42 60
</template>
43 61
44 62
<script>
63
import sysapi from '@/api/usermana'
45 64
export default {
46 65
  props: {
47 66
    visible: {
@ -52,31 +71,27 @@ export default {
52 71
    companyList: {
53 72
      type: Array,
54 73
      default: () => []
55
    },
56
    // 公司对应部门列表
57
    departmentTypesList: {
58
      type: Array,
59
      default: () => []
60 74
    }
61 75
  },
62 76
  data() {
77
    // 手机号验证
78
    // const VALIDATEPASSCHECK = (rule, value, callback) => {
79
    //   if (value === '') {
80
    //     callback(new Error('请输入11位手机号'))
81
    //   } else if (value.length > 0 & value.length !== 11) {
82
    //     callback(new Error('手机号格式不正确'))
83
    //   } else {
84
    //     callback()
85
    //   }
86
    // }
63 87
    return {
64 88
      // 是否为编辑状态
65 89
      isEdit: false,
66
      dataList: [
67
        {
68
          name: '数据一',
69
          value: 1
70
        },
71
        {
72
          name: '数据二',
73
          value: 2
74
        },
75
        {
76
          name: '数据三',
77
          value: 3
78
        }
79
      ],
90
      // 部门列表
91
      departmentTypesList: [],
92
      // 职务列表
93
      uploadList: [],
94
      jobPoisitonList: [],
80 95
      // 新增用户表单
81 96
      addUserModal: {
82 97
        name: '',
@ -86,7 +101,7 @@ export default {
86 101
        mainJobPosition: '',
87 102
        birthday: '',
88 103
        mainWirelessCall: '',
89
        facePicture: ''
104
        facePicture: '123'
90 105
      },
91 106
      // 新增用户表单规则
92 107
      addUserModalRules: {
@ -96,7 +111,7 @@ export default {
96 111
        code: [
97 112
          { required: true, message: '员工编号不能为空', trigger: 'blur' }
98 113
        ],
99
        field4: [
114
        apartments: [
100 115
          { required: true, message: '公司不能为空' }
101 116
        ],
102 117
        organizeCode: [
@ -109,7 +124,7 @@ export default {
109 124
          { required: true, message: '年龄不能为空', trigger: 'blur' }
110 125
        ],
111 126
        mainWirelessCall: [
112
          { required: true, message: '手机不能为空', trigger: 'blur' }
127
          { required: true, message: '请输入11位手机号', trigger: 'blur' }
113 128
        ],
114 129
        facePicture: [
115 130
          { required: true, message: '图片不能为空', trigger: 'blur' }
@ -118,33 +133,201 @@ export default {
118 133
    }
119 134
  },
120 135
  computed: {
121
    // 显示/隐藏对话框
122
    visibled: {
123
      set(val) {
124
        this.$emit('visibled', val)
136
    isVisibled: {
137
      set (val) {
138
        this.$emit('update:visible', val)
125 139
      },
126
      get() {
140
      get () {
141
        this.getJobPositionList()
127 142
        return this.visible
128 143
      }
129 144
    }
130 145
  },
146
  watch: {
147
    'addUserModal.apartments' (val) {
148
      // 重置部门回显
149
      this.addUserModal.organizeCode = ''
150
      // 查询部门列表
151
      this.queryCycleChildOrg(val)
152
    }
153
  },
154
  mounted() {
155
    this.getJobPositionList()
156
  },
131 157
  methods: {
132 158
    // 确认新增用户
133 159
    submitModalData() {
134
      this.visible = false
135
      console.log(this.visibled)
136
      console.log(this.visible);
160
      this.$refs['addUserModal'].validate((valid) => {
161
        if (valid) {
162
          this.isVisibled = false
163
          let obj = {
164
            name: this.addUserModal.name, // 员工姓名
165
            code: this.addUserModal.code, // 员工编号
166
            organizeCode: this.addUserModal.organizeCode, // 部门CODE
167
            mainWirelessCall: this.addUserModal.mainWirelessCall, // 手机号码
168
            mainJobPosition: this.addUserModal.mainJobPosition, // 职务
169
            field1: this.addUserModal.facePicture, // 照片标识
170
            field4: this.addUserModal.apartments, // 公司ID
171
            birthday: Math.round(new Date() / 1000) // 生日(时间戳)
172
          }
173
          sysapi.creteEmployee({params: obj}).then(res => {
174
            console.log(res)
175
            if (res.data.success === true) {
176
              this.$Message.success('新增成功')
177
            } else {
178
              console.log(res.data.fail.message)
179
              this.$Message.success(res.data.fail.message)
180
            }
181
          })
182
        }
183
      })
137 184
    },
138 185
    // 重置表单数据
139 186
    resetModalData () {
140
      // this.$refs['activityForm'].resetFields()
187
      this.$refs['addUserModal'].resetFields()
141 188
      this.imgUrl = ''
142
      this.visibled = false
189
      this.isVisibled = false
190
    },
191
    // 查询职务列表
192
    async getJobPositionList() {
193
      const res = await sysapi.getJobPositionList()
194
      if (res.status === 200) {
195
        this.jobPoisitonList = res.data.data
196
      } else {
197
        this.$Message.danger('职务类型列表数据获取失败!')
198
      }
199
    },
200
    // 查询部门列表
201
    async queryCycleChildOrg (id) {
202
      const res = await sysapi.queryCycleChildOrg(id)
203
      if (res.status === 200) {
204
        const data = []
205
        // 递归 实现tree组件所需部门数据结构
206
        this.nextDepartment(res.data, data)
207
        // 深拷贝data
208
        const data1 = JSON.parse(JSON.stringify(data))
209
        // 用部门id映射关系代替code与parentCode父子映射关系
210
        data.forEach(item => {
211
          // 删除pid为"-1"的的pid属性,否则tree渲染的时候没有根节点渲染不出来
212
          if (item.pid === '-1') {
213
            delete item.pid
214
          }
215
          item.id = item.orgId
216
          data1.some((item1) => {
217
            if (item.pid === item1.id) {
218
              item.pid = item1.orgId
219
            } else {
220
              return false
221
            }
222
          })
223
        })
224
        // eslint-disable-next-line no-return-assign
225
        this.departmentTypesList = data.filter(item => item.data = item.id)
226
      } else {
227
        this.$Message.danger('部门类型列表数据获取失败!')
228
      }
229
    },
230
    startPickerDateChange() {
231
    },
232
    // 如果部门还有下级 递归
233
    nextDepartment (data, arr) {
234
      if (data.length > 0) {
235
        data.forEach(item => {
236
          arr.push({
237
            orgId: item.id + '',
238
            id: item.code,
239
            label: item.name,
240
            pid: item.parentCode
241
          })
242
          this.nextDepartment(item.departments, arr)
243
        })
244
      }
245
    },
246
    $_onDeleteIconClick (file) {
247
      this.$refs.uploader.removeFile(file)
248
    },
249
    $_onUploadRemoveFlie (file, fileList) {
250
      this.uploadList = fileList
251
    },
252
    $_onUploadPreviewFlie (file) {
253
      console.log(file)
254
    },
255
    $_onUploadProgress (e, file) {
256
      console.log(e)
257
      console.log(file)
258
    },
259
    $_onUploadSuccess (res, file) {
260
      this.imgUrl = res.data.data.toolPictureUrl
261
      this.addDeviceModalForm.pictureUrl = res.data.data.pictureUrl
262
      // 因为演示用的上传服务器返回数据格式的原因,这里模拟添加 url
263
      console.log(file)
264
      this.uploadList.push(file)
265
    },
266
    $_onUploadRemoveFile () { },
267
    $_onUploadExceededSize () { },
268
    $_onUploadError (errMsg, response, file) {
269
      console.log(file)
270
      console.log(errMsg.message)
271
      this.$Notice.warning({
272
        title: `文件${file.name}上传失败`,
273
        desc:
274
          '原因:' + errMsg
275
      })
276
    },
277
    $_onUploadFileExtError (file, files) {
278
      this.$Notice.warning({
279
        title: '文件格式不正确',
280
        desc:
281
          '文件 ' + file.name + ' 格式不正确,请上传 jpg 或 png 格式的图片。'
282
      })
283
      console.log(files)
284
    },
285
    $_onUploadFileExceededSize (file) {
286
      this.$Notice.warning({
287
        title: '超出文件大小限制',
288
        desc: '文件 ' + file.name + ' 太大,不能超过 2M。'
289
      })
290
    },
291
    $_onUploadFormatError () { },
292
    $_onUploadBeforeUpload () {
293
      const check = this.uploadList.length < 5
294
      if (!check) {
295
        this.$Notice.warning({
296
          title: '最多只能上传 5 张图片。'
297
        })
298
      }
299
      return check
143 300
    }
144 301
  }
145 302
}
146 303
</script>
147 304
148
<style>
149
305
<style lang="scss" scoped>
306
.demo-upload-list{
307
  .upload--drag{
308
  background-color:#FFFFFF
309
}
310
}
311
.picture-upload{
312
  display:flex;
313
  flex-direction:column;
314
  width:100%;
315
  height: 100%;
316
  justify-content: center;
317
  .upload-icon{
318
    align-items:center;
319
    justify-content:center;
320
    color:white;
321
    display: flex;
322
  }
323
  .aidicon.aidicon-plus-outline:before{
324
    width: 32px;
325
    height: 32px;
326
    display: flex;
327
    justify-content: center;
328
    align-items: center;
329
    background-color: #D0D0D0;
330
    border-radius:45px;
331
  }
332
}
150 333
</style>

+ 1 - 2
security-protection-platform/src/modules/usermana/index.vue

@ -64,7 +64,7 @@
64 64
        </t-pager>
65 65
      </div>
66 66
    </t-card>
67
    <add-user-modal :department-types-list="departmentTypesList" :company-list="companyTypesList" :visible.sync="addDeviceModal"></add-user-modal>
67
    <add-user-modal :company-list="companyTypesList" :visible.sync="addDeviceModal"></add-user-modal>
68 68
    <auditModal :auditshow.sync="auditshow" :auditid="auditid" :company-name="companyName" @refeshUserList="getUserList"></auditModal>
69 69
  </div>
70 70
</template>
@ -306,7 +306,6 @@ export default {
306 306
    // 显示新增设备对话框
307 307
    showAddDeviceModal () {
308 308
      this.addDeviceModal = true
309
      console.log(this.addDeviceModal)
310 309
    },
311 310
    async editDeviceData (id) {
312 311
      const res = await sysapi.getDeviceInfo(id)

+ 154 - 81
security-protection-platform/src/modules/videoSurveillance/index.vue

@ -11,18 +11,21 @@
11 11
        <t-option v-for="(item,index) in organizationList" :key="index" :value="item.id">{{ item.name }}</t-option>
12 12
      </t-select>
13 13
    </div>
14
    <div class="page-bottom">
15
      <div v-for="(item,index) in videoList" :key="index" :value="item.resourceToolId" style="width:400px;margin:24px 0px 0 24px;">
16
        <videoPlayer
17
          ref="videoPlayer"
18
          :options="videoOptions"
19
          :playsinline="true"
20
          class="vjs-custom-skin videoPlayer"
21
        />
22
        <!-- <rtmp-video :list="getVideoPlayList(item)" @goDistinguishRecord="goDistinguishRecord(item.resourceToolId)" @videoReplay="handleReview"></rtmp-video> -->
23
      </div>
14
15
    <div class="page-bottom grid-demo">
16
      <t-col v-for="(item,index) in videoList" :span="viewLayoutSpan" :key="index" :value="item.resourceToolId" style="margin-top:24px">
17
        <video-player
18
            :ref="'video'+index"
19
            :options="videoOptions[index]"
20
            :playsinline="false"
21
            :events="events"
22
            class="vjs-custom-skin videoPlayer"
23
            @dblclick="handlefullscreenchange"
24
        ></video-player>
25
      </t-col>
26
      <!-- <rtmp-video :list="getVideoPlayList(item)" @goDistinguishRecord="goDistinguishRecord(item.resourceToolId)" @videoReplay="handleReview"></rtmp-video> -->
24 27
    </div>
25
    <t-pager :page-size="videoPageSize" :current="videoCurrent" :total="videoTotal" :sizer-range="[ 5, 10, 20, 30 ]" class="pager" show-elevator @on-change="onChangeGate"></t-pager>
28
    <t-pager :page-size="videoPageSize" :current="videoCurrent" :total="videoTotal" :sizer-range="[ 1, 4, 9, 16 ]" class="pager" show-elevator @on-change="onChangeGate"></t-pager>
26 29
    <replay-dialog :list="replayList" :visibled.sync="showReplayDialog" @get-list="queryMonitorVideoLog" />
27 30
  </div>
28 31
</template>
@ -30,18 +33,15 @@
30 33
import sysapi from '@/api/videoSurveillance'
31 34
import RtmpVideo from './components/rtmpVideoPlay'
32 35
import ReplayDialog from './components/ReplayDialog'
33
import VideoPlayer from '@/components/VideoPlayer'
34 36
import formatDateTime from '@/utils/formatDateTime.js'
35 37
import videojs from 'video.js'
36 38
window.videojs = videojs
37 39
38
require('videojs-flash')
39
require('videojs-playlist')
40 40
require('video.js/dist/lang/zh-CN.js')
41 41
require('video.js/dist/video-js.min.css')
42 42
43 43
export default {
44
  components: { ReplayDialog, VideoPlayer, RtmpVideo },
44
  components: { ReplayDialog, RtmpVideo },
45 45
  filters: {
46 46
    handleText (value) {
47 47
      if (!value) return ''
@ -53,36 +53,9 @@ export default {
53 53
  },
54 54
  data () {
55 55
    return {
56
      videoOptions: {
57
        autoplay: true, // 如果true,浏览器准备好时开始回放。
58
        muted: true, // 默认情况下将会消除任何音频。
59
        loop: false, // 导致视频一结束就重新开始。
60
        preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
61
        language: 'zh-CN',
62
        aspectRatio: '13:10', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
63
        // fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
64
        // 是否流体自适应容器宽高
65
        fluid: true,
66
        // // 设置视频播放器的显示宽度(以像素为单位)
67
        // width: '100px',
68
        // // 设置视频播放器的显示高度(以像素为单位)
69
        // height: '300px',
70
        sources: [{
71
          withCredentials: false,
72
          type: 'application/x-mpegURL', // 这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
73
          src: 'http://10.19.90.34:1080/live/1.m3u8' // url地址
74
        }],
75
        flash: { hls: { withCredentials: false } },
76
        html5: { hls: { withCredentials: false } },
77
        notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
78
        controlBar: {
79
          timeDivider: false,
80
          // durationDisplay: true,
81
          remainingTimeDisplay: false,
82
          fullscreenToggle: true, // 全屏按钮,
83
          pictureInPictureToggle: false
84
        }
85
      },
56
      viewLayoutSpan: 3,
57
      events: ['fullscreenchange'],
58
      videoOptions: [],
86 59
      videoCurrent: 1, // 大门分页数据
87 60
      videoPageSize: 10, // 大门分页数据
88 61
      videoTotal: 0, // 大门分页总数
@ -105,16 +78,61 @@ export default {
105 78
      // endDay: '2020-12-19 20:14:00'
106 79
    }
107 80
  },
81
  computed: {
82
    player() {
83
      return this.$refs.videoPlayer1.player
84
    }
85
  },
108 86
  mounted () {
109 87
    this.getWindFiledList() // 获取风场列表
110 88
  },
111 89
  methods: {
112
    getVideoPlayList (item) {
113
      return [{
114
        fileId: item.videoUrl,
115
        fileType: 'rtmp/flv',
116
        id: item.resourceToolId
117
      }]
90
    // 修改视频组件控制栏的元素以及样式
91
    async createMyButton () {
92
      this.$nextTick(() => {
93
        const bars = document.querySelectorAll('.vjs-control-bar')
94
        let time = document.getElementsByClassName('vjs-current-time vjs-time-control vjs-control')
95
        let start = document.getElementsByClassName('vjs-play-control vjs-control vjs-button')
96
        let volume = document.getElementsByClassName('vjs-volume-panel vjs-control vjs-volume-panel-horizontal')
97
        let text = document.getElementsByClassName('vjs-live-control vjs-control')
98
        bars.forEach((item, index) => {
99
          time.forEach(item => {
100
            item.remove()
101
          })
102
          start.forEach(item => {
103
            item.remove()
104
          })
105
          volume.forEach(item => {
106
            item.remove()
107
          })
108
          text.forEach(item => {
109
            item.remove()
110
          })
111
          let txt = document.createElement('span')
112
          txt.innerHTML = '集控室(人脸识别)'
113
          txt.style.marginLeft = '12px'
114
          let btn = document.createElement('button')
115
          btn.style.color = 'white'
116
          btn.style.cursor = 'pointer'
117
          btn.style.marginLeft = 'auto'
118
          btn.className = 'aidicon aidicon-image-outline'
119
          btn.setAttribute('title', '识别记录')
120
          btn.addEventListener('click', () => {
121
            this.goDistinguishRecord()
122
          })
123
          let btn1 = document.createElement('button')
124
          btn1.style.color = 'white'
125
          btn1.style.cursor = 'pointer'
126
          btn1.className = 'aidicon aidicon-piechart-outline'
127
          btn1.setAttribute('title', '视频回放')
128
          btn1.addEventListener('click', () => {
129
            this.handleReview(this.videoList[index].id)
130
          })
131
          item.appendChild(txt)
132
          item.appendChild(btn)
133
          item.appendChild(btn1)
134
        })
135
      })
118 136
    },
119 137
    // 获取场景列表
120 138
    getSceneList () {
@ -124,6 +142,19 @@ export default {
124 142
        if (element.id === this.gateFieldData) {
125 143
          sysapi.getMonitorScene(this.organizationList[index].id).then((resp) => {
126 144
            this.sceneList = resp.data.data || []
145
            if (resp.data.data[0].monitorViewLayout === '1X1') {
146
              this.viewLayoutSpan = 10
147
              this.videoPageSize = 1
148
            } else if (resp.data.data[0].monitorViewLayout === '2X2') {
149
              this.viewLayoutSpan = 6
150
              this.videoPageSize = 4
151
            } else if (resp.data.data[0].monitorViewLayout === '3X3') {
152
              this.viewLayoutSpan = 4
153
              this.videoPageSize = 9
154
            } else if (resp.data.data[0].monitorViewLayout === '4X4') {
155
              this.viewLayoutSpan = 3
156
              this.videoPageSize = 16
157
            }
127 158
            this.tabClick(this.sceneList[0].monitorSceneId)
128 159
          })
129 160
        }
@ -170,15 +201,51 @@ export default {
170 201
        console.log(err)
171 202
      })
172 203
    },
204
    handlefullscreenchange(val) {
205
      // 因为我是又封装了一个组件,打印val会有相应所需的属性,全屏状态为:isFullscreen_
206
      val.isFullscreen_ = !val.isFullscreen_
207
      // this.$emit('fullscreenchange', val)
208
    },
173 209
    // 获得风场大门数据
174 210
    getVideoSurveillanceData () {
175 211
      var id = this.tabId
176 212
      this.paramsObj.page = this.videoCurrent
177
      sysapi.getVideoSurveillanceDataForPage({ params: { monitorSceneId: id, pageNumber: this.videoCurrent, pageSize: this.videoPageSize} })
178
      .then(res => {
179
        debugger
180
        this.videoList = res.data.data.data
181
        this.videoTotal = res.data.data.total
213
      sysapi.getVideoSurveillanceData({ params: { monitorSceneId: id } }).then(res => {
214
        this.videoList = res.data.data
215
        for (let i in res.data.data) {
216
          let obj = {
217
            autoplay: true, // 如果true,浏览器准备好时开始回放。
218
            muted: true, // 默认情况下将会消除任何音频。
219
            loop: false, // 导致视频一结束就重新开始。
220
            preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
221
            language: 'zh-CN',
222
            aspectRatio: '13:10', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
223
            // fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
224
            // 是否流体自适应容器宽高
225
            fluid: true,
226
            // // 设置视频播放器的显示宽度(以像素为单位)
227
            // width: '100px',
228
            // // 设置视频播放器的显示高度(以像素为单位)
229
            // height: '300px',
230
            sources: [{
231
              withCredentials: false,
232
              type: 'application/x-mpegURL', // 这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
233
              src: res.data.data[i].videoUrl // url地址
234
            }],
235
            flash: { hls: { withCredentials: false } },
236
            html5: { hls: { withCredentials: false } },
237
            notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
238
            controlBar: {
239
              timeDivider: false,
240
              durationDisplay: false,
241
              remainingTimeDisplay: false,
242
              fullscreenToggle: true, // 全屏按钮,
243
              pictureInPictureToggle: false
244
            }
245
          }
246
          this.videoOptions.push(obj)
247
        }
248
        this.createMyButton()
182 249
      })
183 250
    },
184 251
    // 进入识别记录界面
@ -247,37 +314,43 @@ export default {
247 314
      }
248 315
    }
249 316
  }
250
  .pager {
317
.pager {
251 318
    margin-right: auto;
252 319
    margin: 21px 0px 24px 0;
253 320
    float: right;
254 321
  }
255
  .btn-primary,
256
  .radio-group-button .form-radio:checked,
257
  .radio-group-button .form-radio[checked] {
258
    color: #0089d4;
259
    background-color: #fff;
260
    border: 1px solid #0089d4;
261
  }
262
  .btn-secondary,
263
  .radio-group-button .form-radio,
264
  .checkbox-group--button .form-checkbox .form-checkbox__inner,
265
  .btn-dashed-secondary,
266
  .btn-outline-secondary {
267
    background: none;
268
  }
269
  .video-js .vjs-control:focus, .video-js .vjs-control:focus:before, .video-js .vjs-control:hover:before{
270
    color:#0089d4;
271
    text-shadow: none;
272
  }
273
  .vjs-control-bar{
274
    justify-content: flex-end;
275
  }
276
  .video-js .vjs-control{
322
.vjs-custom-skin > .video-js .vjs-control-bar .vjs-fullscreen-control{
323
  height:38px !important;
324
}
325
.video-js .vjs-control{
277 326
    cursor: pointer;
327
    width: 28px;
328
    margin-right:12px;
278 329
  }
279
.video-js .vjs-fullscreen-control{
280
  order:2;
330
.vjs-control-bar{
331
    display: flex;
332
    justify-content: center;
333
    align-items: center;
334
}
335
.video-js button{
336
  font-size:16px;
337
}
338
.aidicon-image-outline:hover{
339
  color: #0089d4 !important;
340
}
341
.aidicon-piechart-outline:hover{
342
  color: #0089d4 !important;
343
}
344
.vjs-icon-placeholder:hover{
345
  color: #0089d4 !important;
346
}.vjs-icon-placeholder{
347
  font-size: 13px;
348
  display: flex;
349
  justify-content: center;
350
  align-items: center;
351
}
352
.vjs-tech {
353
  pointer-events: none;
281 354
}
282 355
}
283 356
</style>

+ 1 - 1
security-protection-service/src/main/java/com/ai/bss/security/protection/controller/EmployeeManagementController.java

@ -133,7 +133,7 @@ public class EmployeeManagementController {
133 133
	@ResponseBody
134 134
	@RequestMapping("/uploadEmployeePicture")
135 135
	public CommonResponse<Map<String, String>> uploadEmployeePicture(
136
			@RequestParam(value = "picture") MultipartFile meFile, @RequestParam(required = false) String pictureUrl)
136
			@RequestParam(value = "file") MultipartFile meFile, @RequestParam(required = false) String pictureUrl)
137 137
			throws Exception {
138 138
		if (meFile == null || StringUtils.isEmpty(meFile.getOriginalFilename())) {
139 139
			return CommonResponse.fail("500", "上传失败");

+ 16 - 1
security-protection-service/src/main/java/com/ai/bss/security/protection/controller/InAndOutRecordController.java

@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestParam;
19 19
import org.springframework.web.bind.annotation.ResponseBody;
20 20
21 21
import java.util.HashMap;
22
import java.util.List;
22 23
import java.util.Map;
23 24
24 25
/**
@ -72,5 +73,19 @@ public class InAndOutRecordController {
72 73
73 74
		return aiIdenLogManageService.queryOneAiIdenLog(aiIdenLogId);
74 75
	}
75
76
	
77
	/**
78
	 * 首页查询进出记录
79
	 * @return
80
	 * @throws Exception
81
	 */
82
	@ResponseBody
83
	@RequestMapping("/queryHomeLastInAndOutRecord")
84
	public CommonResponse<List<Map<String, Object>>> queryHomeLastInAndOutRecord(@RequestParam String monitorSceneId) throws Exception {
85
		Map<String, String> params=new HashMap<String, String>();
86
		params.put("sceneId", monitorSceneId);
87
		params.put("aiIdenModel", EbcConstant.AI_MODEL_FACE);
88
		
89
		return aiIdenLogManageService.selectLastAiIdenLog(params);
90
	}
76 91
}

+ 2 - 2
security-protection-service/src/main/java/com/ai/bss/security/protection/controller/ResourceToolManageController.java

@ -154,7 +154,7 @@ public class ResourceToolManageController {
154 154
	@ResponseBody
155 155
	@RequestMapping("/uploadResourceToolPicture")
156 156
	public CommonResponse<Map<String, String>> uploadResourceToolPicture(
157
			@RequestParam(value = "picture") MultipartFile meFile, @RequestParam(required = false) String pictureUrl)
157
			@RequestParam(value = "file") MultipartFile meFile, @RequestParam(required = false) String pictureUrl)
158 158
			throws Exception {
159 159
		if (meFile == null || StringUtils.isEmpty(meFile.getOriginalFilename())) {
160 160
			return CommonResponse.fail("500", "上传失败");
@ -166,7 +166,7 @@ public class ResourceToolManageController {
166 166
	}
167 167
168 168
	/**
169
	 * 根据设备CODE获取场景、AI任务等相关信息
169
	 * 根据设备CODE获取AI任务等相关信息
170 170
	 * @param meFile
171 171
	 * @return
172 172
	 * @throws Exception

+ 122 - 12
security-protection-service/src/main/java/com/ai/bss/security/protection/service/impl/AiIdenLogManageServiceImpl.java

@ -1,5 +1,6 @@
1 1
package com.ai.bss.security.protection.service.impl;
2 2
3
import java.math.BigDecimal;
3 4
import java.util.ArrayList;
4 5
import java.util.HashMap;
5 6
import java.util.List;
@ -13,6 +14,7 @@ import org.springframework.util.CollectionUtils;
13 14
import com.ai.abc.api.model.CommonRequest;
14 15
import com.ai.abc.api.model.CommonResponse;
15 16
import com.ai.bss.components.common.model.PageBean;
17
import com.ai.bss.components.minio.config.MinioConfig;
16 18
import com.ai.bss.security.protection.model.EbcMonitorVideoLog;
17 19
import com.ai.bss.security.protection.service.interfaces.AiIdenLogManageService;
18 20
import com.ai.bss.security.protection.service.interfaces.CharSpecService;
@ -27,6 +29,7 @@ import com.ai.bss.work.safety.service.api.AiTaskCommand;
27 29
import com.ai.bss.work.safety.service.api.AiTaskQuery;
28 30
import com.alibaba.fastjson.JSON;
29 31
import com.alibaba.fastjson.JSONArray;
32
import com.alibaba.fastjson.JSONObject;
30 33
import com.alibaba.fastjson.TypeReference;
31 34
32 35
@Service
@ -50,6 +53,9 @@ public class AiIdenLogManageServiceImpl implements AiIdenLogManageService {
50 53
	@Autowired
51 54
	private MonitorVideoLogManageService monitorVideoLogManageService;
52 55
56
	@Autowired
57
	private MinioConfig minioConfig;
58
53 59
	@Override
54 60
	public CommonResponse<PageBean<Map<String, Object>>> queryPageAiIdenLog(Map<String, Object> params, int pageNumber,
55 61
			int pageSize) throws Exception {
@ -68,14 +74,29 @@ public class AiIdenLogManageServiceImpl implements AiIdenLogManageService {
68 74
		for (Map<String, Object> dataMap : response.getData().getData()) {
69 75
			dataMap.put("taskExecuteTime", DateUtil.formatObjectToDate(dataMap.get("taskExecuteTime")));
70 76
			dataMap.put("idenPictureSnapDate", DateUtil.formatObjectToDate(dataMap.get("idenPictureSnapDate")));
71
			
77
72 78
			// 结果详情
73
			String idenResultArr = dataMap.get("idenResult") == null ? "" : String.valueOf(dataMap.get("idenResult"));
74
			if (StringUtils.isNotEmpty(idenResultArr)) {
75
				List<Map<String, String>> idenResultList = JSONArray.parseObject(idenResultArr, List.class);
76
				if (!CollectionUtils.isEmpty(idenResultList)) {
77
					dataMap.put("idenResult", idenResultList.get(0));
78
					//dataMap.putAll(idenResultList.get(0));
79
			String idenResultString = dataMap.get("idenResult") == null ? ""
80
					: String.valueOf(dataMap.get("idenResult"));
81
			if (StringUtils.isNotEmpty(idenResultString)) {
82
				Object idenResultObject = JSON.parse(idenResultString);
83
				if (idenResultObject instanceof JSONObject) {
84
					Map<String, String> idenResultMap = JSON.parseObject(idenResultString, Map.class);
85
					dataMap.putAll(idenResultMap);
86
87
					if (idenResultMap.get("simi") != null) {
88
						Object simiObject = idenResultMap.get("simi");
89
						BigDecimal simiBigDecimal = new BigDecimal(String.valueOf(simiObject));
90
						float simi = simiBigDecimal.multiply(new BigDecimal("100"))
91
								.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
92
						dataMap.put("simi", simi + "%");
93
					}
94
95
				} else if (idenResultObject instanceof JSONArray) {
96
					List<Map<String, String>> idenResultList = JSONArray.parseObject(idenResultString, List.class);
97
					if (!CollectionUtils.isEmpty(idenResultList)) {
98
						dataMap.putAll(idenResultList.get(0));
99
					}
79 100
				}
80 101
			}
81 102
@ -92,7 +113,7 @@ public class AiIdenLogManageServiceImpl implements AiIdenLogManageService {
92 113
					dataMap.put("employeeName", employeeResponse.getData().getName());
93 114
					dataMap.put("employeeCode", employeeResponse.getData().getCode());
94 115
95
					dataMap.put("companyName", employeeResponse.getData().getField4());
116
					dataMap.put("companyId", employeeResponse.getData().getField4());
96 117
					dataMap.put("organizationCode", employeeResponse.getData().getOrganizeCode());
97 118
					dataMap.put("organizationName", employeeResponse.getData().getOrgName());
98 119
@ -133,7 +154,7 @@ public class AiIdenLogManageServiceImpl implements AiIdenLogManageService {
133 154
			String pictureUrl = String.valueOf(dataMap.get("idenPictureUrl"));
134 155
			if (pictureUrl.length() > 20 && pictureUrl.lastIndexOf(".") > 18
135 156
					&& pictureUrl.lastIndexOf(EbcConstant.AI_MONITOR_FILE_PREFIX_PICTURE) > 0) {
136
				
157
137 158
				int picturePrefixIndex = pictureUrl.lastIndexOf(EbcConstant.AI_MONITOR_FILE_PREFIX_PICTURE)
138 159
						+ EbcConstant.AI_MONITOR_FILE_PREFIX_PICTURE.length();
139 160
				String fileName = pictureUrl.substring(picturePrefixIndex, picturePrefixIndex + 4) + "-"
@ -165,11 +186,29 @@ public class AiIdenLogManageServiceImpl implements AiIdenLogManageService {
165 186
				new TypeReference<Map<String, String>>() {
166 187
				});
167 188
189
		aiIdenLogInfoMap.put("taskExecuteTime",
190
				DateUtil.formatDate(Long.valueOf(aiIdenLogInfoMap.get("taskExecuteTime"))));
191
168 192
		// 结果详情
169 193
		if (StringUtils.isNotEmpty(aiIdenLog.getIdenResult())) {
170
			List<Map<String, String>> idenResultList = JSONArray.parseObject(aiIdenLog.getIdenResult(), List.class);
171
			if (!CollectionUtils.isEmpty(idenResultList)) {
172
				aiIdenLogInfoMap.putAll(idenResultList.get(0));
194
			Object idenResultObject = JSON.parse(aiIdenLog.getIdenResult());
195
			if (idenResultObject instanceof JSONObject) {
196
				Map<String, String> idenResultMap = JSON.parseObject(aiIdenLog.getIdenResult(), Map.class);
197
				aiIdenLogInfoMap.putAll(idenResultMap);
198
199
				if (idenResultMap.get("simi") != null) {
200
					Object simiObject = idenResultMap.get("simi");
201
					BigDecimal simiBigDecimal = new BigDecimal(String.valueOf(simiObject));
202
					float simi = simiBigDecimal.multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP)
203
							.floatValue();
204
					aiIdenLogInfoMap.put("simi", simi + "%");
205
				}
206
207
			} else if (idenResultObject instanceof JSONArray) {
208
				List<Map<String, String>> idenResultList = JSONArray.parseObject(aiIdenLog.getIdenResult(), List.class);
209
				if (!CollectionUtils.isEmpty(idenResultList)) {
210
					aiIdenLogInfoMap.putAll(idenResultList.get(0));
211
				}
173 212
			}
174 213
		}
175 214
@ -186,6 +225,10 @@ public class AiIdenLogManageServiceImpl implements AiIdenLogManageService {
186 225
				aiIdenLogInfoMap.put("employeeName", employeeResponse.getData().getName());
187 226
				aiIdenLogInfoMap.put("employeeCode", employeeResponse.getData().getCode());
188 227
228
				String headerImageName = employeeResponse.getData().getField1();
229
				String headerImage = uploadFileService.getFileUrl(headerImageName, minioConfig.getBucketHeaderImage());
230
				aiIdenLogInfoMap.put("headerImage", headerImage);
231
189 232
				/*
190 233
				String employeePosition = employeeResponse.getData().getMainJobPosition();
191 234
				aiIdenLogInfoMap.put("employeePosition", employeePosition);
@ -226,6 +269,73 @@ public class AiIdenLogManageServiceImpl implements AiIdenLogManageService {
226 269
	}
227 270
228 271
	@Override
272
	public CommonResponse<List<Map<String, Object>>> selectLastAiIdenLog(Map<String, String> params) throws Exception {
273
		CommonRequest<Map<String, String>> request = new CommonRequest<Map<String, String>>(params);
274
		CommonResponse<List<Map<String, Object>>> response = aiTaskQuery
275
				.selectAiIdenLogBySceneIdAndAiIdenModel(request);
276
277
		if (response == null || response.getData() == null || CollectionUtils.isEmpty(response.getData())) {
278
			return response;
279
		}
280
281
		for (Map<String, Object> dataMap : response.getData()) {
282
			dataMap.put("taskExecuteTime", DateUtil.formatObjectToDate(dataMap.get("taskExecuteTime")));
283
284
			String idenPictureName = String.valueOf(dataMap.get("idenPictureUrl"));
285
			String idenPictureUrl = uploadFileService.getFileUrl(idenPictureName);
286
			dataMap.put("idenPictureUrl", idenPictureUrl);
287
288
			// 结果详情
289
			String idenResultString = dataMap.get("idenResult") == null ? ""
290
					: String.valueOf(dataMap.get("idenResult"));
291
			if (StringUtils.isNotEmpty(idenResultString)) {
292
				Object idenResultObject = JSON.parse(idenResultString);
293
				if (idenResultObject instanceof JSONObject) {
294
					Map<String, String> idenResultMap = JSON.parseObject(idenResultString, Map.class);
295
					dataMap.putAll(idenResultMap);
296
297
					if (idenResultMap.get("simi") != null) {
298
						Object simiObject = idenResultMap.get("simi");
299
						BigDecimal simiBigDecimal = new BigDecimal(String.valueOf(simiObject));
300
						float simi = simiBigDecimal.multiply(new BigDecimal("100"))
301
								.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
302
						dataMap.put("simi", simi + "%");
303
					}
304
305
				} else if (idenResultObject instanceof JSONArray) {
306
					List<Map<String, String>> idenResultList = JSONArray.parseObject(idenResultString, List.class);
307
					if (!CollectionUtils.isEmpty(idenResultList)) {
308
						dataMap.putAll(idenResultList.get(0));
309
					}
310
				}
311
			}
312
313
			// 员工信息
314
			if (dataMap.get("relateEmployeeRoleId") != null) {
315
				long relateEmployeeRoleId = Long.parseLong(String.valueOf(dataMap.get("relateEmployeeRoleId")));
316
317
				EmployeeDto employeeDto = new EmployeeDto();
318
				employeeDto.setId(relateEmployeeRoleId);
319
				CommonRequest<EmployeeDto> requestEmployeeDto = CommonRequest.<EmployeeDto>builder().data(employeeDto)
320
						.build();
321
				CommonResponse<EmployeeDto> employeeResponse = employeeService.queryEmployee(requestEmployeeDto);
322
323
				if (employeeResponse.getData() != null) {
324
					dataMap.put("employeeName", employeeResponse.getData().getName());
325
					dataMap.put("employeeCode", employeeResponse.getData().getCode());
326
327
					String headerImageName = employeeResponse.getData().getField1();
328
					String headerImage = uploadFileService.getFileUrl(headerImageName,
329
							minioConfig.getBucketHeaderImage());
330
					dataMap.put("headerImage", headerImage);
331
				}
332
			}
333
		}
334
335
		return response;
336
	}
337
338
	@Override
229 339
	public CommonResponse<AiIdenLog> createAiIdenLog(AiIdenLog aiIdenLog) throws Exception {
230 340
		CommonRequest<AiIdenLog> aiIdenLogRequest = new CommonRequest<AiIdenLog>(aiIdenLog);
231 341
		return aiTaskCommand.createAiIdenLog(aiIdenLogRequest);

+ 8 - 0
security-protection-service/src/main/java/com/ai/bss/security/protection/service/interfaces/AiIdenLogManageService.java

@ -45,6 +45,14 @@ public interface AiIdenLogManageService {
45 45
	CommonResponse<Map<String, Object>> queryOneAiIdenLog(Long aiIdenLogId) throws Exception;
46 46
47 47
	/**
48
	 * 查询所有设备最后一个识别记录
49
	 * @param params
50
	 * @return
51
	 * @throws Exception
52
	 */
53
	CommonResponse<List<Map<String, Object>>> selectLastAiIdenLog(Map<String, String> params) throws Exception;
54
	
55
	/**
48 56
	 * 创建AI执行结果
49 57
	 * @param aiIdenLog
50 58
	 * @return

+ 1 - 1
security-protection-service/src/main/java/com/ai/bss/security/protection/service/interfaces/ResourceToolManageService.java

@ -84,7 +84,7 @@ public interface ResourceToolManageService {
84 84
	Map<String, String> uploadResourceToolPicture(MultipartFile meFile, String pictureUrl) throws Exception;
85 85
	
86 86
	/**
87
	 * 根据设备CODE获取场景、AI任务等相关信息
87
	 * 根据设备CODE获取AI任务等相关信息
88 88
	 * @param resourceToolCode
89 89
	 * @return
90 90
	 */

+ 30 - 11
security-protection-service/src/main/java/com/ai/bss/security/protection/service/task/AiResultRecordKafkaTask.java

@ -14,8 +14,9 @@ import com.ai.abc.api.model.CommonRequest;
14 14
import com.ai.abc.api.model.CommonResponse;
15 15
import com.ai.abc.util.JsonUtils;
16 16
import com.ai.bss.security.protection.service.interfaces.AiIdenLogManageService;
17
import com.ai.bss.security.protection.service.interfaces.ResourceToolManageService;
18 17
import com.ai.bss.security.protection.utils.EbcConstant;
18
import com.ai.bss.user.dto.EmployeeDto;
19
import com.ai.bss.user.service.api.EmployeeService;
19 20
import com.ai.bss.work.safety.model.AiIdenLog;
20 21
import com.ai.bss.work.safety.service.api.AiTaskCommand;
21 22
import com.ai.bss.work.safety.service.api.MonitorSceneQuery;
@ -38,14 +39,14 @@ public class AiResultRecordKafkaTask {
38 39
	private AiTaskCommand aiTaskCommand;
39 40
40 41
	@Autowired
41
	private ResourceToolManageService resourceToolManageService;
42
43
	@Autowired
44 42
	private MonitorSceneQuery monitorSceneQuery;
45 43
46 44
	@Autowired
47 45
	private AiIdenLogManageService aiIdenLogManageService;
48 46
47
	@Autowired
48
	private EmployeeService employeeService;
49
49 50
	@KafkaListener(containerFactory = "kafkaBatchListener6", topics = "${kafka.topic.aitask:topic_ai_task}", groupId = "ai_group")
50 51
	public void AiResultRecordListener(ConsumerRecord<String, String> records, Acknowledgment ack) throws Throwable {
51 52
		try {
@ -54,11 +55,15 @@ public class AiResultRecordKafkaTask {
54 55
			String message = records.value();
55 56
			log.info("已接AI任务执行结果消息,消息为:" + message);
56 57
58
			AiIdenLog aiIdenLog = JSON.parseObject(message, new TypeReference<AiIdenLog>() {
59
			});
60
57 61
			JSONObject messageJson = JSONObject.parseObject(message);
58 62
			String resourceToolId = messageJson.getString("resourceToolId");
59 63
			String idenResultType = messageJson.getString("idenResultType");
64
			Long relateEmployeeRoleId = messageJson.getLong("relateEmployeeRoleId");
60 65
61
			// 查询相关数据
66
			// 关联场景信息
62 67
			CommonResponse<List<Map<String, Object>>> sceneTerminalRelResponse = monitorSceneQuery
63 68
					.selectSceneTerminalRel(new CommonRequest<Long>(Long.valueOf(resourceToolId)));
64 69
			if (sceneTerminalRelResponse == null || CollectionUtils.isEmpty(sceneTerminalRelResponse.getData())) {
@ -68,9 +73,6 @@ public class AiResultRecordKafkaTask {
68 73
69 74
			Map<String, Object> sceneTerminalRelMap = sceneTerminalRelResponse.getData().get(0);
70 75
71
			// 封装数据
72
			AiIdenLog aiIdenLog = JSON.parseObject(message, new TypeReference<AiIdenLog>() {
73
			});
74 76
			aiIdenLog.setMonitorSceneId(sceneTerminalRelMap.get("monitorSceneId") == null ? ""
75 77
					: String.valueOf(sceneTerminalRelMap.get("monitorSceneId")));
76 78
			aiIdenLog.setMonitorSceneName(sceneTerminalRelMap.get("monitorSceneName") == null ? ""
@ -82,9 +84,26 @@ public class AiResultRecordKafkaTask {
82 84
			aiIdenLog.setOrganizationId(
83 85
					sceneTerminalRelMap.get("orgId") == null ? "" : String.valueOf(sceneTerminalRelMap.get("orgId")));
84 86
85
			// TODO 人员信息暂时默认
86
			aiIdenLog.setRelateEmployeeRoleId("201613310867");
87
			aiIdenLog.setRelateEmployeeRoleName("王浩");
87
			// 关联员工信息
88
			EmployeeDto employeeDto = null;
89
			if (relateEmployeeRoleId != null) {
90
				employeeDto = new EmployeeDto();
91
				employeeDto.setId(relateEmployeeRoleId);
92
				CommonRequest<EmployeeDto> employeeDtoRequest = new CommonRequest<EmployeeDto>(employeeDto);
93
				CommonResponse<EmployeeDto> employeeDtoResponse = employeeService.queryEmployee(employeeDtoRequest);
94
				if (employeeDtoResponse == null || employeeDtoResponse.getData() == null) {
95
					employeeDto = null;
96
				} else {
97
					employeeDto = employeeDtoResponse.getData();
98
				}
99
			}
100
			if (employeeDto != null) {
101
				aiIdenLog.setRelateEmployeeRoleName(employeeDto.getName());
102
				aiIdenLog.setOrganizationId(String.valueOf(employeeDto.getOrganizeId()));
103
			} else {
104
				aiIdenLog.setRelateEmployeeRoleId("-1");
105
				aiIdenLog.setRelateEmployeeRoleName(null);
106
			}
88 107
89 108
			// 执行操作
90 109
			CommonResponse<AiIdenLog> aiIdenLogRunningResult = aiIdenLogManageService.createAiIdenLog(aiIdenLog);