yingp 6 роки тому
батько
коміт
e23d7d93df
40 змінених файлів з 1185 додано та 52 видалено
  1. 37 0
      applications/device/device-client/pom.xml
  2. 27 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/DeviceClientApplication.java
  3. 25 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/config/DeviceServerProperties.java
  4. 21 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/config/WebMvcConfig.java
  5. 60 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/config/WebSecurityConfig.java
  6. 43 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/controller/AccessControlController.java
  7. 41 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/init/AccessControlInitializer.java
  8. 36 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/listener/AccessControlListener.java
  9. 79 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/po/AccessControl.java
  10. 22 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/repository/AccessControlRepository.java
  11. 71 0
      applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/service/AccessControlService.java
  12. 27 0
      applications/device/device-client/src/main/resources/application.yml
  13. 5 0
      applications/device/device-client/src/main/resources/static/css/bootstrap.min.css
  14. 87 0
      applications/device/device-client/src/main/resources/static/css/login.css
  15. 24 0
      applications/device/device-client/src/main/resources/static/iccard.html
  16. 108 0
      applications/device/device-client/src/main/resources/static/index.html
  17. 5 0
      applications/device/device-client/src/main/resources/static/js/bootstrap.min.js
  18. 5 0
      applications/device/device-client/src/main/resources/static/js/index.js
  19. 1 0
      applications/device/device-client/src/main/resources/static/js/jquery.min.js
  20. 31 0
      applications/device/device-client/src/main/resources/static/login.html
  21. BIN
      applications/device/device-client/src/main/winserver/deviceclient.exe
  22. 14 0
      applications/device/device-client/src/main/winserver/deviceclient.xml
  23. 20 0
      applications/device/device-core/pom.xml
  24. 105 0
      applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/base/Result.java
  25. 41 0
      applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/context/SpringContextHolder.java
  26. 15 0
      applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/context/SpringContextListener.java
  27. 23 0
      applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/BaseException.java
  28. 21 0
      applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/BaseExceptionCode.java
  29. 42 0
      applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/BaseUncheckedException.java
  30. 33 0
      applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/BizException.java
  31. 52 0
      applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/ExceptionCode.java
  32. 3 0
      applications/device/device-core/src/main/resources/META-INF/spring.factories
  33. 2 0
      applications/device/device-core/src/main/resources/message_zh_CN.properties
  34. 9 1
      applications/device/device-sdk-dahua/pom.xml
  35. 1 1
      applications/device/device-sdk-dahua/src/main/java/com/usoftchina/smartschool/device/dahua/lib/DahuaSdk.java
  36. 1 1
      applications/device/device-sdk-dahua/src/main/java/com/usoftchina/smartschool/device/dahua/service/DahuaDataAnalyzeService.java
  37. 12 0
      applications/device/device-sdk/src/main/java/com/usoftchina/smartschool/device/dto/AccessControlInfo.java
  38. 28 49
      applications/device/device-sdk/src/main/java/com/usoftchina/smartschool/device/dto/DeviceInfo.java
  39. 3 0
      applications/device/pom.xml
  40. 5 0
      pom.xml

+ 37 - 0
applications/device/device-client/pom.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>device</artifactId>
+        <groupId>com.usoftchina.smartschool</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <description>device client for school</description>
+
+    <artifactId>device-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>com.usoftchina.smartschool</groupId>
+            <artifactId>device-sdk-dahua</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 27 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/DeviceClientApplication.java

@@ -0,0 +1,27 @@
+package com.usoftchina.smartschool.device.client;
+
+import com.usoftchina.smartschool.device.client.config.DeviceServerProperties;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@SpringBootApplication
+@EnableAsync
+@EnableConfigurationProperties(DeviceServerProperties.class)
+public class DeviceClientApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(DeviceClientApplication.class, args);
+    }
+
+    @Bean
+    public RestTemplate restTemplate() {
+        return new RestTemplate();
+    }
+}

+ 25 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/config/DeviceServerProperties.java

@@ -0,0 +1,25 @@
+package com.usoftchina.smartschool.device.client.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@ConfigurationProperties(DeviceServerProperties.PREFIX)
+public class DeviceServerProperties {
+    public static final String PREFIX = "device.server";
+
+    /**
+     * 门禁事件的服务端接口
+     */
+    private String accessControlEvent;
+
+    public String getAccessControlEvent() {
+        return accessControlEvent;
+    }
+
+    public void setAccessControlEvent(String accessControlEvent) {
+        this.accessControlEvent = accessControlEvent;
+    }
+}

+ 21 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/config/WebMvcConfig.java

@@ -0,0 +1,21 @@
+package com.usoftchina.smartschool.device.client.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addViewControllers(ViewControllerRegistry registry) {
+        registry.addViewController("/index").setViewName("index.html");
+        registry.addViewController("/").setViewName("index.html");
+        registry.addViewController("/login").setViewName("/login.html");
+        registry.addViewController("/iccard").setViewName("/iccard.html");
+    }
+}

+ 60 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/config/WebSecurityConfig.java

@@ -0,0 +1,60 @@
+package com.usoftchina.smartschool.device.client.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@Configuration
+@EnableWebSecurity
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        web.ignoring().antMatchers("/resources/**", "/static/**", "/public/**",
+                "/html/**", "/css/**", "/js/**", "**/*.css", "**/*.js");
+    }
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.authorizeRequests()
+                .antMatchers("/login")
+                .permitAll()
+                .anyRequest()
+                .authenticated()
+                .and()
+                .formLogin()
+                .loginPage("/login")
+                .and()
+                .csrf()
+                .disable()
+                .sessionManagement()
+                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
+    }
+
+    @Autowired
+    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+        auth.inMemoryAuthentication().passwordEncoder(new PlainTextPasswordEncoder())
+                .withUser("admin").password("select111***").roles("ADMIN");
+    }
+
+    class PlainTextPasswordEncoder implements PasswordEncoder {
+        @Override
+        public String encode(CharSequence rawPassword) {
+            return rawPassword.toString();
+        }
+
+        @Override
+        public boolean matches(CharSequence rawPassword, String encodedPassword) {
+            return encodedPassword.equals(rawPassword.toString());
+        }
+    }
+}

+ 43 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/controller/AccessControlController.java

@@ -0,0 +1,43 @@
+package com.usoftchina.smartschool.device.client.controller;
+
+import com.usoftchina.smartschool.device.base.Result;
+import com.usoftchina.smartschool.device.client.po.AccessControl;
+import com.usoftchina.smartschool.device.client.service.AccessControlService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@RestController
+@RequestMapping("/accesscontrol")
+public class AccessControlController {
+
+    @Autowired
+    private AccessControlService accessControlService;
+
+    /**
+     * 查询全部门禁设备
+     *
+     * @return
+     */
+    @GetMapping
+    public Result<List<AccessControl>> findAll() {
+        return Result.success(accessControlService.findAll());
+    }
+
+    /**
+     * 保存门禁设备信息
+     *
+     * @param accessControl
+     * @return
+     */
+    @PostMapping
+    public Result save(@RequestBody AccessControl accessControl) {
+        accessControlService.save(accessControl);
+        return Result.success();
+    }
+}

+ 41 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/init/AccessControlInitializer.java

@@ -0,0 +1,41 @@
+package com.usoftchina.smartschool.device.client.init;
+
+import com.usoftchina.smartschool.device.api.DeviceApi;
+import com.usoftchina.smartschool.device.client.po.AccessControl;
+import com.usoftchina.smartschool.device.client.service.AccessControlService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 门禁设备初始化
+ *
+ * @author yingp
+ * @date 2019/3/11
+ */
+@Component
+public class AccessControlInitializer implements CommandLineRunner {
+
+    @Autowired
+    private AccessControlService accessControlService;
+
+    @Autowired
+    private DeviceApi deviceApi;
+
+    /**
+     * 程序启动后,开始监听门禁事件
+     *
+     * @param args
+     * @throws Exception
+     */
+    @Override
+    public void run(String... args) throws Exception {
+        List<AccessControl> accessControls = accessControlService.findAll();
+        if (!CollectionUtils.isEmpty(accessControls)) {
+            accessControls.forEach(deviceApi::add);
+        }
+    }
+}

+ 36 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/listener/AccessControlListener.java

@@ -0,0 +1,36 @@
+package com.usoftchina.smartschool.device.client.listener;
+
+import com.usoftchina.smartschool.device.client.service.AccessControlService;
+import com.usoftchina.smartschool.device.event.AccessControlEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@Component
+public class AccessControlListener {
+    private Logger logger = LoggerFactory.getLogger(AccessControlListener.class);
+
+    @Autowired
+    private AccessControlService accessControlService;
+
+    /**
+     * 门禁事件
+     *
+     * @param event
+     */
+    @Async
+    @EventListener(AccessControlEvent.class)
+    public void onAccessControlEvent(AccessControlEvent event) {
+        if(logger.isDebugEnabled()) {
+            logger.debug(event.getAccessControlInfo().toString());
+        }
+        accessControlService.saveRecord(event.getAccessControlInfo());
+    }
+}

+ 79 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/po/AccessControl.java

@@ -0,0 +1,79 @@
+package com.usoftchina.smartschool.device.client.po;
+
+import com.usoftchina.smartschool.device.dto.DeviceInfo;
+
+import javax.persistence.*;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@Entity
+@Table(indexes = {@Index(name = "idx_access_control_ip_port", columnList = "ip,port", unique = true)})
+public class AccessControl implements DeviceInfo{
+    @Id
+    @GeneratedValue
+    private Integer id;
+
+    private String name;
+
+    private String ip;
+
+    private int port;
+
+    private String username;
+
+    private String password;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+
+    @Override
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    @Override
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    @Override
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}

+ 22 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/repository/AccessControlRepository.java

@@ -0,0 +1,22 @@
+package com.usoftchina.smartschool.device.client.repository;
+
+import com.usoftchina.smartschool.device.client.po.AccessControl;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@Repository
+public interface AccessControlRepository extends JpaRepository<AccessControl, Integer> {
+
+    /**
+     * 按IP+PORT查找
+     *
+     * @param ip
+     * @param port
+     * @return
+     */
+    AccessControl findByIpAndPort(String ip, int port);
+}

+ 71 - 0
applications/device/device-client/src/main/java/com/usoftchina/smartschool/device/client/service/AccessControlService.java

@@ -0,0 +1,71 @@
+package com.usoftchina.smartschool.device.client.service;
+
+import com.usoftchina.smartschool.device.base.Result;
+import com.usoftchina.smartschool.device.client.config.DeviceServerProperties;
+import com.usoftchina.smartschool.device.client.po.AccessControl;
+import com.usoftchina.smartschool.device.client.repository.AccessControlRepository;
+import com.usoftchina.smartschool.device.dto.AccessControlInfo;
+import com.usoftchina.smartschool.device.exception.ExceptionCode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.List;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+@Service
+public class AccessControlService {
+    @Autowired
+    private AccessControlRepository accessControlRepository;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    private DeviceServerProperties deviceServerProperties;
+
+    public List<AccessControl> findAll() {
+        return accessControlRepository.findAll();
+    }
+
+    /**
+     * 保存门禁配置
+     *
+     * @param accessControl
+     */
+    public void save(AccessControl accessControl) {
+        AccessControl oldOne = accessControlRepository.findByIpAndPort(accessControl.getIp(),
+                accessControl.getPort());
+        if (null != oldOne) {
+            if (accessControl.getId() == null || accessControl.getId() <= 0) {
+                accessControl.setId(oldOne.getId());
+            } else if (!accessControl.getId().equals(oldOne.getId())) {
+                ExceptionCode.ERROR_IP_PORT_EXIST.occur();
+            }
+        }
+        accessControlRepository.save(accessControl);
+    }
+
+    /**
+     * 远程保存门禁记录
+     *
+     * @param info
+     */
+    public void saveRecord(AccessControlInfo info) {
+        ResponseEntity<Result> response = restTemplate.postForEntity(
+                deviceServerProperties.getAccessControlEvent(), info, Result.class);
+        if (response.getStatusCode() == HttpStatus.OK) {
+            Result result = response.getBody();
+            if (!result.isSuccess()) {
+                ExceptionCode.ERROR_UNKNOWN.occur(result.getMessage());
+            }
+        } else {
+            ExceptionCode.ERROR_UNKNOWN.occur("保存门禁记录失败");
+        }
+    }
+}

+ 27 - 0
applications/device/device-client/src/main/resources/application.yml

@@ -0,0 +1,27 @@
+device:
+  dahua:
+    wait-time: 5000
+    connect-time: 10000
+  server:
+  # 门禁事件的服务端接口
+    accessControlEvent: https://school-api.ydyhz.com/device/accesscontrol/event
+server:
+  tomcat:
+    uri-encoding: UTF-8
+spring:
+  http:
+    encoding:
+      force: true
+      charset: utf-8
+      enabled: true
+  datasource:
+    driver-class-name: org.h2.Driver
+    url: jdbc:h2:file:./data/device-client;FILE_LOCK=NO;DB_CLOSE_ON_EXIT=FALSE
+    username: admin
+    password: select111***
+    hikari:
+      minimum-idle: 5
+      maximum-pool-size: 50
+      idle-timeout: 30000
+      max-lifetime: 1800000
+      connection-timeout: 30000

Різницю між файлами не показано, бо вона завелика
+ 5 - 0
applications/device/device-client/src/main/resources/static/css/bootstrap.min.css


+ 87 - 0
applications/device/device-client/src/main/resources/static/css/login.css

@@ -0,0 +1,87 @@
+:root {
+    --input-padding-x: .75rem;
+    --input-padding-y: .75rem;
+}
+
+html,
+body {
+    height: 100%;
+}
+
+body {
+    display: -ms-flexbox;
+    display: -webkit-box;
+    display: flex;
+    -ms-flex-align: center;
+    -ms-flex-pack: center;
+    -webkit-box-align: center;
+    align-items: center;
+    -webkit-box-pack: center;
+    justify-content: center;
+    padding-top: 40px;
+    padding-bottom: 40px;
+    background-color: #f5f5f5;
+}
+
+.form-signin {
+    width: 100%;
+    max-width: 420px;
+    padding: 15px;
+    margin: 0 auto;
+}
+
+.form-label-group {
+    position: relative;
+    margin-bottom: 1rem;
+}
+
+.form-label-group > input,
+.form-label-group > label {
+    padding: var(--input-padding-y) var(--input-padding-x);
+}
+
+.form-label-group > label {
+    position: absolute;
+    top: 0;
+    left: 0;
+    display: block;
+    width: 100%;
+    margin-bottom: 0; /* Override default `<label>` margin */
+    line-height: 1.5;
+    color: #495057;
+    border: 1px solid transparent;
+    border-radius: .25rem;
+    transition: all .1s ease-in-out;
+}
+
+.form-label-group input::-webkit-input-placeholder {
+    color: transparent;
+}
+
+.form-label-group input:-ms-input-placeholder {
+    color: transparent;
+}
+
+.form-label-group input::-ms-input-placeholder {
+    color: transparent;
+}
+
+.form-label-group input::-moz-placeholder {
+    color: transparent;
+}
+
+.form-label-group input::placeholder {
+    color: transparent;
+}
+
+.form-label-group input:not(:placeholder-shown) {
+    padding-top: calc(var(--input-padding-y) + var(--input-padding-y) * (2 / 3));
+    padding-bottom: calc(var(--input-padding-y) / 3);
+}
+
+.form-label-group input:not(:placeholder-shown) ~ label {
+    padding-top: calc(var(--input-padding-y) / 3);
+    padding-bottom: calc(var(--input-padding-y) / 3);
+    font-size: 12px;
+    color: #777;
+}

+ 24 - 0
applications/device/device-client/src/main/resources/static/iccard.html

@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html lang="zh-CN">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <title>智慧校园 - 设备监听管理</title>
+    <link rel="stylesheet" href="/css/bootstrap.min.css">
+</head>
+<body>
+<nav class="navbar navbar-expand-lg navbar-light bg-light">
+    <a class="navbar-brand" href="#">设备监听管理</a>
+
+    <div class="collapse navbar-collapse">
+        <ul class="navbar-nav mr-auto">
+            <li class="nav-item">
+                <a class="nav-link" href="/">门禁设备</a>
+            </li>
+            <li class="nav-item active">
+                <a class="nav-link" href="#">消费卡</a>
+            </li>
+        </ul>
+    </div>
+</nav>
+</body>

+ 108 - 0
applications/device/device-client/src/main/resources/static/index.html

@@ -0,0 +1,108 @@
+<!DOCTYPE HTML>
+<html lang="zh-CN">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <title>智慧校园 - 设备监听管理</title>
+    <link rel="stylesheet" href="/css/bootstrap.min.css">
+</head>
+<body>
+<nav class="navbar navbar-expand-lg navbar-light bg-light">
+    <a class="navbar-brand" href="#">设备监听管理</a>
+
+    <div class="collapse navbar-collapse">
+        <ul class="navbar-nav mr-auto">
+            <li class="nav-item active">
+                <a class="nav-link" href="#">门禁设备</a>
+            </li>
+            <li class="nav-item">
+                <a class="nav-link" href="/iccard">消费卡</a>
+            </li>
+        </ul>
+    </div>
+
+    <div>
+        <button class="btn btn-outline-success" id="addBtn"
+                data-toggle="modal" data-target="#formModal">添加</button>
+    </div>
+</nav>
+<!-- Modal -->
+<div class="modal fade" id="formModal" tabindex="-1" role="dialog" aria-labelledby="formModalTitle" aria-hidden="true">
+    <div class="modal-dialog modal-dialog-scrollable" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="formModalTitle">添加门禁设备</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <form>
+                    <div class="form-group">
+                        <label for="nameInput">名称</label>
+                        <input type="text" class="form-control" id="nameInput" required
+                               aria-describedby="nameHelp" placeholder="设备名称">
+                    </div>
+                    <div class="form-group">
+                        <label for="ipInput">IP</label>
+                        <input type="text" class="form-control" id="ipInput" required
+                               aria-describedby="ipHelp" placeholder="ip地址,例如192.168.1.100">
+                    </div>
+                    <div class="form-group">
+                        <label for="portInput">端口</label>
+                        <input type="text" class="form-control" id="portInput" required
+                               aria-describedby="portHelp" placeholder="tcp端口,例如37777">
+                    </div>
+                    <div class="form-group">
+                        <label for="usernameInput">账号</label>
+                        <input type="text" class="form-control" id="usernameInput" value="admin" required
+                               aria-describedby="usernameHelp" placeholder="登录账号,例如admin">
+                    </div>
+                    <div class="form-group">
+                        <label for="passwordInput">密码</label>
+                        <input type="password" class="form-control" id="passwordInput" required
+                               aria-describedby="passwordHelp" placeholder="登录密码">
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-primary" id="saveBtn">保存</button>
+            </div>
+        </div>
+    </div>
+</div>
+<table class="table">
+    <thead class="thead-light">
+    <tr>
+        <th scope="col">#</th>
+        <th scope="col">名称</th>
+        <th scope="col">IP</th>
+        <th scope="col">端口</th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr>
+        <th scope="row">1</th>
+        <td>Mark</td>
+        <td>Otto</td>
+        <td>@mdo</td>
+    </tr>
+    <tr>
+        <th scope="row">2</th>
+        <td>Jacob</td>
+        <td>Thornton</td>
+        <td>@fat</td>
+    </tr>
+    <tr>
+        <th scope="row">3</th>
+        <td>Larry</td>
+        <td>the Bird</td>
+        <td>@twitter</td>
+    </tr>
+    </tbody>
+</table>
+<script src="/js/jquery.min.js"></script>
+<script src="/js/bootstrap.min.js"></script>
+<script src="/js/index.js"></script>
+</body>

Різницю між файлами не показано, бо вона завелика
+ 5 - 0
applications/device/device-client/src/main/resources/static/js/bootstrap.min.js


+ 5 - 0
applications/device/device-client/src/main/resources/static/js/index.js

@@ -0,0 +1,5 @@
+$(document).ready(function () {
+   $('#saveBtn').click(function(){
+
+   });
+});

Різницю між файлами не показано, бо вона завелика
+ 1 - 0
applications/device/device-client/src/main/resources/static/js/jquery.min.js


+ 31 - 0
applications/device/device-client/src/main/resources/static/login.html

@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html lang="zh-CN">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <title>智慧校园 - 设备监听管理</title>
+    <link rel="stylesheet" href="/css/bootstrap.min.css">
+    <link rel="stylesheet" href="/css/login.css" />
+</head>
+<body>
+<form class="form-signin" action="" method="POST">
+    <div class="text-center mb-4">
+        <h1 class="h3 mb-3 font-weight-normal">账户登录</h1>
+    </div>
+    <div class="form-label-group">
+        <input type="text" id="inputUsername" name="username" class="form-control" placeholder="账户" required autofocus>
+        <label for="inputUsername">账户</label>
+    </div>
+    <div class="form-label-group">
+        <input type="password" id="inputPassword" name="password" class="form-control" placeholder="密码" required>
+        <label for="inputPassword">密码</label>
+    </div>
+    <div class="checkbox mb-3">
+        <label>
+            <input type="checkbox" checked name="remember-me" value="remember-me"> 记住用户
+        </label>
+    </div>
+    <button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
+</form>
+</body>
+</html>

BIN
applications/device/device-client/src/main/winserver/deviceclient.exe


+ 14 - 0
applications/device/device-client/src/main/winserver/deviceclient.xml

@@ -0,0 +1,14 @@
+<service>
+    <id>deviceclient</id>
+    <name>device client</name>
+    <description>client server for smart school platform</description>
+    <!-- java环境变量 -->
+    <env name="JAVA_HOME" value="%JAVA_HOME%"/>
+    <executable>java</executable>
+    <arguments>-jar "E:\springboot\ test.jar"</arguments>
+    <!-- 开机启动 -->
+    <startmode>Automatic</startmode>
+    <!-- 日志配置 -->
+    <logpath>%BASE%\log</logpath>
+    <logmode>rotate</logmode>
+</service>

+ 20 - 0
applications/device/device-core/pom.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>device</artifactId>
+        <groupId>com.usoftchina.smartschool</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>device-core</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 105 - 0
applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/base/Result.java

@@ -0,0 +1,105 @@
+package com.usoftchina.smartschool.device.base;
+
+import java.io.Serializable;
+
+/**
+ * 结果
+ *
+ * @author yingp
+ * @date 2018/9/29
+ */
+public class Result<T> implements Serializable {
+    /**
+     * 是否成功
+     */
+    private boolean success;
+    /**
+     * 错误码
+     */
+    private int code;
+    /**
+     * 错误消息
+     */
+    private String message;
+    /**
+     * 结果
+     */
+    private T data;
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public static Result success() {
+        Result result = new Result();
+        result.setSuccess(true);
+        return result;
+    }
+
+    public static <T> Result success(T data) {
+        Result<T> result = success();
+        result.setData(data);
+        return result;
+    }
+
+    public static Result error() {
+        Result result = new Result();
+        result.setSuccess(false);
+        return result;
+    }
+
+    public static Result error(String message) {
+        Result result = error();
+        result.setMessage(message);
+        return result;
+    }
+
+    public static Result error(Result from) {
+        Result result = error();
+        result.setCode(from.getCode());
+        result.setMessage(from.getMessage());
+        return result;
+    }
+
+    public static Result error(int code, String message) {
+        Result result = error();
+        result.setCode(code);
+        result.setMessage(message);
+        return result;
+    }
+
+    public static Result error(int code, String message, Object... args) {
+        Result result = error();
+        result.setCode(code);
+        result.setMessage(String.format(message, args));
+        return result;
+    }
+}

+ 41 - 0
applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/context/SpringContextHolder.java

@@ -0,0 +1,41 @@
+package com.usoftchina.smartschool.device.context;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.util.Assert;
+
+import java.util.Locale;
+
+/**
+ * @author yingp
+ * @date 2019/3/11
+ */
+public class SpringContextHolder {
+    private static ApplicationContext context;
+
+    /**
+     * spring context 刷新的时候执行
+     *
+     * @param context
+     */
+    public static void setContext(ApplicationContext context) {
+        SpringContextHolder.context = context;
+    }
+
+    public static ApplicationContext getContext() {
+        Assert.notNull(context, "spring context not ready");
+        return context;
+    }
+
+    public static String getMessage(String code) {
+        return getMessage(code, new Object[]{});
+    }
+
+    public static String getMessage(String code, Object[] args) {
+        return getMessage(code, args, Locale.getDefault());
+    }
+
+    public static String getMessage(String code, Object[] args, Locale locale) {
+        Assert.notNull(context, "spring context not ready");
+        return context.getMessage(code, args, locale);
+    }
+}

+ 15 - 0
applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/context/SpringContextListener.java

@@ -0,0 +1,15 @@
+package com.usoftchina.smartschool.device.context;
+
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+
+/**
+ * @author yingp
+ * @date 2018/7/18
+ */
+public class SpringContextListener implements ApplicationListener<ContextRefreshedEvent> {
+    @Override
+    public void onApplicationEvent(ContextRefreshedEvent event) {
+        SpringContextHolder.setContext(event.getApplicationContext());
+    }
+}

+ 23 - 0
applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/BaseException.java

@@ -0,0 +1,23 @@
+package com.usoftchina.smartschool.device.exception;
+
+/**
+ * 异常接口
+ *
+ * @author yingp
+ * @date 2018/9/29
+ */
+public interface BaseException {
+    /**
+     * 异常信息
+     *
+     * @return
+     */
+    String getMessage();
+
+    /**
+     * 异常编码
+     *
+     * @return
+     */
+    int getCode();
+}

+ 21 - 0
applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/BaseExceptionCode.java

@@ -0,0 +1,21 @@
+package com.usoftchina.smartschool.device.exception;
+
+/**
+ * @author yingp
+ * @date 2018/9/30
+ */
+public interface BaseExceptionCode {
+    /**
+     * 异常编码
+     *
+     * @return
+     */
+    int getCode();
+
+    /**
+     * 异常信息
+     *
+     * @return
+     */
+    String getMessage();
+}

+ 42 - 0
applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/BaseUncheckedException.java

@@ -0,0 +1,42 @@
+package com.usoftchina.smartschool.device.exception;
+
+/**
+ * 非检查型异常
+ *
+ * @author yingp
+ * @date 2018/9/29
+ */
+public abstract class BaseUncheckedException extends RuntimeException implements BaseException {
+    /**
+     * 异常信息
+     */
+    protected String message;
+
+    /**
+     * 异常编码
+     */
+    protected int code;
+
+    public BaseUncheckedException(int code, String message) {
+        super(message);
+        this.code = code;
+        this.message = message;
+    }
+
+    public BaseUncheckedException(int code, String message, Object... args) {
+        super(String.format(message, args));
+        this.code = code;
+        this.message = String.format(message, args);
+    }
+
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    @Override
+    public int getCode() {
+        return code;
+    }
+}

+ 33 - 0
applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/BizException.java

@@ -0,0 +1,33 @@
+package com.usoftchina.smartschool.device.exception;
+
+/**
+ * 业务异常
+ *
+ * @author yingp
+ * @date 2018/9/29
+ */
+public class BizException extends BaseUncheckedException {
+
+    public BizException(int code, String message) {
+        super(code, message);
+    }
+
+    public BizException(BaseExceptionCode code) {
+        super(code.getCode(), code.getMessage());
+    }
+
+    public BizException(int code, String message, Object... args) {
+        super(code, String.format(message, args));
+        this.code = code;
+        this.message = String.format(message, args);
+    }
+
+    public static BizException wrap(int code, String message, Object... args) {
+        return new BizException(code, message, args);
+    }
+
+    @Override
+    public String toString() {
+        return "BizException [message=" + message + ", code=" + code + "]";
+    }
+}

+ 52 - 0
applications/device/device-core/src/main/java/com/usoftchina/smartschool/device/exception/ExceptionCode.java

@@ -0,0 +1,52 @@
+package com.usoftchina.smartschool.device.exception;
+
+import com.usoftchina.smartschool.device.context.SpringContextHolder;
+import org.springframework.util.StringUtils;
+
+/**
+ * @author yingp
+ * @date 2018/9/30
+ */
+public enum ExceptionCode implements BaseExceptionCode {
+
+    ERROR_UNKNOWN(500),
+    ERROR_IP_PORT_EXIST(501);
+
+    private int code;
+
+    ExceptionCode(int code) {
+        this.code = code;
+    }
+
+    @Override
+    public int getCode() {
+        return code;
+    }
+
+    /**
+     * 配置到多语言包的异常
+     *
+     * @return
+     */
+    @Override
+    public String getMessage() {
+        return SpringContextHolder.getMessage(name());
+    }
+
+    /**
+     * 触发该异常
+     */
+    public void occur() {
+        throw new BizException(this);
+    }
+
+    /**
+     * 触发该异常,并指定额外的错误信息
+     */
+    public void occur(String message) {
+        if (StringUtils.isEmpty(message)) {
+            message = getMessage();
+        }
+        throw new BizException(code, message);
+    }
+}

+ 3 - 0
applications/device/device-core/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,3 @@
+# Application Listeners
+org.springframework.context.ApplicationListener=\
+com.usoftchina.smartschool.device.context.SpringContextListener

+ 2 - 0
applications/device/device-core/src/main/resources/message_zh_CN.properties

@@ -0,0 +1,2 @@
+ERROR_UNKNOWN=\u672a\u77e5\u5f02\u5e38
+ERROR_IP_PORT_EXIST=IP\u548c\u7aef\u53e3\u5df2\u5b58\u5728

+ 9 - 1
applications/device/device-sdk-dahua/pom.xml

@@ -23,7 +23,15 @@
         </dependency>
         <dependency>
             <groupId>com.usoftchina.smartschool</groupId>
-            <artifactId>core</artifactId>
+            <artifactId>device-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
         </dependency>
     </dependencies>
 </project>

+ 1 - 1
applications/device/device-sdk-dahua/src/main/java/com/usoftchina/smartschool/device/dahua/lib/DahuaSdk.java

@@ -3,7 +3,7 @@ package com.usoftchina.smartschool.device.dahua.lib;
 import com.sun.jna.Native;
 import com.sun.jna.NativeLong;
 import com.sun.jna.Platform;
-import com.usoftchina.smartschool.context.SpringContextHolder;
+import com.usoftchina.smartschool.device.context.SpringContextHolder;
 import com.usoftchina.smartschool.device.dahua.config.DahuaProperties;
 import com.usoftchina.smartschool.device.dahua.lib.DahuaLibrary.*;
 import com.usoftchina.smartschool.device.dto.DeviceId;

+ 1 - 1
applications/device/device-sdk-dahua/src/main/java/com/usoftchina/smartschool/device/dahua/service/DahuaDataAnalyzeService.java

@@ -3,7 +3,7 @@ package com.usoftchina.smartschool.device.dahua.service;
 import com.sun.jna.NativeLong;
 import com.sun.jna.Pointer;
 
-import com.usoftchina.smartschool.context.SpringContextHolder;
+import com.usoftchina.smartschool.device.context.SpringContextHolder;
 import com.usoftchina.smartschool.device.dahua.lib.DahuaEvents;
 import com.usoftchina.smartschool.device.dahua.lib.DahuaLibrary.*;
 import com.usoftchina.smartschool.device.dahua.lib.DahuaSdk;

+ 12 - 0
applications/device/device-sdk/src/main/java/com/usoftchina/smartschool/device/dto/AccessControlInfo.java

@@ -1,6 +1,7 @@
 package com.usoftchina.smartschool.device.dto;
 
 import java.io.Serializable;
+import java.util.Arrays;
 import java.util.Date;
 
 /**
@@ -75,6 +76,17 @@ public class AccessControlInfo implements Serializable {
         this.openMethod = openMethod;
     }
 
+    @Override
+    public String toString() {
+        return "AccessControlInfo{" +
+                "eventTime=" + eventTime +
+                ", eventType=" + eventType +
+                ", cardNo='" + cardNo + '\'' +
+                ", imageData=" + Arrays.toString(imageData) +
+                ", openMethod=" + openMethod +
+                '}';
+    }
+
     /**
      * 事件类型
      */

+ 28 - 49
applications/device/device-sdk/src/main/java/com/usoftchina/smartschool/device/dto/DeviceInfo.java

@@ -1,58 +1,37 @@
 package com.usoftchina.smartschool.device.dto;
 
-import java.io.Serializable;
-
 /**
  * 设备信息
  *
  * @author yingp
  * @date 2019/3/8
  */
-public class DeviceInfo implements Serializable {
-    private String ip;
-    private int port;
-    private String username;
-    private String password;
-
-    public DeviceInfo() {
-    }
-
-    public DeviceInfo(String ip, int port, String username, String password) {
-        this.ip = ip;
-        this.port = port;
-        this.username = username;
-        this.password = password;
-    }
-
-    public String getIp() {
-        return ip;
-    }
-
-    public void setIp(String ip) {
-        this.ip = ip;
-    }
-
-    public int getPort() {
-        return port;
-    }
-
-    public void setPort(int port) {
-        this.port = port;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
+public interface DeviceInfo {
+    /**
+     * ip
+     *
+     * @return
+     */
+    String getIp();
+
+    /**
+     * port
+     *
+     * @return
+     */
+    int getPort();
+
+    /**
+     * username
+     *
+     * @return
+     */
+    String getUsername();
+
+    /**
+     * password
+     *
+     * @return
+     */
+    String getPassword();
 }

+ 3 - 0
applications/device/pom.xml

@@ -16,6 +16,9 @@
         <module>device-sdk-dahua</module>
         <module>device-server</module>
         <module>device-sdk</module>
+        <module>device-client</module>
+        <module>device-api</module>
+        <module>device-core</module>
     </modules>
 
 </project>

+ 5 - 0
pom.xml

@@ -268,6 +268,11 @@
                 <artifactId>file-dto</artifactId>
                 <version>${project.release.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.usoftchina.smartschool</groupId>
+                <artifactId>device-core</artifactId>
+                <version>${project.release.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.usoftchina.smartschool</groupId>
                 <artifactId>device-sdk</artifactId>

Деякі файли не було показано, через те що забагато файлів було змінено