Explorar el Código

【新增】 算法模块代码合入

linfutong hace 3 años
padre
commit
c6534e76ee
Se han modificado 75 ficheros con 8375 adiciones y 21 borrados
  1. 72 2
      zd-modules/zd-algorithm/pom.xml
  2. 7 7
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/AlgorithmApplication.java
  3. 73 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/controller/AlarmController.java
  4. 107 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/domain/AlarmLog.java
  5. 63 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/mapper/AlarmLogMapper.java
  6. 236 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/mqtt/MqttConfig.java
  7. 63 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/service/IAlarmLogService.java
  8. 93 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/service/impl/AlarmLogServiceImpl.java
  9. 126 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/utils/AlarmUtil.java
  10. 0 2
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/controller/TestController.java
  11. 137 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/config/FaceProperties.java
  12. 105 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/controller/FaceApi.java
  13. 138 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/controller/FaceManagerApi.java
  14. 170 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/handle/FaceEngineFactory.java
  15. 27 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/handle/SDKRegister.java
  16. 100 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/service/FaceService.java
  17. 29 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/utils/FileUtil.java
  18. 26 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/valid/KeyNotNull.java
  19. 26 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/valid/KeyValidator.java
  20. 126 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SlApplyApprovalController.java
  21. 197 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SlOpendoorApplyController.java
  22. 191 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SlSubjectRelationController.java
  23. 121 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SlUserRelationController.java
  24. 53 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SmartlockController.java
  25. 70 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/BaseDomain.java
  26. 99 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/SlApplyApproval.java
  27. 300 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/SlOpendoorApply.java
  28. 188 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/SlSubjectRelation.java
  29. 86 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/SlUserRelation.java
  30. 104 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlBuild.java
  31. 84 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlDoorLock.java
  32. 58 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlGroup.java
  33. 42 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlLockOnline.java
  34. 80 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlOpenAndClosLog.java
  35. 82 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlOpenDoorSearch.java
  36. 123 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlPostUser.java
  37. 157 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlRoom.java
  38. 74 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlUser.java
  39. 32 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlupdateAuths.java
  40. 67 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/vo/SlOpendoorApplyVo.java
  41. 25 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/vo/SlSubjectRelationVo.java
  42. 69 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/mapper/SlApplyApprovalMapper.java
  43. 71 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/mapper/SlOpendoorApplyMapper.java
  44. 70 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/mapper/SlSubjectRelationMapper.java
  45. 69 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/mapper/SlUserRelationMapper.java
  46. 81 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/ISlApplyApprovalService.java
  47. 86 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/ISlOpendoorApplyService.java
  48. 71 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/ISlSubjectRelationService.java
  49. 70 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/ISlUserRelationService.java
  50. 410 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/impl/SlApplyApprovalServiceImpl.java
  51. 276 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/impl/SlOpendoorApplyServiceImpl.java
  52. 146 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/impl/SlSubjectRelationServiceImpl.java
  53. 108 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/impl/SlUserRelationServiceImpl.java
  54. 629 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/utils/SmartlockUtil.java
  55. 15 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/Interceptor/NetInterceptor.java
  56. 89 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/config/OkHttpConfiguration.java
  57. 232 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/controller/SpeakerController.java
  58. 80 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/RemoteAddress.java
  59. 42 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/vo/ParamVo.java
  60. 73 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/vo/PlayBatchVo.java
  61. 106 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/vo/PlayVo.java
  62. 38 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/vo/UrlVo.java
  63. 107 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/service/ISpeakerService.java
  64. 316 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/service/impl/SpeakerServiceImpl.java
  65. 186 0
      zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/utils/OkHttpRequest.java
  66. 40 0
      zd-modules/zd-algorithm/src/main/resources/application.yml
  67. 10 0
      zd-modules/zd-algorithm/src/main/resources/banner.txt
  68. 5 10
      zd-modules/zd-algorithm/src/main/resources/bootstrap.yml
  69. BIN
      zd-modules/zd-algorithm/src/main/resources/libs/arcsoft-sdk-face-3.0.0.0.jar
  70. 74 0
      zd-modules/zd-algorithm/src/main/resources/logback.xml
  71. 119 0
      zd-modules/zd-algorithm/src/main/resources/mapper/alarm/AlarmLogMapper.xml
  72. 125 0
      zd-modules/zd-algorithm/src/main/resources/mapper/smartlock/SlApplyApprovalMapper.xml
  73. 285 0
      zd-modules/zd-algorithm/src/main/resources/mapper/smartlock/SlOpendoorApplyMapper.xml
  74. 191 0
      zd-modules/zd-algorithm/src/main/resources/mapper/smartlock/SlSubjectRelationMapper.xml
  75. 129 0
      zd-modules/zd-algorithm/src/main/resources/mapper/smartlock/SlUserRelationMapper.xml

+ 72 - 2
zd-modules/zd-algorithm/pom.xml

@@ -14,18 +14,88 @@
     <description>算法服务</description>
 
     <dependencies>
+        <!-- SpringCloud Alibaba Nacos -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Alibaba Nacos Config -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+        <!-- SpringBoot Actuator -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+
+        <!-- Mysql Connector -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <!-- zd Common DataSource -->
         <dependency>
             <groupId>com.zd</groupId>
-            <artifactId>zd-common-core</artifactId>
+            <artifactId>zd-common-datasource</artifactId>
         </dependency>
+
         <!-- SpringBoot Web -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
+        <!-- zd Common Log -->
+        <dependency>
+            <groupId>com.zd</groupId>
+            <artifactId>zd-common-log</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.zd</groupId>
+            <artifactId>zd-common-datascope</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.zd</groupId>
-            <artifactId>zd-common-security</artifactId>
+            <artifactId>zd-common-mqtt</artifactId>
+        </dependency>
+
+        <!--mqtt客户端链接服务-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-integration</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-stream</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-mqtt</artifactId>
+        </dependency>
+
+        <!-- zd okhttp -->
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>3.10.0</version>
+        </dependency>
+
+        <!-- zd Common Swagger -->
+        <dependency>
+            <groupId>com.zd</groupId>
+            <artifactId>zd-common-swagger</artifactId>
+        </dependency>
+
+        <!-- 人脸对接  -->
+        <dependency>
+            <groupId>arcsoft</groupId>
+            <artifactId>arcsoft-sdk-face</artifactId>
+            <version>3.0.0.0</version>
+            <scope>system</scope>
+            <systemPath>${pom.basedir}/src/main/resources/libs/arcsoft-sdk-face-3.0.0.0.jar</systemPath>
         </dependency>
     </dependencies>
 </project>

+ 7 - 7
zd-modules/zd-algorithm/src/main/java/com/zd/alg/AlgorithmApplication.java

@@ -1,16 +1,16 @@
 package com.zd.alg;
 
+
+import com.zd.common.security.annotation.EnableCustomConfig;
+import com.zd.common.security.annotation.EnableRyFeignClients;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.web.servlet.ServletComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import springfox.documentation.oas.annotations.EnableOpenApi;
-
 
-@ServletComponentScan("com.zd.iot.vmp.conf")
+@EnableCustomConfig
+@EnableRyFeignClients
 @SpringBootApplication
-@EnableScheduling
-@EnableOpenApi
+@Slf4j
 public class AlgorithmApplication {
 
     public static void main(String[] args) {

+ 73 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/controller/AlarmController.java

@@ -0,0 +1,73 @@
+package com.zd.alg.alarm.controller;
+
+import com.zd.alg.alarm.domain.AlarmLog;
+import com.zd.alg.alarm.service.IAlarmLogService;
+import com.zd.alg.alarm.utils.AlarmUtil;
+import com.zd.common.core.utils.DateUtils;
+import com.zd.common.core.web.domain.AjaxResult;
+import com.zd.system.api.alarm.domain.AlarmEntrty;
+import com.zd.system.api.alarm.domain.SendTypes;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping("/alarm")
+public class AlarmController {
+
+    @Autowired
+    private AlarmUtil alarmUtil;
+
+    @Autowired
+    private IAlarmLogService alarmLogService;
+
+    @PostMapping("/send")
+    public AjaxResult queryOption(@RequestBody AlarmEntrty alarmEntrty) {
+        Map<String, String> map = alarmUtil.sendPost(alarmEntrty);
+
+        String data = map.get("Reply");
+        if((SendTypes.Call + "").equals(alarmEntrty.getType()) || (SendTypes.All + "").equals(alarmEntrty.getType())){
+            if("OK".equals(data)) {
+                String[] phones = alarmEntrty.getTo();
+                for (String phone : phones) {
+                    AlarmLog alarmLog = new AlarmLog();
+                    alarmLog.setIsBack(1);
+                    alarmLog.setPhone(phone);
+                    alarmLog.setNotice(alarmEntrty.getText());
+                    alarmLog.setMethod("电话");
+                    alarmLog.setStatus("成功");
+                    alarmLog.setCreateTime(DateUtils.getNowDate());
+                    alarmLog.setUpdateTime(DateUtils.getNowDate());
+
+                    alarmLogService.insertAlarmLog(alarmLog);
+                }
+                return AjaxResult.success();
+            }else {
+                String[] phones = alarmEntrty.getTo();
+                for (String phone : phones) {
+                    AlarmLog alarmLog = new AlarmLog();
+                    alarmLog.setIsBack(1);
+                    alarmLog.setPhone(phone);
+                    alarmLog.setNotice(alarmEntrty.getText());
+                    alarmLog.setMethod("电话");
+                    alarmLog.setStatus("失败");
+                    alarmLog.setRemark(data);
+                    alarmLog.setCreateTime(DateUtils.getNowDate());
+                    alarmLog.setUpdateTime(DateUtils.getNowDate());
+
+                    alarmLogService.insertAlarmLog(alarmLog);
+                }
+                return AjaxResult.error(data);
+            }
+        }else if((SendTypes.SMS + "").equals(alarmEntrty.getType())) {
+            if ("OK".equals(data)) {
+                return AjaxResult.success();
+            }
+        }
+        return AjaxResult.error("报警发送错误:" + data);
+    }
+}

+ 107 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/domain/AlarmLog.java

@@ -0,0 +1,107 @@
+package com.zd.alg.alarm.domain;
+
+import cn.hutool.json.JSONUtil;
+import com.zd.common.core.annotation.Excel;
+import com.zd.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 电话报警推送日志对象 alarm_log
+ *
+ * @author liubo
+ * @date 2021-11-11
+ */
+@ApiModel("电话报警推送日志")
+public class AlarmLog extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * $column.columnComment
+     */
+    @ApiModelProperty(value = "${comment}")
+    private Long id;
+    /**
+     * 电话号码
+     */
+    @Excel(name = "电话号码")
+    @ApiModelProperty(value = "电话号码")
+    private String phone;
+    /**
+     * 报警状态(字符串)
+     */
+    @Excel(name = "报警状态", readConverterExp = "字=符串")
+    @ApiModelProperty(value = "报警状态")
+    private String status;
+    /**
+     * 报警内容
+     */
+    @Excel(name = "报警内容")
+    @ApiModelProperty(value = "报警内容")
+    private String notice;
+    /**
+     * 报警方式
+     */
+    @Excel(name = "报警方式")
+    @ApiModelProperty(value = "报警方式")
+    private String method;
+    /**
+     * 是否回写(0 默认,1 已回写)
+     */
+    @Excel(name = "是否回写", readConverterExp = "0=默认,1=已回写")
+    @ApiModelProperty(value = "是否回写")
+    private Integer isBack;
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setNotice(String notice) {
+        this.notice = notice;
+    }
+
+    public String getNotice() {
+        return notice;
+    }
+
+    public void setMethod(String method) {
+        this.method = method;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public void setIsBack(Integer isBack) {
+        this.isBack = isBack;
+    }
+
+    public Integer getIsBack() {
+        return isBack;
+    }
+
+    @Override
+    public String toString() {
+        return JSONUtil.toJsonStr(this);
+    }
+}

+ 63 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/mapper/AlarmLogMapper.java

@@ -0,0 +1,63 @@
+package com.zd.alg.alarm.mapper;
+
+import com.zd.alg.alarm.domain.AlarmLog;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 电话报警推送日志Mapper接口
+ *
+ * @author liubo
+ * @date 2021-11-11
+ */
+public interface AlarmLogMapper {
+    /**
+     * 查询电话报警推送日志
+     *
+     * @param id 电话报警推送日志主键
+     * @return 电话报警推送日志
+     */
+    public AlarmLog selectAlarmLogById(Long id);
+
+    /**
+     * 查询电话报警推送日志列表
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 电话报警推送日志集合
+     */
+    public List<AlarmLog> selectAlarmLogList(AlarmLog alarmLog);
+
+    /**
+     * 新增电话报警推送日志
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 结果
+     */
+    public int insertAlarmLog(AlarmLog alarmLog);
+
+    /**
+     * 修改电话报警推送日志
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 结果
+     */
+    public int updateAlarmLog(AlarmLog alarmLog);
+
+    /**
+     * 删除电话报警推送日志
+     *
+     * @param id 电话报警推送日志主键
+     * @return 结果
+     */
+    public int deleteAlarmLogById(Long id);
+
+    /**
+     * 批量删除电话报警推送日志
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteAlarmLogByIds(Long[] ids);
+
+    List<AlarmLog> selectNoBackAlarmLogList(Map<String, Object> params);
+}

+ 236 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/mqtt/MqttConfig.java

@@ -0,0 +1,236 @@
+package com.zd.alg.alarm.mqtt;
+
+import com.alibaba.druid.support.json.JSONUtils;
+import com.alibaba.fastjson.JSON;
+import com.zd.alg.alarm.domain.AlarmLog;
+import com.zd.alg.alarm.service.IAlarmLogService;
+import com.zd.alg.alarm.utils.AlarmUtil;
+import com.zd.common.core.utils.DateUtils;
+import com.zd.system.api.alarm.domain.AlarmEntrty;
+import com.zd.system.api.alarm.domain.Routes;
+import com.zd.system.api.alarm.domain.SendTypes;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.core.MessageProducer;
+import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
+import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
+import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
+import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
+import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
+import org.springframework.integration.mqtt.support.MqttHeaders;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.MessageHandler;
+import org.springframework.messaging.MessagingException;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * mqtt配置
+ */
+@Configuration
+public class MqttConfig {
+
+    @Autowired
+    private AlarmUtil alarmUtil;
+    @Autowired
+    private IAlarmLogService alarmLogService;
+
+    static Logger logger = LoggerFactory.getLogger(MqttConfig.class);
+
+    private static final byte[] WILL_DATA;
+
+    static {
+        WILL_DATA = "offline".getBytes();
+    }
+
+    public static final String MQTT_INBOUND_CHANNEL = "mqttInboundChannel";
+
+
+    public static final String MQTT_OUTBOUND_CHANNEL = "mqttOutboundChannel";
+
+    @Value("${mqtt.username:}")
+    private String username;
+
+    @Value("${mqtt.password:}")
+    private String password;
+
+    @Value("${mqtt.url}")
+    private String url;
+
+    @Value("${mqtt.defaultTopic}")
+    private String defaultTopic;
+
+    @Value("${mqtt.producer.clientId}")
+    private String producerClientId;
+
+    @Value("${mqtt.consumer.clientId}")
+    private String consumerClientId;
+
+    @Value("${mqtt.consumer.maxInflight}")
+    private Integer maxInflight;
+
+    private MqttPahoMessageDrivenChannelAdapter adapter;
+
+    /**
+     * 连接mqtt配置
+     */
+    @Bean
+    public MqttConnectOptions mqttConnectOptions() {
+        MqttConnectOptions options = new MqttConnectOptions();
+        // false,服务器会保留客户端的连接记录
+        // true,表示每次连接到服务器都以新的身份连接
+        options.setCleanSession(false);
+        options.setUserName(username);
+        options.setPassword(password.toCharArray());
+//        options.setMaxInflight(maxInflight);
+        options.setServerURIs(StringUtils.split(url, ","));
+        //超时时间 单位为秒
+        options.setConnectionTimeout(10);
+        //会话心跳时间 单位: s, 间隔时间:1.5*20秒向客户端发送心跳判断客户端是否在线
+        options.setKeepAliveInterval(60);
+        //设置“遗嘱”消息的话题,若客户端与服务器之间的连接意外中断,服务器将发布客户端的“遗嘱”消息。
+//        options.setWill("willTopic", WILL_DATA, 2, false);
+        return options;
+    }
+
+
+    /**
+     * MQTT客户端
+     */
+    @Bean
+    public MqttPahoClientFactory mqttClientFactory() {
+        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
+        factory.setConnectionOptions(mqttConnectOptions());
+        return factory;
+    }
+
+    /**
+     * 发送者消息通道
+     */
+    @Bean(name = MQTT_OUTBOUND_CHANNEL)
+    public MessageChannel mqttOutboundChannel() {
+        return new DirectChannel();
+    }
+
+    /**
+     * 发送者消息处理
+     */
+    @Bean
+    @ServiceActivator(inputChannel = MQTT_OUTBOUND_CHANNEL)
+    public MessageHandler mqttOutbound() {
+        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(
+                producerClientId,
+                mqttClientFactory());
+        messageHandler.setAsync(true);
+        messageHandler.setDefaultTopic(defaultTopic);
+        return messageHandler;
+    }
+
+    /**
+     * 消息订阅
+     */
+    @Bean
+    public MessageProducer inbound() {
+        // 可同时消费(订阅)多个Topic
+        adapter = new MqttPahoMessageDrivenChannelAdapter(consumerClientId, mqttClientFactory(), StringUtils.split(defaultTopic, ","));
+        adapter.setCompletionTimeout(5000);
+        adapter.setConverter(new DefaultPahoMessageConverter());
+        adapter.setQos(2);
+        // 设置订阅通道
+        adapter.setOutputChannel(mqttInboundChannel());
+        return adapter;
+    }
+
+
+    /**
+     * 消费者消息通道
+     */
+    @Bean(name = MQTT_INBOUND_CHANNEL)
+    public MessageChannel mqttInboundChannel() {
+        return new DirectChannel();
+    }
+
+    /**
+     * 消费者消息处理
+     *设备心跳
+     */
+    @Bean
+    @ServiceActivator(inputChannel = MQTT_INBOUND_CHANNEL)
+    public MessageHandler mqttInbound() {
+
+        return new MessageHandler() {
+            @Override
+            public void handleMessage(Message<?> message) throws MessagingException {
+                String receivedTopic = (String) message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC);
+
+                logger.info("MQTT 接收 topic:  {}",receivedTopic);
+
+                String msg = (String) message.getPayload();
+                logger.info("MQTT 接收 消息体:  {}",msg);
+
+                try {
+                    String type = SendTypes.All+"";
+                    Map<String,Object> map = JSON.parseObject(msg, Map.class);
+
+                    map = JSON.parseObject(map.get("data")+"", Map.class);
+
+                    String text = (String) map.get("text");
+                    List<String> list = JSON.parseArray(map.get("to")+"", String.class);
+                    if(CollectionUtils.isEmpty(list)){
+                        logger.error("接收告警消息手机号为空!");
+                        return;
+                    }
+
+                    Set<String> set = new HashSet<>(list);
+                    String[] to = new String[set.size()];
+                    set.toArray(to);
+
+                    String dataType = (String) map.get("type");
+                    if(map.get("type") != null && ((SendTypes.All+"").equals(dataType)
+                            || (SendTypes.Call+"").equals(dataType) || (SendTypes.SMS+"").equals(dataType))){
+                        type = dataType;
+                    }
+
+                    AlarmEntrty alarmEntrty = new AlarmEntrty(Routes.NoticePush, to, type, text);
+
+                    map = alarmUtil.sendPost(alarmEntrty);
+
+                    String data = (String) map.get("Reply");
+                    if("OK".equals(data)){
+                        String[] phones = alarmEntrty.getTo();
+                        for (String phone : phones) {
+                            AlarmLog alarmLog = new AlarmLog();
+                            alarmLog.setRemark("预案ID/实验室ID: " + receivedTopic.replace(defaultTopic, ""));
+                            alarmLog.setIsBack(0);
+                            alarmLog.setStatus("失败");
+                            alarmLog.setPhone(phone);
+                            alarmLog.setNotice(alarmEntrty.getText());
+                            alarmLog.setCreateTime(DateUtils.getNowDate());
+
+                            alarmLogService.insertAlarmLog(alarmLog);
+                        }
+                    }else {
+                        logger.error("报警电话推送错误:" + JSONUtils.toJSONString(map));
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                    logger.error("报警处理数据异常:" + e.getMessage());
+                }
+
+            }
+        };
+    }
+}

+ 63 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/service/IAlarmLogService.java

@@ -0,0 +1,63 @@
+package com.zd.alg.alarm.service;
+
+import com.zd.alg.alarm.domain.AlarmLog;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 电话报警推送日志Service接口
+ *
+ * @author liubo
+ * @date 2021-11-11
+ */
+public interface IAlarmLogService {
+    /**
+     * 查询电话报警推送日志
+     *
+     * @param id 电话报警推送日志主键
+     * @return 电话报警推送日志
+     */
+    public AlarmLog selectAlarmLogById(Long id);
+
+    /**
+     * 查询电话报警推送日志列表
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 电话报警推送日志集合
+     */
+    public List<AlarmLog> selectAlarmLogList(AlarmLog alarmLog);
+
+    /**
+     * 新增电话报警推送日志
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 结果
+     */
+    public int insertAlarmLog(AlarmLog alarmLog);
+
+    /**
+     * 修改电话报警推送日志
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 结果
+     */
+    public int updateAlarmLog(AlarmLog alarmLog);
+
+    /**
+     * 批量删除电话报警推送日志
+     *
+     * @param ids 需要删除的电话报警推送日志主键集合
+     * @return 结果
+     */
+    public int deleteAlarmLogByIds(Long[] ids);
+
+    /**
+     * 删除电话报警推送日志信息
+     *
+     * @param id 电话报警推送日志主键
+     * @return 结果
+     */
+    public int deleteAlarmLogById(Long id);
+
+    List<AlarmLog> selectNoBackAlarmLogList(Map<String, Object> params);
+}

+ 93 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/service/impl/AlarmLogServiceImpl.java

@@ -0,0 +1,93 @@
+package com.zd.alg.alarm.service.impl;
+
+import com.zd.alg.alarm.domain.AlarmLog;
+import com.zd.alg.alarm.mapper.AlarmLogMapper;
+import com.zd.alg.alarm.service.IAlarmLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 电话报警推送日志Service业务层处理
+ *
+ * @author liubo
+ * @date 2021-11-11
+ */
+@Service
+public class AlarmLogServiceImpl implements IAlarmLogService {
+    @Autowired
+    private AlarmLogMapper alarmLogMapper;
+
+    /**
+     * 查询电话报警推送日志
+     *
+     * @param id 电话报警推送日志主键
+     * @return 电话报警推送日志
+     */
+    @Override
+    public AlarmLog selectAlarmLogById(Long id) {
+        return alarmLogMapper.selectAlarmLogById(id);
+    }
+
+    /**
+     * 查询电话报警推送日志列表
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 电话报警推送日志
+     */
+    @Override
+    public List<AlarmLog> selectAlarmLogList(AlarmLog alarmLog) {
+        return alarmLogMapper.selectAlarmLogList(alarmLog);
+    }
+
+    /**
+     * 新增电话报警推送日志
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 结果
+     */
+    @Override
+    public int insertAlarmLog(AlarmLog alarmLog) {
+        return alarmLogMapper.insertAlarmLog(alarmLog);
+    }
+
+    /**
+     * 修改电话报警推送日志
+     *
+     * @param alarmLog 电话报警推送日志
+     * @return 结果
+     */
+    @Override
+    public int updateAlarmLog(AlarmLog alarmLog) {
+        return alarmLogMapper.updateAlarmLog(alarmLog);
+    }
+
+    /**
+     * 批量删除电话报警推送日志
+     *
+     * @param ids 需要删除的电话报警推送日志主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlarmLogByIds(Long[] ids) {
+        return alarmLogMapper.deleteAlarmLogByIds(ids);
+    }
+
+    /**
+     * 删除电话报警推送日志信息
+     *
+     * @param id 电话报警推送日志主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlarmLogById(Long id) {
+        return alarmLogMapper.deleteAlarmLogById(id);
+    }
+
+    @Override
+    public List<AlarmLog> selectNoBackAlarmLogList(Map<String, Object> params) {
+        return alarmLogMapper.selectNoBackAlarmLogList(params);
+    }
+}

+ 126 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/alarm/utils/AlarmUtil.java

@@ -0,0 +1,126 @@
+package com.zd.alg.alarm.utils;
+
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.zd.alg.alarm.domain.AlarmLog;
+import com.zd.alg.alarm.service.IAlarmLogService;
+import com.zd.common.core.utils.DateUtils;
+import com.zd.system.api.alarm.domain.AlarmEntrty;
+import com.zd.system.api.alarm.domain.Routes;
+import com.zd.system.api.alarm.domain.SendTypes;
+import org.apache.commons.collections4.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.validation.constraints.NotNull;
+import java.util.*;
+
+/**
+ * 报警工具类
+ * @author liubo
+ */
+@Component
+@EnableScheduling
+public class AlarmUtil {
+    private static final Logger logger = LoggerFactory.getLogger(AlarmUtil.class);
+
+    @Value("${alarm.host}")
+    private String alarmUrl ;
+
+    @Value("${alarm.retry}")
+    private Integer retryCount ;
+
+    @Autowired
+    private IAlarmLogService alarmLogService;
+
+
+    /**
+     * 链接超时 项目启动会失败
+     */
+    @PostConstruct
+    private void alarmInint(){
+        sendGet(Routes.SystemStatusSnapshot);
+        sendPost(new AlarmEntrty(Routes.NoticePush, new String[]{"18681887295"}, SendTypes.Call+"","启动项目电话报警服务测试!"));
+    }
+
+    /**
+     * 发送语音报警对接功能
+     */
+    public Map sendPost(AlarmEntrty alarmEntrty) {
+        logger.info("语音报警发送内容:" + alarmEntrty.toString());
+
+        String url = alarmUrl + alarmEntrty.getRoute().getUrl();
+
+        String result = HttpUtil.post(url, alarmEntrty.toString());
+
+        logger.info("语音报警发送结果:" + result);
+        Map<String, String> map = JSONObject.parseObject(result, Map.class);
+        return map;
+    }
+
+    /**
+     * 发送除语音报警 的其他功能
+     */
+    public String sendGet(@NotNull Routes route){
+        return HttpUtil.get(alarmUrl + route.getUrl(), 3000);
+    }
+
+
+
+    /**
+     * 定时检测 重试
+     */
+    @Scheduled(fixedRate=60 * 1000)
+    public void timerCount(){
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("retryCount", retryCount);
+        params.put("date", DateUtils.getNowDate());
+        List<AlarmLog> alarmLogs = alarmLogService.selectNoBackAlarmLogList(params);
+        if(CollectionUtils.isNotEmpty(alarmLogs)){
+            String data = sendGet(Routes.NoticeResult);
+            List<Map> datas = JSONObject.parseArray(data, Map.class);
+            if(CollectionUtils.isNotEmpty(datas)){
+
+                Date date;
+                List<String> failPhones = new ArrayList<>();
+                for (AlarmLog alarmLog : alarmLogs) {
+                    for (Map map : datas) {
+
+                        if("电话".equals(map.get("method")) && alarmLog.getPhone().equals(map.get("to")) && alarmLog.getNotice().equals(map.get("notice"))){
+                            date = DateUtil.parse(map.get("time")+ "");
+                            Long timer = DateUtil.between(date, alarmLog.getCreateTime(), DateUnit.MINUTE, false);
+
+                            // 此处 > 0 校验 电话报警发送在日志记录之前
+                            // < 30 报警在 30 分钟只能完成,超过则不发
+                            if(timer <= 0 && timer > -30){
+                                alarmLog.setIsBack(alarmLog.getIsBack() + 1);
+                                alarmLog.setStatus(map.get("status")+ "");
+                                alarmLog.setMethod(map.get("method")+"");
+                                alarmLog.setUpdateTime(DateUtils.getNowDate());
+                                alarmLogService.updateAlarmLog(alarmLog);
+
+                                if("失败".equals(map.get("status"))){
+                                    System.out.println("重发数据: "+  alarmLog.toString());
+                                    // TODO 运行异常 需记录 重拨ID或手机号 避免一次运行多次拨号
+                                    if(!failPhones.contains(alarmLog.getPhone())){
+                                        failPhones.add(alarmLog.getPhone());
+                                        sendPost(new AlarmEntrty(Routes.NoticePush, new String[]{alarmLog.getPhone()}, SendTypes.Call+"", alarmLog.getNotice()));
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 0 - 2
zd-modules/zd-algorithm/src/main/java/com/zd/alg/controller/TestController.java

@@ -1,2 +0,0 @@
-package com.zd.alg.controller;public class TestController {
-}

+ 137 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/config/FaceProperties.java

@@ -0,0 +1,137 @@
+package com.zd.alg.face.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @Author: zhoupan
+ * @Date: 2021/10/12/10:39
+ * @Description:
+ */
+@ConfigurationProperties(prefix = "face" ,ignoreUnknownFields=true,ignoreInvalidFields=true)
+@Validated
+public class FaceProperties {
+
+    boolean isInit;
+
+    @NotBlank(message = "应用ID不能为空,请配置!")
+    String appId;
+
+
+//    @NotBlank(message = "sdk key 不能为空,请配置!")
+    /**
+     * 已放弃使用改为linuxKey和winKey
+     */
+    @Deprecated
+    String sdkKey;
+
+    String linuxKey;
+
+    String winKey;
+
+    public String getLinuxKey() {
+        return linuxKey;
+    }
+
+    public void setLinuxKey(String linuxKey) {
+        this.linuxKey = linuxKey;
+    }
+
+    public String getWinKey() {
+        return winKey;
+    }
+
+    public void setWinKey(String winKey) {
+        this.winKey = winKey;
+    }
+
+    /**
+     * 是否激活
+     */
+    Boolean isActivation =false;
+    /**
+     * lib路径 暂时没有业务
+     */
+    String libPath;
+
+    /**
+     * 人脸对比匹配度阈值
+     */
+    float score = 0.8f;
+
+    /**
+     * 是否打开视频引擎
+     */
+    Boolean video=false;
+
+    /**
+     * 默认 arcsoft_lib
+     */
+    String lib_folder="arcsoft_lib";
+
+    public boolean isInit() {
+        return isInit;
+    }
+
+    public void setInit(boolean init) {
+        isInit = init;
+    }
+
+    public Boolean getActivation() {
+        return isActivation;
+    }
+
+    public void setActivation(Boolean activation) {
+        isActivation = activation;
+    }
+
+    public String getLib_folder() {
+        return lib_folder;
+    }
+
+    public void setLib_folder(String lib_folder) {
+        this.lib_folder = lib_folder;
+    }
+
+    public Boolean getVideo() {
+        return video;
+    }
+
+    public void setVideo(Boolean video) {
+        this.video = video;
+    }
+
+    public float getScore() {
+        return score;
+    }
+
+    public void setScore(float score) {
+        this.score = score;
+    }
+
+    public String getLibPath() {
+        return libPath;
+    }
+
+    public void setLibPath(String libPath) {
+        this.libPath = libPath;
+    }
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public String getSdkKey() {
+        return sdkKey;
+    }
+
+    public void setSdkKey(String sdkKey) {
+        this.sdkKey = sdkKey;
+    }
+}

+ 105 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/controller/FaceApi.java

@@ -0,0 +1,105 @@
+package com.zd.alg.face.controller;
+
+import com.arcsoft.face.FaceFeature;
+import com.arcsoft.face.FaceInfo;
+import com.arcsoft.face.toolkit.ImageInfo;
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import com.zd.common.core.domain.R;
+import com.zd.common.core.web.domain.ResultData;
+import com.zd.common.swagger.config.Knife4jConfiguration;
+import com.zd.alg.face.service.FaceService;
+import com.zd.alg.face.utils.FileUtil;
+import com.zd.system.api.domain.LabStudentsInfo;
+import com.zd.system.api.face.FaceCompare;
+import com.zd.system.api.students.RemoteStudentsService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.*;
+import java.util.List;
+
+/**
+ * @Author: zhoupan
+ * @Date: 2021/10/12/13:36
+ * @Description:
+ */
+
+@Api(tags = "【人脸识别】")
+@ApiSupport(author = Knife4jConfiguration.Author.ZP)
+@RestController
+@RequestMapping("/faceApi")
+public class FaceApi {
+
+    @Autowired
+    FaceService faceService;
+
+    @Autowired
+    RemoteStudentsService remoteStudentsService;
+
+
+    @ApiOperation("根据照片文件获取特征码")
+    @PostMapping("faceFeature")
+    public ResultData faceFeature(@RequestParam("file") MultipartFile file) throws IOException {
+        ImageInfo imageInfo;
+        File file1=null;
+        try {
+            file1= FileUtil.multipartFileToFile(file);
+            imageInfo = faceService.getImageInfo(file1);
+        } finally {
+            if(file1!=null)
+            {
+                file1.delete();
+            }
+        }
+        List<FaceInfo> faceInfos = faceService.faceDetect(imageInfo);
+        FaceFeature faceFeature = faceService.faceFeature(imageInfo, faceInfos);
+        return ResultData.success(faceFeature.getFeatureData());
+    }
+    /**
+     * 人脸比较
+     * @return
+     */
+    @ApiOperation("人脸比较")
+    @PostMapping("/compare")
+    public ResultData faceDetection(@RequestBody  FaceCompare faceCompare)
+    {
+
+        R<LabStudentsInfo> info = remoteStudentsService.getInfo(faceCompare.getUserId());
+        if(info.getCode()==200&&info.getData()!=null)
+        {
+            FaceFeature target = new FaceFeature(info.getData().getFaceFeature());
+            FaceFeature source = new FaceFeature(faceCompare.getData());
+            Boolean compore = faceService.compore(target, source);
+
+            return ResultData.result(compore,()->"人脸对比不符!");
+        }else
+        {
+            return ResultData.fail("未获取到对比数据!:"+info.getMsg());
+        }
+    }
+
+
+
+    //获取流文件
+    private static void inputStreamToFile(InputStream ins, File file) {
+        try {
+            OutputStream os = new FileOutputStream(file);
+            int bytesRead = 0;
+            byte[] buffer = new byte[8192];
+            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            ins.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+
+
+
+}

+ 138 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/controller/FaceManagerApi.java

@@ -0,0 +1,138 @@
+package com.zd.alg.face.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import com.zd.common.core.domain.R;
+import com.zd.common.core.exception.ServiceException;
+import com.zd.common.core.utils.IdUtils;
+import com.zd.common.swagger.config.Knife4jConfiguration;
+import com.zd.alg.face.config.FaceProperties;
+import com.zd.alg.face.handle.FaceEngineFactory;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @Author: zhoupan
+ * @Date: 2021/10/13/13:21
+ * @Description:
+ */
+@Api(tags = "【人脸识别服务管理】")
+@ApiSupport(author = Knife4jConfiguration.Author.ZP)
+@RestController
+@RequestMapping("faceManagerApi")
+public class FaceManagerApi {
+    @Autowired
+    FaceEngineFactory faceEngineFactory;
+
+    @Autowired
+    FaceProperties faceProperties;
+
+
+    final static Set<String> libSet = new HashSet<>();
+    static {
+        libSet.add("libarcsoft_face.dll");
+        libSet.add("libarcsoft_face_engine.dll");
+        libSet.add("libarcsoft_face_engine_jni.dll");
+        libSet.add("libarcsoft_face.so");
+        libSet.add("libarcsoft_face_engine.so");
+        libSet.add("libarcsoft_face_engine_jni.so");
+
+    }
+
+
+    @PostMapping()
+    @ApiOperation("上传sdk-lib")
+    public R uploadLib(@RequestParam("files") MultipartFile [] multipartFiles) throws IOException {
+
+        String path =faceEngineFactory.getPath();
+
+//        final String path = absolutePath+ File.separator+faceProperties.getLib_folder();
+
+        //先删除原来的文件。。如果直接删除,但又没有保存成功还会导致之前的功能异常,所以这里要先保存再删除
+        //生成操作ID
+        String id= IdUtils.simpleUUID();
+
+        Map<String,MultipartFile> temp = new HashMap<>(multipartFiles.length);
+
+        for (int i = 0; i < multipartFiles.length; i++) {
+
+            String originalFilename = multipartFiles[i].getOriginalFilename();
+            if(!libSet.contains(originalFilename))
+            {
+                return R.fail("上传文件名错误,请确认为:"+libSet.stream().collect(Collectors.joining(",")));
+            }
+            temp.put( originalFilename,multipartFiles[i]);
+        }
+
+        if(CollUtil.isNotEmpty(temp))
+        {
+            try {
+                Map<String,File> tempFile = new HashMap<>(temp.size());
+                temp.forEach((k,v)->{
+                    //创建文件
+                    File touch = FileUtil.touch(path + File.separator + k+id);
+                    try {
+                        v.transferTo(touch);
+                        tempFile.put(k,touch);
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                        throw new ServiceException("创建lib文件出错:"+e.getMessage());
+                    }
+                });
+                //todo 这里应该先备份一次
+                temp.forEach((a,b)->{
+                    FileUtil.copy(path + File.separator +a,path + File.separator +a+"_copy",true);
+                });
+                try {
+                    tempFile.forEach((a,b)->{
+                        FileUtil.rename(b,path+ File.separator,true);
+                    });
+                } catch (Exception e) {
+                    //出现异常后还原文件
+                    tempFile.forEach((a,b)->{
+                        FileUtil.copy(path + File.separator +a+"_copy",path + File.separator +a,true);
+                    });
+                    throw new ServiceException("替换lib文件出错:"+e.getMessage());
+                }
+                //如果是三个lib文件都上传了,则调用激活
+                faceEngineFactory.activeOnline();
+            } finally {
+                //是否成功都要删除
+                temp.forEach((k,v)->{
+                    FileUtil.del(path + File.separator + k + id);
+                    FileUtil.del(path + File.separator + k + "_copy");
+                });
+
+            }
+        }
+        else
+        {
+            R.fail("没有找到符合的lib文件!");
+        }
+        return R.ok();
+
+    }
+
+
+    @PostMapping("activation")
+    @ApiOperation("激活")
+    public R activation() throws IOException {
+        faceEngineFactory.activeOnline();
+        return R.ok("激活成功!");
+    }
+
+}

+ 170 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/handle/FaceEngineFactory.java

@@ -0,0 +1,170 @@
+package com.zd.alg.face.handle;
+
+import cn.hutool.core.util.StrUtil;
+import com.arcsoft.face.ActiveFileInfo;
+import com.arcsoft.face.EngineConfiguration;
+import com.arcsoft.face.FaceEngine;
+import com.arcsoft.face.FunctionConfiguration;
+import com.arcsoft.face.enums.DetectMode;
+import com.arcsoft.face.enums.DetectOrient;
+import com.arcsoft.face.enums.ErrorInfo;
+import com.zd.common.core.exception.ServiceException;
+import com.zd.alg.face.config.FaceProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @Author: zhoupan
+ * @Date: 2021/10/12/11:14
+ * @Description:
+ */
+@Service
+@EnableConfigurationProperties(FaceProperties.class)
+public class FaceEngineFactory {
+    Logger logger = LoggerFactory.getLogger(FaceEngineFactory.class);
+
+    @Autowired
+    FaceProperties faceProperties;
+
+    @Autowired
+    EngineConfiguration getEngineConfiguration;
+
+    //初始化一个图片模式引擎
+    public FaceEngine initFaceEngineImage() {
+        //初始化IMAGE模式
+        return init();
+    }
+
+    private FaceEngine init() {
+        FaceEngine faceEngine = getFaceEngine();
+        int errorCode;
+        //初始化引擎
+        errorCode = faceEngine.init(getEngineConfiguration);
+        if (errorCode != ErrorInfo.MOK.getValue()) {
+            logger.error("初始化引擎失败:errorCode:{},", errorCode);
+            throw new ServiceException("初始化引擎失败!");
+        }
+        return faceEngine;
+    }
+
+    /**
+     * 获取激活信息
+     * @param faceEngine
+     * @return
+     */
+    private void getActiveInfo(FaceEngine faceEngine) {
+        int errorCode;
+        ActiveFileInfo activeFileInfo = new ActiveFileInfo();
+        errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
+        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
+            logger.error("获取激活文件信息失败:errorCode:{},", errorCode);
+            throw new ServiceException("获取激活文件信息失败");
+        }
+    }
+
+    public String getPath() throws IOException {
+        FileSystemResource resource = new FileSystemResource("../");
+        String canonicalPath  = resource.getFile().getCanonicalPath();
+        if(StrUtil.isNotBlank(faceProperties.getLib_folder()))
+        {
+            canonicalPath =canonicalPath+File.separator+faceProperties.getLib_folder();
+        }
+        return canonicalPath;
+    }
+
+    public void activation(FaceEngine faceEngine) {
+
+        //
+        String key ="";
+        String os =  System.getProperty("os.name");
+        if (os.toLowerCase().startsWith("win")) {
+            key=faceProperties.getWinKey();
+        }else
+        {
+            key=faceProperties.getLinuxKey();
+
+        }
+        logger.info("配置信息打印:" + faceProperties.getAppId() + ", " + key);
+        int errorCode = faceEngine.activeOnline(faceProperties.getAppId(), key);
+        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
+            logger.error("引擎激活失败:errorCode:{},", errorCode);
+            throw new ServiceException("引擎激活失败");
+        }
+    }
+
+    /**
+     * 在线激活
+     */
+    public void activeOnline()
+    {
+        FaceEngine faceEngine = getFaceEngine();
+        if (faceEngine == null) return;
+        activation(faceEngine);
+        getActiveInfo(faceEngine);
+    }
+
+    private FaceEngine getFaceEngine() {
+        FaceEngine faceEngine =null;
+        //默认放在资源文件下
+
+        String canonicalPath = null;
+        try {
+            //FaceEngine 里加载sdk的方法已经写死了,没办法从打的jar文件中正确获取文件,
+            // 里面用的System.load方法,没办法通过路径加载jar文件中的文件
+            //所以这里只能把lib文件放在jar文件外部
+            canonicalPath = getPath();
+            logger.info("获取lib文件路径!:{}",canonicalPath);
+            faceEngine =new FaceEngine(canonicalPath);
+        } catch (IOException e) {
+            logger.error("lib文件路径获取失败,引擎初始化中断,请正确配置后激活!当前读取路径:{}",canonicalPath);
+            throw new ServiceException("lib文件加载失败!");
+        }
+        return faceEngine;
+    }
+
+
+    /**
+     * 注入IMAGE 模式配置
+     * @return
+     */
+    @Bean
+    public EngineConfiguration getEngineConfiguration() {
+        //引擎配置
+        EngineConfiguration engineConfiguration = new EngineConfiguration();
+        //检测模式
+        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
+        //人脸检测角度,根据官网说明按当前一体机使用情况 0角度检测 最佳
+        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);
+        engineConfiguration.setDetectFaceMaxNum(10);
+        engineConfiguration.setDetectFaceScaleVal(32);
+        //人脸识别时一般都需要supportFaceDetect和supportFaceRecognition这两个属性。
+        //需要防止纸张、屏幕等攻击可以传入supportLiveness和supportIRLiveness,RGB和IR活体检测根据用户的摄像头类型及实际的业务需求来决定如何选择。
+        //功能配置
+        FunctionConfiguration functionConfiguration = new FunctionConfiguration();
+        //是否支持年龄检测功能
+        functionConfiguration.setSupportAge(false);
+        //是否支持3D检测功能
+        functionConfiguration.setSupportFace3dAngle(false);
+        //是否支持人脸检测功能
+        functionConfiguration.setSupportFaceDetect(true);
+        //是否支持人脸识别功能
+        functionConfiguration.setSupportFaceRecognition(true);
+        //是否支持性别检测功能
+        functionConfiguration.setSupportGender(false);
+        //是否支持RGB活体检测功能
+        functionConfiguration.setSupportLiveness(true);
+        //是否支持IR活体检测功能
+        functionConfiguration.setSupportIRLiveness(true);
+        engineConfiguration.setFunctionConfiguration(functionConfiguration);
+        return engineConfiguration;
+    }
+
+}

+ 27 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/handle/SDKRegister.java

@@ -0,0 +1,27 @@
+package com.zd.alg.face.handle;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.event.ApplicationStartedEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.stereotype.Component;
+
+/**
+ * 初始化SDK
+ * @Author: zhoupan
+ * @Date: 2021/10/12/10:17
+ * @Description:
+ */
+@Component
+@ConditionalOnProperty(prefix = "face",name = "init",havingValue = "true",matchIfMissing = true)
+public class SDKRegister implements ApplicationListener<ApplicationStartedEvent> {
+
+    @Autowired
+    FaceEngineFactory faceEngineFactory;
+
+    @Override
+    public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {
+        //在线激活
+        faceEngineFactory.activeOnline();
+    }
+}

+ 100 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/service/FaceService.java

@@ -0,0 +1,100 @@
+package com.zd.alg.face.service;
+
+import com.arcsoft.face.FaceEngine;
+import com.arcsoft.face.FaceFeature;
+import com.arcsoft.face.FaceInfo;
+import com.arcsoft.face.FaceSimilar;
+import com.arcsoft.face.enums.ErrorInfo;
+import com.arcsoft.face.toolkit.ImageInfo;
+import com.zd.common.core.utils.Assert;
+import com.zd.alg.face.config.FaceProperties;
+import com.zd.alg.face.handle.FaceEngineFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;
+
+/**
+ * @Author: zhoupan
+ * @Date: 2021/10/12/14:30
+ * @Description:
+ */
+@Service
+public class FaceService {
+
+    @Autowired
+    FaceEngineFactory faceEngineFactory;
+
+    @Autowired
+    FaceProperties faceProperties;
+
+
+    /**
+     * 人脸检测
+     * @param imageInfo 待检测的图片信息
+     * @return
+     */
+    public List<FaceInfo>  faceDetect(ImageInfo imageInfo)
+    {
+        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
+        int errorCode = faceEngineFactory.initFaceEngineImage().detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
+        Assert.isTrue(errorCode==ErrorInfo.MOK.getValue(),"人脸检测失败!");
+        return faceInfoList;
+    }
+
+
+
+    /**
+     * 人脸特征提取
+     * @return
+     */
+    public FaceFeature faceFeature(ImageInfo imageInfo,List<FaceInfo> faceInfoList)
+    {
+        FaceFeature faceFeature = new FaceFeature();
+        FaceEngine imageFaceEngine = null;
+        int errorCode;
+        try {
+            imageFaceEngine = faceEngineFactory.initFaceEngineImage();
+            errorCode = imageFaceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);
+        } finally {
+            if(imageFaceEngine!=null)
+            {
+                imageFaceEngine.unInit();
+            }
+
+        }
+
+        Assert.isTrue(errorCode==ErrorInfo.MOK.getValue(),"人脸特征提取失败!");
+
+        return faceFeature;
+    }
+    /**
+     * 人脸对比
+     * @return
+     */
+    public Boolean compore(FaceFeature targetFaceFeature,FaceFeature sourceFaceFeature)
+    {
+
+        FaceSimilar faceSimilar = new FaceSimilar();
+        FaceEngine faceEngine = null;
+        int errorCode = 0;
+        try {
+            faceEngine = faceEngineFactory.initFaceEngineImage();
+            errorCode = faceEngine.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
+        } finally {
+            if(faceEngine!=null)
+            {
+                faceEngine.unInit();
+            }
+        }
+        Assert.isTrue(errorCode==ErrorInfo.MOK.getValue(),"人脸对比失败!");
+        return faceSimilar.getScore()>=faceProperties.getScore();
+    }
+
+    public ImageInfo getImageInfo(File file) {
+        ImageInfo imageInfo = getRGBData(file);
+        return imageInfo;
+    }
+}

+ 29 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/utils/FileUtil.java

@@ -0,0 +1,29 @@
+package com.zd.alg.face.utils;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @Author: zhoupan
+ * @Date: 2021/10/14/9:38
+ * @Description:
+ */
+public class FileUtil {
+
+    public static File multipartFileToFile(MultipartFile file) throws IOException {
+        File toFile = null;
+
+
+        String originalFilename = file.getOriginalFilename();
+        String[] filename = originalFilename.split("\\.");
+        toFile=File.createTempFile(filename[0], filename[1]);
+        file.transferTo(toFile);
+//        toFile.deleteOnExit();//在jvm 退出时删除
+        return toFile;
+    }
+
+
+
+}

+ 26 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/valid/KeyNotNull.java

@@ -0,0 +1,26 @@
+package com.zd.alg.face.valid;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.*;
+
+/**
+ * 枚舉自定義驗證
+ *
+ * @Author: zhoupan
+ * @Date: 2021/10/28/9:00
+ * @Description:
+ */
+@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Constraint(validatedBy = KeyValidator.class)//标明由哪个类执行校验逻辑
+public @interface KeyNotNull {
+
+    String message() default "值错误!";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+
+}

+ 26 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/face/valid/KeyValidator.java

@@ -0,0 +1,26 @@
+package com.zd.alg.face.valid;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * 暂未使用,还未完成
+ * @Author: zhoupan
+ * @Date: 2021/10/28/9:07
+ * @Description:
+ */
+public class KeyValidator implements ConstraintValidator<KeyNotNull, Object> {
+
+
+    @Override
+    public boolean isValid(Object s, ConstraintValidatorContext constraintValidatorContext) {
+
+        if (s == null) return true;
+        return false;
+    }
+
+    @Override
+    public void initialize(KeyNotNull constraintAnnotation) {
+        ConstraintValidator.super.initialize(constraintAnnotation);
+    }
+}

+ 126 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SlApplyApprovalController.java

@@ -0,0 +1,126 @@
+package com.zd.alg.smartlock.controller;
+
+import com.zd.alg.smartlock.domain.SlApplyApproval;
+import com.zd.alg.smartlock.service.ISlApplyApprovalService;
+import com.zd.common.core.utils.poi.ExcelUtil;
+import com.zd.common.core.web.controller.BaseController;
+import com.zd.common.core.web.domain.AjaxResult;
+import com.zd.common.core.web.domain.ResultData;
+import com.zd.common.core.web.page.TableDataInfo;
+import com.zd.common.log.annotation.Log;
+import com.zd.common.log.enums.BusinessType;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 门锁申请审核Controller
+ *
+ * @author xxf
+ * @date 2022-09-02
+ */
+@RestController
+@Api(tags = "【申请审核】")
+@RequestMapping("/approval")
+public class SlApplyApprovalController extends BaseController
+{
+    @Autowired
+    private ISlApplyApprovalService slApplyApprovalService;
+
+
+    /**
+     * 查询申请审核列表
+     */
+    //@PreAuthorize(hasPermi = "laboratory:approval:list")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询申请审核列表")
+    public TableDataInfo<SlApplyApproval> list(SlApplyApproval slApplyApproval)
+    {
+        startPage();
+        List<SlApplyApproval> list = slApplyApprovalService.selectSlApplyApprovalList(slApplyApproval);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出申请审核列表
+     */
+    @ApiOperation(value = "导出申请审核列表")
+    //@PreAuthorize(hasPermi = "laboratory:approval:export")
+    @Log(title = "申请审核", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SlApplyApproval slApplyApproval) throws IOException
+    {
+        List<SlApplyApproval> list = slApplyApprovalService.selectSlApplyApprovalList(slApplyApproval);
+        ExcelUtil<SlApplyApproval> util = new ExcelUtil<SlApplyApproval>(SlApplyApproval.class);
+        util.exportExcel(response, list, "申请审核数据");
+    }
+
+    /**
+     * 获取申请审核详细信息
+     */
+    @ApiOperation(value = "获取申请审核详细信息")
+    //@PreAuthorize(hasPermi = "laboratory:approval:query")
+    @GetMapping(value = "/{id}")
+    public ResultData<SlApplyApproval> getInfo(@PathVariable("id") Long id)
+    {
+        return ResultData.success(slApplyApprovalService.selectSlApplyApprovalById(id));
+    }
+
+    /**
+     * 新增申请审核
+     */
+    @ApiOperation(value = "新增申请审核")
+    //@PreAuthorize(hasPermi = "laboratory:approval:add")
+    @Log(title = "申请审核", businessType = BusinessType.INSERT)
+    @PostMapping
+    public ResultData add(@RequestBody SlApplyApproval slApplyApproval)
+    {
+        return ResultData.result(slApplyApprovalService.insertSlApplyApproval(slApplyApproval));
+    }
+
+    /**
+     * 修改申请审核
+     */
+    @ApiOperation(value = "修改申请审核")
+    //@PreAuthorize(hasPermi = "laboratory:approval:edit")
+    @Log(title = "申请审核", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public ResultData edit(@RequestBody SlApplyApproval slApplyApproval)
+    {
+        return  ResultData.result(slApplyApprovalService.updateSlApplyApproval(slApplyApproval));
+    }
+
+    /**
+     * 删除申请审核
+     */
+    @ApiOperation(value = "删除申请审核")
+    //@PreAuthorize(hasPermi = "laboratory:approval:remove")
+    @Log(title = "申请审核", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public ResultData remove(@PathVariable Long[] ids)
+    {
+        return ResultData.result(slApplyApprovalService.deleteSlApplyApprovalByIds(ids));
+    }
+
+    /***
+     * 短信审核
+     * @param phone 电话
+     * @param content 1通过 0拒绝
+     * @param lockApplyId
+     * @return
+     */
+    @ApiOperation(value = "门锁短信审核")
+    @GetMapping("/sysMsgApprova")
+    public AjaxResult sysMsgApprova(String phone, String content, Long lockApplyId)
+    {   // msg:异常说明  status:处理状态(ok-成功  error-失败)
+        Map<String,Object> map = slApplyApprovalService.sysMsgApprova(phone,content,lockApplyId);
+        return AjaxResult.success(map);
+    }
+
+}

+ 197 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SlOpendoorApplyController.java

@@ -0,0 +1,197 @@
+package com.zd.alg.smartlock.controller;
+
+import com.zd.alg.smartlock.domain.SlOpendoorApply;
+import com.zd.alg.smartlock.domain.vo.SlOpendoorApplyVo;
+import com.zd.alg.smartlock.service.ISlOpendoorApplyService;
+import com.zd.common.core.domain.per.PerFun;
+import com.zd.common.core.domain.per.PerPrefix;
+import com.zd.common.core.utils.poi.ExcelUtil;
+import com.zd.common.core.web.controller.BaseController;
+import com.zd.common.core.web.domain.AjaxResult;
+import com.zd.common.core.web.domain.ResultData;
+import com.zd.common.core.web.page.TableDataInfo;
+import com.zd.common.log.annotation.Log;
+import com.zd.common.log.enums.BusinessType;
+import com.zd.common.security.annotation.PreAuthorize;
+import com.zd.common.security.service.TokenService;
+import com.zd.system.api.domain.SysUser;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 申请开门Controller
+ *
+ * @author xxf
+ * @date 2022-09-03
+ */
+@RestController
+@Api(tags = "【申请开门】")
+@RequestMapping("/openDoorApply")
+public class SlOpendoorApplyController extends BaseController
+{
+    @Autowired
+    private ISlOpendoorApplyService slOpendoorApplyService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 查询申请开门列表
+     */
+    @PreAuthorize(hasPermi = PerPrefix.SMARTLOCK_OPENDOORAPPLY+ PerFun.LIST)
+    @GetMapping("/list")
+    @ApiOperation(value = "查询申请开门列表")
+    public TableDataInfo<SlOpendoorApplyVo> list(SlOpendoorApplyVo slOpendoorApply)
+    {
+        //获取登录用户
+        SysUser sysUser = tokenService.getLoginUser().getSysUser();
+        startPage();
+        List<SlOpendoorApplyVo> list = slOpendoorApplyService.selectSlOpendoorApplyList(slOpendoorApply);
+        for (SlOpendoorApplyVo vo:list) {
+                if(vo.getLoseTime().getTime()<System.currentTimeMillis()){
+                    vo.setApplyStatus(2L);
+                }
+        }
+        return getDataTable(list);
+    }
+
+    /**
+     * 授权申请
+     */
+    //@PreAuthorize(hasPermi = PerPrefix.SMARTLOCK_OPENDOORAPPLY+ "applyList")
+    @GetMapping("/applyList")
+    @ApiOperation(value = "查询申请开门列表")
+    public TableDataInfo<SlOpendoorApplyVo> applylist(SlOpendoorApplyVo slOpendoorApply)
+    {
+        //获取登录用户
+        SysUser sysUser = tokenService.getLoginUser().getSysUser();
+        slOpendoorApply.setUserId(sysUser.getUserId());
+        startPage();
+        List<SlOpendoorApplyVo> list = slOpendoorApplyService.selectSlOpendoorApplyList(slOpendoorApply);
+        for (SlOpendoorApplyVo vo:list) {
+            if(vo.getLoseTime().getTime()<System.currentTimeMillis()){
+                vo.setApplyStatus(2L);
+            }
+        }
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询申请开门列表(学生端)
+     */
+    @GetMapping("/listStudent")
+    @ApiOperation(value = "查询申请开门列表(学生端)")
+    public TableDataInfo<SlOpendoorApplyVo> listStudent(SlOpendoorApplyVo slOpendoorApply)
+    {
+        //获取登录用户
+        SysUser sysUser = tokenService.getLoginUser().getSysUser();
+        slOpendoorApply.setUserId(sysUser.getUserId());
+
+        startPage();
+        List<SlOpendoorApplyVo> list = slOpendoorApplyService.selectSlOpendoorApplyListStudent(slOpendoorApply);
+        for (SlOpendoorApplyVo vo:list) {
+            if(vo.getLoseTime().getTime()<System.currentTimeMillis()){
+                vo.setApplyStatus(2L);
+            }
+        }
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出申请开门列表
+     */
+    @ApiOperation(value = "导出申请开门列表")
+    @PreAuthorize(hasPermi = PerPrefix.SMARTLOCK_OPENDOORAPPLY+ PerFun.EXPORT)
+    @Log(title = "申请开门", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SlOpendoorApplyVo slOpendoorApply) throws IOException
+    {
+        List<SlOpendoorApplyVo> list = slOpendoorApplyService.selectSlOpendoorApplyList(slOpendoorApply);
+        ExcelUtil<SlOpendoorApplyVo> util = new ExcelUtil<SlOpendoorApplyVo>(SlOpendoorApplyVo.class);
+        util.exportExcel(response, list, "申请开门数据");
+    }
+
+    /**
+     * 获取申请开门详细信息
+     */
+    @ApiOperation(value = "获取申请开门详细信息")
+    @PreAuthorize(hasPermi = PerPrefix.SMARTLOCK_OPENDOORAPPLY+ PerFun.QUERY)
+    @GetMapping(value = "/{id}")
+    public ResultData<SlOpendoorApply> getInfo(@PathVariable("id") Long id)
+    {
+        return ResultData.success(slOpendoorApplyService.selectSlOpendoorApplyById(id));
+    }
+
+    /**
+     * 新增申请开门
+     */
+    @ApiOperation(value = "新增申请开门")
+    @PreAuthorize(hasPermi = PerPrefix.SMARTLOCK_OPENDOORAPPLY+ PerFun.ADD)
+    @Log(title = "申请开门", businessType = BusinessType.INSERT)
+    @PostMapping
+    public ResultData add(@RequestBody SlOpendoorApply slOpendoorApply)
+    {
+        /*user_id 申请人id
+        user_id2 人员2 id
+        subject_id 实验室id
+        subject_name 实验室名称
+        position
+        */
+
+        return ResultData.result(slOpendoorApplyService.insertSlOpendoorApply(slOpendoorApply));
+    }
+
+    /**
+     * 新增申请开门
+     */
+    @ApiOperation(value = "新增申请开门")
+    @Log(title = "申请开门", businessType = BusinessType.INSERT)
+    @PostMapping("/addStudent")
+    public ResultData addStudent(@RequestBody SlOpendoorApply slOpendoorApply)
+    {
+        return ResultData.result(slOpendoorApplyService.insertSlOpendoorApply(slOpendoorApply));
+    }
+
+
+    /**
+     * 修改申请开门
+     */
+    @ApiOperation(value = "修改申请开门")
+    @PreAuthorize(hasPermi = PerPrefix.SMARTLOCK_OPENDOORAPPLY+ PerFun.EDIT)
+    @Log(title = "申请开门", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public ResultData edit(@RequestBody SlOpendoorApply slOpendoorApply)
+    {
+        return  ResultData.result(slOpendoorApplyService.updateSlOpendoorApply(slOpendoorApply));
+    }
+
+    /**
+     * 删除申请开门
+     */
+    @ApiOperation(value = "删除申请开门")
+    @PreAuthorize(hasPermi = PerPrefix.SMARTLOCK_OPENDOORAPPLY+ PerFun.REMOVE)
+    @Log(title = "申请开门", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public ResultData remove(@PathVariable Long[] ids)
+    {
+        return ResultData.result(slOpendoorApplyService.deleteSlOpendoorApplyByIds(ids));
+    }
+
+    /***
+     * 重新授权
+     * @param id 申请主键
+     * @return
+     */
+    @ApiOperation(value = "重新授权")
+    @GetMapping("/auth/{id}")
+    public AjaxResult againAuth(@PathVariable Long id)
+    {
+        return AjaxResult.success(slOpendoorApplyService.againAuth(id));
+    }
+}

+ 191 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SlSubjectRelationController.java

@@ -0,0 +1,191 @@
+package com.zd.alg.smartlock.controller;
+
+import com.zd.alg.smartlock.domain.SlSubjectRelation;
+import com.zd.alg.smartlock.domain.api.SlLockOnline;
+import com.zd.alg.smartlock.domain.api.SlRoom;
+import com.zd.alg.smartlock.domain.vo.SlSubjectRelationVo;
+import com.zd.alg.smartlock.service.ISlSubjectRelationService;
+import com.zd.alg.smartlock.utils.SmartlockUtil;
+import com.zd.common.core.utils.poi.ExcelUtil;
+import com.zd.common.core.web.controller.BaseController;
+import com.zd.common.core.web.domain.ResultData;
+import com.zd.common.core.web.page.TableDataInfo;
+import com.zd.common.log.annotation.Log;
+import com.zd.common.log.enums.BusinessType;
+import com.zd.common.security.annotation.PreAuthorize;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 实验室关联Controller
+ *
+ * @author xxf
+ * @date 2022-09-03
+ */
+@RestController
+@Api(tags = "【实验室关联】")
+@RequestMapping("/subjectRelation")
+public class SlSubjectRelationController extends BaseController {
+    @Autowired
+    private ISlSubjectRelationService slSubjectRelationService;
+
+    /**
+     * 查询实验室关联列表
+     */
+    @PreAuthorize(hasPermi = "laboratory:subjectRelation:list")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询实验室关联列表")
+    public TableDataInfo<SlSubjectRelationVo> list(SlSubjectRelationVo slSubjectRelation) {
+        startPage();
+        List<SlSubjectRelationVo> list = slSubjectRelationService.selectSlSubjectRelationList(slSubjectRelation);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询实验室关联列表-无权限
+     */
+    @GetMapping("/listSub")
+    @ApiOperation(value = "查询实验室关联列表")
+    public TableDataInfo<SlSubjectRelationVo> listSub(SlSubjectRelationVo slSubjectRelation) {
+        startPage();
+        List<SlSubjectRelationVo> list = slSubjectRelationService.selectSlSubjectRelationList(slSubjectRelation);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出实验室关联列表
+     */
+    @ApiOperation(value = "导出实验室关联列表")
+    @PreAuthorize(hasPermi = "laboratory:subjectRelation:export")
+    @Log(title = "实验室关联", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SlSubjectRelationVo slSubjectRelation) throws IOException {
+        List<SlSubjectRelationVo> list = slSubjectRelationService.selectSlSubjectRelationList(slSubjectRelation);
+        ExcelUtil<SlSubjectRelationVo> util = new ExcelUtil<SlSubjectRelationVo>(SlSubjectRelationVo.class);
+        util.exportExcel(response, list, "实验室关联数据");
+    }
+
+    /**
+     * 获取实验室关联详细信息
+     */
+    @ApiOperation(value = "获取实验室关联详细信息")
+    @PreAuthorize(hasPermi = "laboratory:subjectRelation:query")
+    @GetMapping(value = "/{id}")
+    public ResultData<SlSubjectRelation> getInfo(@PathVariable("id") Long id) {
+        return ResultData.success(slSubjectRelationService.selectSlSubjectRelationById(id));
+    }
+
+    /**
+     * 新增实验室关联
+     */
+    @ApiOperation(value = "新增实验室关联")
+    @PreAuthorize(hasPermi = "laboratory:subjectRelation:add")
+    @Log(title = "实验室关联", businessType = BusinessType.INSERT)
+    @PostMapping
+    public ResultData add(@RequestBody SlSubjectRelationVo vo) {
+        /*`subjectId`  '实验室id',
+        `subjectName` '实验室名称',
+        `lockRoomId` '房间id', =roomid
+        `lockCode`  '门锁编号', = roomcode2
+        `roomLocation`  '房间位置 =roomlocation',
+        `roomName`   '房间名称' =roomname,
+        */
+        return ResultData.result(slSubjectRelationService.insertSlSubjectRelation(vo));
+    }
+
+    /**
+     * 新增实验室关联-无权限
+     */
+    @ApiOperation(value = "新增实验室关联")
+    @Log(title = "实验室关联", businessType = BusinessType.INSERT)
+    @PostMapping("/addSub")
+    public ResultData addSub(@RequestBody SlSubjectRelationVo vo) {
+
+        return ResultData.result(slSubjectRelationService.insertSlSubjectRelation(vo));
+    }
+
+    /**
+     * 修改实验室关联
+     */
+    @ApiOperation(value = "修改实验室关联")
+    @PreAuthorize(hasPermi = "laboratory:subjectRelation:edit")
+    @Log(title = "实验室关联", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public ResultData edit(@RequestBody SlSubjectRelation slSubjectRelation) {
+        return ResultData.result(slSubjectRelationService.updateSlSubjectRelation(slSubjectRelation));
+    }
+
+    /**
+     * 删除实验室关联
+     */
+    @ApiOperation(value = "删除实验室关联")
+    @Log(title = "实验室关联", businessType = BusinessType.DELETE)
+    @DeleteMapping("/removeSub/{ids}")
+    public ResultData removeSub(@PathVariable Long[] ids) {
+        return ResultData.result(slSubjectRelationService.deleteSlSubjectRelationByIds(ids));
+    }
+
+    /**
+     * 删除实验室关联
+     */
+    @ApiOperation(value = "删除实验室关联")
+    @PreAuthorize(hasPermi = "laboratory:subjectRelation:remove")
+    @Log(title = "实验室关联", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public ResultData remove(@PathVariable Long[] ids) {
+        return ResultData.result(slSubjectRelationService.deleteSlSubjectRelationByIds(ids));
+    }
+
+    /**
+     * 查询智能锁房间列表
+     */
+    @GetMapping("/listLockRoom")
+    @ApiOperation(value = "查询实验室关联列表")
+    public TableDataInfo<SlRoom> listLockRoom(SlRoom slRoom) {
+        List<SlRoom> list = SmartlockUtil.getRoom( slRoom);
+
+        /*List<SlRoom> list = new ArrayList<>();
+        slRoom.setRoomname("房间1");
+        slRoom.setRoomcode2("MS001");
+        slRoom.setRoomlocation("1-1-110");
+        slRoom.setRoomid(220);
+        list.add(slRoom);
+
+        SlRoom slRoom1 = new SlRoom();
+        slRoom1.setRoomname("房间2");
+        slRoom1.setRoomcode2("MS002");
+        slRoom1.setRoomlocation("1-1-112");
+        slRoom1.setRoomid(330);
+        list.add(slRoom1);*/
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询实验室门锁状态
+     */
+    @GetMapping("/lockListDetails")
+    @ApiOperation(value = "查询实验室门锁状态")
+    public TableDataInfo<SlLockOnline> lockListDetails(Long subjectId) {
+        //List<SlRoom> list = SmartlockUtil.getRoom( slRoom);
+        //查询实验室下绑定的门锁
+        SlSubjectRelationVo subjectRelation = new SlSubjectRelationVo();
+        subjectRelation.setSubjectId(subjectId);
+        List<SlSubjectRelationVo> listrelation = slSubjectRelationService.selectSlSubjectRelationList(subjectRelation);
+
+        List<SlLockOnline> onlineList = new ArrayList<>();
+        for (SlSubjectRelation rl:listrelation) {
+            SlLockOnline lockOnline = SmartlockUtil.getRoomDetails(rl.getLockRoomId());
+            if(lockOnline!=null){
+                onlineList.add(lockOnline);
+            }
+        }
+        return getDataTable(onlineList);
+    }
+}

+ 121 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SlUserRelationController.java

@@ -0,0 +1,121 @@
+package com.zd.alg.smartlock.controller;
+
+import com.zd.alg.smartlock.domain.SlUserRelation;
+import com.zd.alg.smartlock.domain.api.SlUser;
+import com.zd.alg.smartlock.service.ISlUserRelationService;
+import com.zd.alg.smartlock.utils.SmartlockUtil;
+import com.zd.common.core.utils.poi.ExcelUtil;
+import com.zd.common.core.web.controller.BaseController;
+import com.zd.common.core.web.domain.ResultData;
+import com.zd.common.core.web.page.TableDataInfo;
+import com.zd.common.log.annotation.Log;
+import com.zd.common.log.enums.BusinessType;
+import com.zd.common.security.annotation.PreAuthorize;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 人员关联Controller
+ *
+ * @author xxf
+ * @date 2022-09-02
+ */
+@RestController
+@Api(tags = "【人员关联】")
+@RequestMapping("/userRelation")
+public class SlUserRelationController extends BaseController
+{
+    @Autowired
+    private ISlUserRelationService slUserRelationService;
+
+    /**
+     * 查询人员关联列表
+     */
+    @PreAuthorize(hasPermi = "laboratory:relation:list")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询人员关联列表")
+    public TableDataInfo<SlUserRelation> list(SlUserRelation slUserRelation)
+    {
+        startPage();
+        List<SlUserRelation> list = slUserRelationService.selectSlUserRelationList(slUserRelation);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出人员关联列表
+     */
+    @ApiOperation(value = "导出人员关联列表")
+    @PreAuthorize(hasPermi = "laboratory:relation:export")
+    @Log(title = "人员关联", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SlUserRelation slUserRelation) throws IOException
+    {
+        List<SlUserRelation> list = slUserRelationService.selectSlUserRelationList(slUserRelation);
+        ExcelUtil<SlUserRelation> util = new ExcelUtil<SlUserRelation>(SlUserRelation.class);
+        util.exportExcel(response, list, "人员关联数据");
+    }
+
+    /**
+     * 获取人员关联详细信息
+     */
+    @ApiOperation(value = "获取人员关联详细信息")
+    @PreAuthorize(hasPermi = "laboratory:relation:query")
+    @GetMapping(value = "/{id}")
+    public ResultData<SlUserRelation> getInfo(@PathVariable("id") Long id)
+    {
+        return ResultData.success(slUserRelationService.selectSlUserRelationById(id));
+    }
+
+    /**
+     * 新增人员关联
+     */
+    @ApiOperation(value = "新增人员关联")
+    @PreAuthorize(hasPermi = "laboratory:relation:add")
+    @Log(title = "人员关联", businessType = BusinessType.INSERT)
+    @PostMapping
+    public ResultData add(@RequestBody SlUserRelation slUserRelation)
+    {
+        return ResultData.result(slUserRelationService.insertSlUserRelation(slUserRelation));
+    }
+
+    /**
+     * 修改人员关联
+     */
+    @ApiOperation(value = "修改人员关联")
+    @PreAuthorize(hasPermi = "laboratory:relation:edit")
+    @Log(title = "人员关联", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public ResultData edit(@RequestBody SlUserRelation slUserRelation)
+    {
+        return  ResultData.result(slUserRelationService.updateSlUserRelation(slUserRelation));
+    }
+
+    /**
+     * 删除人员关联
+     */
+    @ApiOperation(value = "删除人员关联")
+    @PreAuthorize(hasPermi = "laboratory:relation:remove")
+    @Log(title = "人员关联", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public ResultData remove(@PathVariable Long[] ids)
+    {
+        return ResultData.result(slUserRelationService.deleteSlUserRelationByIds(ids));
+    }
+
+    /**
+     * 查询智能锁人员列表
+     */
+    @GetMapping("/listLockUser")
+    @ApiOperation(value = "查询智能锁人员列表")
+    public TableDataInfo<SlUser> listLockUser(SlUser sluser)
+    {
+        List<SlUser> list = SmartlockUtil.getUser(sluser);
+        return getDataTable(list);
+    }
+}

+ 53 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/controller/SmartlockController.java

@@ -0,0 +1,53 @@
+package com.zd.alg.smartlock.controller;
+
+import com.zd.alg.smartlock.domain.api.SlLockOnline;
+import com.zd.alg.smartlock.domain.vo.SlSubjectRelationVo;
+import com.zd.alg.smartlock.service.ISlSubjectRelationService;
+import com.zd.alg.smartlock.utils.SmartlockUtil;
+import com.zd.common.core.web.controller.BaseController;
+import com.zd.common.core.web.page.TableDataInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: xxf
+ * @Date: 2022/09/07/9:43
+ * @Description:
+ */
+
+@RestController
+@Api(tags = "门锁相关信息查询")
+@RequestMapping("/lockinfo")
+public class SmartlockController extends BaseController {
+
+    @Autowired
+    private ISlSubjectRelationService slSubjectRelationService;
+
+    /**
+     * 查询实验室门锁信息
+     */
+    @GetMapping("/detalis")
+    @ApiOperation(value = "查询实验室门锁信息")
+    public TableDataInfo<SlLockOnline> list(Long subjectId)
+    {
+        List<SlLockOnline> lockOnlineslist = new ArrayList<>();
+
+        //查询实验室绑定的门锁集合
+        SlSubjectRelationVo subjectRelation = new SlSubjectRelationVo();
+        subjectRelation.setSubjectId(subjectId);
+        List<SlSubjectRelationVo> list = slSubjectRelationService.selectSlSubjectRelationList(subjectRelation);
+        for (SlSubjectRelationVo sub: list ) {
+            //查询门锁状态
+            SlLockOnline lockOnline = SmartlockUtil.getRoomDetails(sub.getLockRoomId());
+            lockOnlineslist.add(lockOnline);
+        }
+        return getDataTable(lockOnlineslist);
+    }
+}

+ 70 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/BaseDomain.java

@@ -0,0 +1,70 @@
+package com.zd.alg.smartlock.domain;
+
+import java.io.Serializable;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/08/30/16:33
+ * @Description:
+ */
+public class BaseDomain implements Serializable {
+
+    /**
+     * 每一页显示数量
+     */
+    public  String  pageSize;
+
+    /**
+     * 页码
+     */
+    public  String  pageNumber;
+
+    /**
+     * 总数
+     */
+    public Integer total;
+
+    /**
+     * token
+     */
+    public String token;
+
+    /**
+     * 搜索条件
+     */
+    public  String  search;
+
+    public String getPageSize() {
+        return pageSize= pageSize==null || "".equals(pageSize)?"20":pageSize;
+    }
+
+    public void setPageSize(String pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public String getPageNumber() {
+        return pageNumber =  "".equals(pageNumber) || pageNumber==null?"1":pageNumber;
+    }
+
+    public void setPageNumber(String pageNumber) {
+        this.pageNumber = pageNumber;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public Integer getTotal() {        return total;    }
+
+    public void setTotal(Integer total) {
+        this.total = total;
+    }
+
+    public String getSearch() {        return search;    }
+
+    public void setSearch(String search) {        this.search = search;    }
+}

+ 99 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/SlApplyApproval.java

@@ -0,0 +1,99 @@
+package com.zd.alg.smartlock.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zd.common.core.annotation.Excel;
+import com.zd.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.Length;
+
+import java.util.Date;
+
+/**
+ * 人员关联对象 sl_user_relation
+ *
+ * @author zd
+ * @date 2022-09-02
+ */
+@ApiModel("人员关联")
+public class SlApplyApproval extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    @ApiModelProperty(value = "${comment}")
+    private Long id;
+    /** 申请表主键 */
+    @Excel(name = "申请表主键")
+    @ApiModelProperty(value = "申请表主键")
+    private Long applyId;
+    /** 审核人id */
+    @Excel(name = "审核人id")
+    @ApiModelProperty(value = "审核人id")
+    private Long approvaId;
+    /** 审核人姓名 */
+    @Excel(name = "审核人姓名")
+    @Length(message = "审核人姓名长度不能超过50")
+    @ApiModelProperty(value = "审核人姓名")
+    private String approvaName;
+    /** 1通过 2驳回 */
+    @Excel(name = "1通过 2驳回")
+    @ApiModelProperty(value = "1通过 2驳回")
+    private Long approvaStatus;
+    /** $column.columnComment */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "1通过 2驳回", width = 30, dateFormat = "yyyy-MM-dd")
+    @ApiModelProperty(value = "1通过 2驳回")
+    private Date cretaTime;
+
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getApplyId() {
+        return applyId;
+    }
+
+    public void setApplyId(Long applyId) {
+        this.applyId = applyId;
+    }
+
+    public Long getApprovaId() {
+        return approvaId;
+    }
+
+    public void setApprovaId(Long approvaId) {
+        this.approvaId = approvaId;
+    }
+
+    public String getApprovaName() {
+        return approvaName;
+    }
+
+    public void setApprovaName(String approvaName) {
+        this.approvaName = approvaName;
+    }
+
+    public Long getApprovaStatus() {
+        return approvaStatus;
+    }
+
+    public void setApprovaStatus(Long approvaStatus) {
+        this.approvaStatus = approvaStatus;
+    }
+
+    public Date getCretaTime() {
+        return cretaTime;
+    }
+
+    public void setCretaTime(Date cretaTime) {
+        this.cretaTime = cretaTime;
+    }
+
+}

+ 300 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/SlOpendoorApply.java

@@ -0,0 +1,300 @@
+package com.zd.alg.smartlock.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zd.common.core.annotation.Excel;
+import com.zd.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.Length;
+
+import java.util.Date;
+
+/**
+ * 申请开门对象 sl_opendoor_apply
+ *
+ * @author zd
+ * @date 2022-09-03
+ */
+@ApiModel("申请开门")
+public class SlOpendoorApply extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    @ApiModelProperty(value = "${comment}")
+    private Long id;
+    /** 申请姓名 */
+    @Excel(name = "申请姓名")
+    @Length(message = "申请姓名长度不能超过50")
+    @ApiModelProperty(value = "申请姓名")
+    private String userName;
+    /** 人员2 id */
+    @Excel(name = "人员2 id")
+    @ApiModelProperty(value = "人员2 id")
+    private Long userId2;
+    /** $column.columnComment */
+    @Excel(name = "人员2 id")
+    @Length(message = "人员2 id长度不能超过50")
+    @ApiModelProperty(value = "人员2 id")
+    private String userName2;
+    /** 实验室id  */
+    @Excel(name = "实验室id ")
+    @ApiModelProperty(value = "实验室id ")
+    private Long subjectId;
+    /** 实验室名称  */
+    @Excel(name = "实验室名称 ")
+    @Length(message = "实验室名称 长度不能超过50")
+    @ApiModelProperty(value = "实验室名称 ")
+    private String subjectName;
+    /** 位置 */
+    @Excel(name = "位置")
+    @Length(message = "位置长度不能超过255")
+    @ApiModelProperty(value = "位置")
+    private String position;
+    /** 学院 */
+    @Excel(name = "学院")
+    @Length(message = "学院长度不能超过255")
+    @ApiModelProperty(value = "学院")
+    private String college;
+    /** 1审核中 2 通过 3驳回 */
+    @Excel(name = "1审核中 2 通过 3驳回")
+    @ApiModelProperty(value = "1审核中 2 通过 3驳回")
+    private Long applyStatus;
+
+    /** 审核次数 */
+    @Excel(name = "审核次数")
+    @ApiModelProperty(value = "审核次数")
+    private Long applyNumber;
+
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @ApiModelProperty(value = "创建时间")
+    private Date creatTime;
+
+
+    /** 人员1编号*/
+    @Excel(name = "人员1编号")
+    @ApiModelProperty(value = "人员1编号")
+    private String userCode;
+
+    /** 人员2编号*/
+    @Excel(name = "人员2编号")
+    @ApiModelProperty(value = "人员2编号")
+    private String userCode2;
+
+    /** 人员1性别*/
+    @Excel(name = "人员1性别")
+    @ApiModelProperty(value = "人员1性别")
+    private Integer userSex;
+
+    /** 人员2性别*/
+    @Excel(name = "人员2性别")
+    @ApiModelProperty(value = "人员2性别")
+    private Integer userSex2;
+
+    /** 人员1电话*/
+    @Excel(name = "人员1电话")
+    @ApiModelProperty(value = "人员1电话")
+    private String phonenumber;
+
+    /** 人员2电话*/
+    @Excel(name = "人员2电话")
+    @ApiModelProperty(value = "人员2电话")
+    private String phonenumber2;
+
+    /** 说明*/
+    @Excel(name = "说明")
+    @ApiModelProperty(value = "说明")
+    private String illustrate;
+
+    /** 审核完成时间 */
+    @Excel(name = "审核完成时间 ")
+    @ApiModelProperty(value = "审核完成时间 ")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date approvalTime;
+
+    /** 审核人*/
+    @Excel(name = "审核人 ")
+    @ApiModelProperty(value = "审核人 ")
+    private String approvalUser;
+
+    /** 安全负责人*/
+    @Excel(name = "安全负责人 ")
+    @ApiModelProperty(value = "安全负责人 ")
+    private String safeUserName;
+
+    @ApiModelProperty(value = "实验室安全负责人ID集合")
+    private String safeUserId;
+
+    @ApiModelProperty(value = "实验室安全负责人电话集合")
+    private String safeUserPhone;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public Long getUserId2() {
+        return userId2;
+    }
+
+    public void setUserId2(Long userId2) {
+        this.userId2 = userId2;
+    }
+
+    public String getUserName2() {
+        return userName2;
+    }
+
+    public void setUserName2(String userName2) {
+        this.userName2 = userName2;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public String getPosition() {
+        return position;
+    }
+
+    public void setPosition(String position) {
+        this.position = position;
+    }
+
+    public String getCollege() {
+        return college;
+    }
+
+    public void setCollege(String college) {
+        this.college = college;
+    }
+
+    public Long getApplyStatus() {
+        return applyStatus;
+    }
+
+    public void setApplyStatus(Long applyStatus) {
+        this.applyStatus = applyStatus;
+    }
+
+    public Date getCreatTime() {
+        return creatTime;
+    }
+
+    public void setCreatTime(Date creatTime) {
+        this.creatTime = creatTime;
+    }
+
+    public Long getApplyNumber() {
+        return applyNumber;
+    }
+
+    public void setApplyNumber(Long applyNumber) {
+        this.applyNumber = applyNumber;
+    }
+
+    public String getUserCode() {
+        return userCode;
+    }
+
+    public void setUserCode(String userCode) {
+        this.userCode = userCode;
+    }
+
+    public String getUserCode2() {
+        return userCode2;
+    }
+
+    public void setUserCode2(String userCode2) {
+        this.userCode2 = userCode2;
+    }
+
+    public Integer getUserSex() {
+        return userSex;
+    }
+
+    public void setUserSex(Integer userSex) {
+        this.userSex = userSex;
+    }
+
+    public Integer getUserSex2() {
+        return userSex2;
+    }
+
+    public void setUserSex2(Integer userSex2) {
+        this.userSex2 = userSex2;
+    }
+
+    public String getIllustrate() {
+        return illustrate;
+    }
+
+    public void setIllustrate(String illustrate) {
+        this.illustrate = illustrate;
+    }
+
+    public String getPhonenumber() {        return phonenumber;    }
+
+    public void setPhonenumber(String phonenumber) {        this.phonenumber = phonenumber;    }
+
+    public String getPhonenumber2() {
+        return phonenumber2;
+    }
+
+    public void setPhonenumber2(String phonenumber2) {
+        this.phonenumber2 = phonenumber2;
+    }
+
+    public Date getApprovalTime() {
+        return approvalTime;
+    }
+
+    public void setApprovalTime(Date approvalTime) {
+        this.approvalTime = approvalTime;
+    }
+
+    public String getApprovalUser() {
+        return approvalUser;
+    }
+
+    public void setApprovalUser(String approvalUser) {
+        this.approvalUser = approvalUser;
+    }
+
+    public String getSafeUserName() {        return safeUserName;    }
+
+    public void setSafeUserName(String safeUserName) {        this.safeUserName = safeUserName;    }
+
+    public String getSafeUserId() {        return safeUserId;    }
+
+    public void setSafeUserId(String safeUserId) {        this.safeUserId = safeUserId;    }
+
+    public String getSafeUserPhone() {        return safeUserPhone;    }
+
+    public void setSafeUserPhone(String safeUserPhone) {        this.safeUserPhone = safeUserPhone;    }
+}

+ 188 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/SlSubjectRelation.java

@@ -0,0 +1,188 @@
+package com.zd.alg.smartlock.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zd.common.core.annotation.Excel;
+import com.zd.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.Length;
+
+import java.util.Date;
+
+/**
+ * 实验室关联对象 sl_subject_relation
+ *
+ * @author zd
+ * @date 2022-09-03
+ */
+@ApiModel("实验室关联")
+public class SlSubjectRelation extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    @ApiModelProperty(value = "${comment}")
+    private Long id;
+    /** 实验室id */
+    @Excel(name = "实验室id")
+    @ApiModelProperty(value = "实验室id")
+    private Long subjectId;
+    /** 实验室名称 */
+    @Excel(name = "实验室名称")
+    @Length(message = "实验室名称长度不能超过50")
+    @ApiModelProperty(value = "实验室名称")
+    private String subjectName;
+    /** 房间id */
+    @Excel(name = "房间id")
+    @Length(message = "房间id长度不能超过255")
+    @ApiModelProperty(value = "房间id")
+    private String lockRoomId;
+    /** 门锁编号 */
+    @Excel(name = "门锁编号")
+    @Length(message = "门锁编号长度不能超过255")
+    @ApiModelProperty(value = "门锁编号")
+    private String lockCode;
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @ApiModelProperty(value = "创建时间")
+    private Date creatTime;
+    /** 房间位置 */
+    @Excel(name = "房间位置")
+    @Length(message = "房间位置长度不能超过255")
+    @ApiModelProperty(value = "房间位置")
+    private String roomLocation;
+
+    /** 房间名称 */
+    @Excel(name = "房间名称")
+    @Length(message = "房间名称长度不能超过255")
+    @ApiModelProperty(value = "房间名称")
+    private String roomName;
+
+    /** 实验室位置 */
+    @Excel(name = "实验室位置")
+    @Length(message = "实验室位置长度不能超过255")
+    @ApiModelProperty(value = "实验室位置")
+    private String subjectLocation;
+
+    /** 学院 */
+    @Excel(name = "学院")
+    @Length(message = "学院长度不能超过255")
+    @ApiModelProperty(value = "学院")
+    private String college;
+
+    @ApiModelProperty(value = "安全负责人id")
+    private Long safeUserId;
+
+    @ApiModelProperty(value = "安全负责人姓名")
+    private String safeUserName;
+
+    @ApiModelProperty(value = "安全负责人电话")
+    private String safeUserPhone;
+
+    private Long deptId;
+
+    private String deptName;
+
+    private Long userId;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public String getLockRoomId() {
+        return lockRoomId;
+    }
+
+    public void setLockRoomId(String lockRoomId) {
+        this.lockRoomId = lockRoomId;
+    }
+
+    public String getLockCode() {
+        return lockCode;
+    }
+
+    public void setLockCode(String lockCode) {
+        this.lockCode = lockCode;
+    }
+
+    public Date getCreatTime() {
+        return creatTime;
+    }
+
+    public void setCreatTime(Date creatTime) {
+        this.creatTime = creatTime;
+    }
+
+    @Override
+    public String getDeptName() {
+        return deptName;
+    }
+
+    @Override
+    public void setDeptName(String deptName) {
+        this.deptName = deptName;
+    }
+
+    public String getRoomLocation() {        return roomLocation;    }
+
+    public void setRoomLocation(String roomLocation) {        this.roomLocation = roomLocation;    }
+
+    public String getRoomName() {        return roomName;    }
+
+    public void setRoomName(String roomName) {        this.roomName = roomName;    }
+
+    @Override
+    public Long getDeptId() {        return deptId;    }
+
+    @Override
+    public void setDeptId(Long deptId) {        this.deptId = deptId;    }
+
+    @Override
+    public Long getUserId() {        return userId;    }
+
+    @Override
+    public void setUserId(Long userId) {        this.userId = userId;    }
+
+    public String getSubjectLocation() {        return subjectLocation;    }
+
+    public void setSubjectLocation(String subjectLocation) {        this.subjectLocation = subjectLocation;    }
+
+    public String getCollege() {        return college;    }
+
+    public void setCollege(String college) {
+        this.college = college;
+    }
+
+    public Long getSafeUserId() {        return safeUserId;    }
+
+    public void setSafeUserId(Long safeUserId) {        this.safeUserId = safeUserId;    }
+
+    public String getSafeUserName() {        return safeUserName;    }
+
+    public void setSafeUserName(String safeUserName) {        this.safeUserName = safeUserName;    }
+
+    public String getSafeUserPhone() {        return safeUserPhone;    }
+
+    public void setSafeUserPhone(String safeUserPhone) {        this.safeUserPhone = safeUserPhone;    }
+}

+ 86 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/SlUserRelation.java

@@ -0,0 +1,86 @@
+package com.zd.alg.smartlock.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zd.common.core.annotation.Excel;
+import com.zd.common.core.web.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.Length;
+
+import java.util.Date;
+
+/**
+ * 人员关联对象 sl_user_relation
+ *
+ * @author zd
+ * @date 2022-09-02
+ */
+@ApiModel("人员关联")
+public class SlUserRelation extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    @ApiModelProperty(value = "${comment}")
+    private Long id;
+    /** 用户姓名 */
+    @Excel(name = "用户姓名")
+    @Length(message = "用户姓名长度不能超过50")
+    @ApiModelProperty(value = "用户姓名")
+    private String userName;
+    /** 门锁服务人员编号 */
+    @Excel(name = "门锁服务人员编号")
+    @Length(message = "门锁服务人员编号长度不能超过50")
+    @ApiModelProperty(value = "门锁服务人员编号")
+    private String lockUserCode;
+    /** $column.columnComment */
+    @Excel(name = "门锁服务人员编号")
+    @ApiModelProperty(value = "门锁服务人员编号")
+    private Long type;
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @ApiModelProperty(value = "创建时间")
+    private Date creatTime;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getLockUserCode() {
+        return lockUserCode;
+    }
+
+    public void setLockUserCode(String lockUserCode) {
+        this.lockUserCode = lockUserCode;
+    }
+
+    public Long getType() {
+        return type;
+    }
+
+    public void setType(Long type) {
+        this.type = type;
+    }
+
+    public Date getCreatTime() {
+        return creatTime;
+    }
+
+    public void setCreatTime(Date creatTime) {
+        this.creatTime = creatTime;
+    }
+}

+ 104 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlBuild.java

@@ -0,0 +1,104 @@
+package com.zd.alg.smartlock.domain.api;
+
+import com.zd.alg.smartlock.domain.BaseDomain;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/08/29/14:29
+ * @Description:
+ */
+@ApiModel("建筑查询实体")
+public class SlBuild extends BaseDomain {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "建筑编号")
+    private String buildcode;
+
+    @ApiModelProperty(value = "父级建筑id")
+    private String buildfatherid;
+
+    @ApiModelProperty(value = "建筑id")
+    private Integer buildid;
+
+    @ApiModelProperty(value = "建筑名称")
+    private String buildname;
+
+    @ApiModelProperty(value = "建筑类型,1园区,2楼栋,3楼层,4房间,5楼梯,6装饰间,7门禁")
+    private String buildtype;
+
+    @ApiModelProperty(value = "建筑类型,1园区,2楼栋,3楼层,4房间,5楼梯,6装饰间,7门禁")
+    private String  buildtypename;
+
+    @ApiModelProperty(value = "区域房间类型,1宿舍区域,2公共区域,3随房间属性")
+    private String roomtype;
+
+    @ApiModelProperty(value = "区域房间类型,1宿舍区域,2公共区域,3随房间属性")
+    private String roomtypename;
+
+
+    public String getBuildcode() {
+        return buildcode;
+    }
+
+    public void setBuildcode(String buildcode) {
+        this.buildcode = buildcode;
+    }
+
+    public String getBuildfatherid() {
+        return buildfatherid;
+    }
+
+    public void setBuildfatherid(String buildfatherid) {
+        this.buildfatherid = buildfatherid;
+    }
+
+    public Integer getBuildid() {
+        return buildid;
+    }
+
+    public void setBuildid(Integer buildid) {
+        this.buildid = buildid;
+    }
+
+    public String getBuildname() {
+        return buildname;
+    }
+
+    public void setBuildname(String buildname) {
+        this.buildname = buildname;
+    }
+
+    public String getBuildtype() {
+        return buildtype;
+    }
+
+    public void setBuildtype(String buildtype) {
+        this.buildtype = buildtype;
+    }
+
+    public String getBuildtypename() {
+        return buildtypename;
+    }
+
+    public void setBuildtypename(String buildtypename) {
+        this.buildtypename = buildtypename;
+    }
+
+    public String getRoomtype() {
+        return roomtype;
+    }
+
+    public void setRoomtype(String roomtype) {
+        this.roomtype = roomtype;
+    }
+
+    public String getRoomtypename() {
+        return roomtypename;
+    }
+
+    public void setRoomtypename(String roomtypename) {
+        this.roomtypename = roomtypename;
+    }
+}

+ 84 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlDoorLock.java

@@ -0,0 +1,84 @@
+package com.zd.alg.smartlock.domain.api;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/08/29/14:48
+ * @Description:
+ */
+@ApiModel("门锁中间表")
+public class SlDoorLock {
+
+    @ApiModelProperty(value = "主键")
+    private Long id;
+
+    @ApiModelProperty(value = "人员id")
+    private Long userId;
+
+    @ApiModelProperty(value = "人员姓名")
+    private String userName;
+
+    @ApiModelProperty(value = "人员卡号")
+    private String cardNum;
+
+    @ApiModelProperty(value = "实验室id")
+    private Long subjectId;
+
+    @ApiModelProperty(value = "实验室名称")
+    private String subjectName;
+
+    @ApiModelProperty(value = "部门id")
+    private Long deptId;
+
+    @ApiModelProperty(value = "部门名称")
+    private String deptName;
+
+    @ApiModelProperty(value = "门锁id")
+    private String doorLockid;
+
+    @ApiModelProperty(value = "人脸编号")
+    private String faceCode;
+
+    @ApiModelProperty(value = "人脸状态(1正常,0停用)")
+    private Long faceState;
+
+    @ApiModelProperty(value = "手指 1-10")
+    private Long finger;
+
+    @ApiModelProperty(value = "指纹编号")
+    private String fingerCode;
+
+    @ApiModelProperty(value = "指纹状态(1正常,0停用)")
+    private Long fingerState;
+
+    @ApiModelProperty(value = "卡片状态(1正常,0停用)")
+    private Long cardState;
+
+    @ApiModelProperty(value = "开始时间")
+    private Date cardBegintime;
+
+    @ApiModelProperty(value = "结束时间")
+    private Date cardEndtime;
+
+    @ApiModelProperty(value = "1人脸  2指纹 3门卡")
+    private Long dataType;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "修改人")
+    private String updateBy;
+
+    @ApiModelProperty(value = "创建人")
+    private String cereatBy;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+}

+ 58 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlGroup.java

@@ -0,0 +1,58 @@
+package com.zd.alg.smartlock.domain.api;
+
+import com.zd.alg.smartlock.domain.BaseDomain;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/05/15:36
+ * @Description:
+ */
+@ApiModel("组织信息")
+public class SlGroup extends BaseDomain {
+
+    @ApiModelProperty(value = "组织编号")
+    private String pgcode;
+
+    @ApiModelProperty(value = "父级组织id")
+    private String pgfatherid;
+
+    @ApiModelProperty(value = "父级组织id")
+    private String pgid;
+
+    @ApiModelProperty(value = "组织名称")
+    private String pgname;
+
+    public String getPgcode() {
+        return pgcode;
+    }
+
+    public void setPgcode(String pgcode) {
+        this.pgcode = pgcode;
+    }
+
+    public String getPgfatherid() {
+        return pgfatherid;
+    }
+
+    public void setPgfatherid(String pgfatherid) {
+        this.pgfatherid = pgfatherid;
+    }
+
+    public String getPgid() {
+        return pgid;
+    }
+
+    public void setPgid(String pgid) {
+        this.pgid = pgid;
+    }
+
+    public String getPgname() {
+        return pgname;
+    }
+
+    public void setPgname(String pgname) {
+        this.pgname = pgname;
+    }
+}

+ 42 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlLockOnline.java

@@ -0,0 +1,42 @@
+package com.zd.alg.smartlock.domain.api;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/05/14:30
+ * @Description:
+ */
+@ApiModel("门锁状态")
+public class SlLockOnline {
+
+    @ApiModelProperty(value = "是否在线")
+    private String onLine;
+
+    @ApiModelProperty(value = "1在线/0离线")
+    private Integer onLineStatus;
+
+    @ApiModelProperty(value = "门锁编号")
+    private String lockCode;
+
+    public String getOnLine() {
+        return onLine;
+    }
+
+    public void setOnLine(String onLine) {
+        this.onLine = onLine;
+    }
+
+    public String getLockCode() {
+        return lockCode;
+    }
+
+    public void setLockCode(String lockCode) {
+        this.lockCode = lockCode;
+    }
+
+    public Integer getOnLineStatus() {        return onLineStatus;    }
+
+    public void setOnLineStatus(Integer onLineStatus) {        this.onLineStatus = onLineStatus;    }
+}

+ 80 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlOpenAndClosLog.java

@@ -0,0 +1,80 @@
+package com.zd.alg.smartlock.domain.api;
+
+import com.zd.alg.smartlock.domain.BaseDomain;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/03/14:50
+ * @Description:
+ */
+@ApiModel("开关门记录")
+public class SlOpenAndClosLog extends BaseDomain {
+
+    @ApiModelProperty(value = "卡号/指纹号/人脸号/二维码编号")
+    private String cardcode;
+
+    @ApiModelProperty(value = "学/工号")
+    private String personcode;
+
+    @ApiModelProperty(value = "组织")
+    private String personlocation;
+
+    @ApiModelProperty(value = "姓名")
+    private String personname;
+
+    @ApiModelProperty(value = "开门日期")
+    private String unlockingdate;
+
+    @ApiModelProperty(value = "开门方式")
+    private String unlockingtype;
+
+    public String getCardcode() {
+        return cardcode;
+    }
+
+    public void setCardcode(String cardcode) {
+        this.cardcode = cardcode;
+    }
+
+    public String getPersoncode() {
+        return personcode;
+    }
+
+    public void setPersoncode(String personcode) {
+        this.personcode = personcode;
+    }
+
+    public String getPersonlocation() {
+        return personlocation;
+    }
+
+    public void setPersonlocation(String personlocation) {
+        this.personlocation = personlocation;
+    }
+
+    public String getPersonname() {
+        return personname;
+    }
+
+    public void setPersonname(String personname) {
+        this.personname = personname;
+    }
+
+    public String getUnlockingdate() {
+        return unlockingdate;
+    }
+
+    public void setUnlockingdate(String unlockingdate) {
+        this.unlockingdate = unlockingdate;
+    }
+
+    public String getUnlockingtype() {
+        return unlockingtype;
+    }
+
+    public void setUnlockingtype(String unlockingtype) {
+        this.unlockingtype = unlockingtype;
+    }
+}

+ 82 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlOpenDoorSearch.java

@@ -0,0 +1,82 @@
+package com.zd.alg.smartlock.domain.api;
+
+import com.zd.alg.smartlock.domain.BaseDomain;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/03/15:04
+ * @Description:
+ */
+@ApiModel("开关门记录查询条件")
+public class SlOpenDoorSearch extends BaseDomain {
+
+    @ApiModelProperty(value = "房间id")
+    private String roomid;
+
+    @ApiModelProperty(value = "结束日期")
+    private String edate;
+
+    @ApiModelProperty(value = "类型(0或空=所有记录,1=报警记录,2=开门记录)")
+    private String recordtype;
+
+    @ApiModelProperty(value = "起始日期")
+    private String sdate;
+
+    @ApiModelProperty(value = "根据人员姓名/人员编号/卡号/指纹编号/人脸编号/二维码编号检索")
+    private String search;
+
+    @ApiModelProperty(value = "操作类型 (0或空=所有记录,1=报警记录,2=开门记录)")
+    private String unlockingtype;
+
+    public String getRoomid() {
+        return roomid;
+    }
+
+    public void setRoomid(String roomid) {
+        this.roomid = roomid;
+    }
+
+    public String getEdate() {
+        return edate;
+    }
+
+    public void setEdate(String edate) {
+        this.edate = edate;
+    }
+
+    public String getRecordtype() {
+        return recordtype;
+    }
+
+    public void setRecordtype(String recordtype) {
+        this.recordtype = recordtype;
+    }
+
+    public String getSdate() {
+        return sdate;
+    }
+
+    public void setSdate(String sdate) {
+        this.sdate = sdate;
+    }
+
+    @Override
+    public String getSearch() {
+        return search;
+    }
+
+    @Override
+    public void setSearch(String search) {
+        this.search = search;
+    }
+
+    public String getUnlockingtype() {
+        return unlockingtype;
+    }
+
+    public void setUnlockingtype(String unlockingtype) {
+        this.unlockingtype = unlockingtype;
+    }
+}

+ 123 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlPostUser.java

@@ -0,0 +1,123 @@
+package com.zd.alg.smartlock.domain.api;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/05/16:01
+ * @Description:
+ */
+@ApiModel("添加人员信息")
+public class SlPostUser {
+
+    @ApiModelProperty(value = "卡号")
+    private String cardcode;
+
+    @ApiModelProperty(value = "是否下发人脸(1是,0否)")
+    private String issendface;
+
+    @ApiModelProperty(value = "是否下发指纹(1是,0否)")
+    private String issendfinger;
+
+    @ApiModelProperty(value = "是否下发密码(1是,0否)")
+    private String issendpass;
+
+    @ApiModelProperty(value = "权限类型(1管理权限,0使用权限,管理权限不占用入住人数)")
+    private Integer managertype;
+
+    @ApiModelProperty(value = "6位数字密码(不允许连续数字或连续三个及以上相同数字)")
+    private String password;
+
+    @ApiModelProperty(value = "学号")
+    private String personcode;
+
+    @ApiModelProperty(value = "房间id")
+    private String roomid;
+
+    @ApiModelProperty(value = "授权开始日期")
+    private String empsdate;
+
+    @ApiModelProperty(value = "授权结束日期")
+    private String empedate;
+
+    public String getCardcode() {
+        return cardcode;
+    }
+
+    public void setCardcode(String cardcode) {
+        this.cardcode = cardcode;
+    }
+
+    public String getIssendface() {
+        return issendface;
+    }
+
+    public void setIssendface(String issendface) {
+        this.issendface = issendface;
+    }
+
+    public String getIssendfinger() {
+        return issendfinger;
+    }
+
+    public void setIssendfinger(String issendfinger) {
+        this.issendfinger = issendfinger;
+    }
+
+    public String getIssendpass() {
+        return issendpass;
+    }
+
+    public void setIssendpass(String issendpass) {
+        this.issendpass = issendpass;
+    }
+
+    public Integer getManagertype() {
+        return managertype;
+    }
+
+    public void setManagertype(Integer managertype) {
+        this.managertype = managertype;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getPersoncode() {
+        return personcode;
+    }
+
+    public void setPersoncode(String personcode) {
+        this.personcode = personcode;
+    }
+
+    public String getRoomid() {
+        return roomid;
+    }
+
+    public void setRoomid(String roomid) {
+        this.roomid = roomid;
+    }
+
+    public String getEmpsdate() {
+        return empsdate;
+    }
+
+    public void setEmpsdate(String empsdate) {
+        this.empsdate = empsdate;
+    }
+
+    public String getEmpedate() {
+        return empedate;
+    }
+
+    public void setEmpedate(String empedate) {
+        this.empedate = empedate;
+    }
+}

+ 157 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlRoom.java

@@ -0,0 +1,157 @@
+package com.zd.alg.smartlock.domain.api;
+
+import com.zd.alg.smartlock.domain.BaseDomain;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/08/30/10:42
+ * @Description:
+ */
+@ApiModel("房间信息")
+public class SlRoom extends BaseDomain {
+    @ApiModelProperty(value = "归属楼层建筑ID")
+    private String buildid;
+
+    @ApiModelProperty(value = "房间预约功能(-1不支持,0关闭,1打开)")
+    private Integer isbook;
+
+    @ApiModelProperty(value = "房间位置(1左侧2右侧)")
+    private Integer leftright;
+
+    @ApiModelProperty(value = "房间编号")
+    private String roomcode;
+
+    @ApiModelProperty(value = "门锁唯一ID")
+    private String roomcode2;
+
+    @ApiModelProperty(value = "房间id")
+    private Integer roomid;
+
+    @ApiModelProperty(value = "房间位置")
+    private String roomlocation;
+
+    @ApiModelProperty(value = "房间最大支持入住人数")
+    private  Integer roommaxperson;
+
+    @ApiModelProperty(value = "房间名称")
+    private  String roomname;
+
+    @ApiModelProperty(value = "公共房间类型(1教室,2办公室,3会议室,4实验室)")
+    private  Integer roomnexttype;
+
+    @ApiModelProperty(value = "房间类型(1宿舍,2公共房间,4酒店房间)")
+    private  Integer roomtype;
+
+    @ApiModelProperty(value = "房间类型2(1房间,2楼梯,3装饰房间)")
+    private  Integer roomtype2;
+
+    @ApiModelProperty(value = "排列顺序(从左到右由小到大排列)")
+    private  Integer sequence;
+
+
+    public String getBuildid() {
+        return buildid;
+    }
+
+    public void setBuildid(String buildid) {
+        this.buildid = buildid;
+    }
+
+    public Integer getIsbook() {
+        return isbook;
+    }
+
+    public void setIsbook(Integer isbook) {
+        this.isbook = isbook;
+    }
+
+    public Integer getLeftright() {
+        return leftright;
+    }
+
+    public void setLeftright(Integer leftright) {
+        this.leftright = leftright;
+    }
+
+    public String getRoomcode() {
+        return roomcode;
+    }
+
+    public void setRoomcode(String roomcode) {
+        this.roomcode = roomcode;
+    }
+
+    public String getRoomcode2() {
+        return roomcode2;
+    }
+
+    public void setRoomcode2(String roomcode2) {
+        this.roomcode2 = roomcode2;
+    }
+
+    public Integer getRoomid() {
+        return roomid;
+    }
+
+    public void setRoomid(Integer roomid) {
+        this.roomid = roomid;
+    }
+
+    public String getRoomlocation() {
+        return roomlocation;
+    }
+
+    public void setRoomlocation(String roomlocation) {
+        this.roomlocation = roomlocation;
+    }
+
+    public Integer getRoommaxperson() {
+        return roommaxperson;
+    }
+
+    public void setRoommaxperson(Integer roommaxperson) {
+        this.roommaxperson = roommaxperson;
+    }
+
+    public String getRoomname() {
+        return roomname;
+    }
+
+    public void setRoomname(String roomname) {
+        this.roomname = roomname;
+    }
+
+    public Integer getRoomnexttype() {
+        return roomnexttype;
+    }
+
+    public void setRoomnexttype(Integer roomnexttype) {
+        this.roomnexttype = roomnexttype;
+    }
+
+    public Integer getRoomtype() {
+        return roomtype;
+    }
+
+    public void setRoomtype(Integer roomtype) {
+        this.roomtype = roomtype;
+    }
+
+    public Integer getRoomtype2() {
+        return roomtype2;
+    }
+
+    public void setRoomtype2(Integer roomtype2) {
+        this.roomtype2 = roomtype2;
+    }
+
+    public Integer getSequence() {
+        return sequence;
+    }
+
+    public void setSequence(Integer sequence) {
+        this.sequence = sequence;
+    }
+}

+ 74 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlUser.java

@@ -0,0 +1,74 @@
+package com.zd.alg.smartlock.domain.api;
+
+import com.zd.alg.smartlock.domain.BaseDomain;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/03/13:37
+ * @Description:
+ */
+@ApiModel("查询人员信息")
+public class SlUser extends BaseDomain {
+
+    @ApiModelProperty(value = "身份证")
+    private String  personcard;
+
+    @ApiModelProperty(value = "学/工号")
+    private String personcode;
+
+    @ApiModelProperty(value = "手机号")
+    private String personmobile;
+
+    @ApiModelProperty(value = "姓名")
+    private String personname;
+
+    @ApiModelProperty(value = "性别")
+    private String personsex;
+
+    @ApiModelProperty(value = "人员类别(1=学生,2=教职工,3=临时人员)")
+    private String persontype;
+
+    public String getPersoncard() {
+        return personcard;
+    }
+
+    public void setPersoncard(String personcard) {
+        this.personcard = personcard;
+    }
+
+    public String getPersoncode() {
+        return personcode;
+    }
+
+    public void setPersoncode(String personcode) {
+        this.personcode = personcode;
+    }
+
+    public String getPersonmobile() {
+        return personmobile;
+    }
+
+    public void setPersonmobile(String personmobile) {
+        this.personmobile = personmobile;
+    }
+
+    public String getPersonname() {
+        return personname;
+    }
+
+    public void setPersonname(String personname) {
+        this.personname = personname;
+    }
+
+    public String getPersonsex() {        return personsex;    }
+
+    public void setPersonsex(String personsex) {        this.personsex = personsex;    }
+
+    public String getPersontype() {        return persontype;    }
+
+    public void setPersontype(String persontype) {
+        this.persontype = persontype;
+    }
+}

+ 32 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/api/SlupdateAuths.java

@@ -0,0 +1,32 @@
+package com.zd.alg.smartlock.domain.api;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/06/19:18
+ * @Description:
+ */
+public class SlupdateAuths {
+
+    @ApiModelProperty(value = "授权id")
+    private Integer authid;
+    @ApiModelProperty(value = "授权类型(1卡片,2指纹,3密码,4蓝牙)")
+    private Integer rctype;
+
+    public Integer getAuthid() {
+        return authid;
+    }
+
+    public void setAuthid(Integer authid) {
+        this.authid = authid;
+    }
+
+    public Integer getRctype() {
+        return rctype;
+    }
+
+    public void setRctype(Integer rctype) {
+        this.rctype = rctype;
+    }
+}

+ 67 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/vo/SlOpendoorApplyVo.java

@@ -0,0 +1,67 @@
+package com.zd.alg.smartlock.domain.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zd.alg.smartlock.domain.SlOpendoorApply;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/06/15:01
+ * @Description:
+ */
+public class SlOpendoorApplyVo extends SlOpendoorApply {
+
+    @ApiModelProperty(value = "是否安全负责人")
+    private Boolean safe;
+
+    @ApiModelProperty(value = "审批人集合")
+    private String examineName;
+
+    @ApiModelProperty(value = "授权人集合")
+    private String authName;
+
+    @ApiModelProperty(value = "开始时间")
+    private String startTime;
+
+    @ApiModelProperty(value = "结束时间")
+    private String endTime;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "失效时间")
+    private Date loseTime;
+
+    public Boolean getSafe() {
+        return safe;
+    }
+
+    public void setSafe(Boolean safe) {
+        this.safe = safe;
+    }
+
+    public String getExamineName() {        return examineName;    }
+
+    public void setExamineName(String examineName) {        this.examineName = examineName;    }
+
+
+    public String getStartTime() {        return startTime;    }
+
+    public void setStartTime(String startTime) {        this.startTime = startTime;    }
+
+    public String getEndTime() {        return endTime;    }
+
+    public void setEndTime(String endTime) {        this.endTime = endTime;    }
+
+    public Date getLoseTime() {        return loseTime;    }
+
+    public void setLoseTime(Date loseTime) {        this.loseTime = loseTime;    }
+
+    public String getAuthName() {
+        return authName;
+    }
+
+    public void setAuthName(String authName) {
+        this.authName = authName;
+    }
+}

+ 25 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/domain/vo/SlSubjectRelationVo.java

@@ -0,0 +1,25 @@
+package com.zd.alg.smartlock.domain.vo;
+
+import com.zd.alg.smartlock.domain.SlSubjectRelation;
+import com.zd.alg.smartlock.domain.api.SlLockOnline;
+import java.util.List;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/05/11:05
+ * @Description:
+ */
+public class SlSubjectRelationVo extends SlSubjectRelation {
+
+    private List<SlSubjectRelation> slSubjectList;
+
+    private SlLockOnline slLockOnline;
+
+    public List<SlSubjectRelation> getSlSubjectList() {        return slSubjectList;    }
+
+    public void setSlSubjectList(List<SlSubjectRelation> slSubjectList) {        this.slSubjectList = slSubjectList;    }
+
+    public SlLockOnline getSlLockOnline() {        return slLockOnline;    }
+
+    public void setSlLockOnline(SlLockOnline slLockOnline) {        this.slLockOnline = slLockOnline;    }
+}

+ 69 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/mapper/SlApplyApprovalMapper.java

@@ -0,0 +1,69 @@
+package com.zd.alg.smartlock.mapper;
+
+import com.zd.alg.smartlock.domain.SlApplyApproval;
+
+import java.util.List;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/02/18:10
+ * @Description:
+ */
+public interface SlApplyApprovalMapper {
+
+    /**
+     * 查询申请审核
+     *
+     * @param id 申请审核主键
+     * @return 申请审核
+     */
+    SlApplyApproval selectSlApplyApprovalById(Long id);
+
+    /**
+     * 查询申请审核列表
+     *
+     * @param slApplyApproval 申请审核
+     * @return 申请审核集合
+     */
+    List<SlApplyApproval> selectSlApplyApprovalList(SlApplyApproval slApplyApproval);
+
+    /**
+     * 根据主键集合查询申请审核列表
+     *
+     * @param ids 主键集合
+     * @return 申请审核集合
+     */
+    List<SlApplyApproval> getListByIds(List<Long> ids);
+
+    /**
+     * 新增申请审核
+     *
+     * @param slApplyApproval 申请审核
+     * @return 结果
+     */
+    int insertSlApplyApproval(SlApplyApproval slApplyApproval);
+
+    /**
+     * 修改申请审核
+     *
+     * @param slApplyApproval 申请审核
+     * @return 结果
+     */
+    int updateSlApplyApproval(SlApplyApproval slApplyApproval);
+
+    /**
+     * 删除申请审核
+     *
+     * @param id 申请审核主键
+     * @return 结果
+     */
+    int deleteSlApplyApprovalById(Long id);
+
+    /**
+     * 批量删除申请审核
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteSlApplyApprovalByIds(Long[] ids);
+}

+ 71 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/mapper/SlOpendoorApplyMapper.java

@@ -0,0 +1,71 @@
+package com.zd.alg.smartlock.mapper;
+
+import com.zd.alg.smartlock.domain.SlOpendoorApply;
+import com.zd.alg.smartlock.domain.vo.SlOpendoorApplyVo;
+
+import java.util.List;
+
+/**
+ * 申请开门Mapper接口
+ *
+ * @author zd
+ * @date 2022-09-03
+ */
+public interface SlOpendoorApplyMapper
+{
+    /**
+     * 查询申请开门
+     *
+     * @param id 申请开门主键
+     * @return 申请开门
+     */
+    SlOpendoorApply selectSlOpendoorApplyById(Long id);
+
+    /**
+     * 查询申请开门列表
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 申请开门集合
+     */
+    List<SlOpendoorApplyVo> selectSlOpendoorApplyList(SlOpendoorApplyVo slOpendoorApply);
+
+    /**
+     * 根据主键集合查询申请开门列表
+     *
+     * @param ids 主键集合
+     * @return 申请开门集合
+     */
+    List<SlOpendoorApply> getListByIds(List<Long> ids);
+
+    /**
+     * 新增申请开门
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 结果
+     */
+    int insertSlOpendoorApply(SlOpendoorApply slOpendoorApply);
+
+    /**
+     * 修改申请开门
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 结果
+     */
+    int updateSlOpendoorApply(SlOpendoorApply slOpendoorApply);
+
+    /**
+     * 删除申请开门
+     *
+     * @param id 申请开门主键
+     * @return 结果
+     */
+    int deleteSlOpendoorApplyById(Long id);
+
+    /**
+     * 批量删除申请开门
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteSlOpendoorApplyByIds(Long[] ids);
+}

+ 70 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/mapper/SlSubjectRelationMapper.java

@@ -0,0 +1,70 @@
+package com.zd.alg.smartlock.mapper;
+
+import com.zd.alg.smartlock.domain.SlSubjectRelation;
+import com.zd.alg.smartlock.domain.vo.SlSubjectRelationVo;
+
+import java.util.List;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/02/18:10
+ * @Description:
+ */
+public interface SlSubjectRelationMapper {
+
+    /**
+     * 查询实验室关联
+     *
+     * @param id 实验室关联主键
+     * @return 实验室关联
+     */
+    SlSubjectRelation selectSlSubjectRelationById(Long id);
+
+    /**
+     * 查询实验室关联列表
+     *
+     * @param slSubjectRelation 实验室关联
+     * @return 实验室关联集合
+     */
+    List<SlSubjectRelationVo> selectSlSubjectRelationList(SlSubjectRelationVo slSubjectRelation);
+
+    /**
+     * 根据主键集合查询实验室关联列表
+     *
+     * @param ids 主键集合
+     * @return 实验室关联集合
+     */
+    List<SlSubjectRelation> getListByIds(List<Long> ids);
+
+    /**
+     * 新增实验室关联
+     *
+     * @param slSubjectRelation 实验室关联
+     * @return 结果
+     */
+    int insertSlSubjectRelation(SlSubjectRelation slSubjectRelation);
+
+    /**
+     * 修改实验室关联
+     *
+     * @param slSubjectRelation 实验室关联
+     * @return 结果
+     */
+    int updateSlSubjectRelation(SlSubjectRelation slSubjectRelation);
+
+    /**
+     * 删除实验室关联
+     *
+     * @param id 实验室关联主键
+     * @return 结果
+     */
+    int deleteSlSubjectRelationById(Long id);
+
+    /**
+     * 批量删除实验室关联
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteSlSubjectRelationByIds(Long[] ids);
+}

+ 69 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/mapper/SlUserRelationMapper.java

@@ -0,0 +1,69 @@
+package com.zd.alg.smartlock.mapper;
+
+import com.zd.alg.smartlock.domain.SlUserRelation;
+
+import java.util.List;
+
+/**
+ * @Author: liujh
+ * @Date: 2022/09/02/18:10
+ * @Description:
+ */
+public interface SlUserRelationMapper {
+
+    /**
+     * 查询人员关联
+     *
+     * @param id 人员关联主键
+     * @return 人员关联
+     */
+    SlUserRelation selectSlUserRelationById(Long id);
+
+    /**
+     * 查询人员关联列表
+     *
+     * @param slUserRelation 人员关联
+     * @return 人员关联集合
+     */
+    List<SlUserRelation> selectSlUserRelationList(SlUserRelation slUserRelation);
+
+    /**
+     * 根据主键集合查询人员关联列表
+     *
+     * @param ids 主键集合
+     * @return 人员关联集合
+     */
+    List<SlUserRelation> getListByIds(List<Long> ids);
+
+    /**
+     * 新增人员关联
+     *
+     * @param slUserRelation 人员关联
+     * @return 结果
+     */
+    int insertSlUserRelation(SlUserRelation slUserRelation);
+
+    /**
+     * 修改人员关联
+     *
+     * @param slUserRelation 人员关联
+     * @return 结果
+     */
+    int updateSlUserRelation(SlUserRelation slUserRelation);
+
+    /**
+     * 删除人员关联
+     *
+     * @param id 人员关联主键
+     * @return 结果
+     */
+    int deleteSlUserRelationById(Long id);
+
+    /**
+     * 批量删除人员关联
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteSlUserRelationByIds(Long[] ids);
+}

+ 81 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/ISlApplyApprovalService.java

@@ -0,0 +1,81 @@
+package com.zd.alg.smartlock.service;
+
+import com.zd.alg.smartlock.domain.SlApplyApproval;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 申请审核Service接口
+ *
+ * @author zd
+ * @date 2022-09-02
+ */
+public interface ISlApplyApprovalService
+{
+    /**
+     * 查询申请审核
+     *
+     * @param id 申请审核主键
+     * @return 申请审核
+     */
+    SlApplyApproval selectSlApplyApprovalById(Long id);
+
+    /**
+     * 查询申请审核列表
+     *
+     * @param slApplyApproval 申请审核
+     * @return 申请审核集合
+     */
+    List<SlApplyApproval> selectSlApplyApprovalList(SlApplyApproval slApplyApproval);
+
+    /**
+     * 根据主键集合查询申请审核列表
+     *
+     * @param ids 主键集合
+     * @return 申请审核集合
+     */
+    List<SlApplyApproval> getListByIds(List<Long> ids);
+
+    /**
+     * 新增申请审核
+     *
+     * @param slApplyApproval 申请审核
+     * @return 结果
+     */
+    int insertSlApplyApproval(SlApplyApproval slApplyApproval);
+
+    /**
+     * 修改申请审核
+     *
+     * @param slApplyApproval 申请审核
+     * @return 结果
+     */
+    int updateSlApplyApproval(SlApplyApproval slApplyApproval);
+
+    /**
+     * 批量删除申请审核
+     *
+     * @param ids 需要删除的申请审核主键集合
+     * @return 结果
+     */
+    int deleteSlApplyApprovalByIds(Long[] ids);
+
+    /**
+     * 删除申请审核信息
+     *
+     * @param id 申请审核主键
+     * @return 结果
+     */
+    int deleteSlApplyApprovalById(Long id);
+
+    /**
+     *短信审核
+     * @param phone 回复人电话
+     * @param content 回复内容
+     * @param lockApplyId 申请id
+     * @return
+     */
+    Map<String,Object> sysMsgApprova(String phone, String content, Long lockApplyId);
+
+}

+ 86 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/ISlOpendoorApplyService.java

@@ -0,0 +1,86 @@
+package com.zd.alg.smartlock.service;
+
+import com.zd.alg.smartlock.domain.SlOpendoorApply;
+import com.zd.alg.smartlock.domain.vo.SlOpendoorApplyVo;
+
+import java.util.List;
+
+/**
+ * 申请开门Service接口
+ *
+ * @author zd
+ * @date 2022-09-03
+ */
+public interface ISlOpendoorApplyService
+{
+    /**
+     * 查询申请开门
+     *
+     * @param id 申请开门主键
+     * @return 申请开门
+     */
+    SlOpendoorApply selectSlOpendoorApplyById(Long id);
+
+    /**
+     * 查询申请开门列表
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 申请开门集合
+     */
+    List<SlOpendoorApplyVo> selectSlOpendoorApplyList(SlOpendoorApplyVo slOpendoorApply);
+
+    /**
+     * 查询申请开门列表-学生端
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 申请开门集合
+     */
+    List<SlOpendoorApplyVo> selectSlOpendoorApplyListStudent(SlOpendoorApplyVo slOpendoorApply);
+
+    /**
+     * 根据主键集合查询申请开门列表
+     *
+     * @param ids 主键集合
+     * @return 申请开门集合
+     */
+    List<SlOpendoorApply> getListByIds(List<Long> ids);
+
+    /**
+     * 新增申请开门
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 结果
+     */
+    int insertSlOpendoorApply(SlOpendoorApply slOpendoorApply);
+
+    /**
+     * 修改申请开门
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 结果
+     */
+    int updateSlOpendoorApply(SlOpendoorApply slOpendoorApply);
+
+    /**
+     * 批量删除申请开门
+     *
+     * @param ids 需要删除的申请开门主键集合
+     * @return 结果
+     */
+    int deleteSlOpendoorApplyByIds(Long[] ids);
+
+    /**
+     * 删除申请开门信息
+     *
+     * @param id 申请开门主键
+     * @return 结果
+     */
+    int deleteSlOpendoorApplyById(Long id);
+
+    /***
+     * 门锁申请重新授权
+     * @param id
+     * @return
+     */
+    String againAuth(Long id);
+}

+ 71 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/ISlSubjectRelationService.java

@@ -0,0 +1,71 @@
+package com.zd.alg.smartlock.service;
+
+import com.zd.alg.smartlock.domain.SlSubjectRelation;
+import com.zd.alg.smartlock.domain.vo.SlSubjectRelationVo;
+
+import java.util.List;
+
+/**
+ * 实验室关联Service接口
+ *
+ * @author zd
+ * @date 2022-09-03
+ */
+public interface ISlSubjectRelationService
+{
+    /**
+     * 查询实验室关联
+     *
+     * @param id 实验室关联主键
+     * @return 实验室关联
+     */
+    SlSubjectRelation selectSlSubjectRelationById(Long id);
+
+    /**
+     * 查询实验室关联列表
+     *
+     * @param slSubjectRelation 实验室关联
+     * @return 实验室关联集合
+     */
+    List<SlSubjectRelationVo> selectSlSubjectRelationList(SlSubjectRelationVo slSubjectRelation);
+
+    /**
+     * 根据主键集合查询实验室关联列表
+     *
+     * @param ids 主键集合
+     * @return 实验室关联集合
+     */
+    List<SlSubjectRelation> getListByIds(List<Long> ids);
+
+    /**
+     * 新增实验室关联
+     *
+     * @param vo 实验室关联
+     * @return 结果
+     */
+    int insertSlSubjectRelation(SlSubjectRelationVo vo);
+
+    /**
+     * 修改实验室关联
+     *
+     * @param slSubjectRelation 实验室关联
+     * @return 结果
+     */
+    int updateSlSubjectRelation(SlSubjectRelation slSubjectRelation);
+
+    /**
+     * 批量删除实验室关联
+     *
+     * @param ids 需要删除的实验室关联主键集合
+     * @return 结果
+     */
+    int deleteSlSubjectRelationByIds(Long[] ids);
+
+    /**
+     * 删除实验室关联信息
+     *
+     * @param id 实验室关联主键
+     * @return 结果
+     */
+    int deleteSlSubjectRelationById(Long id);
+}

+ 70 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/ISlUserRelationService.java

@@ -0,0 +1,70 @@
+package com.zd.alg.smartlock.service;
+
+import com.zd.alg.smartlock.domain.SlUserRelation;
+
+import java.util.List;
+
+/**
+ * 人员关联Service接口
+ *
+ * @author zd
+ * @date 2022-09-02
+ */
+public interface ISlUserRelationService
+{
+    /**
+     * 查询人员关联
+     *
+     * @param id 人员关联主键
+     * @return 人员关联
+     */
+    SlUserRelation selectSlUserRelationById(Long id);
+
+    /**
+     * 查询人员关联列表
+     *
+     * @param slUserRelation 人员关联
+     * @return 人员关联集合
+     */
+    List<SlUserRelation> selectSlUserRelationList(SlUserRelation slUserRelation);
+
+    /**
+     * 根据主键集合查询人员关联列表
+     *
+     * @param ids 主键集合
+     * @return 人员关联集合
+     */
+    List<SlUserRelation> getListByIds(List<Long> ids);
+
+    /**
+     * 新增人员关联
+     *
+     * @param slUserRelation 人员关联
+     * @return 结果
+     */
+    int insertSlUserRelation(SlUserRelation slUserRelation);
+
+    /**
+     * 修改人员关联
+     *
+     * @param slUserRelation 人员关联
+     * @return 结果
+     */
+    int updateSlUserRelation(SlUserRelation slUserRelation);
+
+    /**
+     * 批量删除人员关联
+     *
+     * @param ids 需要删除的人员关联主键集合
+     * @return 结果
+     */
+    int deleteSlUserRelationByIds(Long[] ids);
+
+    /**
+     * 删除人员关联信息
+     *
+     * @param id 人员关联主键
+     * @return 结果
+     */
+    int deleteSlUserRelationById(Long id);
+}

+ 410 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/impl/SlApplyApprovalServiceImpl.java

@@ -0,0 +1,410 @@
+package com.zd.alg.smartlock.service.impl;
+
+import com.zd.alg.smartlock.domain.SlApplyApproval;
+import com.zd.alg.smartlock.domain.SlOpendoorApply;
+import com.zd.alg.smartlock.domain.api.SlUser;
+import com.zd.alg.smartlock.domain.vo.SlSubjectRelationVo;
+import com.zd.alg.smartlock.mapper.SlApplyApprovalMapper;
+import com.zd.alg.smartlock.mapper.SlOpendoorApplyMapper;
+import com.zd.alg.smartlock.mapper.SlSubjectRelationMapper;
+import com.zd.alg.smartlock.service.ISlApplyApprovalService;
+import com.zd.alg.smartlock.utils.SmartlockUtil;
+import com.zd.common.core.domain.R;
+import com.zd.common.core.exception.ServiceException;
+import com.zd.common.security.service.TokenService;
+import com.zd.system.api.RemoteUserService;
+import com.zd.system.api.chemical.RemoteStockService;
+import com.zd.system.api.domain.SysUser;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
+/**
+ * 人员关联Service业务层处理
+ *
+ * @author zd
+ * @date 2022-09-02
+ */
+@Slf4j
+@Service
+public class SlApplyApprovalServiceImpl implements ISlApplyApprovalService
+{
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private SlApplyApprovalMapper slApplyApprovalMapper;
+
+    @Autowired
+    private SlOpendoorApplyMapper slOpendoorApplyMapper;
+
+    @Autowired
+    private SlSubjectRelationMapper slSubjectRelationMapper;
+
+    @Autowired
+    private RemoteStockService remoteStockService;
+
+    @Autowired
+    private RemoteUserService remoteUserService;
+
+
+    /**
+     * 查询申请审核
+     *
+     * @param id 申请审核主键
+     * @return 申请审核
+     */
+    @Override
+    public SlApplyApproval selectSlApplyApprovalById(Long id)
+    {
+        return slApplyApprovalMapper.selectSlApplyApprovalById(id);
+    }
+
+    /**
+     * 查询申请审核列表
+     *
+     * @param slApplyApproval 申请审核
+     * @return 申请审核
+     */
+    @Override
+    public List<SlApplyApproval> selectSlApplyApprovalList(SlApplyApproval slApplyApproval)
+    {
+        return slApplyApprovalMapper.selectSlApplyApprovalList(slApplyApproval);
+    }
+
+    @Override
+    public List<SlApplyApproval> getListByIds(List<Long> ids){
+        if (ids.isEmpty()){
+            new ArrayList<>();
+        }
+        return slApplyApprovalMapper.getListByIds(ids);
+    }
+
+    /**
+     * 新增申请审核-需求变更废弃 2022-09-27
+     *
+     * @param slApplyApproval 申请审核
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int insertSlApplyApproval(SlApplyApproval slApplyApproval)
+    {
+        int flg=0;
+        try {
+            SysUser sysUser = tokenService.getLoginUser().getSysUser();
+            //部门id
+            slApplyApproval.setDeptId(sysUser.getDept().getDeptId());
+            //部门名称
+            slApplyApproval.setDeptName(sysUser.getDept().getDeptName());
+            //审核人id
+            slApplyApproval.setApprovaId(sysUser.getUserId());
+            //审核人姓名
+            slApplyApproval.setApprovaName(sysUser.getNickName());
+            //审核时间
+            slApplyApproval.setCretaTime(new Date());
+
+            //查询申请记录
+            SlOpendoorApply opendoorApply = slOpendoorApplyMapper.selectSlOpendoorApplyById(slApplyApproval.getApplyId());
+
+            if(opendoorApply.getApplyStatus()==3){
+                throw new ServiceException("该记录已驳回,无需审核!");
+            }
+            if(opendoorApply.getApplyNumber()==2){
+                throw new ServiceException("该记录已有两次审核,无需再次审核!");
+            }
+            //通过
+            if(slApplyApproval.getApprovaStatus()==1){
+                opendoorApply.setApplyNumber(opendoorApply.getApplyNumber()+1);
+                //审核通过,下发密码(第二次,审核通过的情况下)
+                if(opendoorApply.getApplyNumber()==2){
+                    //判断是否同一个人连续审核
+                    SlApplyApproval approval = new SlApplyApproval();
+                    approval.setApplyId(slApplyApproval.getApplyId());
+                    approval.setApprovaId(sysUser.getUserId());
+                    List<SlApplyApproval> applyVoList = slApplyApprovalMapper.selectSlApplyApprovalList(approval);
+                    if(applyVoList.size()>0){
+                        throw new ServiceException("您已审核过该条申请,无需重复审核!");
+                    }
+                    //审核通过,刷新审核状态
+                    opendoorApply.setApplyStatus(2L);
+                    //审核通过后,添加人员并且授权、短信发送
+                    String str =  authPower(opendoorApply.getId());
+                    if(!"ok".equals(str)){
+                        log.info("人员授权以及短信发送结果:"+str);
+                        throw new ServiceException(str);
+                    }
+                }
+            }else if(slApplyApproval.getApprovaStatus()==2){
+                //驳回
+                opendoorApply.setApplyNumber(opendoorApply.getApplyNumber()+1);
+                //修改申请表状态
+                opendoorApply.setApplyStatus(3L);
+
+                //申请人1短信发送通知
+               R r1= remoteStockService.sendSydSms("【实验室安全系统】"+opendoorApply.getSubjectName()+"-门禁远程授权申请已拒绝,请联系实验室管理人员。",3,opendoorApply.getId(),opendoorApply.getPhonenumber());
+               log.info("开门申请拒绝,人员1短信通知结果:"+r1);
+                //申请人2短信发送通知
+               R r2= remoteStockService.sendSydSms("【实验室安全系统】"+opendoorApply.getSubjectName()+"-门禁远程授权申请已拒绝,请联系实验室管理人员。",3,opendoorApply.getId(),opendoorApply.getPhonenumber2());
+                log.info("开门申请拒绝,人员2短信通知结果:"+r2);
+            }
+            //申请表操作
+            opendoorApply.setApprovalTime(new Date());
+            opendoorApply.setApprovalUser(sysUser.getNickName());
+
+            slOpendoorApplyMapper.updateSlOpendoorApply(opendoorApply);
+            flg= slApplyApprovalMapper.insertSlApplyApproval(slApplyApproval);
+        }catch (Exception e){
+            log.info("申请审核异常"+e);
+        }
+        return flg;
+    }
+
+    /**
+     * 修改申请审核
+     *
+     * @param slApplyApproval 申请审核
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int updateSlApplyApproval(SlApplyApproval slApplyApproval)
+    {
+        return slApplyApprovalMapper.updateSlApplyApproval(slApplyApproval);
+    }
+
+    /**
+     * 批量删除申请审核
+     *
+     * @param ids 需要删除的申请审核主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteSlApplyApprovalByIds(Long[] ids)
+    {
+        return slApplyApprovalMapper.deleteSlApplyApprovalByIds(ids);
+    }
+
+    /**
+     * 删除申请审核信息
+     *
+     * @param id 申请审核主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteSlApplyApprovalById(Long id)
+    {
+        return slApplyApprovalMapper.deleteSlApplyApprovalById(id);
+    }
+
+    /***
+     * 短信审核 需求变更,废弃2022-09-27
+     * @param phone 回复人电话
+     * @param content 回复内容
+     * @param lockApplyId 申请id
+     * @return
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Map<String,Object> sysMsgApprova(String phone, String content, Long lockApplyId) {
+        Map<String,Object> map = new HashMap<>();
+        try {
+            //审核状态 1通过 2驳回
+            Long approvalStatus=1L ;
+            SysUser sysUser =  remoteUserService.getUserByPhone(phone).getData();
+            if(sysUser==null){
+                map.put("msg","未查询到相关人信息");
+                map.put("status","error");
+                return map;
+            }
+
+            //查询申请记录
+            SlOpendoorApply opendoorApply = slOpendoorApplyMapper.selectSlOpendoorApplyById(lockApplyId);
+
+            if(opendoorApply.getApplyStatus()==3){
+                map.put("msg","该记录已驳回,无需审核!");
+                map.put("status","error");
+                return map;
+            }
+            if(opendoorApply.getApplyNumber()==2){
+                map.put("msg","该记录已有两次审核,无需再次审核!");
+                map.put("status","error");
+                return map;
+            }
+            //通过
+            if( "1".equals(content)){
+                opendoorApply.setApplyNumber(opendoorApply.getApplyNumber()+1);
+                //审核通过,下发密码(第二次,审核通过的情况下)
+                if(opendoorApply.getApplyNumber()==2){
+                    //判断是否同一个人连续审核
+                    SlApplyApproval approval = new SlApplyApproval();
+                    approval.setApplyId(lockApplyId);
+                    approval.setApprovaId(sysUser.getUserId());
+                    List<SlApplyApproval> applyVoList = slApplyApprovalMapper.selectSlApplyApprovalList(approval);
+                    if(applyVoList.size()>0){
+                        map.put("msg","您已审核过该条申请,无需重复审核!");
+                        map.put("status","error");
+                        return map;
+                    }
+                    //审核通过,刷新审核状态
+                    opendoorApply.setApplyStatus(2L);
+
+                    //审核通过后,添加人员并且授权、短信发送
+                    String str =  authPower(opendoorApply.getId());
+                    if(!"ok".equals(str)){
+                        map.put("msg",str);
+                        map.put("status","error");
+                        return map;
+                    }
+                }
+            }else if( "0".equals(content)){
+                approvalStatus=2L;
+                //驳回
+                opendoorApply.setApplyNumber(opendoorApply.getApplyNumber()+1);
+                //修改申请表状态
+                opendoorApply.setApplyStatus(3L);
+
+                //申请人1短信发送通知
+                R r1= remoteStockService.sendSydSms("【实验室安全系统】"+opendoorApply.getSubjectName()+"-门禁远程授权申请已拒绝,请联系实验室管理人员。",3,opendoorApply.getId(),opendoorApply.getPhonenumber());
+                log.info("短信开门申请拒绝,人员1短信通知结果:"+r1);
+                //申请人2短信发送通知
+                R r2= remoteStockService.sendSydSms("【实验室安全系统】"+opendoorApply.getSubjectName()+"-门禁远程授权申请已拒绝,请联系实验室管理人员。",3,opendoorApply.getId(),opendoorApply.getPhonenumber2());
+                log.info("短信开门申请拒绝,人员2短信通知结果:"+r2);
+            }
+            //申请表操作
+            opendoorApply.setApprovalTime(new Date());
+            opendoorApply.setApprovalUser(sysUser.getNickName());
+
+            slOpendoorApplyMapper.updateSlOpendoorApply(opendoorApply);
+            SlApplyApproval approval = new SlApplyApproval();
+            approval.setApplyId(lockApplyId);
+            approval.setApprovaId(sysUser.getUserId());
+            approval.setDeptId(sysUser.getDept().getDeptId());
+            approval.setDeptName(sysUser.getDept().getDeptName());
+            approval.setApprovaId(sysUser.getUserId());
+            approval.setApprovaName(sysUser.getNickName());
+            approval.setApprovaStatus(approvalStatus);
+            approval.setCretaTime(new Date());
+            slApplyApprovalMapper.insertSlApplyApproval(approval);
+        }catch (Exception e){
+            log.info("短信审核处理异常:"+e);
+            map.put("msg",e);
+            map.put("status","error");
+            return map;
+        }
+        map.put("msg","成功");
+        map.put("status","ok");
+        return map;
+    }
+
+    /***
+     * 审批通过后人员密码授权处理- 需求变更,废弃2022-09-27
+     * @param applyId 申请id
+     */
+    public String authPower(Long applyId) throws Exception {
+        log.info("========开始门锁授权===========");
+        //人员1 授权结果
+        Boolean auths1=false;
+        //人员2授权结果
+        Boolean auths2=false;
+        //返回值
+        String strMsg="ok";
+        try {
+            //查询申请记录
+            SlOpendoorApply opendoorApply = slOpendoorApplyMapper.selectSlOpendoorApplyById(applyId);
+
+            SlSubjectRelationVo subjectRelation = new SlSubjectRelationVo();
+            subjectRelation.setSubjectId(opendoorApply.getSubjectId());
+            List<SlSubjectRelationVo>  listsubRla = slSubjectRelationMapper.selectSlSubjectRelationList(subjectRelation);
+            if(listsubRla.size()!=2){
+                strMsg="该实验室暂未绑定双锁!";
+            }
+
+            Map<String,Object> detalisMap = new HashMap<>();
+            SlUser user = new SlUser();
+            //学号、工号
+            user.setPersoncode(opendoorApply.getUserCode());
+            //姓名
+            user.setPersonname(opendoorApply.getUserName());
+            //性别 (0=女,1=男)
+            user.setPersonsex(opendoorApply.getUserSex()==null?1+"":0+"");
+            //人员类别(1=学生,2=教职工,3=临时人员)
+            user.setPersontype("1");
+            //电话
+            user.setPersonmobile(opendoorApply.getPhonenumber());
+            log.info("=======人员1授权开始========");
+            Map<String,Object> map1= SmartlockUtil.addUser(user,listsubRla.get(0).getLockRoomId());
+
+            if(!SmartlockUtil.resultMsg.equals(map1.get("resultMsg").toString())){
+                log.info("人员:"+opendoorApply.getUserName()+",授权失败,原因:"+map1.get("resultMsg")+",请联系管理员");
+                strMsg="人员:"+opendoorApply.getUserName()+",授权失败,原因:"+map1.get("resultMsg")+",请联系管理员";
+                return strMsg;
+            }else {
+                log.info("=======人员1授权成功========");
+                auths1=true;
+            }
+
+
+            //人员1 备注详情
+            detalisMap.put("人员1",opendoorApply.getUserName());
+            detalisMap.put("锁编1号",listsubRla.get(0).getLockCode());
+            detalisMap.put("人员1密码",map1.get("password"));
+
+            //学号、工号
+            user.setPersoncode(opendoorApply.getUserCode2());
+            //姓名
+            user.setPersonname(opendoorApply.getUserName2());
+            //性别 (0=女,1=男)
+            user.setPersonsex(opendoorApply.getUserSex2()==null?1+"":0+"");
+            //人员类别(1=学生,2=教职工,3=临时人员)
+            user.setPersontype("1");
+            //电话
+            user.setPersonmobile(opendoorApply.getPhonenumber2());
+
+            log.info("=======人员2授权开始========");
+            Map<String,Object> map2= SmartlockUtil.addUser(user,listsubRla.get(1).getLockRoomId());
+
+            //人员2 备注详情
+            detalisMap.put("人员2",opendoorApply.getUserName());
+            detalisMap.put("锁编2号",listsubRla.get(1).getLockCode());
+            detalisMap.put("人员2密码",map2.get("password"));
+            if(!SmartlockUtil.resultMsg.equals(map2.get("resultMsg").toString())){
+                log.info("人员2:"+opendoorApply.getUserName()+",授权失败,原因:"+map2.get("resultMsg")+",请联系管理员");
+                strMsg="人员:"+opendoorApply.getUserName()+",授权失败,原因:"+map2.get("resultMsg")+",请联系管理员";
+                return strMsg;
+            }else {
+                log.info("=======人员2授权成功========");
+                auths2=true;
+            }
+
+
+
+            log.info("=======授权结束========人员1授权结果:"+auths1+" ,人员2授权结果:"+auths2);
+            //人员入住办理成功,发送短信提示
+            if(auths1 && auths2){
+                log.info("=============双人授权成功,下发短信================");
+                R p1 = remoteStockService.sendSydSms("【实验室安全系统】授权码:"+map1.get("password")+"("+SmartlockUtil.authsLength+"小时内有效),"+opendoorApply.getSubjectName()+"-门禁远程授权申请已通过,请勿泄露给他人。",3,applyId,new String[] {opendoorApply.getPhonenumber()});
+                log.info("人员1短信发送结果:"+p1);
+
+                R p2 = remoteStockService.sendSydSms("【实验室安全系统】授权码:"+map1.get("password")+"("+SmartlockUtil.authsLength+"小时内有效),"+opendoorApply.getSubjectName()+"-门禁远程授权申请已通过,请勿泄露给他人。",3,applyId,new String[] {opendoorApply.getPhonenumber2()});
+                log.info("人员2短信发送结果:"+p2);
+
+            /*String msg1="开门申请成功,门锁编号:"+listsubRla.get(0).getLockCode()+"密码:"+map1.get("password");
+            String msg2="开门申请成功,门锁编号:"+listsubRla.get(1).getLockCode()+"密码:"+map1.get("password");*/
+            }
+
+            opendoorApply.setIllustrate(detalisMap.toString());
+            slOpendoorApplyMapper.updateSlOpendoorApply(opendoorApply);
+
+        }catch (Exception e){
+            log.info("=======人员授权失败========"+e);
+        }
+        return strMsg;
+    }
+}

+ 276 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/impl/SlOpendoorApplyServiceImpl.java

@@ -0,0 +1,276 @@
+package com.zd.alg.smartlock.service.impl;
+
+import com.zd.alg.smartlock.domain.SlOpendoorApply;
+import com.zd.alg.smartlock.domain.api.SlUser;
+import com.zd.alg.smartlock.domain.vo.SlOpendoorApplyVo;
+import com.zd.alg.smartlock.domain.vo.SlSubjectRelationVo;
+import com.zd.alg.smartlock.mapper.SlOpendoorApplyMapper;
+import com.zd.alg.smartlock.mapper.SlSubjectRelationMapper;
+import com.zd.alg.smartlock.service.ISlOpendoorApplyService;
+import com.zd.alg.smartlock.utils.SmartlockUtil;
+import com.zd.common.core.domain.R;
+import com.zd.common.core.domain.per.PerPrefix;
+import com.zd.common.core.exception.ServiceException;
+import com.zd.common.core.utils.StringUtils;
+import com.zd.common.datascope.annotation.DataScope;
+import com.zd.common.security.service.TokenService;
+import com.zd.system.api.RemoteUserService;
+import com.zd.system.api.chemical.RemoteStockService;
+import com.zd.system.api.domain.SysUser;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
+/**
+ * 申请开门Service业务层处理
+ *
+ * @author zd
+ * @date 2022-09-03
+ */
+@Slf4j
+@Service
+public class SlOpendoorApplyServiceImpl implements ISlOpendoorApplyService {
+    @Autowired
+    private SlOpendoorApplyMapper slOpendoorApplyMapper;
+
+    @Autowired
+    private RemoteUserService remoteUserService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private SlSubjectRelationMapper slSubjectRelationMapper;
+
+    @Autowired
+    private RemoteStockService remoteStockService;
+
+    /**
+     * 查询申请开门
+     *
+     * @param id 申请开门主键
+     * @return 申请开门
+     */
+    @Override
+    public SlOpendoorApply selectSlOpendoorApplyById(Long id) {
+        return slOpendoorApplyMapper.selectSlOpendoorApplyById(id);
+    }
+
+    /**
+     * 查询申请开门列表
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 申请开门
+     */
+    @Override
+    @DataScope(deptAlias = "d", userAlias = "u", permi = PerPrefix.SMARTLOCK_OPENDOORAPPLY)
+    public List<SlOpendoorApplyVo> selectSlOpendoorApplyList(SlOpendoorApplyVo slOpendoorApply) {
+        return slOpendoorApplyMapper.selectSlOpendoorApplyList(slOpendoorApply);
+    }
+
+    /**
+     * 查询申请开门列表-学生端
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 申请开门集合
+     */
+    @Override
+    public List<SlOpendoorApplyVo> selectSlOpendoorApplyListStudent(SlOpendoorApplyVo slOpendoorApply) {
+        return slOpendoorApplyMapper.selectSlOpendoorApplyList(slOpendoorApply);
+    }
+
+    @Override
+    public List<SlOpendoorApply> getListByIds(List<Long> ids) {
+        if (ids.isEmpty()) {
+            new ArrayList<>();
+        }
+        return slOpendoorApplyMapper.getListByIds(ids);
+    }
+
+    /**
+     * 新增申请开门
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 结果
+     */
+    @Override
+    //@Transactional(rollbackFor = Exception.class)
+    public int insertSlOpendoorApply(SlOpendoorApply slOpendoorApply) {
+
+        SysUser sysUser = tokenService.getLoginUser().getSysUser();
+
+        //1.校验实验室是否配置并且关联双锁
+        SlSubjectRelationVo subjectRelation = new SlSubjectRelationVo();
+        subjectRelation.setSubjectId(slOpendoorApply.getSubjectId());
+        List<SlSubjectRelationVo> subjectList = slSubjectRelationMapper.selectSlSubjectRelationList(subjectRelation);
+        if (subjectList.size() < 2) {
+            throw new ServiceException("该实验室关联门锁不足2个!");
+        }
+        //2.校验人员电话是否为空
+        if (StringUtils.isEmpty(sysUser.getPhonenumber())) {
+            throw new ServiceException("申请人:" + sysUser.getNickName() + "电话为空!");
+        }
+
+        if (StringUtils.isEmpty(slOpendoorApply.getSafeUserPhone())) {
+            throw new ServiceException("实验室负责人:" + slOpendoorApply.getSafeUserName() + "电话为空!");
+        }
+
+        slOpendoorApply.setUserId(sysUser.getUserId());
+        slOpendoorApply.setUserName(sysUser.getNickName());
+        slOpendoorApply.setDeptId(sysUser.getDept().getDeptId());
+        slOpendoorApply.setDeptName(sysUser.getDept().getDeptName());
+        slOpendoorApply.setUserCode(sysUser.getUserName());
+        slOpendoorApply.setUserSex(sysUser.getSex() == null ? 1 : Integer.valueOf(sysUser.getSex()));
+        slOpendoorApply.setPhonenumber(sysUser.getPhonenumber());
+        slOpendoorApply.setCreatTime(new Date());
+        slOpendoorApplyMapper.insertSlOpendoorApply(slOpendoorApply);
+        try {
+            //授权并且发送短信通知实验室门锁对应的安全负责人
+           String msg=  authPowerNew(slOpendoorApply.getId());
+           log.info("授权或者短信通知结果:"+msg);
+        } catch (Exception e) {
+            log.info("授权失败:"+e);
+        }
+        return 1;
+    }
+
+    /**
+     * 修改申请开门
+     *
+     * @param slOpendoorApply 申请开门
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int updateSlOpendoorApply(SlOpendoorApply slOpendoorApply) {
+        return slOpendoorApplyMapper.updateSlOpendoorApply(slOpendoorApply);
+    }
+
+    /**
+     * 批量删除申请开门
+     *
+     * @param ids 需要删除的申请开门主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteSlOpendoorApplyByIds(Long[] ids) {
+        return slOpendoorApplyMapper.deleteSlOpendoorApplyByIds(ids);
+    }
+
+    /**
+     * 删除申请开门信息
+     *
+     * @param id 申请开门主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteSlOpendoorApplyById(Long id) {
+        return slOpendoorApplyMapper.deleteSlOpendoorApplyById(id);
+    }
+
+
+    /***
+     * 门锁申请重新授权
+     * @param id
+     * @return
+     */
+    @Override
+    public String againAuth(Long id) {
+        String str="";
+        try {
+            str =  authPowerNew(id);
+        }catch (Exception e) {
+            e.printStackTrace();
+            log.error("重新授权失败:"+e);
+        }
+        return str;
+    }
+
+    /***
+     * 审批通过后人员密码授权处理
+     * @param applyId 申请id
+     */
+    public String authPowerNew(Long applyId) throws Exception {
+        log.info("========开始门锁授权===========");
+        //人员1 授权结果
+        Boolean auths1=false;
+        //返回值
+        String strMsg="ok";
+        try {
+            //查询申请记录
+            SlOpendoorApply opendoorApply = slOpendoorApplyMapper.selectSlOpendoorApplyById(applyId);
+
+            SlSubjectRelationVo subjectRelation = new SlSubjectRelationVo();
+            subjectRelation.setSubjectId(opendoorApply.getSubjectId());
+            List<SlSubjectRelationVo>  listsubRla = slSubjectRelationMapper.selectSlSubjectRelationList(subjectRelation);
+            if(listsubRla.size()!=2){
+                strMsg="该实验室暂未绑定双锁!";
+            }
+
+            Map<String,Object> detalisMap = new HashMap<>();
+            SlUser user = new SlUser();
+            //学号、工号
+            user.setPersoncode(opendoorApply.getUserCode());
+            //姓名
+            user.setPersonname(opendoorApply.getUserName());
+            //性别 (0=女,1=男)
+            user.setPersonsex(opendoorApply.getUserSex()==null?1+"":0+"");
+            //人员类别(1=学生,2=教职工,3=临时人员)
+            user.setPersontype("1");
+            //电话
+            user.setPersonmobile(opendoorApply.getPhonenumber());
+            log.info("=======人员1授权开始========");
+            Map<String,Object> map1= SmartlockUtil.addUser(user,listsubRla.get(0).getLockRoomId());
+
+            if(!SmartlockUtil.resultMsg.equals(map1.get("resultMsg").toString())){
+                log.info("人员:"+opendoorApply.getUserName()+",授权失败,原因:"+map1.get("resultMsg")+",请联系管理员");
+                strMsg="人员:"+opendoorApply.getUserName()+",授权失败,原因:"+map1.get("resultMsg")+",请联系管理员";
+                return strMsg;
+            }else {
+                log.info("=======人员1授权成功========");
+                auths1=true;
+            }
+
+            log.info("=======授权结束========人员授权结果:"+auths1);
+            //人员入住办理成功,发送短信提示
+            if(auths1){
+                SlSubjectRelationVo relationVo = new SlSubjectRelationVo();
+                relationVo.setSubjectId(opendoorApply.getSubjectId());
+                List<SlSubjectRelationVo> relist = slSubjectRelationMapper.selectSlSubjectRelationList(relationVo);
+                if(relist.size()<2){
+                    log.info("该实验室暂未关联双门锁。");
+                    throw  new ServiceException("该实验室暂未关联双门锁。");
+                }
+
+                for (SlSubjectRelationVo rvo:relist) {
+                    if(opendoorApply.getSafeUserId().equals(String.valueOf(rvo.getSubjectId())) ){
+                        log.info("=============授权成功,下发短信================");
+                        //人员1 备注详情
+                        detalisMap.put("人员",opendoorApply.getUserName());
+                        detalisMap.put("锁编号",rvo.getLockCode());
+                        detalisMap.put("人员密码",map1.get("password"));
+
+                        R r1= remoteStockService.sendSydSms(
+                                "【实验室安全系统】" + opendoorApply.getUserName() + "申请" +
+                                        opendoorApply.getSubjectName() +
+                                        "-门禁远程授权,手机号:"+opendoorApply.getPhonenumber()+",授权码:"+map1.get("password")+
+                                        "("+ SmartlockUtil.authsLength+"小时内有效),请勿泄露给他人。",
+                                3, opendoorApply.getId(), rvo.getSafeUserPhone());
+                        log.info("人员1短信发送结果:"+r1);
+                    }
+                }
+            }
+            opendoorApply.setIllustrate(detalisMap.toString());
+            slOpendoorApplyMapper.updateSlOpendoorApply(opendoorApply);
+
+        }catch (Exception e){
+            log.info("=======人员授权失败========"+e);
+        }
+        return strMsg;
+    }
+}

+ 146 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/impl/SlSubjectRelationServiceImpl.java

@@ -0,0 +1,146 @@
+package com.zd.alg.smartlock.service.impl;
+
+import com.zd.alg.smartlock.domain.SlSubjectRelation;
+import com.zd.alg.smartlock.domain.vo.SlSubjectRelationVo;
+import com.zd.alg.smartlock.mapper.SlSubjectRelationMapper;
+import com.zd.alg.smartlock.service.ISlSubjectRelationService;
+import com.zd.common.core.exception.ServiceException;
+import com.zd.common.core.utils.SecurityUtils;
+import com.zd.common.core.utils.StringUtils;
+import com.zd.common.security.service.TokenService;
+import com.zd.system.api.domain.SysUser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 实验室关联Service业务层处理
+ *
+ * @author zd
+ * @date 2022-09-03
+ */
+@Service
+public class SlSubjectRelationServiceImpl implements ISlSubjectRelationService
+{
+    @Autowired
+    private SlSubjectRelationMapper slSubjectRelationMapper;
+
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 查询实验室关联
+     *
+     * @param id 实验室关联主键
+     * @return 实验室关联
+     */
+    @Override
+    public SlSubjectRelation selectSlSubjectRelationById(Long id)
+    {
+        return slSubjectRelationMapper.selectSlSubjectRelationById(id);
+    }
+
+    /**
+     * 查询实验室关联列表
+     *
+     * @param slSubjectRelation 实验室关联
+     * @return 实验室关联
+     */
+    @Override
+    public List<SlSubjectRelationVo> selectSlSubjectRelationList(SlSubjectRelationVo slSubjectRelation)
+    {
+        return slSubjectRelationMapper.selectSlSubjectRelationList(slSubjectRelation);
+    }
+
+    @Override
+    public List<SlSubjectRelation> getListByIds(List<Long> ids){
+        if (ids.isEmpty()){
+            new ArrayList<>();
+        }
+        return slSubjectRelationMapper.getListByIds(ids);
+    }
+
+    /**
+     * 新增实验室关联
+     *
+     * @param vo 实验室关联
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int insertSlSubjectRelation(SlSubjectRelationVo vo)
+    {
+        List<SlSubjectRelation> list = vo.getSlSubjectList();
+        if(list==null || list.size()==0){
+            throw new ServiceException("没有要关联的数据!");
+        }
+        System.out.println(SecurityUtils.getUsername());
+        //校验本次提交是否存在已绑定情况
+        SlSubjectRelationVo subjectRelation = new SlSubjectRelationVo();
+        for (SlSubjectRelation sl:list ) {
+            if(StringUtils.isEmpty(sl.getLockCode())){
+                throw new ServiceException("房间: "+sl.getRoomName()+",位置: "+sl.getRoomLocation()+"未绑定门锁。");
+            }
+            subjectRelation.setLockRoomId(sl.getLockRoomId());
+            List<SlSubjectRelationVo> sellist=  slSubjectRelationMapper.selectSlSubjectRelationList(subjectRelation);
+            if(sellist.size()>0){
+                throw new ServiceException("房间: "+sl.getRoomName()+",位置: "+sl.getRoomLocation()+"已被绑定。");
+            }
+        }
+
+        SysUser sysUser = tokenService.getLoginUser().getSysUser();
+        //关系绑定
+        for (SlSubjectRelation slsub:list ) {
+            slsub.setDeptId(sysUser.getDept().getDeptId());
+            slsub.setDeptName(sysUser.getDept().getDeptName());
+            slsub.setUserId(sysUser.getUserId());
+            slsub.setCreateBy(sysUser.getNickName());
+            slsub.setCreatTime(new Date());
+            slSubjectRelationMapper.insertSlSubjectRelation(slsub);
+        }
+        return 1;
+    }
+
+    /**
+     * 修改实验室关联
+     *
+     * @param slSubjectRelation 实验室关联
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int updateSlSubjectRelation(SlSubjectRelation slSubjectRelation)
+    {
+        return slSubjectRelationMapper.updateSlSubjectRelation(slSubjectRelation);
+    }
+
+    /**
+     * 批量删除实验室关联
+     *
+     * @param ids 需要删除的实验室关联主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteSlSubjectRelationByIds(Long[] ids)
+    {
+        return slSubjectRelationMapper.deleteSlSubjectRelationByIds(ids);
+    }
+
+    /**
+     * 删除实验室关联信息
+     *
+     * @param id 实验室关联主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteSlSubjectRelationById(Long id)
+    {
+        return slSubjectRelationMapper.deleteSlSubjectRelationById(id);
+    }
+}

+ 108 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/service/impl/SlUserRelationServiceImpl.java

@@ -0,0 +1,108 @@
+package com.zd.alg.smartlock.service.impl;
+
+import com.zd.alg.smartlock.domain.SlUserRelation;
+import com.zd.alg.smartlock.mapper.SlUserRelationMapper;
+import com.zd.alg.smartlock.service.ISlUserRelationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 人员关联Service业务层处理
+ *
+ * @author zd
+ * @date 2022-09-02
+ */
+@Service
+public class SlUserRelationServiceImpl implements ISlUserRelationService
+{
+    @Autowired
+    private SlUserRelationMapper slUserRelationMapper;
+
+    /**
+     * 查询人员关联
+     *
+     * @param id 人员关联主键
+     * @return 人员关联
+     */
+    @Override
+    public SlUserRelation selectSlUserRelationById(Long id)
+    {
+        return slUserRelationMapper.selectSlUserRelationById(id);
+    }
+
+    /**
+     * 查询人员关联列表
+     *
+     * @param slUserRelation 人员关联
+     * @return 人员关联
+     */
+    @Override
+    public List<SlUserRelation> selectSlUserRelationList(SlUserRelation slUserRelation)
+    {
+        return slUserRelationMapper.selectSlUserRelationList(slUserRelation);
+    }
+
+    @Override
+    public List<SlUserRelation> getListByIds(List<Long> ids){
+        if (ids.isEmpty()){
+            new ArrayList<>();
+        }
+        return slUserRelationMapper.getListByIds(ids);
+    }
+
+    /**
+     * 新增人员关联
+     *
+     * @param slUserRelation 人员关联
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int insertSlUserRelation(SlUserRelation slUserRelation)
+    {
+        return slUserRelationMapper.insertSlUserRelation(slUserRelation);
+    }
+
+    /**
+     * 修改人员关联
+     *
+     * @param slUserRelation 人员关联
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int updateSlUserRelation(SlUserRelation slUserRelation)
+    {
+        return slUserRelationMapper.updateSlUserRelation(slUserRelation);
+    }
+
+    /**
+     * 批量删除人员关联
+     *
+     * @param ids 需要删除的人员关联主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteSlUserRelationByIds(Long[] ids)
+    {
+        return slUserRelationMapper.deleteSlUserRelationByIds(ids);
+    }
+
+    /**
+     * 删除人员关联信息
+     *
+     * @param id 人员关联主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int deleteSlUserRelationById(Long id)
+    {
+        return slUserRelationMapper.deleteSlUserRelationById(id);
+    }
+}

+ 629 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/smartlock/utils/SmartlockUtil.java

@@ -0,0 +1,629 @@
+package com.zd.alg.smartlock.utils;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.zd.alg.smartlock.domain.api.*;
+import com.zd.common.core.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+/**
+ * @Author: liujh
+ * @Date: 2022/08/29/11:30
+ * @Description:
+ */
+public class SmartlockUtil {
+    private static final Logger logger = LoggerFactory.getLogger(SmartlockUtil.class);
+
+    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    /**
+     * 服务访问地址
+     */
+    private final static String serviceurl = "http://192.168.249.12/info";
+
+    /***
+     * 登陆账户
+     */
+    private final static String userlogin = "admin";
+
+    /***
+     * 登陆密码
+     */
+    private final static String password = "admin123";
+
+    /**
+     * 智能锁返回成功字符描述
+     */
+    public final static String resultMsg = "ok";
+
+    /**
+     * //授权时长(小时)
+     */
+    public final static Integer authsLength=1;
+
+
+
+
+    public static HttpRequest httpSendPost(String url, String json) {
+        return HttpRequest.post(url)
+                .header("Content-Type", "application/json")
+                .body(json);
+    }
+
+
+    /***
+     * 获取token
+     * @return
+     */
+    public static String getToken() {
+        String token = null;
+        String url = serviceurl + "/login/1/gettoken?userlogin=" + userlogin + "&password=" + password;
+        JSONObject json = new JSONObject();
+        try {
+            HttpRequest request = HttpRequest.post(url)
+                    .header("Content-Type", "application/json")
+                    .body(json.toString());
+            HttpResponse response = request.execute();
+            String resultMsg = JSON.parseObject(response.body()).get("resultMsg").toString();
+            //请求是否成功
+            if (SmartlockUtil.resultMsg.equals(resultMsg)) {
+                token = JSON.parseObject(JSON.parseObject(response.body()).get("result").toString()).get("token").toString();
+            } else {
+                logger.info("智能锁获取token失败:" + resultMsg);
+            }
+        } catch (Exception e) {
+            logger.info("获取token失败:" + e);
+        }
+        return token;
+    }
+
+    /**
+     * 获取顶级建筑
+     */
+    public static SlBuild getTopBuild() {
+        SlBuild slBuild = null;
+        try {
+            String token = SmartlockUtil.getToken();
+            String url = SmartlockUtil.serviceurl + "/build/1/getbuild?buildfatherid=0&page=1&rows=10&token=" + token;
+            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
+            HttpResponse response = request.execute();
+            // System.out.println(response.body());
+            String resultMsg = JSON.parseObject(response.body().toString()).get("resultMsg").toString();
+            if (SmartlockUtil.resultMsg.equals(resultMsg)) {
+                List<SlBuild> list = JSON.parseArray(JSON.parseObject(response.body().toString()).get("result").toString(), SlBuild.class);
+                slBuild = list.get(0);
+            }
+        } catch (Exception e) {
+            logger.error("获取顶级建筑失败:" + e);
+        }
+        return slBuild;
+    }
+
+    /**
+     * 查询房间
+     *
+     * @param
+     * @return
+     */
+    public static List<SlRoom> getRoom(SlRoom room) {
+        SlBuild slBuild = null;
+        String token = SmartlockUtil.getToken();
+        List<SlRoom> listRoom = new ArrayList<>();
+        // System.out.println(token);
+        try {
+            //获取楼层建筑id
+            String urlLc = SmartlockUtil.serviceurl + "/build/1/getbuild?buildid=0&page=1&rows=30&token=" + token;
+            HttpRequest requestLc = SmartlockUtil.httpSendPost(urlLc, "");
+            HttpResponse responseLc = requestLc.execute();
+            String str = responseLc.body();
+            //查询失败直接返回
+            String resultMsg = JSON.parseObject(str).get("resultMsg").toString();
+            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+                logger.error("获取楼层建筑id失败:" + resultMsg);
+                return listRoom;
+            }
+            String data = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("data").toString();
+            List<SlBuild> listLc = JSON.parseArray(data, SlBuild.class);
+            for (SlBuild build : listLc) {
+                if ("3".equals(build.getBuildtype())) {
+                    slBuild = build;
+                    break;
+                }
+            }
+
+            //查询房间 不支持条件搜索
+            String urlroom = SmartlockUtil.serviceurl + "/build/2/getroom?buildid=" + slBuild.getBuildid() + "&page=" + slBuild.getPageNumber() + "&rows=" + slBuild.getPageSize() + "&token=" + token;
+            HttpRequest requestRoom = SmartlockUtil.httpSendPost(urlroom, "");
+            HttpResponse response = requestRoom.execute();
+            String strRoom = response.body();
+            String dataRoom = JSON.parseObject(JSON.parseObject(strRoom).get("result").toString()).get("data").toString();
+            listRoom = JSON.parseArray(dataRoom, SlRoom.class);
+        } catch (Exception e) {
+            logger.error("查询房间失败:" + e);
+        }
+        return listRoom;
+    }
+
+    /**
+     * 查询用户集合
+     *
+     * @param sluser
+     */
+    public static List<SlUser> getUser(SlUser sluser) {
+        List<SlUser> list = new ArrayList<>();
+        try {
+            String token = SmartlockUtil.getToken();
+            //sluser.getSearch() 该查询条件支持:人员编号/人员姓名/手机号检索
+            String url = SmartlockUtil.serviceurl + "/card/save/8/getcardperson?persontype=1&page=" + sluser.getPageNumber() + "&rows=" + sluser.getPageSize() + "&search=" + sluser.getSearch() + "&token=" + token;
+            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
+            HttpResponse response = request.execute();
+            //查询失败直接返回
+            String resultMsg = JSON.parseObject(response.body().toString()).get("resultMsg").toString();
+            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+                logger.error("查询用户集合失败1:" + resultMsg);
+                return list;
+            }
+            String str = response.body();
+            String data = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("data").toString();
+            list = JSON.parseArray(data, SlUser.class);
+        } catch (Exception e) {
+            logger.error("查询用户集合失败2:" + e);
+        }
+        return list;
+    }
+
+    /**
+     * 获取房间详情
+     *
+     * @param roomId 房间roomid
+     *               返回参数根据后期需求 扩展,
+     * @return
+     */
+    public static SlLockOnline getRoomDetails(String roomId) {
+        SlLockOnline lockOnline = new SlLockOnline();
+        try {
+            if (StringUtils.isEmpty(roomId)) {
+                logger.error("获取房间详情失败,参数roomid为空:");
+                return lockOnline;
+            }
+            String token = SmartlockUtil.getToken();
+            String url = SmartlockUtil.serviceurl + "/lockauth/operate/1/getroominfo?roomid=" + roomId + "&token=" + token;
+            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
+            HttpResponse response = request.execute();
+            //查询失败直接返回
+            String resultMsg = JSON.parseObject(response.body()).get("resultMsg").toString();
+            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+                logger.error("获取房间详情失败1:" + resultMsg);
+                return lockOnline;
+            }
+            String str = response.body();
+            //System.out.println(str);
+            //在线状态
+            String roomnetquality = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("roomnetquality").toString();
+            //门锁编号
+            String lockCode = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("roomcode2").toString();
+            lockOnline.setOnLine(roomnetquality);
+            lockOnline.setLockCode(lockCode);
+            lockOnline.setOnLineStatus("在线".equals(roomnetquality)?1:0);
+            // System.out.println("房间详情,门锁状态 roomnetquality: " + roomnetquality + " lockCode: " + lockCode);
+        } catch (Exception e) {
+            logger.error("获取房间详情失败2:" + e);
+        }
+        return lockOnline;
+    }
+
+    /***
+     * 开门记录
+     * @param openDoorSearch
+     */
+    public static List<SlOpenAndClosLog> getOpenDoorLog(SlOpenDoorSearch openDoorSearch) {
+        List<SlOpenAndClosLog> list = new ArrayList<>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        try {
+            String token = SmartlockUtil.getToken();
+
+            if (StringUtils.isEmpty(openDoorSearch.getRoomid())) {
+                logger.error("查询开门记录集合失败,roomid为空:" + resultMsg);
+                return list;
+            }
+            if (StringUtils.isEmpty(openDoorSearch.getRecordtype())) {
+                //0或空=所有记录,1=报警记录,2=开门记录)
+                openDoorSearch.setRecordtype("2");
+            }
+            String sdate = sdf.format(new Date()) + " 00:00:00";
+            String edate = sdf.format(new Date()) + " 23:59:59";
+
+            //sluser.getSearch() 该查询条件支持:人员编号/人员姓名/手机号检索
+            String url = SmartlockUtil.serviceurl + "/lockauth/operate/2/getlockinfo?persontype=1&page=" + openDoorSearch.getPageNumber() + "&rows=" + openDoorSearch.getPageSize() +
+                    "&roomid=" + openDoorSearch.getRoomid() + "&token=" + token + "&recordtype=" + openDoorSearch.getRecordtype()
+                    + "&search=" + openDoorSearch.getSearch() + "&sdate=" + sdate + "&edate=" + edate;
+            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
+            HttpResponse response = request.execute();
+            // System.out.println(response.body());
+            //查询失败直接返回
+            String resultMsg = JSON.parseObject(response.body()).get("resultMsg").toString();
+            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+                logger.error("查询开门记录集合失败1:" + resultMsg);
+                return list;
+            }
+            String str = response.body();
+            String data = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("data").toString();
+            list = JSON.parseArray(data, SlOpenAndClosLog.class);
+        } catch (Exception e) {
+            logger.error("查询开门记录集合失败2:" + e);
+        }
+        return list;
+    }
+
+    /**
+     * 获取组织信息
+     *
+     * @param group
+     */
+    public static List<SlGroup> getGroup(SlGroup group) {
+        List<SlGroup> list = new ArrayList<>();
+        String token = SmartlockUtil.getToken();
+        try {
+            String url = SmartlockUtil.serviceurl + "/group/1/getgroup?&token=" + token
+                    + "&page=" + group.getPageNumber() + "&rows=" + group.getPageSize() + "&pgfatherid=0";
+            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
+            HttpResponse response = request.execute();
+            //查询失败直接返回
+            String resultMsg = JSON.parseObject(response.body()).get("resultMsg").toString();
+            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+                logger.error("查询开门记录集合失败1:" + resultMsg);
+                return list;
+            }
+            String str = response.body();
+            String data = JSON.parseObject(JSON.parseObject(str).get("result").toString()).get("data").toString();
+            list = JSON.parseArray(data, SlGroup.class);
+        } catch (Exception e) {
+            logger.error("查询组织信息失败:" + e);
+        }
+        return list;
+    }
+
+    /***
+     * 添加人员并且办理入住
+     * 返回操作状态
+     */
+    public static Map<String, Object> addUser(SlUser user, String roomId) {
+        List<SlGroup> listgroup = getGroup(new SlGroup());
+        Map<String, Object> map = new HashMap<>();
+        try {
+            //获取组织id
+            String pgid = listgroup.get(0).getPgid();
+            String token = SmartlockUtil.getToken();
+
+            /*roomId="109";
+            user.setPersoncode("C016");//学号、工号
+            user.setPersonname("姓名016");//姓名
+            user.setPersonsex("1");//性别 (0=女,1=男)
+            user.setPersontype("1");//人员类别(1=学生,2=教职工,3=临时人员
+            user.setPersonmobile("13039856924");//电话*/
+
+            //查询人员是否存在
+            Boolean flg = checkUserExis(user.getPersoncode(), "1", token);
+            if (!flg) {
+                //新增人员
+                String url = SmartlockUtil.serviceurl + "/person/save/1/saveperson?" +
+                        "personcode=" + user.getPersoncode() + "&personname=" + user.getPersonname() + "&personsex=" + user.getPersonsex() +
+                        "&personmobile=" + user.getPersonmobile() + "&persontype=" + user.getPersontype() + "&pgid=" + pgid + "&token=" + token;
+                HttpRequest request = SmartlockUtil.httpSendPost(url, "");
+                HttpResponse response = request.execute();
+                // System.out.println(response.body());
+                //查询失败直接返回
+                String resultMsg = JSON.parseObject(response.body().toString()).get("resultMsg").toString();
+                // System.out.println(resultMsg);
+                if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+                    logger.error("人员添加失败1:" + resultMsg);
+                    map.put("resultMsg", resultMsg);
+                    return map;
+                }
+
+                //添加授权
+                map = addUserAuths(token, user.getPersoncode(), roomId);
+            } else {
+                //查询用户是否存在授权
+                String authis = checkUserAuthExis(user.getPersoncode(), token);
+                if (StringUtils.isNotEmpty(authis)) {
+                    //修改授权
+                    map = updateAuths(token, roomId, Integer.valueOf(authis));
+                } else {
+                    //添加授权
+                    map = addUserAuths(token, user.getPersoncode(), roomId);
+                }
+            }
+            //操作结果
+            map.put("resultMsg", resultMsg);
+        } catch (Exception e) {
+            logger.error("添加人员并且办理入住异常:" + e);
+        }
+        return map;
+    }
+
+    /***
+     * 修改用户授权
+     * @param token
+     * @param roomId
+     * @param authid
+     */
+    public static Map<String, Object> updateAuths(String token, String roomId, Integer authid) {
+        Map<String, Object> map = new HashMap<>();
+        try {
+            List<SlupdateAuths> list = new ArrayList<>();
+            SlupdateAuths slupdateAuths = new SlupdateAuths();
+            slupdateAuths.setAuthid(authid);
+            slupdateAuths.setRctype(3);
+            list.add(slupdateAuths);
+            //授权开始日期
+            String empsdate =sdf.format(new Date());
+            //授权结束日期
+            String empedate = sdf.format(getTime(authsLength));
+
+            String pw = getRandom(6);
+            String url2 = SmartlockUtil.serviceurl + "/lockauth/operate/7/updateauths?token=" + token + "&roomid=" + roomId + "&password=" + pw
+                    +"&empsdate="+empsdate+"&empedate="+empedate;
+            HttpRequest request2 = SmartlockUtil.httpSendPost(url2, JSONObject.toJSONString(list));
+            HttpResponse response2 = request2.execute();
+            String resultMsg = JSON.parseObject(response2.body()).get("resultMsg").toString();
+            logger.info("用户申请修改:"+response2.body());
+            // System.out.println(response2.body());
+            logger.info("用户密码:"+pw);
+            // System.out.println(pw);
+            map.put("password", pw);
+            map.put("resultMsg", resultMsg);
+        } catch (Exception e) {
+            logger.error("修改用户授权失败" + e);
+            // System.out.println("修改用户授权失败:" + resultMsg);
+        }
+        return map;
+    }
+
+    /**
+     * 添加授权
+     *
+     * @param token
+     * @param personcode
+     * @param roomId
+     * @return
+     */
+    public static Map<String, Object> addUserAuths(String token, String personcode, String roomId) {
+        Map<String, Object> map = new HashMap<>();
+        try {
+            //入住办理
+            JSONObject json = new JSONObject();
+            String pw = getRandom(6);
+            List<SlPostUser> postlist = new ArrayList<>();
+            SlPostUser postUser = new SlPostUser();
+            postUser.setPersoncode(personcode);//学号、工号
+            postUser.setIssendface("1");//是否下发人脸(1是,0否)
+            postUser.setIssendfinger("1");//是否下发指纹(1是,0否)
+            postUser.setIssendpass("1");//是否下发密码(1是,0否)
+            postUser.setManagertype(0);//权限类型(1管理权限,0使用权限,管理权限不占用入住人数)
+            postUser.setPassword(pw);//6位数字密码(不允许连续数字或连续三个及以上相同数字)
+            postUser.setEmpsdate(sdf.format(new Date()));//授权开始时间
+            postUser.setEmpedate(sdf.format(getTime(authsLength)));  //授权结束时间,当前时间加1小时
+            postlist.add(postUser);
+            //System.out.println("开始时间:" + sdf.format(new Date()) + "结束时间:" + sdf.format(getTime(1)));
+
+            //将对象转为json
+            //JSONObject jsonStr = JSON.parseObject(JSONObject.toJSONString( postlist ));
+            String url2 = SmartlockUtil.serviceurl + "/lockauth/save/4/saveauths?token=" + token + "&roomid=" + roomId;
+            HttpRequest request2 = SmartlockUtil.httpSendPost(url2, JSONObject.toJSONString(postlist));
+            HttpResponse response2 = request2.execute();
+            //System.out.println(response2.body());
+            //查询失败直接返回
+            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+                logger.error("人员添加后办理入住失败1:" + resultMsg);
+                map.put("resultMsg", resultMsg);
+                return map;
+            }
+            //密码
+            map.put("password", pw);
+        } catch (Exception e) {
+
+        }
+        return map;
+    }
+
+    /***
+     * 入住-授权
+     * @param user 用户参数
+     * @param roomId  房间id
+     * @return
+     */
+    public static void AuthCheckInTest(SlUser user, String roomId) {
+
+        List<SlGroup> listgroup = getGroup(new SlGroup());
+        Map<String, Object> map = new HashMap<>();
+        String token = SmartlockUtil.getToken();
+        roomId = "109";
+
+        //获取组织id
+        String pgid = listgroup.get(0).getPgid();
+        //roomId="109";
+        user.setPersoncode("C010");//学号、工号
+        user.setPersonname("姓名c10");//姓名
+        user.setPersonsex("1");//性别 (0=女,1=男)
+        user.setPersontype("1");//人员类别(1=学生,2=教职工,3=临时人员)
+
+        //查询人员是否存在
+        Boolean flg = checkUserExis(user.getPersoncode(), "1", token);
+        if (!flg) {
+            String url = SmartlockUtil.serviceurl + "/person/save/1/saveperson?" +
+                    "personcode=" + user.getPersoncode() + "&personname=" + user.getPersonname() + "&personsex=" + user.getPersonsex() +
+                    "&persontype=" + user.getPersontype() + "&pgid=" + pgid + "&token=" + token;
+            HttpRequest request = SmartlockUtil.httpSendPost(url, "");
+            HttpResponse response = request.execute();
+            //System.out.println(response.body());
+            //查询失败直接返回
+            String resultMsg = JSON.parseObject(response.body().toString()).get("resultMsg").toString();
+            //System.out.println(resultMsg);
+            if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+                logger.error("人员添加失败1:" + resultMsg);
+                map.put("resultMsg", resultMsg);
+            }
+        }
+
+
+        //入住办理
+        String pw = getRandom(6);
+        List<SlPostUser> postlist = new ArrayList<>();
+        SlPostUser postUser = new SlPostUser();
+        postUser.setPersoncode("C010");//学号、工号
+        postUser.setIssendface("1");//是否下发人脸(1是,0否)
+        postUser.setIssendfinger("1");//是否下发指纹(1是,0否)
+        postUser.setIssendpass("1");//是否下发密码(1是,0否)
+        postUser.setManagertype(1);//权限类型(1管理权限,0使用权限,管理权限不占用入住人数)
+        postUser.setPassword(pw);//6位数字密码(不允许连续数字或连续三个及以上相同数字)
+        postUser.setRoomid(roomId);
+        postUser.setEmpsdate(sdf.format(new Date()));//授权开始时间
+        postUser.setEmpedate(sdf.format(getTime(1)));  //授权结束时间,当前时间加1小时
+        postlist.add(postUser);
+
+        //将对象转为json
+        //JSONObject jsonStr = JSON.parseObject(JSONObject.toJSONString( postlist ));
+        String url2 = SmartlockUtil.serviceurl + "/lockauth/operate/9/batchauths?token=" + token;
+        HttpRequest request2 = SmartlockUtil.httpSendPost(url2, JSONObject.toJSONString(postlist));
+        HttpResponse response2 = request2.execute();
+        //System.out.println(response2.body());
+        //查询失败直接返回
+        if (!SmartlockUtil.resultMsg.equals(resultMsg)) {
+            logger.error("人员添加后办理入住失败1:" + resultMsg);
+            map.put("resultMsg", resultMsg);
+        }
+        //密码
+        map.put("password", pw);
+        //操作结果
+        map.put("resultMsg", resultMsg);
+
+
+    }
+
+    /***
+     * 查询人员是否存在
+     * @param personcode 人员编码
+     * @param cardtype 1(学生卡)/2(职工卡)/3(管理卡)/6(临时卡)/7(身份证)
+     */
+    public static Boolean checkUserExis(String personcode, String cardtype, String token) {
+        Boolean flg = false;
+        //String token =  SmartlockUtil.getToken();
+        String urlexis = SmartlockUtil.serviceurl + "/card/save/8/getcardperson?token=" + token + "&cardtype=" + cardtype + "&page=1&rows=20&search=" + personcode;
+        HttpRequest requestexis = SmartlockUtil.httpSendPost(urlexis, "");
+        HttpResponse responseexis = requestexis.execute();
+        //System.out.println(responseexis.body());
+        String data = JSON.parseObject(JSON.parseObject(responseexis.body()).get("result").toString()).get("data").toString();
+        JSONArray array = JSON.parseArray(data);
+        if (array.size() > 0) {
+            flg = true;
+        }
+        return flg;
+    }
+
+
+    /***
+     * 查询用户是否存在授权
+     * @param personcode
+     * @return
+     */
+    public static String checkUserAuthExis(String personcode, String token) {
+        String authid = null;
+        //查询用户授权信息
+        //String token =  SmartlockUtil.getToken();
+        String urlauth = SmartlockUtil.serviceurl + "/person/2/getpersonauth?" +
+                "personcode=" + personcode + "&page=1" + "&rows=50&token=" + token;
+        HttpRequest requestauth = SmartlockUtil.httpSendPost(urlauth, "");
+        HttpResponse responseauth = requestauth.execute();
+        //System.out.println(responseauth.body());
+
+        String data = JSON.parseObject(JSON.parseObject(responseauth.body()).get("result").toString()).get("data").toString();
+        JSONArray array = JSON.parseArray(data);
+        for (int i = 0; i < array.size(); i++) {
+            //System.out.println(array.get(i) + "");
+            String empedate = JSON.parseObject(array.get(i).toString()).get("empedate").toString();
+            String authtype = JSON.parseObject(array.get(i).toString()).get("authtype").toString();
+            if ("3".equals(authtype)) {
+                authid = JSON.parseObject(array.get(i).toString()).get("authid").toString();
+                break;
+            }
+        }
+        return authid;
+    }
+
+    /**
+     * 当前时间加 N 小时
+     *
+     * @param num
+     * @return
+     */
+    public static Date getTime(int num) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(new Date());
+        cal.add(Calendar.HOUR, num);
+        return cal.getTime();
+    }
+
+    /**
+     * 获取6位随机数
+     *
+     * @param length
+     * @return
+     */
+    public static String getRandom(int length) {
+        String val = "";
+        Random random = new Random();
+        for (int i = 0; i < length; i++) {
+            val += String.valueOf(random.nextInt(10));
+        }
+        return val;
+    }
+
+    public static void main(String[] args) {
+        //getTopBuild();//获取顶级建筑
+        /*List<SlRoom> listRoom =  getRoom( new SlRoom());
+        System.out.println(listRoom.size());
+        for (SlRoom slroom:listRoom ) {
+            System.out.println(slroom.getRoomid()+"== "+slroom.getRoomcode());
+        }*/
+
+        /*List<SlUser> listUser  = getUser(new SlUser());
+        for (SlUser user:listUser ) {
+            System.out.println(user.getPersoncode()+"== "+user.getPersonname());
+        }*/
+
+        //getRoomDetails("109");
+
+       /* SlOpenDoorSearch  search = new SlOpenDoorSearch();
+        search.setRoomid("109");
+        List<SlOpenAndClosLog> list = getOpenDoorLog(search);
+        for (SlOpenAndClosLog oplog:list) {
+            System.out.println(oplog.getPersonname()+"=="+oplog.getUnlockingtype()+" =="+oplog.getUnlockingdate());
+        }*/
+
+        //getGroup(new SlGroup());
+
+        //addUser(new SlUser() , "");
+
+        // AuthCheckIn(new SlUser() , "");
+
+         //addUser(new SlUser() , "");
+
+        // System.out.println(checkUserExis("C008","1"));
+
+        //String token =  SmartlockUtil.getToken();
+        //updateAuths( token,"109", 32);
+
+        //getRoomDetails("109");
+
+        //System.out.println(getRandom(6));
+    }
+}

+ 15 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/Interceptor/NetInterceptor.java

@@ -0,0 +1,15 @@
+package com.zd.alg.speaker.Interceptor;
+
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+
+import java.io.IOException;
+
+public class NetInterceptor implements Interceptor {
+    @Override
+    public Response intercept(Chain chain) throws IOException {
+        Request request = chain.request().newBuilder().addHeader("Connection","close").build();
+        return chain.proceed(request);
+    }
+}

+ 89 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/config/OkHttpConfiguration.java

@@ -0,0 +1,89 @@
+package com.zd.alg.speaker.config;
+
+import com.zd.alg.speaker.Interceptor.NetInterceptor;
+import okhttp3.ConnectionPool;
+import okhttp3.OkHttpClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@RefreshScope
+public class OkHttpConfiguration {
+    @Value("${ok-http.connect-timeout-ms}")
+    private Integer connectTimeout;
+
+    @Value("${ok-http.read-timeout-ms}")
+    private Integer readTimeout;
+
+    @Value("${ok-http.write-timeout-ms}")
+    private Integer writeTimeout;
+
+    @Value("${ok-http.max-idle-connections}")
+    private Integer maxIdleConnections;
+
+    @Value("${ok-http.keep-alive-duration-sec}")
+    private Long keepAliveDuration;
+
+    @Bean
+    public OkHttpClient okHttpClient() {
+        return new OkHttpClient.Builder()
+                .addNetworkInterceptor(new NetInterceptor())
+                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
+                // 是否开启缓存
+                .retryOnConnectionFailure(false)
+                .connectionPool(pool())
+                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
+                .readTimeout(readTimeout, TimeUnit.SECONDS)
+                .writeTimeout(writeTimeout, TimeUnit.SECONDS)
+                .hostnameVerifier((hostname, session) -> true)
+                .build();
+    }
+
+    @Bean
+    public X509TrustManager x509TrustManager() {
+        return new X509TrustManager() {
+            @Override
+            public void checkClientTrusted(X509Certificate[] chain, String authType) {
+            }
+
+            @Override
+            public void checkServerTrusted(X509Certificate[] chain, String authType) {
+            }
+
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                return new X509Certificate[0];
+            }
+        };
+    }
+
+    @Bean
+    public SSLSocketFactory sslSocketFactory() {
+        try {
+            // 信任任何链接
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
+            return sslContext.getSocketFactory();
+        } catch (NoSuchAlgorithmException | KeyManagementException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Bean
+    public ConnectionPool pool() {
+        return new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
+    }
+}

+ 232 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/controller/SpeakerController.java

@@ -0,0 +1,232 @@
+package com.zd.alg.speaker.controller;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.zd.common.core.domain.R;
+import com.zd.common.core.utils.DateUtils;
+import com.zd.common.core.utils.StringUtils;
+import com.zd.common.core.web.domain.AjaxResult;
+import com.zd.alg.speaker.domain.vo.PlayVo;
+import com.zd.alg.speaker.service.ISpeakerService;
+import com.zd.system.api.laboratory.RemoteLaboratoryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * ip喇叭控制类
+ */
+@RestController
+@RequestMapping("/speaker")
+@Api(value = "远程喇叭控制类", tags = "远程喇叭控制类")
+public class SpeakerController {
+
+    private static Logger logger = LoggerFactory.getLogger(SpeakerController.class);
+
+    @Autowired
+    private ISpeakerService iSpeakerService;
+
+    @Autowired
+    private RemoteLaboratoryService remoteLaboratoryService;
+
+
+    /**
+     * 设备登录
+     *
+     * @return
+     */
+    @PostMapping("/login")
+    @ApiOperation(value = "设备登录", notes = "设备登录")
+    public AjaxResult queryOption() {
+        String responseStr = iSpeakerService.login();
+        return AjaxResult.success("操作成功", responseStr);
+    }
+
+    /***
+     * 获取设备列表
+     * @param page
+     * @param pageSize
+     * @return
+     */
+    @RequestMapping("/getDeviceList")
+    @ApiOperation(value = "获取设备列表", notes = "获取设备列表")
+    public AjaxResult getDeviceList(Integer page, Integer pageSize,Long floorId) {
+        R r=remoteLaboratoryService.getSpeakerByFloor(floorId);
+        if(r.getCode()!=200){
+            logger.error(r.getMsg());
+            return AjaxResult.error("获取设备列表失败!");
+        }
+        List<Map<String,Object>> mapList= (List<Map<String, Object>>) r.getData();
+        String responseStr = iSpeakerService.getDeviceList(page, pageSize);
+        if(StringUtils.isEmpty(responseStr)){
+            logger.error(r.getMsg());
+            return AjaxResult.error("获取设备列表失败!");
+        }
+        JSONObject jsonObject=JSONObject.parseObject(responseStr);
+        JSONArray jsonArray=JSONArray.parseArray(jsonObject.getString("rows"));
+        for(Map<String,Object> map: mapList){
+            for(int i=0;i<jsonArray.size();i++){
+                JSONObject extra=jsonArray.getJSONObject(i).getJSONObject("extra");
+                JSONObject obj = extra.getJSONObject("config");
+                if(obj.getString("mac").equals(map.getOrDefault("hardwareNum","").toString())){
+                    map.put("deviceSn",obj.getString("sn"));
+                    map.put("deviceIp",extra.getString("ip"));
+                    map.put("operate",extra.getString("online"));
+                }
+            }
+        }
+        return AjaxResult.success(mapList);
+    }
+
+
+    /***
+     * 获取 实验室/实验室楼层 设备列表
+     * @param page
+     * @param pageSize
+     * @return
+     */
+    @RequestMapping("/getDeviceListBySub")
+    @ApiOperation(value = "获取设备列表", notes = "获取设备列表")
+    public AjaxResult getDeviceList(Integer page, Integer pageSize,Long floorId, Long subId) {
+        R r=remoteLaboratoryService.getSpeakerBySub(floorId, subId);
+        if(r.getCode()!=200){
+            return AjaxResult.error("获取设备列表失败!");
+        }
+        List<Map<String,Object>> mapList= (List<Map<String, Object>>) r.getData();
+        String responseStr = iSpeakerService.getDeviceList(page, pageSize);
+        if(StringUtils.isEmpty(responseStr)){
+            return AjaxResult.error("获取设备列表失败!");
+        }
+        JSONObject jsonObject=JSONObject.parseObject(responseStr);
+        JSONArray jsonArray=JSONArray.parseArray(jsonObject.getString("rows"));
+        for(Map<String,Object> map: mapList){
+            for(int i=0;i<jsonArray.size();i++){
+                JSONObject extra=jsonArray.getJSONObject(i).getJSONObject("extra");
+                JSONObject obj = extra.getJSONObject("config");
+                if(obj.getString("mac").equals(map.getOrDefault("hardwareNum","").toString())){
+                    map.put("deviceSn",obj.getString("sn"));
+                    map.put("deviceIp",extra.getString("ip"));
+                    map.put("operate",extra.getString("online"));
+                }
+            }
+        }
+        return AjaxResult.success(mapList);
+    }
+
+
+    /***
+     * 获取设备信息
+     * @return
+     */
+    @PostMapping("/getDevice")
+    @ApiOperation(value = "获取设备信息", notes = "获取设备信息")
+    public AjaxResult getDeviceList(String deviceId) {
+        String responseStr = iSpeakerService.getDevice(deviceId);
+        return AjaxResult.success(JSONObject.parseObject(responseStr));
+    }
+
+
+    /***
+     * 音乐播放
+     * @return
+     */
+    @PostMapping("/playMusic")
+    @ApiOperation(value = "音乐播放", notes = "音乐播放")
+    public AjaxResult playMusic(@RequestParam(required = true) String ip, @RequestBody PlayVo playVo) {
+        playVo.getParams().setTid(UUID.randomUUID().toString());
+        String body = JSONObject.toJSON(playVo).toString();
+        String responseStr = iSpeakerService.playMusic(ip, body);
+        return AjaxResult.success(JSONObject.parseObject(responseStr));
+    }
+
+
+    /***
+     * 文字转语音播放
+     * @return
+     */
+    @PostMapping("/textPlayMusic")
+    @ApiOperation(value = "文字转语音播放", notes = "文字转语音播放")
+    public AjaxResult textPlayMusic(@RequestParam(required = true) String ip, @RequestParam(required = true) List<String> texts, @RequestBody PlayVo playVo) {
+        playVo.getParams().setTid(UUID.randomUUID().toString());
+        String responseStr = iSpeakerService.textParseVoice(ip, texts, playVo);
+        return AjaxResult.success(JSONObject.parseObject(responseStr));
+    }
+
+
+    /***
+     * 文字转语音播放
+     * @return
+     */
+    @PostMapping("/textParseUrl")
+    @ApiOperation(value = "文字转语音播放地址", notes = "文字转语音播放地址")
+    public AjaxResult textParseUrl(@RequestParam(required = true) Integer speed, @RequestParam(required = true) Integer volume, @RequestParam(required = true) String text) {
+        String responseStr = iSpeakerService.textParseVoiceURL(speed, volume, text);
+        return AjaxResult.success(JSONObject.parseObject(responseStr));
+    }
+
+
+    /***
+     * 文字转语音播放
+     * @return
+     */
+    @RequestMapping("/textParseVideo")
+    @ApiOperation(value = "文字转语音播放地址", notes = "文字转语音播放地址")
+    public String textParseVideo(@RequestParam(required = true) Integer speed, @RequestParam(required = true) Integer volume, @RequestParam(required = true) String text) {
+        String responseStr = iSpeakerService.textParseVoiceURL(speed, volume, text);
+        return responseStr;
+    }
+
+    /***
+     * 文字转语音播放
+     * @return
+     */
+    @PostMapping("/textParseUrlIps")
+    @ApiOperation(value = "文字转语音播放地址", notes = "文字转语音播放地址")
+    public AjaxResult textParseUrl(@RequestParam(required = true) String text,@RequestBody List<PlayVo> playVo) {
+        iSpeakerService.textParseVoiceIps(text,playVo);
+        Map<String,Object> map=new HashMap<>();
+        map.put("text",text);
+        String date=DateUtils.parseDateToStr("HH:MM",new Date());
+        map.put("date",date);
+        return AjaxResult.success(map);
+    }
+
+
+    /***
+     * 文字转语音播放
+     * @return
+     */
+    @PostMapping("/textParseUrlAppIps")
+    @ApiOperation(value = "文字转语音小程序播放地址", notes = "文字转语音小程序播放地址")
+    public AjaxResult textParseUrlAppIps(@RequestParam(required = true) String text,@RequestBody List<PlayVo> playVo) {
+        if(StringUtils.isEmpty(text) || playVo.size()==0){
+            return AjaxResult.error("参数有误,请检查参数!");
+        }
+        text=text.replace("https","http");
+        text=text.replace("https://lab.sxitdlc.com/jdlabSystem/","http://192.168.8.101/jdlabSystem/");
+        iSpeakerService.textParseVoiceAppIps(text,playVo);
+        Map<String,Object> map=new HashMap<>();
+        map.put("text",text);
+        String date=DateUtils.parseDateToStr("HH:MM",new Date());
+        map.put("date",date);
+        return AjaxResult.success(map);
+    }
+
+    /**
+     * 停止播放
+     * @param sn
+     * @param ip
+     * @return
+     */
+    @GetMapping("/stopPlayMusic")
+    @ApiOperation(value = "文字转语音小程序播放地址", notes = "文字转语音小程序播放地址")
+    public AjaxResult stopPlayMusic(@RequestParam(required = true) String sn,@RequestParam(required = true) String ip) {
+        boolean istrue=iSpeakerService.stopPlayMusic(sn,ip);
+        return AjaxResult.success(istrue);
+    }
+}

+ 80 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/RemoteAddress.java

@@ -0,0 +1,80 @@
+package com.zd.alg.speaker.domain;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+@Component
+@RefreshScope
+public class RemoteAddress {
+    @Value("${remote.ip_addr}")
+    private String remoteIp;
+    @Value("${remote.port}")
+    private String remotePort;
+    @Value("${remote.operation.login_url}")
+    private String loginUrl;
+    @Value("${remote.protocol}")
+    private String protocol;
+    @Value("${remote.operation.get_device}")
+    private String deviceUrl;
+    @Value("${remote.tts_ip}")
+    private String ttsIp;
+    @Value("${remote.tts_port}")
+    private String ttsPort;
+
+    public String getRemoteIp() {
+        return remoteIp;
+    }
+
+    public void setRemoteIp(String remoteIp) {
+        this.remoteIp = remoteIp;
+    }
+
+    public String getRemotePort() {
+        return remotePort;
+    }
+
+    public void setRemotePort(String remotePort) {
+        this.remotePort = remotePort;
+    }
+
+    public String getLoginUrl() {
+        return loginUrl;
+    }
+
+    public void setLoginUrl(String loginUrl) {
+        this.loginUrl = loginUrl;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public String getDeviceUrl() {
+        return deviceUrl;
+    }
+
+    public void setDeviceUrl(String deviceUrl) {
+        this.deviceUrl = deviceUrl;
+    }
+
+    public String getTtsIp() {
+        return ttsIp;
+    }
+
+    public void setTtsIp(String ttsIp) {
+        this.ttsIp = ttsIp;
+    }
+
+    public String getTtsPort() {
+        return ttsPort;
+    }
+
+    public void setTtsPort(String ttsPort) {
+        this.ttsPort = ttsPort;
+    }
+}

+ 42 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/vo/ParamVo.java

@@ -0,0 +1,42 @@
+package com.zd.alg.speaker.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 参数类
+ */
+public class ParamVo {
+    @ApiModelProperty(required = false, notes = "任务id, 建议使用UUIDv4生成")
+    private String tid;
+    @ApiModelProperty(required = true, notes = "number (0~100)设备环境音量、通道音量、任务音量")
+    private Integer vol;
+    @ApiModelProperty(required = true, notes = "播放路径")
+    private List<UrlVo> urls;
+
+    public String getTid() {
+        return tid;
+    }
+
+    public void setTid(String tid) {
+        this.tid = tid;
+    }
+
+    public Integer getVol() {
+        return vol;
+    }
+
+    public void setVol(Integer vol) {
+        this.vol = Optional.ofNullable(vol).orElse(80);
+    }
+
+    public List<UrlVo> getUrls() {
+        return urls;
+    }
+
+    public void setUrls(List<UrlVo> urls) {
+        this.urls = urls;
+    }
+}

+ 73 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/vo/PlayBatchVo.java

@@ -0,0 +1,73 @@
+package com.zd.alg.speaker.domain.vo;
+
+import com.zd.common.core.utils.StringUtils;
+import io.swagger.annotations.ApiModelProperty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author 董高升
+ * @descript 播放vo
+ */
+public class PlayBatchVo {
+
+    private static Logger logger = LoggerFactory.getLogger(PlayBatchVo.class);
+
+    @ApiModelProperty(required = true, notes = "设备编号")
+    private String[] sns;
+    @ApiModelProperty(required = false, notes = "方便对接时传递任务类型")
+    private String type;
+    @ApiModelProperty(required = false, notes = "任务名称")
+    private String name;
+    @ApiModelProperty(required = false, notes = "播放参数")
+    private ParamVo params;
+
+    public String[] getSns() {
+        return sns;
+    }
+
+    public void setSns(String[] sns) {
+        this.sns = sns;
+    }
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        if(StringUtils.isBlank(name)){
+            this.type="req";
+        }else{
+            this.type = type;
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        if(StringUtils.isBlank(name)){
+            this.name="songs_queue_append";
+        }else{
+            this.name = name;
+        }
+    }
+
+    public ParamVo getParams() {
+        return params;
+    }
+
+    public void setParams(ParamVo params) {
+        this.params = params;
+    }
+
+    @Override
+    public String toString() {
+        return "PlayVo{" +
+                "sns='" + sns + '\'' +
+                ", type='" + type + '\'' +
+                ", name='" + name + '\'' +
+                ", params=" + params +
+                '}';
+    }
+}

+ 106 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/vo/PlayVo.java

@@ -0,0 +1,106 @@
+package com.zd.alg.speaker.domain.vo;
+
+import com.zd.common.core.utils.StringUtils;
+import io.swagger.annotations.ApiModelProperty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+/**
+ * @author 董高升
+ * @descript 播放vo
+ */
+public class PlayVo {
+
+    private static Logger logger = LoggerFactory.getLogger(PlayVo.class);
+
+    @ApiModelProperty(required = true, notes = "设备编号")
+    private String sn;
+    @ApiModelProperty(required = false, notes = "方便对接时传递任务类型")
+    private String type;
+    @ApiModelProperty(required = false, notes = "任务名称")
+    private String name;
+    @ApiModelProperty(required = true, notes = "播放速度")
+    private Integer speed;
+    @ApiModelProperty(required = false, notes = "播放参数")
+    private ParamVo params;
+    @ApiModelProperty(required = true, notes = "远程端口")
+    private int port;
+    @ApiModelProperty(required = true, notes = "设备Ip")
+    private String deviceIp;
+
+    public String getSn() {
+        return sn;
+    }
+
+    public void setSn(String sn) {
+        this.sn = sn;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        if(StringUtils.isBlank(name)){
+            this.type="req";
+        }else{
+            this.type = type;
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        if(StringUtils.isBlank(name)){
+            this.name="songs_queue_append";
+        }else{
+            this.name = name;
+        }
+    }
+
+    public ParamVo getParams() {
+        return params;
+    }
+
+    public void setParams(ParamVo params) {
+        this.params = params;
+    }
+
+    @Override
+    public String toString() {
+        return "PlayVo{" +
+                "sn='" + sn + '\'' +
+                ", type='" + type + '\'' +
+                ", name='" + name + '\'' +
+                ", params=" + params +
+                '}';
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public Integer getSpeed() {
+        return speed;
+    }
+
+    public void setSpeed(Integer speed) {
+        this.speed = Optional.ofNullable(speed).orElse(50);
+    }
+
+    public String getDeviceIp() {
+        return deviceIp;
+    }
+
+    public void setDeviceIp(String deviceIp) {
+        this.deviceIp = deviceIp;
+    }
+}

+ 38 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/domain/vo/UrlVo.java

@@ -0,0 +1,38 @@
+package com.zd.alg.speaker.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author donggaosheng
+ * urlvo
+ */
+public class UrlVo {
+    @ApiModelProperty(required = true, notes = "播放名称")
+    private String name;
+    @ApiModelProperty(required = true, notes = "播放地址")
+    private String uri;
+
+    public UrlVo() {
+        
+    }
+    public UrlVo(String name, String uri) {
+        this.name = name;
+        this.uri = uri;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+}

+ 107 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/service/ISpeakerService.java

@@ -0,0 +1,107 @@
+package com.zd.alg.speaker.service;
+
+import com.zd.alg.speaker.domain.vo.PlayVo;
+import java.util.List;
+
+/**
+ * 电话报警推送日志Service
+ *
+ * @author donggaosheng
+ * @date 2022-02-09
+ */
+public interface ISpeakerService {
+    /**
+     * 获取token
+     *
+     * @return
+     */
+    String getToken();
+
+    /**
+     * 设置token
+     *
+     * @return
+     */
+    void setToken();
+
+    /**
+     * ip喇叭登录获取token
+     *
+     * @return
+     */
+    String login();
+
+    /**
+     * 获取设备列表
+     *
+     * @param page
+     * @param pageSize
+     * @return
+     */
+    String getDeviceList(Integer page, Integer pageSize);
+
+    /**
+     * 获取设备信息
+     *
+     * @param deviceId
+     * @return
+     */
+    String getDevice(String deviceId);
+
+    /**
+     * 音乐播放
+     *
+     * @param ip
+     * @return
+     */
+    String playMusic(String ip, String body);
+
+    /**
+     * 文字转化音频
+     *
+     * @return
+     */
+    String textParseVoice(String ip, List<String> texts, PlayVo playVo);
+
+    /**
+     * 文字转音频路径
+     *
+     * @param speed  语速
+     * @param volume 音量
+     * @param text   文本内容
+     * @return
+     */
+    String textParseVoiceURL(Integer speed, Integer volume, String text);
+
+    /**
+     * 文字转音频路径
+     * @param texts
+     * @param playVo
+     * @return
+     */
+    void textParseVoiceIps(String texts, List<PlayVo> playVo);
+
+
+    /**
+     * 文字转音频路径
+     * @param texts
+     * @param playVo
+     * @return
+     */
+    void textParseVoiceAppIps(String texts, List<PlayVo> playVo);
+
+    /**
+     * 文字转硬盘播放
+     * @param text
+     * @param playVo
+     */
+    void textParseUrlAppIpsOrigin(String text, List<PlayVo> playVo);
+
+
+    /**
+     * 停止播放音乐
+     * @param sn 设备sn
+     * @param ip 设备ip
+     */
+    boolean stopPlayMusic(String sn,String ip);
+}

+ 316 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/service/impl/SpeakerServiceImpl.java

@@ -0,0 +1,316 @@
+package com.zd.alg.speaker.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.zd.common.core.utils.StringUtils;
+import com.zd.common.redis.service.RedisService;
+import com.zd.alg.speaker.domain.RemoteAddress;
+import com.zd.alg.speaker.domain.vo.PlayBatchVo;
+import com.zd.alg.speaker.domain.vo.PlayVo;
+import com.zd.alg.speaker.domain.vo.UrlVo;
+import com.zd.alg.speaker.service.ISpeakerService;
+import com.zd.alg.speaker.utils.OkHttpRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 电话报警推送日志Service业务层处理
+ *
+ * @author donggaosheng
+ * @date 2021-11-11
+ */
+@Service
+@RefreshScope
+public class SpeakerServiceImpl implements ISpeakerService {
+
+    @Value("${speaker.port:8888}")
+    private String port;
+
+    @Value("${speaker.isOnline:0}")
+    private Integer isOnline;
+
+
+    private static Logger logger = LoggerFactory.getLogger(SpeakerServiceImpl.class);
+    @Autowired
+    private OkHttpRequest okHttpRequest;
+
+    @Autowired
+    private RemoteAddress remoteAddress;
+
+    @Autowired
+    private RedisService redisService;
+
+
+    @Override
+    public String getToken() {
+        String token = redisService.getCacheObject("token");
+        if (StringUtils.isNotEmpty(token) && StringUtils.isNotBlank(token)) {
+            return token;
+        }
+        String tokenStr = login();
+        redisService.setCacheObject("token", tokenStr, 60L, TimeUnit.DAYS);
+        logger.info(tokenStr);
+        return tokenStr;
+    }
+
+    @Override
+    public void setToken() {
+        String tokenStr = login();
+        redisService.setCacheObject("token", tokenStr, 60L, TimeUnit.DAYS);
+    }
+
+    @Override
+    public String login() {
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("email", "ls20@admin");
+        jsonObject.put("password", "admin");
+        JSONObject jsonUser = new JSONObject();
+        jsonUser.put("user", jsonObject);
+        String remoteUrl = remoteAddress.getProtocol() + "://" + remoteAddress.getRemoteIp() + ":" + remoteAddress.getRemotePort() + remoteAddress.getLoginUrl();
+        String responseStr = okHttpRequest.doPostJson(remoteUrl, jsonUser.toString());
+        JSONObject responseJson = JSONObject.parseObject(responseStr);
+        JSONObject userJson = responseJson.getJSONObject("user");
+        String tokenStr = userJson.getString("token");
+        return tokenStr;
+    }
+
+    @Override
+    public String getDeviceList(Integer page, Integer pageSize) {
+        Map<String, Object> jsonObject = new HashMap<>();
+        jsonObject.put("page", page);
+        jsonObject.put("pageSize", pageSize);
+        String remoteUrl = remoteAddress.getProtocol() + "://" + remoteAddress.getRemoteIp() + ":" + remoteAddress.getRemotePort() + remoteAddress.getDeviceUrl();
+        String token = getToken();
+        String[] strings = new String[]{"Authorization", "Bearer " + token};
+        String requestStr = okHttpRequest.doGet(remoteUrl, jsonObject, strings);
+        boolean isTrue = tokenRefresh(requestStr);
+        if (isTrue) {
+            return getDeviceList(page, pageSize);
+        }
+        return requestStr;
+    }
+
+    @Override
+    public String getDevice(String deviceId) {
+        String remoteUrl = remoteAddress.getProtocol() + "://" + remoteAddress.getRemoteIp() + ":" + remoteAddress.getRemotePort() + remoteAddress.getDeviceUrl() + "/" + deviceId;
+        String token = getToken();
+        String[] strings = new String[]{"Authorization", "Bearer " + token};
+        String requestStr = okHttpRequest.doGet(remoteUrl, strings);
+        boolean isTrue = tokenRefresh(requestStr);
+        if (isTrue) {
+            return getDevice(deviceId);
+        }
+        return requestStr;
+    }
+
+    @Override
+    public String playMusic(String ip, String body) {
+        String remoteUrl = remoteAddress.getProtocol() + "://" + ip + ":" + port;
+        String token = getToken();
+        String responseStr = okHttpRequest.doPostJson(remoteUrl, token, body);
+        boolean isTrue = tokenRefresh(responseStr);
+        if (isTrue) {
+            return playMusic(ip, body);
+        }
+        return responseStr;
+    }
+
+    @Override
+    public String textParseVoice(String ip, List<String> texts, PlayVo playVo) {
+        List<UrlVo> urlVoList = new ArrayList<>();
+        for (String text : texts) {
+            UrlVo urlVo = new UrlVo();
+            urlVo.setName(text.substring(0, 8));
+            String remoteUrl = remoteAddress.getProtocol() + "://" + remoteAddress.getTtsIp() + ":" + remoteAddress.getTtsPort() + "/tts_xf.single?text=" + text + "&voice_name=xiaoyan&speed=" + playVo.getSpeed() + "&volume=" + playVo.getParams().getVol();
+            urlVo.setUri(remoteUrl);
+            urlVoList.add(urlVo);
+        }
+        if (null != playVo.getParams()) {
+            playVo.getParams().setUrls(urlVoList);
+        }
+        String body = JSONObject.toJSON(playVo).toString();
+        String remoteUrl = remoteAddress.getProtocol() + "://" + ip + ":" + port;
+        String token = getToken();
+        String responseStr = okHttpRequest.doPostJson(remoteUrl, token, body);
+        boolean isTrue = tokenRefresh(responseStr);
+        if (isTrue) {
+            return textParseVoice(ip, texts, playVo);
+        }
+        return responseStr;
+    }
+
+    @Override
+    public String textParseVoiceURL(Integer speed, Integer volume, String text) {
+        String remoteUrl = remoteAddress.getProtocol() + "://" + remoteAddress.getTtsIp() + ":" + remoteAddress.getTtsPort() + "/tts_xf.multi";
+        String token = getToken();
+        String[] strings = new String[]{"Authorization", "Bearer " + token};
+        Map<String, Object> map = new HashMap<>();
+        map.put("text", text);
+        map.put("voice_name", "xiaoyan");
+        map.put("speed", speed);
+        map.put("volume", volume);
+        map.put("origin", remoteUrl.replace("/tts_xf.multi", ""));
+        String responseStr = okHttpRequest.doGet(remoteUrl, map, strings);
+        boolean isTrue = tokenRefresh(responseStr);
+        if (isTrue) {
+            return textParseVoiceURL(speed, volume, text);
+        }
+        return responseStr;
+    }
+
+    @Override
+    public void textParseVoiceIps(String texts, List<PlayVo> playVoList) {
+        commonTextParseVoice(texts,playVoList);
+    }
+
+    @Override
+    public void textParseVoiceAppIps(String texts,List<PlayVo> playVoList) {
+        if (playVoList.size() == 1) {
+            commonTextUrlVoice(texts, playVoList);
+        } else {
+            PlayBatchVo playBatchVo = new PlayBatchVo();
+            BeanUtils.copyProperties(playVoList.get(0), playBatchVo);
+            List<UrlVo> urlVoList = getUrlList(texts);
+            if (null != playBatchVo.getParams()) {
+                playBatchVo.getParams().setTid(UUID.randomUUID().toString());
+                playBatchVo.getParams().setUrls(urlVoList);
+            }
+            List<String> snsList = new ArrayList<>();
+            for (PlayVo playVo : playVoList) {
+                snsList.add(playVo.getSn());
+            }
+            String deviceIp =playVoList.get(0).getDeviceIp();
+            playBatchVo.setSns(snsList.toArray(new String[snsList.size()]));
+            boolean isTrue = invokePost(JSONObject.toJSON(playBatchVo).toString(), deviceIp,1, playVoList.get(0).getPort());
+            if (isTrue) {
+                textParseVoiceAppIps(texts,playVoList);
+            }
+        }
+    }
+
+    @Override
+    public void textParseUrlAppIpsOrigin(String text,List<PlayVo> playVo) {
+        commonTextParseVoice(text,playVo);
+    }
+
+    @Override
+    public boolean stopPlayMusic(String sn, String ip) {
+        logger.info("********************" + sn + "********************");
+        String remoteUrlIp = remoteAddress.getProtocol() + "://" + remoteAddress.getTtsIp() + ":" + remoteAddress.getRemotePort() + "/api/sendtodevice";
+        String token = getToken();
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("sn", sn);
+        jsonObject.put("type", "req");
+        jsonObject.put("name", "songs_queue_clear");
+        String responseStr = okHttpRequest.doPostJson(remoteUrlIp, token, jsonObject.toString());
+        logger.info("responseStr:+++++++++++++++++++++++++++" + responseStr + "+++++++++++++++++++++++++");
+        return tokenRefresh(responseStr);
+    }
+
+    /**
+     * 认证失败刷新token
+     * @param requestStr
+     * @return
+     */
+    private boolean tokenRefresh(String requestStr) {
+        JSONObject responseJson = JSONObject.parseObject(requestStr);
+        if (StringUtils.isNotNull(responseJson) && StringUtils.isNotNull(responseJson.getInteger("code")) && responseJson.getInteger("code") == 401) {
+            setToken();
+            return true;
+        }
+        return false;
+    }
+
+    private List<UrlVo> getUrlList(String texts) {
+        List<UrlVo> urlVoList = new ArrayList<>();
+        UrlVo urlVo = new UrlVo(texts.substring(0, 1), texts);
+        urlVoList.add(urlVo);
+        return urlVoList;
+    }
+
+    private List<UrlVo> getTextParseUrl(String text,PlayVo playVo) {
+        List<UrlVo> urlVoList = new ArrayList<>();
+        String remoteUrl = remoteAddress.getProtocol() + "://" + remoteAddress.getTtsIp() + ":" + remoteAddress.getTtsPort() + "/tts_xf.single?text=" + text + "&voice_name=xiaoyan&speed=" + playVo.getSpeed() + "&volume=" + playVo.getParams().getVol();
+        UrlVo urlVo = new UrlVo(text.substring(0, 1), remoteUrl);
+        urlVoList.add(urlVo);
+        return urlVoList;
+    }
+
+    /**
+     * 公共的文字转语音播放
+     *
+     * @param texts
+     * @param playVoList
+     */
+    private void commonTextParseVoice(String texts,List<PlayVo> playVoList) {
+        for (PlayVo play : playVoList) {
+            String deviceIp=play.getDeviceIp();
+            List<UrlVo> urlVoList = getTextParseUrl(texts,play);
+            if (null != play.getParams()) {
+                play.getParams().setTid(UUID.randomUUID().toString());
+                play.getParams().setUrls(urlVoList);
+            }
+            boolean isTrue = invokePost(JSONObject.toJSON(play).toString(),deviceIp, 0, play.getPort());
+            if (isTrue) {
+                commonTextParseVoice(texts,playVoList);
+                break;
+            }
+        }
+    }
+
+
+    /**
+     * 公共的语音路径播放
+     * commonTextUrlVoice
+     * @param texts
+     * @param playVoList
+     */
+    private void commonTextUrlVoice(String texts,List<PlayVo> playVoList) {
+        for (PlayVo play : playVoList) {
+            String deviceIp=play.getDeviceIp();
+            List<UrlVo> urlVoList = getUrlList(texts);
+            if (null != play.getParams()) {
+                play.getParams().setTid(UUID.randomUUID().toString());
+                play.getParams().setUrls(urlVoList);
+            }
+            boolean isTrue = invokePost(JSONObject.toJSON(play).toString(),deviceIp, 0, play.getPort());
+            if (isTrue) {
+                commonTextParseVoice(texts,playVoList);
+                break;
+            }
+        }
+    }
+
+    /**
+     * @param body
+     * @param type 0是单个,1是批量
+     */
+    private boolean invokePost(String body,String deviceIp, Integer type, int port) {
+        logger.info("+++++++++++++++++++++++++++" + body + "+++++++++++++++++++++++++");
+        String remoteUrlIp = "";
+        if(isOnline==1){
+            if (type == 0) {
+                remoteUrlIp = remoteAddress.getProtocol() + "://" + remoteAddress.getTtsIp() + ":" + remoteAddress.getRemotePort();
+            } else {
+                remoteUrlIp = remoteAddress.getProtocol() + "://" + remoteAddress.getTtsIp() + ":" + remoteAddress.getRemotePort() + "/api/sendtodevice";
+            }
+        }else{
+            if (type == 0) {
+                remoteUrlIp = remoteAddress.getProtocol() + "://" + deviceIp + ":" + port;
+            } else {
+                remoteUrlIp = remoteAddress.getProtocol() + "://" + remoteAddress.getTtsIp() + ":" + remoteAddress.getRemotePort() + "/api/sendtodevice";
+            }
+        }
+        String token = getToken();
+        String responseStr = okHttpRequest.doPostJson(remoteUrlIp, token, body);
+        logger.info("responseStr:+++++++++++++++++++++++++++" + responseStr + "+++++++++++++++++++++++++");
+        return tokenRefresh(responseStr);
+    }
+}

+ 186 - 0
zd-modules/zd-algorithm/src/main/java/com/zd/alg/speaker/utils/OkHttpRequest.java

@@ -0,0 +1,186 @@
+package com.zd.alg.speaker.utils;
+
+import okhttp3.*;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.Map;
+
+@Component
+public class OkHttpRequest {
+    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+    private static final MediaType XML = MediaType.parse("application/xml; charset=utf-8");
+    private static Logger logger = LoggerFactory.getLogger(OkHttpRequest.class);
+    @Autowired
+    private OkHttpClient okHttpClient;
+
+    /**
+     * get 请求
+     *
+     * @param url 请求url地址
+     * @return string
+     */
+    public String doGet(String url) {
+        return doGet(url, null, null);
+    }
+
+
+    /**
+     * get 请求
+     *
+     * @param url    请求url地址
+     * @param params 请求参数 map
+     * @return string
+     */
+    public String doGet(String url, Map<String, Object> params) {
+        return doGet(url, params, null);
+    }
+
+    /**
+     * get 请求
+     *
+     * @param url     请求url地址
+     * @param headers 请求头字段 {k1, v1 k2, v2, ...}
+     * @return string
+     */
+    public String doGet(String url, String[] headers) {
+        return doGet(url, null, headers);
+    }
+
+
+    /**
+     * get 请求
+     *
+     * @param url     请求url地址
+     * @param params  请求参数 map
+     * @param headers 请求头字段 {k1, v1 k2, v2, ...}
+     * @return string
+     */
+    public String doGet(String url, Map<String, Object> params, String[] headers) {
+        StringBuilder sb = new StringBuilder(url);
+        if (params != null && params.keySet().size() > 0) {
+            boolean firstFlag = true;
+            for (String key : params.keySet()) {
+                if (firstFlag) {
+                    sb.append("?").append(key).append("=").append(params.get(key));
+                    firstFlag = false;
+                } else {
+                    sb.append("&").append(key).append("=").append(params.get(key));
+                }
+            }
+        }
+
+        Request.Builder builder = new Request.Builder();
+        if (headers != null && headers.length > 0) {
+            if (headers.length % 2 == 0) {
+                for (int i = 0; i < headers.length; i = i + 2) {
+                    builder.addHeader(headers[i], headers[i + 1]);
+                }
+            } else {
+                logger.warn("headers's length[{}] is error.", headers.length);
+            }
+
+        }
+
+        Request request = builder.url(sb.toString()).build();
+        logger.info("do get request and url[{}]", sb.toString());
+        return execute(request);
+    }
+
+    /**
+     * post 请求
+     *
+     * @param url    请求url地址
+     * @param params 请求参数 map
+     * @return string
+     */
+    public String doPost(String url, Map<String, String> params) {
+        FormBody.Builder builder = new FormBody.Builder();
+
+        if (params != null && params.keySet().size() > 0) {
+            for (String key : params.keySet()) {
+                builder.add(key, params.get(key));
+            }
+        }
+        Request request = new Request.Builder().url(url).post(builder.build()).build();
+        logger.info("do post request and url[{}]", url);
+
+        return execute(request);
+    }
+
+
+    /**
+     * post 请求, 请求数据为 json 的字符串
+     *
+     * @param url  请求url地址
+     * @param json 请求数据, json 字符串
+     * @return string
+     */
+    public String doPostJson(String url, String json) {
+        logger.info("do post request and url[{}]", url);
+        return exectePost(url, json, JSON);
+    }
+
+    public String doPostJson(String url, String header, String json) {
+        logger.info("do post request and url[{}]", url);
+        return exectePost(url, header, json, JSON);
+    }
+
+    public String doPostText(String url, String json) {
+        logger.info("do post request and url[{}]", url);
+        return exectePost(url, json);
+    }
+
+    /**
+     * post 请求, 请求数据为 xml 的字符串
+     *
+     * @param url 请求url地址
+     * @param xml 请求数据, xml 字符串
+     * @return string
+     */
+    public String doPostXml(String url, String xml) {
+        logger.info("do post request and url[{}]", url);
+        return exectePost(url, xml, XML);
+    }
+
+
+    private String exectePost(String url, String data, MediaType contentType) {
+        RequestBody requestBody = RequestBody.create(contentType, data);
+        Request request = new Request.Builder().url(url).post(requestBody).build();
+
+        return execute(request);
+    }
+
+    private String exectePost(String url, String header, String data, MediaType contentType) {
+        RequestBody requestBody = RequestBody.create(contentType, data);
+        Request request = new Request.Builder().url(url).addHeader("Authorization", "Bearer " + header).post(requestBody).build();
+
+        return execute(request);
+    }
+
+    private String exectePost(String url, String data) {
+        MediaType mediaType = MediaType.parse("text/plain");
+        RequestBody requestBody = RequestBody.create(mediaType, data);
+        Request request = new Request.Builder().url(url).method("POST", requestBody).build();
+
+        return execute(request);
+    }
+
+
+    private String execute(Request request) {
+        Response response = null;
+        try {
+            response = okHttpClient.newCall(request).execute();
+            return response.body().string();
+        } catch (Exception e) {
+            logger.error(ExceptionUtils.getStackTrace(e));
+        } finally {
+            if (response != null) {
+                response.close();
+            }
+        }
+        return "";
+    }
+}

+ 40 - 0
zd-modules/zd-algorithm/src/main/resources/application.yml

@@ -0,0 +1,40 @@
+#okhttp 配置
+ok-http:
+  connect-timeout-ms: 500
+  keep-alive-duration-sec: 5000
+  max-idle-connections: 100
+  read-timeout-ms: 500
+  write-timeout-ms: 500
+
+#远程请求地址配置
+remote:
+  protocol: http
+  ip_addr: 192.168.1.88
+  port: 17808
+  operation:
+    login_url: /api/users/login #登录
+    get_device: /api/devices  #获取设备列表
+    set_device: /api/sendtodevice #设置设备
+  tts_ip: 192.168.1.88
+  tts_port: 10008
+spring:
+  redis:
+    host: 192.168.1.43
+    port: 16379
+    database: 2
+    password: 2ask8to9
+    jedis:
+      pool:
+        max-active: 8
+        max-wait: -1
+        max-idle: 500
+        min-idle: 1
+    timeout: 18000
+    lettuce:
+      shutdown-timeout: 0
+
+#ip喇叭控制端口
+speaker:
+  port: 8888
+  isOnline: 0  #1表示公网部署,0表示局域网部署
+

+ 10 - 0
zd-modules/zd-algorithm/src/main/resources/banner.txt

@@ -0,0 +1,10 @@
+Spring Boot Version: ${spring-boot.version}
+Spring Application Name: ${spring.application.name}
+                            _                           _                    
+                           (_)                         | |                   
+ _ __  _   _   ___   _   _  _  ______  ___  _   _  ___ | |_   ___  _ __ ___  
+| '__|| | | | / _ \ | | | || ||______|/ __|| | | |/ __|| __| / _ \| '_ ` _ \ 
+| |   | |_| || (_) || |_| || |        \__ \| |_| |\__ \| |_ |  __/| | | | | |
+|_|    \__,_| \___/  \__, ||_|        |___/ \__, ||___/ \__| \___||_| |_| |_|
+                      __/ |                  __/ |                           
+                     |___/                  |___/                            

+ 5 - 10
zd-modules/zd-algorithm/src/main/resources/bootstrap.yml

@@ -1,12 +1,12 @@
 # Tomcat
 server:
-  port: 9202
+  port: 9779
 
 # Spring
 spring:
   application:
     # 应用名称
-    name: zd-system
+    name: zd-smartlock
   profiles:
     # 环境配置
     active: dev
@@ -14,19 +14,14 @@ spring:
     nacos:
       discovery:
         # 服务注册地址
+      # server-addr: 180.76.134.43:8848
         server-addr: ${NACOS_HOST:127.0.0.1}:${NACOS_PORT:8848}
       config:
         # 配置中心地址
+        # server-addr: 180.76.134.43:8848
         server-addr: ${NACOS_HOST:127.0.0.1}:${NACOS_PORT:8848}
         # 配置文件格式
         file-extension: yml
         # 共享配置
         shared-configs:
-          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
-
-#mybatis配置
-mybatis:
-  # 搜索指定包别名
-  typeAliasesPackage: com.zd.system
-  # 配置mapper的扫描,找到所有的mapper.xml映射文件
-  mapperLocations: classpath:mapper/**/*.xml
+          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

BIN
zd-modules/zd-algorithm/src/main/resources/libs/arcsoft-sdk-face-3.0.0.0.jar


+ 74 - 0
zd-modules/zd-algorithm/src/main/resources/logback.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!-- 日志存放路径 -->
+    <property name="log.path" value="logs/zd-smartlock"/>
+    <!-- 日志输出格式 -->
+    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 系统日志输出 -->
+    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 系统模块日志级别控制  -->
+    <logger name="com.zd" level="debug"/>
+    <!-- Spring日志级别控制  -->
+    <logger name="org.springframework" level="info"/>
+
+    <root level="debug">
+        <appender-ref ref="console"/>
+    </root>
+
+    <!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info"/>
+        <appender-ref ref="file_error"/>
+    </root>
+</configuration>

+ 119 - 0
zd-modules/zd-algorithm/src/main/resources/mapper/alarm/AlarmLogMapper.xml

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zd.alg.alarm.mapper.AlarmLogMapper">
+
+    <resultMap type="com.zd.alg.alarm.domain.AlarmLog" id="AlarmLogResult">
+        <result property="id" column="id"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="phone" column="phone"/>
+        <result property="status" column="status"/>
+        <result property="notice" column="notice"/>
+        <result property="method" column="method"/>
+        <result property="isBack" column="is_back"/>
+    </resultMap>
+
+    <sql id="selectAlarmLogVo">
+        select id,
+               create_time,
+               update_time,
+               phone,
+               status,
+               notice,
+               method,
+               is_back
+        from alarm_log
+    </sql>
+    <sql id="selectAlarmLogListVo">
+        select t.id,
+               t.create_time,
+               t.update_time,
+               t.phone,
+               t.status,
+               t.notice,
+               t.method,
+               t.is_back
+        from alarm_log as t
+    </sql>
+    <select id="selectAlarmLogList" parameterType="com.zd.alg.alarm.domain.AlarmLog" resultMap="AlarmLogResult">
+        <include refid="selectAlarmLogVo"/>
+        <where>
+            <if test="phone != null  and phone != ''">and phone = #{phone}</if>
+            <if test="status != null  and status != ''">and status = #{status}</if>
+            <if test="notice != null  and notice != ''">and notice = #{notice}</if>
+            <if test="method != null  and method != ''">and method = #{method}</if>
+            <if test="isBack != null ">and is_back = #{isBack}</if>
+        </where>
+    </select>
+
+    <select id="selectAlarmLogById" resultMap="AlarmLogResult">
+        <include refid="selectAlarmLogVo"/>
+        where id = #{id}
+    </select>
+
+
+    <select id="selectNoBackAlarmLogList" resultType="com.zd.alg.alarm.domain.AlarmLog">
+        <include refid="selectAlarmLogVo"/>
+        where is_back &lt; #{retryCount} and status = "失败"
+        having TIMESTAMPDIFF(minute,create_time,#{date}) &lt; 30
+    </select>
+
+    <insert id="insertAlarmLog" parameterType="com.zd.alg.alarm.domain.AlarmLog" useGeneratedKeys="true"
+            keyProperty="id">
+        insert into alarm_log
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="phone != null">phone,</if>
+
+            <if test="status != null">status,</if>
+
+            <if test="notice != null">notice,</if>
+
+            <if test="method != null">method,</if>
+
+            <if test="isBack != null">is_back,</if>
+
+            <if test="remark != null">remark,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="phone != null">#{phone},</if>
+            <if test="status != null">#{status},</if>
+            <if test="notice != null">#{notice},</if>
+            <if test="method != null">#{method},</if>
+            <if test="isBack != null">#{isBack},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <update id="updateAlarmLog" parameterType="com.zd.alg.alarm.domain.AlarmLog">
+        update alarm_log
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="phone != null">phone = #{phone},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="notice != null">notice = #{notice},</if>
+            <if test="method != null">method = #{method},</if>
+            <if test="isBack != null">is_back = #{isBack},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteAlarmLogById">
+        delete
+        from alarm_log
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteAlarmLogByIds">
+        delete from alarm_log where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 125 - 0
zd-modules/zd-algorithm/src/main/resources/mapper/smartlock/SlApplyApprovalMapper.xml

@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zd.alg.smartlock.mapper.SlApplyApprovalMapper">
+
+    <resultMap type="com.zd.alg.smartlock.domain.SlApplyApproval" id="SlApplyApprovalResult">
+        <result property="id" column="id"/>
+        <result property="applyId" column="apply_id"/>
+        <result property="deptId" column="dept_id"/>
+        <result property="deptName" column="dept_name"/>
+        <result property="approvaId" column="approva_id"/>
+        <result property="approvaName" column="approva_name"/>
+        <result property="approvaStatus" column="approva_status"/>
+        <result property="cretaTime" column="creta_time"/>
+    </resultMap>
+
+    <sql id="selectSlApplyApprovalVo">
+        select id,
+               apply_id,
+               dept_id,
+               dept_name,
+               approva_id,
+               approva_name,
+               approva_status,
+               creta_time
+        from sl_apply_approval
+    </sql>
+    <sql id="selectSlApplyApprovalListVo">
+        select t.id,
+               t.apply_id,
+               t.dept_id,
+               t.dept_name,
+               t.approva_id,
+               t.approva_name,
+               t.approva_status,
+               t.creta_time
+        from sl_apply_approval as t
+    </sql>
+    <select id="selectSlApplyApprovalList" parameterType="com.zd.alg.smartlock.domain.SlApplyApproval"
+            resultMap="SlApplyApprovalResult">
+        <include refid="selectSlApplyApprovalVo"/>
+        <where>
+            <if test="applyId != null ">and apply_id = #{applyId}</if>
+            <if test="approvaId != null ">and approva_id = #{approvaId}</if>
+            <if test="approvaName != null  and approvaName != ''">and approva_name like concat('%', #{approvaName},
+                '%')
+            </if>
+            <if test="approvaStatus != null ">and approva_status = #{approvaStatus}</if>
+            <if test="cretaTime != null ">and creta_time = #{cretaTime}</if>
+        </where>
+    </select>
+
+    <select id="getListByIds" resultMap="SlApplyApprovalResult">
+        <include refid="selectSlApplyApprovalVo"/>
+        <where>
+            id in
+            <foreach item="id" collection="list" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </where>
+    </select>
+
+    <select id="selectSlApplyApprovalById" resultMap="SlApplyApprovalResult">
+        <include refid="selectSlApplyApprovalVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertSlApplyApproval" parameterType="com.zd.alg.smartlock.domain.SlApplyApproval" useGeneratedKeys="true"
+            keyProperty="id">
+        insert into sl_apply_approval
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="applyId != null">apply_id,</if>
+
+            <if test="deptId != null">dept_id,</if>
+
+            <if test="deptName != null">dept_name,</if>
+
+            <if test="approvaId != null">approva_id,</if>
+
+            <if test="approvaName != null">approva_name,</if>
+
+            <if test="approvaStatus != null">approva_status,</if>
+
+            <if test="cretaTime != null">creta_time,</if>
+
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="applyId != null">#{applyId},</if>
+            <if test="deptId != null">#{deptId},</if>
+            <if test="deptName != null">#{deptName},</if>
+            <if test="approvaId != null">#{approvaId},</if>
+            <if test="approvaName != null">#{approvaName},</if>
+            <if test="approvaStatus != null">#{approvaStatus},</if>
+            <if test="cretaTime != null">#{cretaTime},</if>
+        </trim>
+    </insert>
+
+    <update id="updateSlApplyApproval" parameterType="com.zd.alg.smartlock.domain.SlApplyApproval">
+        update sl_apply_approval
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="applyId != null">apply_id = #{applyId},</if>
+            <if test="deptId != null">dept_id = #{deptId},</if>
+            <if test="deptName != null">dept_name = #{deptName},</if>
+            <if test="approvaId != null">approva_id = #{approvaId},</if>
+            <if test="approvaName != null">approva_name = #{approvaName},</if>
+            <if test="approvaStatus != null">approva_status = #{approvaStatus},</if>
+            <if test="cretaTime != null">creta_time = #{cretaTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteSlApplyApprovalById">
+        delete
+        from sl_apply_approval
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteSlApplyApprovalByIds">
+        delete from sl_apply_approval where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 285 - 0
zd-modules/zd-algorithm/src/main/resources/mapper/smartlock/SlOpendoorApplyMapper.xml

@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zd.smartlock.mapper.SlOpendoorApplyMapper">
+
+    <resultMap type="com.zd.smartlock.domain.vo.SlOpendoorApplyVo" id="SlOpendoorApplyResult">
+        <result property="id" column="id"/>
+        <result property="userId" column="user_id"/>
+        <result property="userName" column="user_name"/>
+        <result property="deptId" column="dept_id"/>
+        <result property="deptName" column="dept_name"/>
+        <result property="userCode" column="user_code"/>
+        <result property="userSex" column="user_sex"/>
+        <result property="phonenumber" column="phonenumber"/>
+        <result property="userId2" column="user_id2"/>
+        <result property="userName2" column="user_name2"/>
+        <result property="userCode2" column="user_code2"/>
+        <result property="userSex2" column="user_sex2"/>
+        <result property="phonenumber2" column="phonenumber2"/>
+        <result property="subjectId" column="subject_id"/>
+        <result property="subjectName" column="subject_name"/>
+        <result property="safeUserId" column="safe_user_id"/>
+        <result property="safeUserName" column="safe_user_name"/>
+        <result property="safeUserPhone" column="safe_user_phone"/>
+        <result property="position" column="position"/>
+        <result property="college" column="college"/>
+        <result property="applyStatus" column="apply_status"/>
+        <result property="applyNumber" column="apply_number"/>
+        <result property="illustrate" column="illustrate"/>
+        <result property="approvalUser" column="approval_user"/>
+        <result property="approvalTime" column="approval_time"/>
+        <result property="creatTime" column="creat_time"/>
+    </resultMap>
+
+    <sql id="selectSlOpendoorApplyVo">
+        select id,
+               user_id,
+               user_name,
+               dept_id,
+               dept_name,
+               user_code,
+               user_sex,
+               phonenumber,
+               user_id2,
+               user_name2,
+               user_code2,
+               user_sex2,
+               phonenumber2,
+               subject_id,
+               subject_name,
+               safe_user_id,
+               safe_user_name,
+               safe_user_phone,
+               position,
+               college,
+               apply_status,
+               apply_number,
+               illustrate,
+               approval_user,
+               approval_time,
+               creat_time
+        from sl_opendoor_apply t
+    </sql>
+    <sql id="selectSlOpendoorApplyListVo">
+        select t.id,
+               t.user_id,
+               t.user_name,
+               t.dept_id,
+               t.dept_name,
+               t.user_code,
+               t.user_sex,
+               t.phonenumber,
+               t.user_id2,
+               t.user_name2,
+               t.user_code2,
+               t.user_sex2,
+               t.phonenumber,
+               t.subject_id,
+               t.subject_name,
+               t.safe_user_id,
+               t.safe_user_name,
+               t.safe_user_phone,
+               t.position,
+               t.college,
+               t.apply_status,
+               t.apply_number,
+               t.illustrate,
+               t.approval_user,
+               t.approval_time,
+               t.creat_time,
+               (select GROUP_CONCAT(safe_user_name) from sl_subject_relation r where r.subject_id= t.subject_id ) authName,
+               date_add(t.creat_time, interval 1 hour) loseTime
+        from sl_opendoor_apply as t
+        LEFT JOIN   sys_dept d on   t.dept_id=d.dept_id
+        LEFT JOIN sys_user u on  t.user_id=u.user_id
+    </sql>
+    <select id="selectSlOpendoorApplyList" parameterType="com.zd.smartlock.domain.vo.SlOpendoorApplyVo"
+            resultMap="SlOpendoorApplyResult">
+        <include refid="selectSlOpendoorApplyListVo"/>
+        <where>
+            <if test="userId != null ">and t.user_id = #{userId}</if>
+            <if test="userName != null  and userName != ''">and user_name like concat('%', #{userName}, '%')</if>
+            <if test="deptId != null ">and t.dept_id = #{deptId}</if>
+            <if test="deptName != null ">and t.dept_name = #{deptName}</if>
+            <if test="userCode != null ">and t.user_code = #{userCode}</if>
+            <if test="userSex != null ">and t.user_sex = #{userSex}</if>
+            <if test="phonenumber != null ">and t.phonenumber = #{phonenumber}</if>
+            <if test="userId2 != null ">and t.user_id2 = #{userId2}</if>
+            <if test="userName2 != null  and userName2 != ''">and t.user_name2 = #{userName2}</if>
+            <if test="userCode2 != null ">and t.user_code2 = #{userCode2}</if>
+            <if test="userSex2 != null ">and t.user_sex2 = #{userSex2}</if>
+            <if test="phonenumber2 != null ">and t.phonenumber2 = #{phonenumber2}</if>
+            <if test="subjectId != null ">and t.subject_id = #{subjectId}</if>
+            <if test="subjectName != null  and subjectName != ''">and t.subject_name like concat('%', #{subjectName},
+                '%')
+            </if>
+            <if test="safeUserId != null  and position != ''">and t.safe_user_id = #{safeUserId}</if>
+            <if test="safeUserName != null  and position != ''">and t.safe_user_name = #{safeUserName}</if>
+            <if test="position != null  and position != ''">and t.position = #{position}</if>
+            <if test="college != null  and college != ''">and t.college = #{college}</if>
+            <if test="applyStatus != null ">and t.apply_status = #{applyStatus}</if>
+            <if test="applyNumber != null ">and t.apply_number = #{applyNumber}</if>
+            <if test="illustrate != null ">and t.illustrate = #{illustrate}</if>
+            <if test="approvalUser != null ">and t.approval_user = #{approvalUser}</if>
+            <if test="approvalTime != null ">and t.approval_time = #{approvalTime}</if>
+            <if test="creatTime != null ">and t.creat_time = #{creatTime}</if>
+            <if test="searchValue != null and searchValue != ''">
+                and
+                (t.user_name like concat('%', #{searchValue}, '%') or
+                t.user_name2 like concat('%', #{searchValue}, '%') or
+                t.subject_name like concat('%', #{searchValue}, '%')
+                )
+            </if>
+            <if test="startTime != null "> and date_format(t.creat_time,'%Y-%m-%d') &gt;= date_format(#{startTime},'%Y-%m-%d')</if>
+            <if test="endTime != null "> and date_format(t.creat_time,'%Y-%m-%d') &lt;= date_format(#{endTime},'%Y-%m-%d')</if>
+        </where>
+        <!-- 数据范围过滤 -->
+        ${params.dataScope}
+    </select>
+
+    <select id="getListByIds" resultMap="SlOpendoorApplyResult">
+        <include refid="selectSlOpendoorApplyVo"/>
+        <where>
+            id in
+            <foreach item="id" collection="list" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </where>
+    </select>
+
+    <select id="selectSlOpendoorApplyById" resultMap="SlOpendoorApplyResult">
+        <include refid="selectSlOpendoorApplyVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertSlOpendoorApply" parameterType="com.zd.smartlock.domain.SlOpendoorApply" useGeneratedKeys="true"
+            keyProperty="id">
+        insert into sl_opendoor_apply
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="userId != null">user_id,</if>
+
+            <if test="userName != null">user_name,</if>
+
+            <if test="deptId != null">dept_id,</if>
+
+            <if test="deptName != null">dept_name,</if>
+
+            <if test="userCode != null">user_code,</if>
+
+            <if test="userSex != null">user_sex,</if>
+
+            <if test="phonenumber != null">phonenumber,</if>
+
+            <if test="userId2 != null">user_id2,</if>
+
+            <if test="userName2 != null">user_name2,</if>
+
+            <if test="userCode2 != null">user_code2,</if>
+
+            <if test="userSex2 != null">user_sex2,</if>
+
+            <if test="phonenumber2 != null">phonenumber2,</if>
+
+            <if test="subjectId != null">subject_id,</if>
+
+            <if test="subjectName != null">subject_name,</if>
+
+            <if test="safeUserId != null">safe_user_id,</if>
+
+            <if test="safeUserName != null">safe_user_name,</if>
+
+            <if test="safeUserPhone != null">safe_user_phone,</if>
+
+            <if test="position != null">position,</if>
+
+            <if test="college != null">college,</if>
+
+            <if test="applyStatus != null">apply_status,</if>
+
+            <if test="applyNumber != null">apply_number,</if>
+
+            <if test="illustrate != null">illustrate,</if>
+
+            <if test="approvalUser != null">approval_user,</if>
+
+            <if test="approvalTime != null">approval_time,</if>
+
+            <if test="creatTime != null">creat_time,</if>
+
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="userId != null">#{userId},</if>
+            <if test="userName != null">#{userName},</if>
+            <if test="deptId != null">#{deptId},</if>
+            <if test="deptName != null">#{deptName},</if>
+            <if test="userCode != null">#{userCode},</if>
+            <if test="userSex != null">#{userSex},</if>
+            <if test="phonenumber != null">#{phonenumber},</if>
+            <if test="userId2 != null">#{userId2},</if>
+            <if test="userName2 != null">#{userName2},</if>
+            <if test="userCode2 != null">#{userCode2},</if>
+            <if test="userSex2 != null">#{userSex2},</if>
+            <if test="phonenumber2 != null">#{phonenumber2},</if>
+            <if test="subjectId != null">#{subjectId},</if>
+            <if test="subjectName != null">#{subjectName},</if>
+            <if test="safeUserId != null">#{safeUserId},</if>
+            <if test="safeUserName != null">#{safeUserName},</if>
+            <if test="safeUserPhone != null">#{safeUserPhone},</if>
+            <if test="position != null">#{position},</if>
+            <if test="college != null">#{college},</if>
+            <if test="applyStatus != null">#{applyStatus},</if>
+            <if test="applyNumber != null">#{applyNumber},</if>
+            <if test="illustrate != null">#{illustrate},</if>
+            <if test="approvalUser != null">#{approval_user},</if>
+            <if test="approvalTime != null">#{approval_time},</if>
+            <if test="creatTime != null">#{creatTime},</if>
+        </trim>
+    </insert>
+
+    <update id="updateSlOpendoorApply" parameterType="com.zd.smartlock.domain.SlOpendoorApply">
+        update sl_opendoor_apply
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="userName != null">user_name = #{userName},</if>
+            <if test="deptId != null">dept_id = #{deptId},</if>
+            <if test="deptName != null">dept_name = #{deptName},</if>
+            <if test="userCode != null">user_code = #{userCode},</if>
+            <if test="userSex != null">user_sex = #{userSex},</if>
+            <if test="phonenumber != null">phonenumber = #{phonenumber},</if>
+            <if test="userId2 != null">user_id2 = #{userId2},</if>
+            <if test="userName2 != null">user_name2 = #{userName2},</if>
+            <if test="userCode2 != null">user_code2 = #{userCode2},</if>
+            <if test="userSex2 != null">user_sex2 = #{userSex2},</if>
+            <if test="phonenumber2 != null">phonenumber2 = #{phonenumber2},</if>
+            <if test="subjectId != null">subject_id = #{subjectId},</if>
+            <if test="subjectName != null">subject_name = #{subjectName},</if>
+            <if test="safeUserId != null">safe_user_id = #{safeUserId},</if>
+            <if test="safeUserName != null">safe_user_name = #{safeUserName},</if>
+            <if test="safeUserPhone != null">safe_user_phone = #{safeUserPhone},</if>
+            <if test="position != null">position = #{position},</if>
+            <if test="college != null">college = #{college},</if>
+            <if test="applyStatus != null">apply_status = #{applyStatus},</if>
+            <if test="applyNumber != null">apply_number = #{applyNumber},</if>
+            <if test="illustrate != null">illustrate = #{illustrate},</if>
+            <if test="approvalUser != null">approval_user = #{approvalUser},</if>
+            <if test="approvalTime != null">approval_time = #{approvalTime},</if>
+            <if test="creatTime != null">creat_time = #{creatTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteSlOpendoorApplyById">
+        delete
+        from sl_opendoor_apply
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteSlOpendoorApplyByIds">
+        delete from sl_opendoor_apply where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 191 - 0
zd-modules/zd-algorithm/src/main/resources/mapper/smartlock/SlSubjectRelationMapper.xml

@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zd.smartlock.mapper.SlSubjectRelationMapper">
+
+    <resultMap type="com.zd.smartlock.domain.vo.SlSubjectRelationVo" id="SlSubjectRelationResult">
+        <result property="id" column="id"/>
+        <result property="subjectId" column="subject_id"/>
+        <result property="subjectName" column="subject_name"/>
+        <result property="subjectLocation" column="subject_location"/>
+        <result property="college" column="college"/>
+        <result property="deptId" column="dept_id"/>
+        <result property="deptName" column="dept_name"/>
+        <result property="lockRoomId" column="lock_room_id"/>
+        <result property="lockCode" column="lock_code"/>
+        <result property="roomLocation" column="room_location"/>
+        <result property="roomName" column="room_name"/>
+        <result property="safeUserId" column="safe_user_id"/>
+        <result property="safeUserName" column="safe_user_name"/>
+        <result property="safeUserPhone" column="safe_user_phone"/>
+        <result property="userId" column="user_id"/>
+        <result property="createBy" column="create_by"/>
+        <result property="creatTime" column="creat_time"/>
+    </resultMap>
+
+    <sql id="selectSlSubjectRelationVo">
+        select id,
+               subject_id,
+               subject_name,
+               subject_location,
+               college,
+               dept_id,
+               dept_name,
+               lock_room_id,
+               lock_code,
+               room_location,
+               room_name,
+               safe_user_id,
+               safe_user_name,
+               safe_user_phone,
+               user_id,
+               create_by,
+               creat_time
+        from sl_subject_relation
+    </sql>
+    <sql id="selectSlSubjectRelationListVo">
+        select t.id,
+               t.subject_id,
+               t.subject_name,
+               t.subject_location,
+               t.college,
+               t.dept_id,
+               t.dept_name,
+               t.lock_room_id,
+               t.lock_code,
+               t.room_location,
+               t.room_name,
+               t.safe_user_id,
+               t.safe_user_name,
+               t.safe_user_phone,
+               t.user_id,
+               t.create_by,
+               t.creat_time
+        from sl_subject_relation as t
+    </sql>
+    <select id="selectSlSubjectRelationList" parameterType="com.zd.smartlock.domain.SlSubjectRelation"
+            resultMap="SlSubjectRelationResult">
+        <include refid="selectSlSubjectRelationVo"/>
+        <where>
+            <if test="subjectId != null ">and subject_id = #{subjectId}</if>
+            <if test="subjectName != null  and subjectName != ''">and subject_name like concat('%', #{subjectName},
+                '%')
+            </if>
+            <if test="subjectLocation != null  and subjectLocation != ''">and subject_location = #{subjectLocation}</if>
+            <if test="college != null  and college != ''">and college = #{college}</if>
+            <if test="lockRoomId != null  and lockRoomId != ''">and lock_room_id = #{lockRoomId}</if>
+            <if test="lockCode != null  and lockCode != ''">and lock_code = #{lockCode}</if>
+            <if test="roomLocation != null  and roomLocation != ''">and room_location = #{roomLocation}</if>
+            <if test="roomName != null  and roomName != ''">and room_name = #{roomName}</if>
+            <if test="userId != null  ">and user_id = #{userId}</if>
+            <if test="creatTime != null ">and creat_time = #{creatTime}</if>
+        </where>
+    </select>
+
+    <select id="getListByIds" resultMap="SlSubjectRelationResult">
+        <include refid="selectSlSubjectRelationVo"/>
+        <where>
+            id in
+            <foreach item="id" collection="list" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </where>
+    </select>
+
+    <select id="selectSlSubjectRelationById" resultMap="SlSubjectRelationResult">
+        <include refid="selectSlSubjectRelationVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertSlSubjectRelation" parameterType="com.zd.smartlock.domain.SlSubjectRelation"
+            useGeneratedKeys="true" keyProperty="id">
+        insert into sl_subject_relation
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="subjectId != null">subject_id,</if>
+
+            <if test="subjectName != null">subject_name,</if>
+
+            <if test="subjectLocation != null">subject_location,</if>
+
+            <if test="college != null">college,</if>
+
+            <if test="deptId != null">dept_id,</if>
+
+            <if test="deptName != null">dept_name,</if>
+
+            <if test="lockRoomId != null">lock_room_id,</if>
+
+            <if test="lockCode != null">lock_code,</if>
+
+            <if test="roomLocation != null">room_location,</if>
+
+            <if test="roomName != null">room_name,</if>
+
+            <if test="safeUserId != null">safe_user_id,</if>
+            <if test="safeUserName != null">safe_user_name,</if>
+            <if test="safeUserPhone != null">safe_user_phone,</if>
+
+            <if test="userId != null">user_id,</if>
+
+            <if test="createBy != null">create_by,</if>
+
+            <if test="creatTime != null">creat_time,</if>
+
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="subjectId != null">#{subjectId},</if>
+            <if test="subjectName != null">#{subjectName},</if>
+            <if test="subjectLocation != null">#{subjectLocation},</if>
+            <if test="college != null">#{college},</if>
+            <if test="deptId != null">#{deptId},</if>
+            <if test="deptName != null">#{deptName},</if>
+            <if test="lockRoomId != null">#{lockRoomId},</if>
+            <if test="lockCode != null">#{lockCode},</if>
+            <if test="roomLocation != null">#{roomLocation},</if>
+            <if test="roomName != null">#{roomName},</if>
+            <if test="safeUserId != null">#{safeUserId},</if>
+            <if test="safeUserName != null">#{safeUserName},</if>
+            <if test="safeUserPhone != null">#{safeUserPhone},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="creatTime != null">#{creatTime},</if>
+        </trim>
+    </insert>
+
+    <update id="updateSlSubjectRelation" parameterType="com.zd.smartlock.domain.SlSubjectRelation">
+        update sl_subject_relation
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="subjectId != null">subject_id = #{subjectId},</if>
+            <if test="subjectName != null">subject_name = #{subjectName},</if>
+            <if test="subjectLocation != null">subject_location = #{subjectLocation},</if>
+            <if test="college != null">college = #{college},</if>
+            <if test="deptId != null">dept_id = #{deptId},</if>
+            <if test="deptName != null">dept_name = #{deptName},</if>
+            <if test="lockRoomId != null">lock_room_id = #{lockRoomId},</if>
+            <if test="lockCode != null">lock_code = #{lockCode},</if>
+            <if test="roomLocation != null">room_location = #{roomLocation},</if>
+            <if test="roomName != null">room_name = #{roomName},</if>
+            <if test="safeUserId != null">safe_user_id = #{safeUserId},</if>
+            <if test="safeUserName != null">safe_user_name = #{safeUserName},</if>
+            <if test="safeUserPhone != null">safe_user_phone = #{safeUserPhone},</if>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="creatTime != null">creat_time = #{creatTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteSlSubjectRelationById">
+        delete
+        from sl_subject_relation
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteSlSubjectRelationByIds">
+        delete from sl_subject_relation where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 129 - 0
zd-modules/zd-algorithm/src/main/resources/mapper/smartlock/SlUserRelationMapper.xml

@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zd.smartlock.mapper.SlUserRelationMapper">
+
+    <resultMap type="com.zd.smartlock.domain.SlUserRelation" id="SlUserRelationResult">
+        <result property="id" column="id"/>
+        <result property="userId" column="user_id"/>
+        <result property="userName" column="user_name"/>
+        <result property="deptId" column="dept_id"/>
+        <result property="deptName" column="dept_name"/>
+        <result property="lockUserCode" column="lock_user_code"/>
+        <result property="type" column="type"/>
+        <result property="createBy" column="create_by"/>
+        <result property="creatTime" column="creat_time"/>
+    </resultMap>
+
+    <sql id="selectSlUserRelationVo">
+        select id,
+               user_id,
+               user_name,
+               dept_id,
+               dept_name,
+               lock_user_code,
+               type,
+               create_by,
+               creat_time
+        from sl_user_relation
+    </sql>
+    <sql id="selectSlUserRelationListVo">
+        select t.id,
+               t.user_id,
+               t.user_name,
+               t.dept_id,
+               t.dept_name,
+               t.lock_user_code,
+               t.type,
+               t.create_by,
+               t.creat_time
+        from sl_user_relation as t
+    </sql>
+    <select id="selectSlUserRelationList" parameterType="com.zd.smartlock.domain.SlUserRelation"
+            resultMap="SlUserRelationResult">
+        <include refid="selectSlUserRelationVo"/>
+        <where>
+            <if test="userName != null  and userName != ''">and user_name like concat('%', #{userName}, '%')</if>
+            <if test="lockUserCode != null  and lockUserCode != ''">and lock_user_code = #{lockUserCode}</if>
+            <if test="type != null ">and type = #{type}</if>
+            <if test="creatTime != null ">and creat_time = #{creatTime}</if>
+        </where>
+    </select>
+
+    <select id="getListByIds" resultMap="SlUserRelationResult">
+        <include refid="selectSlUserRelationVo"/>
+        <where>
+            id in
+            <foreach item="id" collection="list" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </where>
+    </select>
+
+    <select id="selectSlUserRelationById" resultMap="SlUserRelationResult">
+        <include refid="selectSlUserRelationVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertSlUserRelation" parameterType="com.zd.smartlock.domain.SlUserRelation" useGeneratedKeys="true"
+            keyProperty="id">
+        insert into sl_user_relation
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="userId != null">user_id,</if>
+
+            <if test="userName != null">user_name,</if>
+
+            <if test="deptId != null">dept_id,</if>
+
+            <if test="deptName != null">dept_name,</if>
+
+            <if test="lockUserCode != null">lock_user_code,</if>
+
+            <if test="type != null">type,</if>
+
+            <if test="createBy != null">create_by,</if>
+
+            <if test="creatTime != null">creat_time,</if>
+
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="userId != null">#{userId},</if>
+            <if test="userName != null">#{userName},</if>
+            <if test="deptId != null">#{deptId},</if>
+            <if test="deptName != null">#{deptName},</if>
+            <if test="lockUserCode != null">#{lockUserCode},</if>
+            <if test="type != null">#{type},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="creatTime != null">#{creatTime},</if>
+        </trim>
+    </insert>
+
+    <update id="updateSlUserRelation" parameterType="com.zd.smartlock.domain.SlUserRelation">
+        update sl_user_relation
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="userName != null">user_name = #{userName},</if>
+            <if test="deptId != null">dept_id = #{deptId},</if>
+            <if test="deptName != null">dept_name = #{deptName},</if>
+            <if test="lockUserCode != null">lock_user_code = #{lockUserCode},</if>
+            <if test="type != null">type = #{type},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="creatTime != null">creat_time = #{creatTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteSlUserRelationById">
+        delete
+        from sl_user_relation
+        where id = #{id}
+    </delete>
+
+    <delete id="deleteSlUserRelationByIds">
+        delete from sl_user_relation where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>